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(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=function(e,t){return t===undefined&&(t="undefined"!=typeof window?require("jquery"):require("jquery")(e)),a(t)}:a(window.jQuery)}(function(Z){Z.extend(Z.FE.POPUP_TEMPLATES,{"table.insert":"[_BUTTONS_][_ROWS_COLUMNS_]","table.edit":"[_BUTTONS_]","table.colors":"[_BUTTONS_][_COLORS_][_CUSTOM_COLOR_]"}),Z.extend(Z.FE.DEFAULTS,{tableInsertMaxSize:10,tableEditButtons:["tableHeader","tableRemove","|","tableRows","tableColumns","tableStyle","-","tableCells","tableCellBackground","tableCellVerticalAlign","tableCellHorizontalAlign","tableCellStyle"],tableInsertButtons:["tableBack","|"],tableResizer:!0,tableDefaultWidth:"100%",tableResizerOffset:5,tableResizingLimit:30,tableColorsButtons:["tableBack","|"],tableColors:["#61BD6D","#1ABC9C","#54ACD2","#2C82C9","#9365B8","#475577","#CCCCCC","#41A85F","#00A885","#3D8EB9","#2969B0","#553982","#28324E","#000000","#F7DA64","#FBA026","#EB6B56","#E25041","#A38F84","#EFEFEF","#FFFFFF","#FAC51C","#F37934","#D14841","#B8312F","#7C706B","#D1D5D8","REMOVE"],tableColorsStep:7,tableCellStyles:{"fr-highlighted":"Highlighted","fr-thick":"Thick"},tableStyles:{"fr-dashed-borders":"Dashed Borders","fr-alternate-rows":"Alternate Rows"},tableCellMultipleStyles:!0,tableMultipleStyles:!0,tableInsertHelper:!0,tableInsertHelperOffset:15}),Z.FE.PLUGINS.table=function(E){var C,o,s,r,l,n,w;function h(){var e=O();if(e){var t=E.popups.get("table.edit");if(t||(t=p()),t){E.popups.setContainer("table.edit",E.$sc);var a=_(e),l=(a.left+a.right)/2,s=a.bottom;E.popups.show("table.edit",l,s,a.bottom-a.top),E.edit.isDisabled()&&(1<J().length&&E.toolbar.disable(),E.$el.removeClass("fr-no-selection"),E.edit.on(),E.button.bulkRefresh(),E.selection.setAtEnd(E.$el.find(".fr-selected-cell:last").get(0)),E.selection.restore())}}}function f(){var e,t,a,l,s=O();if(s){var r=E.popups.get("table.colors");r||(r=function(){var e="";0<E.opts.tableColorsButtons.length&&(e='<div class="fr-buttons fr-table-colors-buttons">'+E.button.buildList(E.opts.tableColorsButtons)+"</div>");var t="";E.opts.colorsHEXInput&&(t='<div class="fr-table-colors-hex-layer fr-active fr-layer" id="fr-table-colors-hex-layer-'+E.id+'"><div class="fr-input-line"><input maxlength="7" id="fr-table-colors-hex-layer-text-'+E.id+'" type="text" placeholder="'+E.language.translate("HEX Color")+'" tabIndex="1" aria-required="true"></div><div class="fr-action-buttons"><button type="button" class="fr-command fr-submit" data-cmd="tableCellBackgroundCustomColor" tabIndex="2" role="button">'+E.language.translate("OK")+"</button></div></div>");var a={buttons:e,colors:function(){for(var e='<div class="fr-table-colors">',t=0;t<E.opts.tableColors.length;t++)0!==t&&t%E.opts.tableColorsStep==0&&(e+="<br>"),"REMOVE"!=E.opts.tableColors[t]?e+='<span class="fr-command" style="background: '+E.opts.tableColors[t]+';" tabIndex="-1" role="button" data-cmd="tableCellBackgroundColor" data-param1="'+E.opts.tableColors[t]+'"><span class="fr-sr-only">'+E.language.translate("Color")+" "+E.opts.tableColors[t]+"&nbsp;&nbsp;&nbsp;</span></span>":e+='<span class="fr-command" data-cmd="tableCellBackgroundColor" tabIndex="-1" role="button" data-param1="REMOVE" title="'+E.language.translate("Clear Formatting")+'">'+E.icon.create("tableColorRemove")+'<span class="fr-sr-only">'+E.language.translate("Clear Formatting")+"</span></span>";return e+="</div>"}(),custom_color:t},l=E.popups.create("table.colors",a);return E.events.$on(E.$wp,"scroll.table-colors",function(){E.popups.isVisible("table.colors")&&f()}),u=l,E.events.on("popup.tab",function(e){var t=Z(e.currentTarget);if(!E.popups.isVisible("table.colors")||!t.is("span"))return!0;var a=e.which,l=!0;if(Z.FE.KEYCODE.TAB==a){var s=u.find(".fr-buttons");l=!E.accessibility.focusToolbar(s,!!e.shiftKey)}else if(Z.FE.KEYCODE.ARROW_UP==a||Z.FE.KEYCODE.ARROW_DOWN==a||Z.FE.KEYCODE.ARROW_LEFT==a||Z.FE.KEYCODE.ARROW_RIGHT==a){var r=t.parent().find("span.fr-command"),n=r.index(t),o=E.opts.colorsStep,i=Math.floor(r.length/o),f=n%o,c=Math.floor(n/o),d=c*o+f,p=i*o;Z.FE.KEYCODE.ARROW_UP==a?d=((d-o)%p+p)%p:Z.FE.KEYCODE.ARROW_DOWN==a?d=(d+o)%p:Z.FE.KEYCODE.ARROW_LEFT==a?d=((d-1)%p+p)%p:Z.FE.KEYCODE.ARROW_RIGHT==a&&(d=(d+1)%p);var h=Z(r.get(d));E.events.disableBlur(),h.focus(),l=!1}else Z.FE.KEYCODE.ENTER==a&&(E.button.exec(t),l=!1);return!1===l&&(e.preventDefault(),e.stopPropagation()),l},!0),l;var u}()),E.popups.setContainer("table.colors",E.$sc);var n=_(s),o=(n.left+n.right)/2,i=n.bottom;e=E.popups.get("table.colors"),t=E.$el.find(".fr-selected-cell:first"),a=E.helpers.RGBToHex(t.css("background-color")),l=e.find(".fr-table-colors-hex-layer input"),e.find(".fr-selected-color").removeClass("fr-selected-color fr-active-item"),e.find('span[data-param1="'+a+'"]').addClass("fr-selected-color fr-active-item"),l.val(a).trigger("change"),E.popups.show("table.colors",o,i,n.bottom-n.top)}}function i(){0===J().length&&E.toolbar.enable()}function c(e){if(e)return E.popups.onHide("table.insert",function(){E.popups.get("table.insert").find('.fr-table-size .fr-select-table-size > span[data-row="1"][data-col="1"]').trigger("mouseenter")}),!0;var t="";0<E.opts.tableInsertButtons.length&&(t='<div class="fr-buttons">'+E.button.buildList(E.opts.tableInsertButtons)+"</div>");var a,l={buttons:t,rows_columns:function(){for(var e='<div class="fr-table-size"><div class="fr-table-size-info">1 &times; 1</div><div class="fr-select-table-size">',t=1;t<=E.opts.tableInsertMaxSize;t++){for(var a=1;a<=E.opts.tableInsertMaxSize;a++){var l="inline-block";2<t&&!E.helpers.isMobile()&&(l="none");var s="fr-table-cell ";1==t&&1==a&&(s+=" hover"),e+='<span class="fr-command '+s+'" tabIndex="-1" data-cmd="tableInsert" data-row="'+t+'" data-col="'+a+'" data-param1="'+t+'" data-param2="'+a+'" style="display: '+l+';" role="button"><span></span><span class="fr-sr-only">'+t+" &times; "+a+"&nbsp;&nbsp;&nbsp;</span></span>"}e+='<div class="new-line"></div>'}return e+="</div></div>"}()},s=E.popups.create("table.insert",l);return E.events.$on(s,"mouseenter",".fr-table-size .fr-select-table-size .fr-table-cell",function(e){d(Z(e.currentTarget))},!0),a=s,E.events.$on(a,"focus","[tabIndex]",function(e){var t=Z(e.currentTarget);d(t)}),E.events.on("popup.tab",function(e){var t=Z(e.currentTarget);if(!E.popups.isVisible("table.insert")||!t.is("span, a"))return!0;var a,l=e.which;if(Z.FE.KEYCODE.ARROW_UP==l||Z.FE.KEYCODE.ARROW_DOWN==l||Z.FE.KEYCODE.ARROW_LEFT==l||Z.FE.KEYCODE.ARROW_RIGHT==l){if(t.is("span.fr-table-cell")){var s=t.parent().find("span.fr-table-cell"),r=s.index(t),n=E.opts.tableInsertMaxSize,o=r%n,i=Math.floor(r/n);Z.FE.KEYCODE.ARROW_UP==l?i=Math.max(0,i-1):Z.FE.KEYCODE.ARROW_DOWN==l?i=Math.min(E.opts.tableInsertMaxSize-1,i+1):Z.FE.KEYCODE.ARROW_LEFT==l?o=Math.max(0,o-1):Z.FE.KEYCODE.ARROW_RIGHT==l&&(o=Math.min(E.opts.tableInsertMaxSize-1,o+1));var f=i*n+o,c=Z(s.get(f));d(c),E.events.disableBlur(),c.focus(),a=!1}}else Z.FE.KEYCODE.ENTER==l&&(E.button.exec(t),a=!1);return!1===a&&(e.preventDefault(),e.stopPropagation()),a},!0),s}function d(e){var t=e.data("row"),a=e.data("col"),l=e.parent();l.siblings(".fr-table-size-info").html(t+" &times; "+a),l.find("> span").removeClass("hover fr-active-item");for(var s=1;s<=E.opts.tableInsertMaxSize;s++)for(var r=0;r<=E.opts.tableInsertMaxSize;r++){var n=l.find('> span[data-row="'+s+'"][data-col="'+r+'"]');s<=t&&r<=a?n.addClass("hover"):s<=t+1||s<=2&&!E.helpers.isMobile()?n.css("display","inline-block"):2<s&&!E.helpers.isMobile()&&n.css("display","none")}e.addClass("fr-active-item")}function p(e){if(e)return E.popups.onHide("table.edit",i),!0;if(0<E.opts.tableEditButtons.length){var t={buttons:'<div class="fr-buttons">'+E.button.buildList(E.opts.tableEditButtons)+"</div>"},a=E.popups.create("table.edit",t);return E.events.$on(E.$wp,"scroll.table-edit",function(){E.popups.isVisible("table.edit")&&h()}),a}return!1}function u(){if(0<J().length){var e=Q();E.selection.setBefore(e.get(0))||E.selection.setAfter(e.get(0)),E.selection.restore(),E.popups.hide("table.edit"),e.remove(),E.toolbar.enable()}}function b(e){var t=Q();if(0<t.length){if(0<E.$el.find("th.fr-selected-cell").length&&"above"==e)return;var a,l,s,r=O(),n=$(r);l="above"==e?n.min_i:n.max_i;var o="<tr>";for(a=0;a<r[l].length;a++)if("below"==e&&l<r.length-1&&r[l][a]==r[l+1][a]||"above"==e&&0<l&&r[l][a]==r[l-1][a]){if(0===a||0<a&&r[l][a]!=r[l][a-1]){var i=Z(r[l][a]);i.attr("rowspan",parseInt(i.attr("rowspan"),10)+1)}}else o+="<td><br></td>";o+="</tr>",s=0<E.$el.find("th.fr-selected-cell").length&&"below"==e?Z(t.find("tbody").not(t.find("table tbody"))):Z(t.find("tr").not(t.find("table tr")).get(l)),"below"==e?"TBODY"==s.prop("tagName")?s.prepend(o):s.after(o):"above"==e&&(s.before(o),E.popups.isVisible("table.edit")&&h())}}function g(e,t,a){var l,s,r,n,o,i=0,f=O(a);if(e<(t=Math.min(t,f[0].length-1)))for(s=e;s<=t;s++)if(!(e<s&&f[0][s]==f[0][s-1])&&1<(n=Math.min(parseInt(f[0][s].getAttribute("colspan"),10)||1,t-e+1))&&f[0][s]==f[0][s+1])for(i=n-1,l=1;l<f.length;l++)if(f[l][s]!=f[l-1][s]){for(r=s;r<s+n;r++)if(1<(o=parseInt(f[l][r].getAttribute("colspan"),10)||1)&&f[l][r]==f[l][r+1])r+=i=Math.min(i,o-1);else if(!(i=Math.max(0,i-1)))break;if(!i)break}i&&v(f,i,"colspan",0,f.length-1,e,t)}function m(e,t,a){var l,s,r,n,o,i=0,f=O(a);if(e<(t=Math.min(t,f.length-1)))for(l=e;l<=t;l++)if(!(e<l&&f[l][0]==f[l-1][0])&&1<(n=Math.min(parseInt(f[l][0].getAttribute("rowspan"),10)||1,t-e+1))&&f[l][0]==f[l+1][0])for(i=n-1,s=1;s<f[0].length;s++)if(f[l][s]!=f[l][s-1]){for(r=l;r<l+n;r++)if(1<(o=parseInt(f[r][s].getAttribute("rowspan"),10)||1)&&f[r][s]==f[r+1][s])r+=i=Math.min(i,o-1);else if(!(i=Math.max(0,i-1)))break;if(!i)break}i&&v(f,i,"rowspan",e,t,0,f[0].length-1)}function v(e,t,a,l,s,r,n){var o,i,f;for(o=l;o<=s;o++)for(i=r;i<=n;i++)l<o&&e[o][i]==e[o-1][i]||r<i&&e[o][i]==e[o][i-1]||1<(f=parseInt(e[o][i].getAttribute(a),10)||1)&&(1<f-t?e[o][i].setAttribute(a,f-t):e[o][i].removeAttribute(a))}function R(e,t,a,l,s){m(e,t,s),g(a,l,s)}function t(e){var t=E.$el.find(".fr-selected-cell");"REMOVE"!=e?t.css("background-color",E.helpers.HEXtoRGB(e)):t.css("background-color",""),h()}function O(e){var f=[];return null==(e=e||null)&&0<J().length&&(e=Q()),e&&e.find("tr").not(e.find("table tr")).each(function(o,e){var t=Z(e),i=0;t.find("> th, > td").each(function(e,t){for(var a=Z(t),l=parseInt(a.attr("colspan"),10)||1,s=parseInt(a.attr("rowspan"),10)||1,r=o;r<o+s;r++)for(var n=i;n<i+l;n++)f[r]||(f[r]=[]),f[r][n]?i++:f[r][n]=t;i+=l})}),f}function A(e,t){for(var a=0;a<t.length;a++)for(var l=0;l<t[a].length;l++)if(t[a][l]==e)return{row:a,col:l}}function F(e,t,a){for(var l=e+1,s=t+1;l<a.length;){if(a[l][t]!=a[e][t]){l--;break}l++}for(l==a.length&&l--;s<a[e].length;){if(a[e][s]!=a[e][t]){s--;break}s++}return s==a[e].length&&s--,{row:l,col:s}}function x(){E.el.querySelector(".fr-cell-fixed")&&E.el.querySelector(".fr-cell-fixed").classList.remove("fr-cell-fixed"),E.el.querySelector(".fr-cell-handler")&&E.el.querySelector(".fr-cell-handler").classList.remove("fr-cell-handler")}function D(){var e=E.$el.find(".fr-selected-cell");0<e.length&&e.each(function(){var e=Z(this);e.removeClass("fr-selected-cell"),""===e.attr("class")&&e.removeAttr("class")}),x()}function y(){E.events.disableBlur(),E.selection.clear(),E.$el.addClass("fr-no-selection"),E.$el.blur(),E.events.enableBlur()}function $(e){var t=E.$el.find(".fr-selected-cell");if(0<t.length){var a,l=e.length,s=0,r=e[0].length,n=0;for(a=0;a<t.length;a++){var o=A(t[a],e),i=F(o.row,o.col,e);l=Math.min(o.row,l),s=Math.max(i.row,s),r=Math.min(o.col,r),n=Math.max(i.col,n)}return{min_i:l,max_i:s,min_j:r,max_j:n}}return null}function _(e){var t=$(e),a=Z(e[t.min_i][t.min_j]),l=Z(e[t.min_i][t.max_j]),s=Z(e[t.max_i][t.min_j]);return{left:a.offset().left,right:l.offset().left+l.outerWidth(),top:a.offset().top,bottom:s.offset().top+s.outerHeight()}}function M(t,a){if(Z(t).is(a))D(),Z(t).addClass("fr-selected-cell");else{y(),E.edit.off();var l=O(),s=A(t,l),r=A(a,l),n=function e(t,a,l,s,r){var n,o,i,f,c=t,d=a,p=l,h=s;for(n=c;n<=d;n++)(1<(parseInt(Z(r[n][p]).attr("rowspan"),10)||1)||1<(parseInt(Z(r[n][p]).attr("colspan"),10)||1))&&(f=F((i=A(r[n][p],r)).row,i.col,r),c=Math.min(i.row,c),d=Math.max(f.row,d),p=Math.min(i.col,p),h=Math.max(f.col,h)),(1<(parseInt(Z(r[n][h]).attr("rowspan"),10)||1)||1<(parseInt(Z(r[n][h]).attr("colspan"),10)||1))&&(f=F((i=A(r[n][h],r)).row,i.col,r),c=Math.min(i.row,c),d=Math.max(f.row,d),p=Math.min(i.col,p),h=Math.max(f.col,h));for(o=p;o<=h;o++)(1<(parseInt(Z(r[c][o]).attr("rowspan"),10)||1)||1<(parseInt(Z(r[c][o]).attr("colspan"),10)||1))&&(f=F((i=A(r[c][o],r)).row,i.col,r),c=Math.min(i.row,c),d=Math.max(f.row,d),p=Math.min(i.col,p),h=Math.max(f.col,h)),(1<(parseInt(Z(r[d][o]).attr("rowspan"),10)||1)||1<(parseInt(Z(r[d][o]).attr("colspan"),10)||1))&&(f=F((i=A(r[d][o],r)).row,i.col,r),c=Math.min(i.row,c),d=Math.max(f.row,d),p=Math.min(i.col,p),h=Math.max(f.col,h));return c==t&&d==a&&p==l&&h==s?{min_i:t,max_i:a,min_j:l,max_j:s}:e(c,d,p,h,r)}(Math.min(s.row,r.row),Math.max(s.row,r.row),Math.min(s.col,r.col),Math.max(s.col,r.col),l);D(),t.classList.add("fr-cell-fixed"),a.classList.add("fr-cell-handler");for(var o=n.min_i;o<=n.max_i;o++)for(var i=n.min_j;i<=n.max_j;i++)Z(l[o][i]).addClass("fr-selected-cell")}}function I(e){var t=null,a=Z(e.target);return"TD"==e.target.tagName||"TH"==e.target.tagName?t=e.target:0<a.closest("td").length?t=a.closest("td").get(0):0<a.closest("th").length&&(t=a.closest("th").get(0)),0===E.$el.find(t).length?null:t}function T(){D(),E.popups.hide("table.edit")}function e(e){var t=I(e);if("false"==Z(t).parents("[contenteditable]:not(.fr-element):not(.fr-img-caption):not(body):first").attr("contenteditable"))return!0;if(0<J().length&&!t&&T(),!E.edit.isDisabled()||E.popups.isVisible("table.edit"))if(1!=e.which||1==e.which&&E.helpers.isMac()&&e.ctrlKey)(3==e.which||1==e.which&&E.helpers.isMac()&&e.ctrlKey)&&t&&T();else if(r=!0,t){0<J().length&&!e.shiftKey&&T(),e.stopPropagation(),E.events.trigger("image.hideResizer"),E.events.trigger("video.hideResizer"),s=!0;var a=t.tagName.toLowerCase();e.shiftKey&&0<E.$el.find(a+".fr-selected-cell").length?Z(E.$el.find(a+".fr-selected-cell").closest("table")).is(Z(t).closest("table"))?M(l,t):y():((E.keys.ctrlKey(e)||e.shiftKey)&&(1<J().length||0===Z(t).find(E.selection.element()).length&&!Z(t).is(E.selection.element()))&&y(),M(l=t,l))}}function a(e){if(s||E.$tb.is(e.target)||E.$tb.is(Z(e.target).closest(E.$tb.get(0)))||(0<J().length&&E.toolbar.enable(),D()),!(1!=e.which||1==e.which&&E.helpers.isMac()&&e.ctrlKey)){if(r=!1,s)s=!1,I(e)||1!=J().length?0<J().length&&(E.selection.isCollapsed()?h():D()):D();if(w){w=!1,C.removeClass("fr-moving"),E.$el.removeClass("fr-no-selection"),E.edit.on();var t=parseFloat(C.css("left"))+E.opts.tableResizerOffset+E.$wp.offset().left;E.opts.iframe&&(t-=E.$iframe.offset().left),C.data("release-position",t),C.removeData("max-left"),C.removeData("max-right"),function(){var e=C.data("origin"),t=C.data("release-position");if(e!==t){var a=C.data("first"),l=C.data("second"),s=C.data("table"),r=s.outerWidth();if(E.undo.canDo()||E.undo.saveStep(),null!==a&&null!==l){var n,o,i,f=O(s),c=[],d=[],p=[],h=[];for(n=0;n<f.length;n++)o=Z(f[n][a]),i=Z(f[n][l]),c[n]=o.outerWidth(),p[n]=i.outerWidth(),d[n]=c[n]/r*100,h[n]=p[n]/r*100;for(n=0;n<f.length;n++){o=Z(f[n][a]),i=Z(f[n][l]);var u=(d[n]*(c[n]+t-e)/c[n]).toFixed(4);o.css("width",u+"%"),i.css("width",(d[n]+h[n]-u).toFixed(4)+"%")}}else{var b,g=s.parent(),m=r/g.width()*100,v=(parseInt(s.css("margin-left"),10)||0)/g.width()*100,w=(parseInt(s.css("margin-right"),10)||0)/g.width()*100;"rtl"==E.opts.direction&&0===l||"rtl"!=E.opts.direction&&0!==l?(b=(r+t-e)/r*m,s.css("margin-right","calc(100% - "+Math.round(b).toFixed(4)+"% - "+Math.round(v).toFixed(4)+"%)")):("rtl"==E.opts.direction&&0!==l||"rtl"!=E.opts.direction&&0===l)&&(b=(r-t+e)/r*m,s.css("margin-left","calc(100% - "+Math.round(b).toFixed(4)+"% - "+Math.round(w).toFixed(4)+"%)")),s.css("width",Math.round(b).toFixed(4)+"%")}E.selection.restore(),E.undo.saveStep()}C.removeData("origin"),C.removeData("release-position"),C.removeData("first"),C.removeData("second"),C.removeData("table")}(),B()}}}function N(e){if(!0===s){if(Z(e.currentTarget).closest("table").is(Q())){if("TD"==e.currentTarget.tagName&&0===E.$el.find("th.fr-selected-cell").length)return void M(l,e.currentTarget);if("TH"==e.currentTarget.tagName&&0===E.$el.find("td.fr-selected-cell").length)return void M(l,e.currentTarget)}y()}}function S(e,t,a,l){for(var s,r=t;r!=E.el&&"TD"!=r.tagName&&"TH"!=r.tagName&&("up"==l?s=r.previousElementSibling:"down"==l&&(s=r.nextElementSibling),!s);)r=r.parentNode;"TD"==r.tagName||"TH"==r.tagName?function(e,t){for(var a=e;a&&"TABLE"!=a.tagName&&a.parentNode!=E.el;)a=a.parentNode;if(a&&"TABLE"==a.tagName){var l=O(Z(a));"up"==t?z(A(e,l),a,l):"down"==t&&W(A(e,l),a,l)}}(r,l):s&&("up"==l&&E.selection.setAtEnd(s),"down"==l&&E.selection.setAtStart(s))}function z(e,t,a){0<e.row?E.selection.setAtEnd(a[e.row-1][e.col]):S(0,t,0,"up")}function W(e,t,a){var l=parseInt(a[e.row][e.col].getAttribute("rowspan"),10)||1;e.row<a.length-l?E.selection.setAtStart(a[e.row+l][e.col]):S(0,t,0,"down")}function B(){C&&(C.find("div").css("opacity",0),C.css("top",0),C.css("left",0),C.css("height",0),C.find("div").css("height",0),C.hide())}function k(){o&&o.removeClass("fr-visible").css("left","-9999px")}function K(e,t){var a=Z(t),l=a.closest("table"),s=l.parent();if(t&&"TD"!=t.tagName&&"TH"!=t.tagName&&(0<a.closest("td").length?t=a.closest("td"):0<a.closest("th").length&&(t=a.closest("th"))),!t||"TD"!=t.tagName&&"TH"!=t.tagName)C&&a.get(0)!=C.get(0)&&a.parent().get(0)!=C.get(0)&&E.core.sameInstance(C)&&B();else{if(a=Z(t),0===E.$el.find(a).length)return!1;var r=a.offset().left-1,n=r+a.outerWidth();if(Math.abs(e.pageX-r)<=E.opts.tableResizerOffset||Math.abs(n-e.pageX)<=E.opts.tableResizerOffset){var o,i,f,c,d,p=O(l),h=A(t,p),u=F(h.row,h.col,p),b=l.offset().top,g=l.outerHeight()-1;"rtl"!=E.opts.direction?e.pageX-r<=E.opts.tableResizerOffset?(f=r,0<h.col?(c=r-j(h.col-1,p)+E.opts.tableResizingLimit,d=r+j(h.col,p)-E.opts.tableResizingLimit,o=h.col-1,i=h.col):(o=null,i=0,c=l.offset().left-1-parseInt(l.css("margin-left"),10),d=l.offset().left-1+l.width()-p[0].length*E.opts.tableResizingLimit)):n-e.pageX<=E.opts.tableResizerOffset&&(f=n,u.col<p[u.row].length&&p[u.row][u.col+1]?(c=n-j(u.col,p)+E.opts.tableResizingLimit,d=n+j(u.col+1,p)-E.opts.tableResizingLimit,o=u.col,i=u.col+1):(o=u.col,i=null,c=l.offset().left-1+p[0].length*E.opts.tableResizingLimit,d=s.offset().left-1+s.width()+parseFloat(s.css("padding-left")))):n-e.pageX<=E.opts.tableResizerOffset?(f=n,0<h.col?(c=n-j(h.col,p)+E.opts.tableResizingLimit,d=n+j(h.col-1,p)-E.opts.tableResizingLimit,o=h.col,i=h.col-1):(o=null,i=0,c=l.offset().left+p[0].length*E.opts.tableResizingLimit,d=s.offset().left-1+s.width()+parseFloat(s.css("padding-left")))):e.pageX-r<=E.opts.tableResizerOffset&&(f=r,u.col<p[u.row].length&&p[u.row][u.col+1]?(c=r-j(u.col+1,p)+E.opts.tableResizingLimit,d=r+j(u.col,p)-E.opts.tableResizingLimit,o=u.col+1,i=u.col):(o=u.col,i=null,c=s.offset().left+parseFloat(s.css("padding-left")),d=l.offset().left-1+l.width()-p[0].length*E.opts.tableResizingLimit)),C||(E.shared.$table_resizer||(E.shared.$table_resizer=Z('<div class="fr-table-resizer"><div></div></div>')),C=E.shared.$table_resizer,E.events.$on(C,"mousedown",function(e){return!E.core.sameInstance(C)||(0<J().length&&T(),1==e.which?(E.selection.save(),w=!0,C.addClass("fr-moving"),y(),E.edit.off(),C.find("div").css("opacity",1),!1):void 0)}),E.events.$on(C,"mousemove",function(e){if(!E.core.sameInstance(C))return!0;w&&(E.opts.iframe&&(e.pageX-=E.$iframe.offset().left),X(e))}),E.events.on("shared.destroy",function(){C.html("").removeData().remove(),C=null},!0),E.events.on("destroy",function(){E.$el.find(".fr-selected-cell").removeClass("fr-selected-cell"),C.hide().appendTo(Z("body:first"))},!0)),C.data("table",l),C.data("first",o),C.data("second",i),C.data("instance",E),E.$wp.append(C);var m=f-E.win.pageXOffset-E.opts.tableResizerOffset-E.$wp.offset().left,v=b-E.$wp.offset().top+E.$wp.scrollTop();E.opts.iframe&&(m+=E.$iframe.offset().left,v+=E.$iframe.offset().top,c+=E.$iframe.offset().left,d+=E.$iframe.offset().left),C.data("max-left",c),C.data("max-right",d),C.data("origin",f-E.win.pageXOffset),C.css("top",v),C.css("left",m),C.css("height",g),C.find("div").css("height",g),C.css("padding-left",E.opts.tableResizerOffset),C.css("padding-right",E.opts.tableResizerOffset),C.show()}else E.core.sameInstance(C)&&B()}}function L(e,t){if(E.$box.find(".fr-line-breaker").is(":visible"))return!1;o||q(),E.$box.append(o),o.data("instance",E);var a,l=Z(t).find("tr:first"),s=e.pageX,r=0,n=0;E.opts.iframe&&(r+=E.$iframe.offset().left-E.helpers.scrollLeft(),n+=E.$iframe.offset().top-E.helpers.scrollTop()),l.find("th, td").each(function(){var e=Z(this);return e.offset().left<=s&&s<e.offset().left+e.outerWidth()/2?(a=parseInt(o.find("a").css("width"),10),o.css("top",n+e.offset().top-E.$box.offset().top-E.win.pageYOffset-a-5),o.css("left",r+e.offset().left-E.$box.offset().left-E.win.pageXOffset-a/2),o.data("selected-cell",e),o.data("position","before"),o.addClass("fr-visible"),!1):e.offset().left+e.outerWidth()/2<=s&&s<e.offset().left+e.outerWidth()?(a=parseInt(o.find("a").css("width"),10),o.css("top",n+e.offset().top-E.$box.offset().top-E.win.pageYOffset-a-5),o.css("left",r+e.offset().left-E.$box.offset().left+e.outerWidth()-E.win.pageXOffset-a/2),o.data("selected-cell",e),o.data("position","after"),o.addClass("fr-visible"),!1):void 0})}function H(e,t){if(E.$box.find(".fr-line-breaker").is(":visible"))return!1;o||q(),E.$box.append(o),o.data("instance",E);var a,l=Z(t),s=e.pageY,r=0,n=0;E.opts.iframe&&(r+=E.$iframe.offset().left-E.helpers.scrollLeft(),n+=E.$iframe.offset().top-E.helpers.scrollTop()),l.find("tr").each(function(){var e=Z(this);return e.offset().top<=s&&s<e.offset().top+e.outerHeight()/2?(a=parseInt(o.find("a").css("width"),10),o.css("top",n+e.offset().top-E.$box.offset().top-E.win.pageYOffset-a/2),o.css("left",r+e.offset().left-E.$box.offset().left-E.win.pageXOffset-a-5),o.data("selected-cell",e.find("td:first")),o.data("position","above"),o.addClass("fr-visible"),!1):e.offset().top+e.outerHeight()/2<=s&&s<e.offset().top+e.outerHeight()?(a=parseInt(o.find("a").css("width"),10),o.css("top",n+e.offset().top-E.$box.offset().top+e.outerHeight()-E.win.pageYOffset-a/2),o.css("left",r+e.offset().left-E.$box.offset().left-E.win.pageXOffset-a-5),o.data("selected-cell",e.find("td:first")),o.data("position","below"),o.addClass("fr-visible"),!1):void 0})}function Y(e){n=null;var t=E.doc.elementFromPoint(e.pageX-E.win.pageXOffset,e.pageY-E.win.pageYOffset);E.opts.tableResizer&&(!E.popups.areVisible()||E.popups.areVisible()&&E.popups.isVisible("table.edit"))&&K(e,t),!E.opts.tableInsertHelper||E.popups.areVisible()||E.$tb.hasClass("fr-inline")&&E.$tb.is(":visible")||function(e,t){if(0===J().length){var a,l,s;if(t&&("HTML"==t.tagName||"BODY"==t.tagName||E.node.isElement(t)))for(a=1;a<=E.opts.tableInsertHelperOffset;a++){if(l=E.doc.elementFromPoint(e.pageX-E.win.pageXOffset,e.pageY-E.win.pageYOffset+a),Z(l).hasClass("fr-tooltip"))return;if(l&&("TH"==l.tagName||"TD"==l.tagName||"TABLE"==l.tagName)&&(Z(l).parents(".fr-wrapper").length||E.opts.iframe))return L(e,Z(l).closest("table"));if(s=E.doc.elementFromPoint(e.pageX-E.win.pageXOffset+a,e.pageY-E.win.pageYOffset),Z(s).hasClass("fr-tooltip"))return;if(s&&("TH"==s.tagName||"TD"==s.tagName||"TABLE"==s.tagName)&&(Z(s).parents(".fr-wrapper").length||E.opts.iframe))return H(e,Z(s).closest("table"))}E.core.sameInstance(o)&&k()}}(e,t)}function P(){if(w){var e=C.data("table").offset().top-E.win.pageYOffset;E.opts.iframe&&(e+=E.$iframe.offset().top-E.helpers.scrollTop()),C.css("top",e)}}function j(e,t){var a,l=Z(t[0][e]).outerWidth();for(a=1;a<t.length;a++)l=Math.min(l,Z(t[a][e]).outerWidth());return l}function V(e,t,a){var l,s=0;for(l=e;l<=t;l++)s+=j(l,a);return s}function X(e){if(1<J().length&&r&&y(),!1===r&&!1===s&&!1===w)n&&clearTimeout(n),E.edit.isDisabled()&&!E.popups.isVisible("table.edit")||(n=setTimeout(Y,30,e));else if(w){var t=e.pageX-E.win.pageXOffset;E.opts.iframe&&(t+=E.$iframe.offset().left);var a=C.data("max-left"),l=C.data("max-right");a<=t&&t<=l?C.css("left",t-E.opts.tableResizerOffset-E.$wp.offset().left):t<a&&parseFloat(C.css("left"),10)>a-E.opts.tableResizerOffset?C.css("left",a-E.opts.tableResizerOffset-E.$wp.offset().left):l<t&&parseFloat(C.css("left"),10)<l-E.opts.tableResizerOffset&&C.css("left",l-E.opts.tableResizerOffset-E.$wp.offset().left)}else r&&k()}function U(e){E.node.isEmpty(e.get(0))?e.prepend(Z.FE.MARKERS):e.prepend(Z.FE.START_MARKER).append(Z.FE.END_MARKER)}function q(){E.shared.$ti_helper||(E.shared.$ti_helper=Z('<div class="fr-insert-helper"><a class="fr-floating-btn" role="button" tabIndex="-1" title="'+E.language.translate("Insert")+'"><svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><path d="M22,16.75 L16.75,16.75 L16.75,22 L15.25,22.000 L15.25,16.75 L10,16.75 L10,15.25 L15.25,15.25 L15.25,10 L16.75,10 L16.75,15.25 L22,15.25 L22,16.75 Z"/></svg></a></div>'),E.events.bindClick(E.shared.$ti_helper,"a",function(){var e=o.data("selected-cell"),t=o.data("position"),a=o.data("instance")||E;"before"==t?(E.undo.saveStep(),e.addClass("fr-selected-cell"),a.table.insertColumn(t),e.removeClass("fr-selected-cell"),E.undo.saveStep()):"after"==t?(E.undo.saveStep(),e.addClass("fr-selected-cell"),a.table.insertColumn(t),e.removeClass("fr-selected-cell"),E.undo.saveStep()):"above"==t?(E.undo.saveStep(),e.addClass("fr-selected-cell"),a.table.insertRow(t),e.removeClass("fr-selected-cell"),E.undo.saveStep()):"below"==t&&(E.undo.saveStep(),e.addClass("fr-selected-cell"),a.table.insertRow(t),e.removeClass("fr-selected-cell"),E.undo.saveStep()),k()}),E.events.on("shared.destroy",function(){E.shared.$ti_helper.html("").removeData().remove(),E.shared.$ti_helper=null},!0),E.events.$on(E.shared.$ti_helper,"mousemove",function(e){e.stopPropagation()},!0),E.events.$on(Z(E.o_win),"scroll",function(){k()},!0),E.events.$on(E.$wp,"scroll",function(){k()},!0)),o=E.shared.$ti_helper,E.events.on("destroy",function(){o=null}),E.tooltip.bind(E.$box,".fr-insert-helper > a.fr-floating-btn")}function G(){l=null,clearTimeout(n)}function J(){return E.el.querySelectorAll(".fr-selected-cell")}function Q(){var e=J();if(e.length){for(var t=e[0];t&&"TABLE"!=t.tagName&&t.parentNode!=E.el;)t=t.parentNode;return t&&"TABLE"==t.tagName?Z(t):Z([])}return Z([])}return{_init:function(){if(!E.$wp)return!1;if(!E.helpers.isMobile()){w=s=r=!1,E.events.$on(E.$el,"mousedown",e),E.popups.onShow("image.edit",function(){D(),s=r=!1}),E.popups.onShow("link.edit",function(){D(),s=r=!1}),E.events.on("commands.mousedown",function(e){0<e.parents(".fr-toolbar").length&&D()}),E.events.$on(E.$el,"mouseenter","th, td",N),E.events.$on(E.$win,"mouseup",a),E.opts.iframe&&E.events.$on(Z(E.o_win),"mouseup",a),E.events.$on(E.$win,"mousemove",X),E.events.$on(Z(E.o_win),"scroll",P),E.events.on("contentChanged",function(){0<J().length&&(h(),E.$el.find("img").on("load.selected-cells",function(){Z(this).off("load.selected-cells"),0<J().length&&h()}))}),E.events.$on(Z(E.o_win),"resize",function(){D()}),E.events.on("toolbar.esc",function(){if(0<J().length)return E.events.disableBlur(),E.events.focus(),!1},!0),E.events.$on(Z(E.o_win),"keydown",function(){r&&s&&(s=r=!1,E.$el.removeClass("fr-no-selection"),E.edit.on(),E.selection.setAtEnd(E.$el.find(".fr-selected-cell:last").get(0)),E.selection.restore(),D())}),E.events.$on(E.$el,"keydown",function(e){e.shiftKey?!1===function(e){var t=J();if(0<t.length){var a,l,s=O(),r=e.which;1==t.length?l=a=t[0]:(a=E.el.querySelector(".fr-cell-fixed"),l=E.el.querySelector(".fr-cell-handler"));var n=A(l,s);if(Z.FE.KEYCODE.ARROW_RIGHT==r){if(n.col<s[0].length-1)return M(a,s[n.row][n.col+1]),!1}else if(Z.FE.KEYCODE.ARROW_DOWN==r){if(n.row<s.length-1)return M(a,s[n.row+1][n.col]),!1}else if(Z.FE.KEYCODE.ARROW_LEFT==r){if(0<n.col)return M(a,s[n.row][n.col-1]),!1}else if(Z.FE.KEYCODE.ARROW_UP==r&&0<n.row)return M(a,s[n.row-1][n.col]),!1}}(e)&&setTimeout(function(){h()},0):function(e){var t=e.which,a=E.selection.blocks();if(a.length&&("TD"==(a=a[0]).tagName||"TH"==a.tagName)){for(var l=a;l&&"TABLE"!=l.tagName&&l.parentNode!=E.el;)l=l.parentNode;if(l&&"TABLE"==l.tagName&&(Z.FE.KEYCODE.ARROW_LEFT==t||Z.FE.KEYCODE.ARROW_UP==t||Z.FE.KEYCODE.ARROW_RIGHT==t||Z.FE.KEYCODE.ARROW_DOWN==t)&&(0<J().length&&T(),E.browser.webkit&&(Z.FE.KEYCODE.ARROW_UP==t||Z.FE.KEYCODE.ARROW_DOWN==t))){var s=E.selection.ranges(0).startContainer;if(s.nodeType==Node.TEXT_NODE&&(Z.FE.KEYCODE.ARROW_UP==t&&s.previousSibling||Z.FE.KEYCODE.ARROW_DOWN==t&&s.nextSibling))return;e.preventDefault(),e.stopPropagation();var r=O(Z(l)),n=A(a,r);Z.FE.KEYCODE.ARROW_UP==t?z(n,l,r):Z.FE.KEYCODE.ARROW_DOWN==t&&W(n,l,r),E.selection.restore()}}}(e)}),E.events.on("keydown",function(e){if(!1===function(e){if(e.which==Z.FE.KEYCODE.TAB){var t;if(0<J().length)t=E.$el.find(".fr-selected-cell:last");else{var a=E.selection.element();"TD"==a.tagName||"TH"==a.tagName?t=Z(a):a!=E.el&&(0<Z(a).parentsUntil(E.$el,"td").length?t=Z(a).parents("td:first"):0<Z(a).parentsUntil(E.$el,"th").length&&(t=Z(a).parents("th:first")))}if(t)return e.preventDefault(),!!(0<Z(E.selection.element()).parentsUntil(E.$el,"ol, ul").length&&(0<Z(E.selection.element()).parents("li").prev().length||Z(E.selection.element()).is("li")&&0<Z(E.selection.element()).prev().length))||(T(),e.shiftKey?0<t.prev().length?U(t.prev()):0<t.closest("tr").length&&0<t.closest("tr").prev().length?U(t.closest("tr").prev().find("td:last")):0<t.closest("tbody").length&&0<t.closest("table").find("thead tr").length&&U(t.closest("table").find("thead tr th:last")):0<t.next().length?U(t.next()):0<t.closest("tr").length&&0<t.closest("tr").next().length?U(t.closest("tr").next().find("td:first")):0<t.closest("thead").length&&0<t.closest("table").find("tbody tr").length?U(t.closest("table").find("tbody tr td:first")):(t.addClass("fr-selected-cell"),b("below"),D(),U(t.closest("tr").next().find("td:first"))),E.selection.restore(),!1)}}(e))return!1;var t=J();if(0<t.length){if(0<t.length&&E.keys.ctrlKey(e)&&e.which==Z.FE.KEYCODE.A)return D(),E.popups.isVisible("table.edit")&&E.popups.hide("table.edit"),t=[],!0;if(e.which==Z.FE.KEYCODE.ESC&&E.popups.isVisible("table.edit"))return D(),E.popups.hide("table.edit"),e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),!(t=[]);if(1<t.length&&(e.which==Z.FE.KEYCODE.BACKSPACE||e.which==Z.FE.KEYCODE.DELETE)){E.undo.saveStep();for(var a=0;a<t.length;a++)Z(t[a]).html("<br>"),a==t.length-1&&Z(t[a]).prepend(Z.FE.MARKERS);return E.selection.restore(),E.undo.saveStep(),!(t=[])}if(1<t.length&&e.which!=Z.FE.KEYCODE.F10&&!E.keys.isBrowserAction(e))return e.preventDefault(),!(t=[])}else if(!(t=[])===function(e){if(e.altKey&&e.which==Z.FE.KEYCODE.SPACE){var t,a=E.selection.element();if("TD"==a.tagName||"TH"==a.tagName?t=a:0<Z(a).closest("td").length?t=Z(a).closest("td").get(0):0<Z(a).closest("th").length&&(t=Z(a).closest("th").get(0)),t)return e.preventDefault(),M(t,t),h(),!1}}(e))return!1},!0);var t=[];E.events.on("html.beforeGet",function(){t=J();for(var e=0;e<t.length;e++)t[e].className=(t[e].className||"").replace(/fr-selected-cell/g,"")}),E.events.on("html.afterGet",function(){for(var e=0;e<t.length;e++)t[e].className=(t[e].className?t[e].className.trim()+" ":"")+"fr-selected-cell";t=[]}),c(!0),p(!0)}E.events.on("destroy",G)},insert:function(e,t){var a,l,s="<table "+(E.opts.tableDefaultWidth?'style="width: '+E.opts.tableDefaultWidth+';" ':"")+'class="fr-inserted-table"><tbody>',r=100/t;for(a=0;a<e;a++){for(s+="<tr>",l=0;l<t;l++)s+="<td"+(E.opts.tableDefaultWidth?' style="width: '+r.toFixed(4)+'%;"':"")+">",0===a&&0===l&&(s+=Z.FE.MARKERS),s+="<br></td>";s+="</tr>"}s+="</tbody></table>",E.html.insert(s),E.selection.restore();var n=E.$el.find(".fr-inserted-table");n.removeClass("fr-inserted-table"),E.events.trigger("table.inserted",[n.get(0)])},remove:u,insertRow:b,deleteRow:function(){var e=Q();if(0<e.length){var t,a,l,s=O(),r=$(s);if(0===r.min_i&&r.max_i==s.length-1)u();else{for(t=r.max_i;t>=r.min_i;t--){for(l=Z(e.find("tr").not(e.find("table tr")).get(t)),a=0;a<s[t].length;a++)if(0===a||s[t][a]!=s[t][a-1]){var n=Z(s[t][a]);if(1<parseInt(n.attr("rowspan"),10)){var o=parseInt(n.attr("rowspan"),10)-1;1==o?n.removeAttr("rowspan"):n.attr("rowspan",o)}if(t<s.length-1&&s[t][a]==s[t+1][a]&&(0===t||s[t][a]!=s[t-1][a])){for(var i=s[t][a],f=a;0<f&&s[t][f]==s[t][f-1];)f--;0===f?Z(e.find("tr").not(e.find("table tr")).get(t+1)).prepend(i):Z(s[t+1][f-1]).after(i)}}var c=l.parent();l.remove(),0===c.find("tr").length&&c.remove(),s=O(e)}R(0,s.length-1,0,s[0].length-1,e),0<r.min_i?E.selection.setAtEnd(s[r.min_i-1][0]):E.selection.setAtEnd(s[0][0]),E.selection.restore(),E.popups.hide("table.edit")}}},insertColumn:function(i){var e=Q();if(0<e.length){var f,c=O(),t=$(c);f="before"==i?t.min_j:t.max_j;var a,d=100/c[0].length,p=100/(c[0].length+1);e.find("th, td").each(function(){(a=Z(this)).data("old-width",a.outerWidth()/e.outerWidth()*100)}),e.find("tr").not(e.find("table tr")).each(function(e){for(var t,a=Z(this),l=0,s=0;l-1<f;){if(!(t=a.find("> th, > td").get(s))){t=null;break}t==c[e][l]?(l+=parseInt(Z(t).attr("colspan"),10)||1,s++):(l+=parseInt(Z(c[e][l]).attr("colspan"),10)||1,"after"==i&&(t=0===s?-1:a.find("> th, > td").get(s-1)))}var r,n=Z(t);if("after"==i&&f<l-1||"before"==i&&0<f&&c[e][f]==c[e][f-1]){if(0===e||0<e&&c[e][f]!=c[e-1][f]){var o=parseInt(n.attr("colspan"),10)+1;n.attr("colspan",o),n.css("width",(n.data("old-width")*p/d+p).toFixed(4)+"%"),n.removeData("old-width")}}else r=0<a.find("th").length?'<th style="width: '+p.toFixed(4)+'%;"><br></th>':'<td style="width: '+p.toFixed(4)+'%;"><br></td>',-1==t?a.prepend(r):null==t?a.append(r):"before"==i?n.before(r):"after"==i&&n.after(r)}),e.find("th, td").each(function(){(a=Z(this)).data("old-width")&&(a.css("width",(a.data("old-width")*p/d).toFixed(4)+"%"),a.removeData("old-width"))}),E.popups.isVisible("table.edit")&&h()}},deleteColumn:function(){var e=Q();if(0<e.length){var t,a,l,s=O(),r=$(s);if(0===r.min_j&&r.max_j==s[0].length-1)u();else{var n=0;for(t=0;t<s.length;t++)for(a=0;a<s[0].length;a++)(l=Z(s[t][a])).hasClass("fr-selected-cell")||(l.data("old-width",l.outerWidth()/e.outerWidth()*100),(a<r.min_j||a>r.max_j)&&(n+=l.outerWidth()/e.outerWidth()*100));for(n/=s.length,a=r.max_j;a>=r.min_j;a--)for(t=0;t<s.length;t++)if(0===t||s[t][a]!=s[t-1][a])if(l=Z(s[t][a]),1<(parseInt(l.attr("colspan"),10)||1)){var o=parseInt(l.attr("colspan"),10)-1;1==o?l.removeAttr("colspan"):l.attr("colspan",o),l.css("width",(100*(l.data("old-width")-j(a,s))/n).toFixed(4)+"%"),l.removeData("old-width")}else{var i=Z(l.parent().get(0));l.remove(),0===i.find("> th, > td").length&&(0===i.prev().length||0===i.next().length||i.prev().find("> th[rowspan], > td[rowspan]").length<i.prev().find("> th, > td").length)&&i.remove()}R(0,s.length-1,0,s[0].length-1,e),0<r.min_j?E.selection.setAtEnd(s[r.min_i][r.min_j-1]):E.selection.setAtEnd(s[r.min_i][0]),E.selection.restore(),E.popups.hide("table.edit"),e.find("th, td").each(function(){(l=Z(this)).data("old-width")&&(l.css("width",(100*l.data("old-width")/n).toFixed(4)+"%"),l.removeData("old-width"))})}}},mergeCells:function(){if(1<J().length&&(0===E.$el.find("th.fr-selected-cell").length||0===E.$el.find("td.fr-selected-cell").length)){x();var e,t,a=$(O()),l=E.$el.find(".fr-selected-cell"),s=Z(l[0]),r=s.parent().find(".fr-selected-cell"),n=s.closest("table"),o=s.html(),i=0;for(e=0;e<r.length;e++)i+=Z(r[e]).outerWidth();for(s.css("width",(i/n.outerWidth()*100).toFixed(4)+"%"),a.min_j<a.max_j&&s.attr("colspan",a.max_j-a.min_j+1),a.min_i<a.max_i&&s.attr("rowspan",a.max_i-a.min_i+1),e=1;e<l.length;e++)"<br>"!=(t=Z(l[e])).html()&&""!==t.html()&&(o+="<br>"+t.html()),t.remove();s.html(o),E.selection.setAtEnd(s.get(0)),E.selection.restore(),E.toolbar.enable(),m(a.min_i,a.max_i,n);var f=n.find("tr:empty");for(e=f.length-1;0<=e;e--)Z(f[e]).remove();g(a.min_j,a.max_j,n),h()}},splitCellVertically:function(){if(1==J().length){var e=E.$el.find(".fr-selected-cell"),t=parseInt(e.attr("colspan"),10)||1,a=e.parent().outerWidth(),l=e.outerWidth(),s=e.clone().html("<br>"),r=O(),n=A(e.get(0),r);if(1<t){var o=Math.ceil(t/2);l=V(n.col,n.col+o-1,r)/a*100;var i=V(n.col+o,n.col+t-1,r)/a*100;1<o?e.attr("colspan",o):e.removeAttr("colspan"),1<t-o?s.attr("colspan",t-o):s.removeAttr("colspan"),e.css("width",l.toFixed(4)+"%"),s.css("width",i.toFixed(4)+"%")}else{var f;for(f=0;f<r.length;f++)if(0===f||r[f][n.col]!=r[f-1][n.col]){var c=Z(r[f][n.col]);if(!c.is(e)){var d=(parseInt(c.attr("colspan"),10)||1)+1;c.attr("colspan",d)}}l=l/a*100/2,e.css("width",l.toFixed(4)+"%"),s.css("width",l.toFixed(4)+"%")}e.after(s),D(),E.popups.hide("table.edit")}},splitCellHorizontally:function(){if(1==J().length){var e=E.$el.find(".fr-selected-cell"),t=e.parent(),a=e.closest("table"),l=parseInt(e.attr("rowspan"),10),s=O(),r=A(e.get(0),s),n=e.clone().html("<br>");if(1<l){var o=Math.ceil(l/2);1<o?e.attr("rowspan",o):e.removeAttr("rowspan"),1<l-o?n.attr("rowspan",l-o):n.removeAttr("rowspan");for(var i=r.row+o,f=0===r.col?r.col:r.col-1;0<=f&&(s[i][f]==s[i][f-1]||0<i&&s[i][f]==s[i-1][f]);)f--;-1==f?Z(a.find("tr").not(a.find("table tr")).get(i)).prepend(n):Z(s[i][f]).after(n)}else{var c,d=Z("<tr>").append(n);for(c=0;c<s[0].length;c++)if(0===c||s[r.row][c]!=s[r.row][c-1]){var p=Z(s[r.row][c]);p.is(e)||p.attr("rowspan",(parseInt(p.attr("rowspan"),10)||1)+1)}t.after(d)}D(),E.popups.hide("table.edit")}},addHeader:function(){var e=Q();if(0<e.length&&0===e.find("th").length){var t,a="<thead><tr>",l=0;for(e.find("tr:first > td").each(function(){var e=Z(this);l+=parseInt(e.attr("colspan"),10)||1}),t=0;t<l;t++)a+="<th><br></th>";a+="</tr></thead>",e.prepend(a),h()}},removeHeader:function(){var e=Q(),t=e.find("thead");if(0<t.length)if(0===e.find("tbody tr").length)u();else if(t.remove(),0<J().length)h();else{E.popups.hide("table.edit");var a=e.find("tbody tr:first td:first").get(0);a&&(E.selection.setAtEnd(a),E.selection.restore())}},setBackground:t,showInsertPopup:function(){var e=E.$tb.find('.fr-command[data-cmd="insertTable"]'),t=E.popups.get("table.insert");if(t||(t=c()),!t.hasClass("fr-active")){E.popups.refresh("table.insert"),E.popups.setContainer("table.insert",E.$tb);var a=e.offset().left+e.outerWidth()/2,l=e.offset().top+(E.opts.toolbarBottom?10:e.outerHeight()-10);E.popups.show("table.insert",a,l,e.outerHeight())}},showEditPopup:h,showColorsPopup:f,back:function(){0<J().length?h():(E.popups.hide("table.insert"),E.toolbar.showInline())},verticalAlign:function(e){E.$el.find(".fr-selected-cell").css("vertical-align",e)},horizontalAlign:function(e){E.$el.find(".fr-selected-cell").css("text-align",e)},applyStyle:function(e,t,a,l){if(0<t.length){if(!a){var s=Object.keys(l);s.splice(s.indexOf(e),1),t.removeClass(s.join(" "))}t.toggleClass(e)}},selectedTable:Q,selectedCells:J,customColor:function(){var e=E.popups.get("table.colors").find(".fr-table-colors-hex-layer input");e.length&&t(e.val())}}},Z.FE.DefineIcon("insertTable",{NAME:"table"}),Z.FE.RegisterCommand("insertTable",{title:"Insert Table",undo:!1,focus:!0,refreshOnCallback:!1,popup:!0,callback:function(){this.popups.isVisible("table.insert")?(this.$el.find(".fr-marker").length&&(this.events.disableBlur(),this.selection.restore()),this.popups.hide("table.insert")):this.table.showInsertPopup()},plugin:"table"}),Z.FE.RegisterCommand("tableInsert",{callback:function(e,t,a){this.table.insert(t,a),this.popups.hide("table.insert")}}),Z.FE.DefineIcon("tableHeader",{NAME:"header",FA5NAME:"heading"}),Z.FE.RegisterCommand("tableHeader",{title:"Table Header",focus:!1,toggle:!0,callback:function(){this.popups.get("table.edit").find('.fr-command[data-cmd="tableHeader"]').hasClass("fr-active")?this.table.removeHeader():this.table.addHeader()},refresh:function(e){var t=this.table.selectedTable();0<t.length&&(0===t.find("th").length?e.removeClass("fr-active").attr("aria-pressed",!1):e.addClass("fr-active").attr("aria-pressed",!0))}}),Z.FE.DefineIcon("tableRows",{NAME:"bars"}),Z.FE.RegisterCommand("tableRows",{type:"dropdown",focus:!1,title:"Row",options:{above:"Insert row above",below:"Insert row below","delete":"Delete row"},html:function(){var e='<ul class="fr-dropdown-list" role="presentation">',t=Z.FE.COMMANDS.tableRows.options;for(var a in t)t.hasOwnProperty(a)&&(e+='<li role="presentation"><a class="fr-command" tabIndex="-1" role="option" data-cmd="tableRows" data-param1="'+a+'" title="'+this.language.translate(t[a])+'">'+this.language.translate(t[a])+"</a></li>");return e+="</ul>"},callback:function(e,t){"above"==t||"below"==t?this.table.insertRow(t):this.table.deleteRow()}}),Z.FE.DefineIcon("tableColumns",{NAME:"bars fa-rotate-90"}),Z.FE.RegisterCommand("tableColumns",{type:"dropdown",focus:!1,title:"Column",options:{before:"Insert column before",after:"Insert column after","delete":"Delete column"},html:function(){var e='<ul class="fr-dropdown-list" role="presentation">',t=Z.FE.COMMANDS.tableColumns.options;for(var a in t)t.hasOwnProperty(a)&&(e+='<li role="presentation"><a class="fr-command" tabIndex="-1" role="option" data-cmd="tableColumns" data-param1="'+a+'" title="'+this.language.translate(t[a])+'">'+this.language.translate(t[a])+"</a></li>");return e+="</ul>"},callback:function(e,t){"before"==t||"after"==t?this.table.insertColumn(t):this.table.deleteColumn()}}),Z.FE.DefineIcon("tableCells",{NAME:"square-o",FA5NAME:"square"}),Z.FE.RegisterCommand("tableCells",{type:"dropdown",focus:!1,title:"Cell",options:{merge:"Merge cells","vertical-split":"Vertical split","horizontal-split":"Horizontal split"},html:function(){var e='<ul class="fr-dropdown-list" role="presentation">',t=Z.FE.COMMANDS.tableCells.options;for(var a in t)t.hasOwnProperty(a)&&(e+='<li role="presentation"><a class="fr-command" tabIndex="-1" role="option" data-cmd="tableCells" data-param1="'+a+'" title="'+this.language.translate(t[a])+'">'+this.language.translate(t[a])+"</a></li>");return e+="</ul>"},callback:function(e,t){"merge"==t?this.table.mergeCells():"vertical-split"==t?this.table.splitCellVertically():this.table.splitCellHorizontally()},refreshOnShow:function(e,t){1<this.$el.find(".fr-selected-cell").length?(t.find('a[data-param1="vertical-split"]').addClass("fr-disabled").attr("aria-disabled",!0),t.find('a[data-param1="horizontal-split"]').addClass("fr-disabled").attr("aria-disabled",!0),t.find('a[data-param1="merge"]').removeClass("fr-disabled").attr("aria-disabled",!1)):(t.find('a[data-param1="merge"]').addClass("fr-disabled").attr("aria-disabled",!0),t.find('a[data-param1="vertical-split"]').removeClass("fr-disabled").attr("aria-disabled",!1),t.find('a[data-param1="horizontal-split"]').removeClass("fr-disabled").attr("aria-disabled",!1))}}),Z.FE.DefineIcon("tableRemove",{NAME:"trash"}),Z.FE.RegisterCommand("tableRemove",{title:"Remove Table",focus:!1,callback:function(){this.table.remove()}}),Z.FE.DefineIcon("tableStyle",{NAME:"paint-brush"}),Z.FE.RegisterCommand("tableStyle",{title:"Table Style",type:"dropdown",focus:!1,html:function(){var e='<ul class="fr-dropdown-list" role="presentation">',t=this.opts.tableStyles;for(var a in t)t.hasOwnProperty(a)&&(e+='<li role="presentation"><a class="fr-command" tabIndex="-1" role="option" data-cmd="tableStyle" data-param1="'+a+'" title="'+this.language.translate(t[a])+'">'+this.language.translate(t[a])+"</a></li>");return e+="</ul>"},callback:function(e,t){this.table.applyStyle(t,this.$el.find(".fr-selected-cell").closest("table"),this.opts.tableMultipleStyles,this.opts.tableStyles)},refreshOnShow:function(e,t){var a=this.$el.find(".fr-selected-cell").closest("table");a&&t.find(".fr-command").each(function(){var e=Z(this).data("param1"),t=a.hasClass(e);Z(this).toggleClass("fr-active",t).attr("aria-selected",t)})}}),Z.FE.DefineIcon("tableCellBackground",{NAME:"tint"}),Z.FE.RegisterCommand("tableCellBackground",{title:"Cell Background",focus:!1,popup:!0,callback:function(){this.table.showColorsPopup()}}),Z.FE.RegisterCommand("tableCellBackgroundColor",{undo:!0,focus:!1,callback:function(e,t){this.table.setBackground(t)}}),Z.FE.DefineIcon("tableBack",{NAME:"arrow-left"}),Z.FE.RegisterCommand("tableBack",{title:"Back",undo:!1,focus:!1,back:!0,callback:function(){this.table.back()},refresh:function(e){0!==this.table.selectedCells().length||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"))}}),Z.FE.DefineIcon("tableCellVerticalAlign",{NAME:"arrows-v",FA5NAME:"arrows-alt-v"}),Z.FE.RegisterCommand("tableCellVerticalAlign",{type:"dropdown",focus:!1,title:"Vertical Align",options:{Top:"Align Top",Middle:"Align Middle",Bottom:"Align Bottom"},html:function(){var e='<ul class="fr-dropdown-list" role="presentation">',t=Z.FE.COMMANDS.tableCellVerticalAlign.options;for(var a in t)t.hasOwnProperty(a)&&(e+='<li role="presentation"><a class="fr-command" tabIndex="-1" role="option" data-cmd="tableCellVerticalAlign" data-param1="'+a.toLowerCase()+'" title="'+this.language.translate(t[a])+'">'+this.language.translate(a)+"</a></li>");return e+="</ul>"},callback:function(e,t){this.table.verticalAlign(t)},refreshOnShow:function(e,t){t.find('.fr-command[data-param1="'+this.$el.find(".fr-selected-cell").css("vertical-align")+'"]').addClass("fr-active").attr("aria-selected",!0)}}),Z.FE.DefineIcon("tableCellHorizontalAlign",{NAME:"align-left"}),Z.FE.DefineIcon("align-left",{NAME:"align-left"}),Z.FE.DefineIcon("align-right",{NAME:"align-right"}),Z.FE.DefineIcon("align-center",{NAME:"align-center"}),Z.FE.DefineIcon("align-justify",{NAME:"align-justify"}),Z.FE.RegisterCommand("tableCellHorizontalAlign",{type:"dropdown",focus:!1,title:"Horizontal Align",options:{left:"Align Left",center:"Align Center",right:"Align Right",justify:"Align Justify"},html:function(){var e='<ul class="fr-dropdown-list" role="presentation">',t=Z.FE.COMMANDS.tableCellHorizontalAlign.options;for(var a in t)t.hasOwnProperty(a)&&(e+='<li role="presentation"><a class="fr-command fr-title" tabIndex="-1" role="option" data-cmd="tableCellHorizontalAlign" data-param1="'+a+'" title="'+this.language.translate(t[a])+'">'+this.icon.create("align-"+a)+'<span class="fr-sr-only">'+this.language.translate(t[a])+"</span></a></li>");return e+="</ul>"},callback:function(e,t){this.table.horizontalAlign(t)},refresh:function(e){var t=this.table.selectedCells();t.length&&e.find("> *:first").replaceWith(this.icon.create("align-"+this.helpers.getAlignment(Z(t[0]))))},refreshOnShow:function(e,t){t.find('.fr-command[data-param1="'+this.helpers.getAlignment(this.$el.find(".fr-selected-cell:first"))+'"]').addClass("fr-active").attr("aria-selected",!0)}}),Z.FE.DefineIcon("tableCellStyle",{NAME:"magic"}),Z.FE.RegisterCommand("tableCellStyle",{title:"Cell Style",type:"dropdown",focus:!1,html:function(){var e='<ul class="fr-dropdown-list" role="presentation">',t=this.opts.tableCellStyles;for(var a in t)t.hasOwnProperty(a)&&(e+='<li role="presentation"><a class="fr-command" tabIndex="-1" role="option" data-cmd="tableCellStyle" data-param1="'+a+'" title="'+this.language.translate(t[a])+'">'+this.language.translate(t[a])+"</a></li>");return e+="</ul>"},callback:function(e,t){this.table.applyStyle(t,this.$el.find(".fr-selected-cell"),this.opts.tableCellMultipleStyles,this.opts.tableCellStyles)},refreshOnShow:function(e,t){var a=this.$el.find(".fr-selected-cell:first");a&&t.find(".fr-command").each(function(){var e=Z(this).data("param1"),t=a.hasClass(e);Z(this).toggleClass("fr-active",t).attr("aria-selected",t)})}}),Z.FE.RegisterCommand("tableCellBackgroundCustomColor",{title:"OK",undo:!0,callback:function(){this.table.customColor()}}),Z.FE.DefineIcon("tableColorRemove",{NAME:"eraser"})});
@@ -0,0 +1,194 @@
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
+ $.FE.URLRegEx = '(^| |\\u00A0)(' + $.FE.LinkRegEx + '|' + '([a-z0-9+-_.]{1,}@[a-z0-9+-_.]{1,}\\.[a-z0-9+-_]{1,})' + ')$';
37
+
38
+ $.FE.PLUGINS.url = function (editor) {
39
+ var rel = null;
40
+
41
+ /*
42
+ * Transform string into a hyperlink.
43
+ */
44
+ function _linkReplaceHandler (match, p1, p2) {
45
+ var dots = '';
46
+
47
+ while (p2.length && p2[p2.length - 1] == '.') {
48
+ dots += '.';
49
+ p2 = p2.substring(0, p2.length - 1);
50
+ }
51
+
52
+ var link = p2;
53
+
54
+ // Convert email.
55
+ if (editor.opts.linkConvertEmailAddress) {
56
+ if (editor.helpers.isEmail(link) && !/^mailto:.*/i.test(link)) {
57
+ link = 'mailto:' + link;
58
+ }
59
+ }
60
+ else if (editor.helpers.isEmail(link)) {
61
+ return p1 + p2;
62
+ }
63
+
64
+ if (!/^((http|https|ftp|ftps|mailto|tel|sms|notes|data)\:)/i.test(link)) {
65
+ link = '//' + link;
66
+ }
67
+
68
+ return (p1 ? p1 : '') + '<a' + (editor.opts.linkAlwaysBlank ? ' target="_blank"' : '') + (rel ? (' rel="' + rel + '"') : '') + ' data-fr-linked="true" href="' + link + '">' + p2.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/&amp;/g, '&').replace(/&/g, '&amp;') + '</a>' + dots;
69
+ }
70
+
71
+ function _getRegEx () {
72
+ return new RegExp($.FE.URLRegEx, 'gi');
73
+ }
74
+
75
+ /*
76
+ * Convert link paterns from html into hyperlinks.
77
+ */
78
+ function _convertToLink (html) {
79
+
80
+ if (editor.opts.linkAlwaysNoFollow) {
81
+ rel = 'nofollow';
82
+ }
83
+
84
+ // https://github.com/froala/wysiwyg-editor/issues/1576.
85
+ if (editor.opts.linkAlwaysBlank) {
86
+ if (editor.opts.linkNoOpener) {
87
+ if (!rel) rel = 'noopener';
88
+ else rel += ' noopener';
89
+ }
90
+
91
+ if (editor.opts.linkNoReferrer) {
92
+ if (!rel) rel = 'noreferrer';
93
+ else rel += ' noreferrer';
94
+ }
95
+ }
96
+
97
+ return html.replace(_getRegEx(), _linkReplaceHandler);
98
+ }
99
+
100
+ function _isA (node) {
101
+ if (!node) return false;
102
+
103
+ if (node.tagName === 'A') return true;
104
+
105
+ if (node.parentNode && node.parentNode != editor.el) return _isA(node.parentNode);
106
+
107
+ return false;
108
+ }
109
+
110
+ function _lastPart(text) {
111
+ var splits = text.split(' ');
112
+
113
+ return splits[splits.length - 1];
114
+ }
115
+
116
+ function _inlineType () {
117
+ var range = editor.selection.ranges(0);
118
+ var node = range.startContainer;
119
+
120
+ if (!node || node.nodeType !== Node.TEXT_NODE) return false;
121
+
122
+ if (_isA(node)) return false;
123
+
124
+ if (_getRegEx().test(_lastPart(node.textContent))) {
125
+ $(node).before(_convertToLink(node.textContent));
126
+
127
+ // Get linked link.
128
+ var $link = $(node.parentNode).find('a[data-fr-linked]');
129
+ $link.removeAttr('data-fr-linked');
130
+
131
+ node.parentNode.removeChild(node);
132
+
133
+ // Trigger link event.
134
+ editor.events.trigger('url.linked', [$link.get(0)]);
135
+ }
136
+ else if (node.textContent.split(' ').length <= 2 && node.previousSibling && node.previousSibling.tagName === 'A') {
137
+ var text = node.previousSibling.innerText + node.textContent;
138
+
139
+ if (_getRegEx().test(_lastPart(text))) {
140
+ $(node.previousSibling).replaceWith(_convertToLink(text));
141
+
142
+ node.parentNode.removeChild(node);
143
+ }
144
+ }
145
+ }
146
+
147
+ /*
148
+ * Initialize.
149
+ */
150
+ function _init () {
151
+ // Handle special keys.
152
+ editor.events.on('keypress', function (e) {
153
+ if (editor.selection.isCollapsed() && (e.key == '.' || e.key == ')' || e.key == '(')) {
154
+ _inlineType();
155
+ }
156
+ }, true);
157
+
158
+ // Handle ENTER and SPACE.
159
+ editor.events.on('keydown', function (e) {
160
+ var keycode = e.which;
161
+
162
+ if (editor.selection.isCollapsed() && (keycode == $.FE.KEYCODE.ENTER || keycode == $.FE.KEYCODE.SPACE)) {
163
+ _inlineType();
164
+ }
165
+ }, true);
166
+
167
+ // Handle pasting.
168
+ editor.events.on('paste.beforeCleanup', function (html) {
169
+ if (editor.helpers.isURL(html)) {
170
+ var rel_attr = null;
171
+
172
+ if (editor.opts.linkAlwaysBlank) {
173
+ if (editor.opts.linkNoOpener) {
174
+ if (!rel_attr) rel_attr = 'noopener';
175
+ else rel_attr += ' noopener';
176
+ }
177
+
178
+ if (editor.opts.linkNoReferrer) {
179
+ if (!rel_attr) rel_attr = 'noreferrer';
180
+ else rel_attr += ' noreferrer';
181
+ }
182
+ }
183
+
184
+ return '<a' + (editor.opts.linkAlwaysBlank ? ' target="_blank"' : '') + (rel_attr ? (' rel="' + rel_attr + '"') : '') + ' href="' + html + '" >' + html + '</a>';
185
+ }
186
+ })
187
+ }
188
+
189
+ return {
190
+ _init: _init
191
+ }
192
+ }
193
+
194
+ }));
@@ -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(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&module.exports?module.exports=function(e,n){return n===undefined&&(n="undefined"!=typeof window?require("jquery"):require("jquery")(e)),t(n)}:t(window.jQuery)}(function(p){p.FE.URLRegEx="(^| |\\u00A0)("+p.FE.LinkRegEx+"|([a-z0-9+-_.]{1,}@[a-z0-9+-_.]{1,}\\.[a-z0-9+-_]{1,}))$",p.FE.PLUGINS.url=function(i){var l=null;function n(e,n,t){for(var r="";t.length&&"."==t[t.length-1];)r+=".",t=t.substring(0,t.length-1);var o=t;if(i.opts.linkConvertEmailAddress)i.helpers.isEmail(o)&&!/^mailto:.*/i.test(o)&&(o="mailto:"+o);else if(i.helpers.isEmail(o))return n+t;return/^((http|https|ftp|ftps|mailto|tel|sms|notes|data)\:)/i.test(o)||(o="//"+o),(n||"")+"<a"+(i.opts.linkAlwaysBlank?' target="_blank"':"")+(l?' rel="'+l+'"':"")+' data-fr-linked="true" href="'+o+'">'+t.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/&amp;/g,"&").replace(/&/g,"&amp;")+"</a>"+r}function o(){return new RegExp(p.FE.URLRegEx,"gi")}function a(e){return i.opts.linkAlwaysNoFollow&&(l="nofollow"),i.opts.linkAlwaysBlank&&(i.opts.linkNoOpener&&(l?l+=" noopener":l="noopener"),i.opts.linkNoReferrer&&(l?l+=" noreferrer":l="noreferrer")),e.replace(o(),n)}function s(e){var n=e.split(" ");return n[n.length-1]}function t(){var n=i.selection.ranges(0).startContainer;if(!n||n.nodeType!==Node.TEXT_NODE)return!1;if(function e(n){return!!n&&("A"===n.tagName||!(!n.parentNode||n.parentNode==i.el)&&e(n.parentNode))}(n))return!1;if(o().test(s(n.textContent))){p(n).before(a(n.textContent));var t=p(n.parentNode).find("a[data-fr-linked]");t.removeAttr("data-fr-linked"),n.parentNode.removeChild(n),i.events.trigger("url.linked",[t.get(0)])}else if(n.textContent.split(" ").length<=2&&n.previousSibling&&"A"===n.previousSibling.tagName){var r=n.previousSibling.innerText+n.textContent;o().test(s(r))&&(p(n.previousSibling).replaceWith(a(r)),n.parentNode.removeChild(n))}}return{_init:function(){i.events.on("keypress",function(e){!i.selection.isCollapsed()||"."!=e.key&&")"!=e.key&&"("!=e.key||t()},!0),i.events.on("keydown",function(e){var n=e.which;!i.selection.isCollapsed()||n!=p.FE.KEYCODE.ENTER&&n!=p.FE.KEYCODE.SPACE||t()},!0),i.events.on("paste.beforeCleanup",function(e){if(i.helpers.isURL(e)){var n=null;return i.opts.linkAlwaysBlank&&(i.opts.linkNoOpener&&(n?n+=" noopener":n="noopener"),i.opts.linkNoReferrer&&(n?n+=" noreferrer":n="noreferrer")),"<a"+(i.opts.linkAlwaysBlank?' target="_blank"':"")+(n?' rel="'+n+'"':"")+' href="'+e+'" >'+e+"</a>"}})}}}});
@@ -0,0 +1,2342 @@
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.POPUP_TEMPLATES, {
37
+ 'video.insert': '[_BUTTONS_][_BY_URL_LAYER_][_EMBED_LAYER_][_UPLOAD_LAYER_][_PROGRESS_BAR_]',
38
+ 'video.edit': '[_BUTTONS_]',
39
+ 'video.size': '[_BUTTONS_][_SIZE_LAYER_]'
40
+ })
41
+
42
+ $.extend($.FE.DEFAULTS, {
43
+ videoAllowedTypes: ['mp4', 'webm', 'ogg'],
44
+ videoAllowedProviders: ['.*'],
45
+ videoDefaultAlign: 'center',
46
+ videoDefaultDisplay: 'block',
47
+ videoDefaultWidth: 600,
48
+ videoEditButtons: ['videoReplace', 'videoRemove', '|', 'videoDisplay', 'videoAlign', 'videoSize'],
49
+ videoInsertButtons: ['videoBack', '|', 'videoByURL', 'videoEmbed', 'videoUpload'],
50
+ videoMaxSize: 50 * 1024 * 1024,
51
+ videoMove: true,
52
+ videoResize: true,
53
+ videoSizeButtons: ['videoBack', '|'],
54
+ videoSplitHTML: false,
55
+ videoTextNear: true,
56
+ videoUpload: true,
57
+ videoUploadMethod: 'POST',
58
+ videoUploadParam: 'file',
59
+ videoUploadParams: {},
60
+ videoUploadToS3: false,
61
+ videoUploadURL: 'https://i.froala.com/upload'
62
+ });
63
+
64
+ $.FE.VIDEO_PROVIDERS = [
65
+ {
66
+ test_regex: /^.*((youtu.be)|(youtube.com))\/((v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))?\??v?=?([^#\&\?]*).*/,
67
+ url_regex: /(?:https?:\/\/)?(?:www\.)?(?:m\.)?(?:youtube\.com|youtu\.be)\/(?:watch\?v=|embed\/)?([0-9a-zA-Z_\-]+)(.+)?/g,
68
+ url_text: 'https://www.youtube.com/embed/$1',
69
+ html: '<iframe width="640" height="360" src="{url}?wmode=opaque" frameborder="0" allowfullscreen></iframe>',
70
+ provider: 'youtube'
71
+ },
72
+ {
73
+ test_regex: /^.*(?:vimeo.com)\/(?:channels(\/\w+\/)?|groups\/*\/videos\/​\d+\/|video\/|)(\d+)(?:$|\/|\?)/,
74
+ url_regex: /(?:https?:\/\/)?(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/(?:[^\/]*)\/videos\/|album\/(?:\d+)\/video\/|video\/|)(\d+)(?:[a-zA-Z0-9_\-]+)?/i,
75
+ url_text: 'https://player.vimeo.com/video/$1',
76
+ html: '<iframe width="640" height="360" src="{url}" frameborder="0" allowfullscreen></iframe>',
77
+ provider: 'vimeo'
78
+ },
79
+ {
80
+ test_regex: /^.+(dailymotion.com|dai.ly)\/(video|hub)?\/?([^_]+)[^#]*(#video=([^_&]+))?/,
81
+ url_regex: /(?:https?:\/\/)?(?:www\.)?(?:dailymotion\.com|dai\.ly)\/(?:video|hub)?\/?(.+)/g,
82
+ url_text: 'https://www.dailymotion.com/embed/video/$1',
83
+ html: '<iframe width="640" height="360" src="{url}" frameborder="0" allowfullscreen></iframe>',
84
+ provider: 'dailymotion'
85
+ },
86
+ {
87
+ test_regex: /^.+(screen.yahoo.com)\/[^_&]+/,
88
+ url_regex: '',
89
+ url_text: '',
90
+ html: '<iframe width="640" height="360" src="{url}?format=embed" frameborder="0" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true" allowtransparency="true"></iframe>',
91
+ provider: 'yahoo'
92
+ },
93
+ {
94
+ test_regex: /^.+(rutube.ru)\/[^_&]+/,
95
+ url_regex: /(?:https?:\/\/)?(?:www\.)?(?:rutube\.ru)\/(?:video)?\/?(.+)/g,
96
+ url_text: 'https://rutube.ru/play/embed/$1',
97
+ html: '<iframe width="640" height="360" src="{url}" frameborder="0" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true" allowtransparency="true"></iframe>',
98
+ provider: 'rutube'
99
+ },
100
+ {
101
+ test_regex: /^(?:.+)vidyard.com\/(?:watch)?\/?([^.&/]+)\/?(?:[^_.&]+)?/,
102
+ url_regex: /^(?:.+)vidyard.com\/(?:watch)?\/?([^.&/]+)\/?(?:[^_.&]+)?/g,
103
+ url_text: 'https://play.vidyard.com/$1',
104
+ html: '<iframe width="640" height="360" src="{url}" frameborder="0" allowfullscreen></iframe>',
105
+ provider: 'vidyard'
106
+ }
107
+ ];
108
+
109
+ $.FE.VIDEO_EMBED_REGEX = /^\W*((<iframe.*><\/iframe>)|(<embed.*>))\W*$/i;
110
+
111
+ $.FE.PLUGINS.video = function (editor) {
112
+ var $overlay;
113
+ var $handler;
114
+ var $video_resizer;
115
+ var $current_video;
116
+
117
+ var BAD_LINK = 1;
118
+ var MISSING_LINK = 2;
119
+ var ERROR_DURING_UPLOAD = 3;
120
+ var BAD_RESPONSE = 4;
121
+ var MAX_SIZE_EXCEEDED = 5;
122
+ var BAD_FILE_TYPE = 6;
123
+ var NO_CORS_IE = 7;
124
+
125
+ var error_messages = {};
126
+ error_messages[BAD_LINK] = 'Video cannot be loaded from the passed link.',
127
+ error_messages[MISSING_LINK] = 'No link in upload response.',
128
+ error_messages[ERROR_DURING_UPLOAD] = 'Error during file upload.',
129
+ error_messages[BAD_RESPONSE] = 'Parsing response failed.',
130
+ error_messages[MAX_SIZE_EXCEEDED] = 'File is too large.',
131
+ error_messages[BAD_FILE_TYPE] = 'Video file type is invalid.',
132
+ error_messages[NO_CORS_IE] = 'Files can be uploaded only to same domain in IE 8 and IE 9.'
133
+
134
+ /**
135
+ * Refresh the video insert popup.
136
+ */
137
+ function _refreshInsertPopup () {
138
+ var $popup = editor.popups.get('video.insert');
139
+
140
+ var $url_input = $popup.find('.fr-video-by-url-layer input');
141
+ $url_input.val('').trigger('change');
142
+
143
+ var $embed_area = $popup.find('.fr-video-embed-layer textarea');
144
+ $embed_area.val('').trigger('change');
145
+
146
+ $embed_area = $popup.find('.fr-video-upload-layer input');
147
+ $embed_area.val('').trigger('change');
148
+ }
149
+
150
+ /**
151
+ * Show the video insert popup.
152
+ */
153
+ function showInsertPopup () {
154
+ var $btn = editor.$tb.find('.fr-command[data-cmd="insertVideo"]');
155
+
156
+ var $popup = editor.popups.get('video.insert');
157
+
158
+ if (!$popup) $popup = _initInsertPopup();
159
+
160
+ hideProgressBar();
161
+
162
+ if (!$popup.hasClass('fr-active')) {
163
+ editor.popups.refresh('video.insert');
164
+ editor.popups.setContainer('video.insert', editor.$tb);
165
+
166
+ if ($btn.is(':visible')) {
167
+ var left = $btn.offset().left + $btn.outerWidth() / 2;
168
+ var top = $btn.offset().top + (editor.opts.toolbarBottom ? 10 : $btn.outerHeight() - 10);
169
+ editor.popups.show('video.insert', left, top, $btn.outerHeight());
170
+ }
171
+ else {
172
+ editor.position.forSelection($popup);
173
+ editor.popups.show('video.insert');
174
+ }
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Show the video edit popup.
180
+ */
181
+ function _showEditPopup () {
182
+ var $popup = editor.popups.get('video.edit');
183
+
184
+ if (!$popup) $popup = _initEditPopup();
185
+
186
+ if ($popup) {
187
+ editor.popups.setContainer('video.edit', editor.$sc);
188
+ editor.popups.refresh('video.edit');
189
+
190
+ var $video_obj = $current_video.find('iframe, embed, video');
191
+ var left = $video_obj.offset().left + $video_obj.outerWidth() / 2;
192
+ var top = $video_obj.offset().top + $video_obj.outerHeight();
193
+
194
+ editor.popups.show('video.edit', left, top, $video_obj.outerHeight());
195
+ }
196
+ }
197
+
198
+ function _initInsertPopup (delayed) {
199
+ if (delayed) {
200
+ editor.popups.onRefresh('video.insert', _refreshInsertPopup);
201
+ editor.popups.onHide('image.insert', _hideInsertPopup);
202
+
203
+ return true;
204
+ }
205
+
206
+ // Video buttons.
207
+ var video_buttons = '';
208
+
209
+ if (!editor.opts.videoUpload) {
210
+ editor.opts.videoInsertButtons.splice(editor.opts.videoInsertButtons.indexOf('videoUpload'), 1);
211
+ }
212
+
213
+ if (editor.opts.videoInsertButtons.length > 1) {
214
+ video_buttons = '<div class="fr-buttons">' + editor.button.buildList(editor.opts.videoInsertButtons) + '</div>';
215
+ }
216
+
217
+ // Video by url layer.
218
+ var by_url_layer = '';
219
+
220
+ var uploadIndex = editor.opts.videoInsertButtons.indexOf('videoUpload');
221
+ var urlIndex = editor.opts.videoInsertButtons.indexOf('videoByURL');
222
+ var embedIndex = editor.opts.videoInsertButtons.indexOf('videoEmbed');
223
+
224
+ var active;
225
+
226
+ if (urlIndex >= 0) {
227
+ active = ' fr-active';
228
+
229
+ if ((urlIndex > uploadIndex && uploadIndex >= 0) || (urlIndex > embedIndex && embedIndex >= 0)) {
230
+ active = ''
231
+ }
232
+
233
+ by_url_layer = '<div class="fr-video-by-url-layer fr-layer' + active + '" id="fr-video-by-url-layer-' + editor.id + '"><div class="fr-input-line"><input id="fr-video-by-url-layer-text-' + editor.id + '" type="text" placeholder="' + editor.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">' + editor.language.translate('Insert') + '</button></div></div>'
234
+ }
235
+
236
+ // Video embed layer.
237
+ var embed_layer = '';
238
+
239
+ if (embedIndex >= 0) {
240
+ active = ' fr-active';
241
+
242
+ if ((embedIndex > uploadIndex && uploadIndex >= 0) || (embedIndex > urlIndex && urlIndex >= 0)) {
243
+ active = ''
244
+ }
245
+
246
+ embed_layer = '<div class="fr-video-embed-layer fr-layer' + active + '" id="fr-video-embed-layer-' + editor.id + '"><div class="fr-input-line"><textarea id="fr-video-embed-layer-text' + editor.id + '" type="text" placeholder="' + editor.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">' + editor.language.translate('Insert') + '</button></div></div>'
247
+ }
248
+
249
+ // Video upload layer.
250
+ var upload_layer = '';
251
+
252
+ if (uploadIndex >= 0) {
253
+ active = ' fr-active';
254
+
255
+ if ((uploadIndex > embedIndex && embedIndex >= 0) || (uploadIndex > urlIndex && urlIndex >= 0)) {
256
+ active = ''
257
+ }
258
+
259
+ upload_layer = '<div class="fr-video-upload-layer fr-layer' + active + '" id="fr-video-upload-layer-' + editor.id + '"><strong>' + editor.language.translate('Drop video') + '</strong><br>(' + editor.language.translate('or click') + ')<div class="fr-form"><input type="file" accept="video/' + editor.opts.videoAllowedTypes.join(', video/').toLowerCase() + '" tabIndex="-1" aria-labelledby="fr-video-upload-layer-' + editor.id + '" role="button"></div></div>'
260
+ }
261
+
262
+ // Progress bar.
263
+ var progress_bar_layer = '<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>';
264
+
265
+
266
+ var template = {
267
+ buttons: video_buttons,
268
+ by_url_layer: by_url_layer,
269
+ embed_layer: embed_layer,
270
+ upload_layer: upload_layer,
271
+ progress_bar: progress_bar_layer
272
+ }
273
+
274
+ // Set the template in the popup.
275
+ var $popup = editor.popups.create('video.insert', template);
276
+
277
+ _bindInsertEvents($popup);
278
+
279
+ return $popup;
280
+ }
281
+
282
+ /**
283
+ * Show the video upload layer.
284
+ */
285
+ function showLayer (name) {
286
+ var $popup = editor.popups.get('video.insert');
287
+
288
+ var left;
289
+ var top;
290
+
291
+ if (!$current_video && !editor.opts.toolbarInline) {
292
+ var $btn = editor.$tb.find('.fr-command[data-cmd="insertVideo"]');
293
+ left = $btn.offset().left + $btn.outerWidth() / 2;
294
+ top = $btn.offset().top + (editor.opts.toolbarBottom ? 10 : $btn.outerHeight() - 10);
295
+ }
296
+
297
+ if (editor.opts.toolbarInline) {
298
+
299
+ // Set top to the popup top.
300
+ top = $popup.offset().top - editor.helpers.getPX($popup.css('margin-top'));
301
+
302
+ // If the popup is above apply height correction.
303
+ if ($popup.hasClass('fr-above')) {
304
+ top += $popup.outerHeight();
305
+ }
306
+ }
307
+
308
+ // Show the new layer.
309
+ $popup.find('.fr-layer').removeClass('fr-active');
310
+ $popup.find('.fr-' + name + '-layer').addClass('fr-active');
311
+ editor.popups.show('video.insert', left, top, 0);
312
+ editor.accessibility.focusPopup($popup);
313
+ }
314
+
315
+ /**
316
+ * Refresh the insert by url button.
317
+ */
318
+ function refreshByURLButton ($btn) {
319
+ var $popup = editor.popups.get('video.insert');
320
+
321
+ if ($popup.find('.fr-video-by-url-layer').hasClass('fr-active')) {
322
+ $btn.addClass('fr-active').attr('aria-pressed', true);
323
+ }
324
+ }
325
+
326
+ /**
327
+ * Refresh the insert embed button.
328
+ */
329
+ function refreshEmbedButton ($btn) {
330
+ var $popup = editor.popups.get('video.insert');
331
+
332
+ if ($popup.find('.fr-video-embed-layer').hasClass('fr-active')) {
333
+ $btn.addClass('fr-active').attr('aria-pressed', true);
334
+ }
335
+ }
336
+
337
+ /**
338
+ * Refresh the insert upload button.
339
+ */
340
+ function refreshUploadButton ($btn) {
341
+ var $popup = editor.popups.get('video.insert');
342
+
343
+ if ($popup.find('.fr-video-upload-layer').hasClass('fr-active')) {
344
+ $btn.addClass('fr-active').attr('aria-pressed', true);
345
+ }
346
+ }
347
+
348
+ /**
349
+ * Insert video embedded object.
350
+ */
351
+ function insert (embedded_code) {
352
+
353
+ // Make sure we have focus.
354
+ editor.events.focus(true);
355
+ editor.selection.restore();
356
+
357
+ // Flag to tell if the video is replaced.
358
+ var replaced = false;
359
+
360
+ // If current video found we have to replace it.
361
+ if ($current_video) {
362
+
363
+ // Remove the old video.
364
+ remove();
365
+
366
+ // Mark that the video is replaced.
367
+ replaced = true;
368
+ }
369
+
370
+ editor.html.insert('<span contenteditable="false" draggable="true" class="fr-jiv fr-video">' + embedded_code + '</span>', false, editor.opts.videoSplitHTML);
371
+
372
+ editor.popups.hide('video.insert');
373
+
374
+ var $video = editor.$el.find('.fr-jiv');
375
+ $video.removeClass('fr-jiv');
376
+
377
+ _setStyle($video, editor.opts.videoDefaultDisplay, editor.opts.videoDefaultAlign);
378
+
379
+ $video.toggleClass('fr-draggable', editor.opts.videoMove);
380
+
381
+ editor.events.trigger(replaced ? 'video.replaced' : 'video.inserted', [$video]);
382
+ }
383
+
384
+ function _loadedCallback () {
385
+ var $video = $(this);
386
+
387
+ editor.popups.hide('video.insert');
388
+
389
+ $video.removeClass('fr-uploading');
390
+
391
+ // Select the image.
392
+ if ($video.parent().next().is('br')) {
393
+ $video.parent().next().remove();
394
+ }
395
+
396
+ _editVideo($video.parent());
397
+
398
+ editor.events.trigger('video.loaded', [$video.parent()]);
399
+ }
400
+
401
+ /**
402
+ * Insert html video into the editor.
403
+ */
404
+
405
+ function insertHtmlVideo (link, sanitize, data, $existing_video, response) {
406
+ editor.edit.off();
407
+ _setProgressMessage('Loading video');
408
+
409
+ if (sanitize) link = editor.helpers.sanitizeURL(link);
410
+
411
+ var _add = function () {
412
+ var $video;
413
+ var attr;
414
+
415
+ if ($existing_video) {
416
+ if (!editor.undo.canDo() && !$existing_video.find('video').hasClass('fr-uploading')) editor.undo.saveStep();
417
+
418
+ var old_src = $existing_video.find('video').data('fr-old-src');
419
+
420
+ var replaced = $existing_video.data('fr-replaced');
421
+ $existing_video.data('fr-replaced', false);
422
+
423
+ if (editor.$wp) {
424
+
425
+ // Clone existing video.
426
+ $video = $existing_video.clone();
427
+ $video.find('video').removeData('fr-old-src').removeClass('fr-uploading');
428
+
429
+ // Remove load event.
430
+ $video.find('video').off('canplay');
431
+
432
+ // Set new SRC.
433
+ if (old_src) $existing_video.find('video').attr('src', old_src);
434
+
435
+ // Replace existing video with its clone.
436
+ $existing_video.replaceWith($video);
437
+ }
438
+ else {
439
+ $video = $existing_video;
440
+ }
441
+
442
+ // Remove old data.
443
+ var atts = $video.find('video').get(0).attributes;
444
+
445
+ for (var i = 0; i < atts.length; i++) {
446
+ var att = atts[i];
447
+
448
+ if (att.nodeName.indexOf('data-') === 0) {
449
+ $video.find('video').removeAttr(att.nodeName);
450
+ }
451
+ }
452
+
453
+ // Set new data.
454
+ if (typeof data != 'undefined') {
455
+ for (attr in data) {
456
+ if (data.hasOwnProperty(attr)) {
457
+ if (attr != 'link') {
458
+ $video.find('video').attr('data-' + attr, data[attr]);
459
+ }
460
+ }
461
+ }
462
+ }
463
+
464
+ $video.find('video').on('canplay', _loadedCallback);
465
+ $video.find('video').attr('src', link);
466
+ editor.edit.on();
467
+ _syncVideos();
468
+ editor.undo.saveStep();
469
+
470
+ // Cursor will not appear if we don't make blur.
471
+ editor.$el.blur();
472
+
473
+ editor.events.trigger(replaced ? 'video.replaced' : 'video.inserted', [$video, response]);
474
+ }
475
+ else {
476
+ $video = _addVideo(link, data, _loadedCallback);
477
+ _syncVideos();
478
+ editor.undo.saveStep();
479
+ editor.events.trigger('video.inserted', [$video, response]);
480
+ }
481
+ }
482
+
483
+ showProgressBar('Loading video');
484
+
485
+ _add();
486
+ }
487
+
488
+ /**
489
+ * Show progress bar.
490
+ */
491
+
492
+ function showProgressBar (no_message) {
493
+ var $popup = editor.popups.get('video.insert');
494
+
495
+ if (!$popup) $popup = _initInsertPopup();
496
+
497
+ $popup.find('.fr-layer.fr-active').removeClass('fr-active').addClass('fr-pactive');
498
+ $popup.find('.fr-video-progress-bar-layer').addClass('fr-active');
499
+ $popup.find('.fr-buttons').hide();
500
+
501
+ if ($current_video) {
502
+ var $current_video_obj = $current_video.find('video');
503
+ editor.popups.setContainer('video.insert', editor.$sc);
504
+ var left = $current_video_obj.offset().left + $current_video_obj.width() / 2;
505
+ var top = $current_video_obj.offset().top + $current_video_obj.height();
506
+
507
+ editor.popups.show('video.insert', left, top, $current_video_obj.outerHeight());
508
+ }
509
+
510
+ if (typeof no_message == 'undefined') {
511
+ _setProgressMessage(editor.language.translate('Uploading'), 0);
512
+ }
513
+ }
514
+
515
+ /**
516
+ * Hide progress bar.
517
+ */
518
+ function hideProgressBar (dismiss) {
519
+ var $popup = editor.popups.get('video.insert');
520
+
521
+ if ($popup) {
522
+ $popup.find('.fr-layer.fr-pactive').addClass('fr-active').removeClass('fr-pactive');
523
+ $popup.find('.fr-video-progress-bar-layer').removeClass('fr-active');
524
+ $popup.find('.fr-buttons').show();
525
+
526
+ // Dismiss error message.
527
+ if (dismiss || editor.$el.find('video.fr-error').length) {
528
+ editor.events.focus();
529
+
530
+ if (editor.$el.find('video.fr-error').length) {
531
+ editor.$el.find('video.fr-error').parent().remove();
532
+ editor.undo.saveStep();
533
+ editor.undo.run();
534
+ editor.undo.dropRedo();
535
+ }
536
+
537
+ if (!editor.$wp && $current_video) {
538
+ var $video = $current_video;
539
+ _exitEdit(true);
540
+ editor.selection.setAfter($video.find('video').get(0));
541
+ editor.selection.restore();
542
+ }
543
+ editor.popups.hide('video.insert');
544
+ }
545
+ }
546
+ }
547
+
548
+ /**
549
+ * Set a progress message.
550
+ */
551
+
552
+ function _setProgressMessage (message, progress) {
553
+ var $popup = editor.popups.get('video.insert');
554
+
555
+ if ($popup) {
556
+ var $layer = $popup.find('.fr-video-progress-bar-layer');
557
+ $layer.find('h3').text(message + (progress ? ' ' + progress + '%' : ''));
558
+
559
+ $layer.removeClass('fr-error');
560
+
561
+ if (progress) {
562
+ $layer.find('div').removeClass('fr-indeterminate');
563
+ $layer.find('div > span').css('width', progress + '%');
564
+ }
565
+ else {
566
+ $layer.find('div').addClass('fr-indeterminate');
567
+ }
568
+ }
569
+ }
570
+
571
+ /**
572
+ * Show error message to the user.
573
+ */
574
+
575
+ function _showErrorMessage (message) {
576
+ showProgressBar();
577
+ var $popup = editor.popups.get('video.insert');
578
+ var $layer = $popup.find('.fr-video-progress-bar-layer');
579
+ $layer.addClass('fr-error');
580
+ var $message_header = $layer.find('h3');
581
+ $message_header.text(message);
582
+ editor.events.disableBlur();
583
+ $message_header.focus();
584
+ }
585
+
586
+ /**
587
+ * Insert video by URL.
588
+ */
589
+ function insertByURL (link) {
590
+ if (typeof link == 'undefined') {
591
+ var $popup = editor.popups.get('video.insert');
592
+ link = ($popup.find('.fr-video-by-url-layer input[type="text"]').val() || '').trim();
593
+ }
594
+
595
+ var video = null;
596
+
597
+ if (!/^http/.test(link)) {
598
+ link = 'https://' + link;
599
+ }
600
+
601
+ if (editor.helpers.isURL(link)) {
602
+ for (var i = 0; i < $.FE.VIDEO_PROVIDERS.length; i++) {
603
+ var vp = $.FE.VIDEO_PROVIDERS[i];
604
+
605
+ // Check if video provider is allowed.
606
+ if (vp.test_regex.test(link) && (new RegExp(editor.opts.videoAllowedProviders.join('|'))).test(vp.provider)) {
607
+ video = link.replace(vp.url_regex, vp.url_text);
608
+ video = vp.html.replace(/\{url\}/, video);
609
+ break;
610
+ }
611
+ }
612
+ }
613
+
614
+ if (video) {
615
+ insert(video);
616
+ }
617
+ else {
618
+ editor.events.trigger('video.linkError', [link]);
619
+ }
620
+ }
621
+
622
+ /**
623
+ * Insert embedded video.
624
+ */
625
+ function insertEmbed (code) {
626
+ if (typeof code == 'undefined') {
627
+ var $popup = editor.popups.get('video.insert');
628
+ code = $popup.find('.fr-video-embed-layer textarea').val() || '';
629
+ }
630
+
631
+ if (code.length === 0 || !$.FE.VIDEO_EMBED_REGEX.test(code)) {
632
+ editor.events.trigger('video.codeError', [code]);
633
+ }
634
+ else {
635
+ insert(code);
636
+ }
637
+ }
638
+
639
+ function _editVideo ($video) {
640
+ _edit.call($video.get(0));
641
+ }
642
+
643
+ /**
644
+ * Parse video response.
645
+ */
646
+
647
+ function _parseResponse (response) {
648
+ try {
649
+ if (editor.events.trigger('video.uploaded', [response], true) === false) {
650
+ editor.edit.on();
651
+
652
+ return false;
653
+ }
654
+
655
+ var resp = JSON.parse(response);
656
+
657
+ if (resp.link) {
658
+
659
+ return resp;
660
+ }
661
+ else {
662
+
663
+ // No link in upload request.
664
+ _throwError(MISSING_LINK, response);
665
+
666
+ return false;
667
+ }
668
+ }
669
+ catch (ex) {
670
+
671
+ // Bad response.
672
+ _throwError(BAD_RESPONSE, response);
673
+
674
+ return false;
675
+ }
676
+ }
677
+
678
+ /**
679
+ * Parse video response.
680
+ */
681
+
682
+ function _parseXMLResponse (response) {
683
+ try {
684
+ var link = $(response).find('Location').text();
685
+ var key = $(response).find('Key').text();
686
+
687
+ if (editor.events.trigger('video.uploadedToS3', [link, key, response], true) === false) {
688
+ editor.edit.on();
689
+
690
+ return false;
691
+ }
692
+
693
+ return link;
694
+ }
695
+ catch (ex) {
696
+
697
+ // Bad response.
698
+ _throwError(BAD_RESPONSE, response);
699
+
700
+ return false;
701
+ }
702
+ }
703
+
704
+ /**
705
+ * Video was uploaded to the server and we have a response.
706
+ */
707
+
708
+ function _videoUploaded ($video) {
709
+ _setProgressMessage('Loading video');
710
+
711
+ var status = this.status;
712
+ var response = this.response;
713
+ var responseXML = this.responseXML;
714
+ var responseText = this.responseText;
715
+
716
+ try {
717
+ if (editor.opts.videoUploadToS3) {
718
+ if (status == 201) {
719
+ var link = _parseXMLResponse(responseXML);
720
+
721
+ if (link) {
722
+ insertHtmlVideo(link, false, [], $video, response || responseXML);
723
+ }
724
+ }
725
+ else {
726
+ _throwError(BAD_RESPONSE, response || responseXML);
727
+ }
728
+ }
729
+ else {
730
+ if (status >= 200 && status < 300) {
731
+ var resp = _parseResponse(responseText);
732
+
733
+ if (resp) {
734
+ insertHtmlVideo(resp.link, false, resp, $video, response || responseText);
735
+ }
736
+ }
737
+ else {
738
+ _throwError(ERROR_DURING_UPLOAD, response || responseText);
739
+ }
740
+ }
741
+ }
742
+ catch (ex) {
743
+
744
+ // Bad response.
745
+ _throwError(BAD_RESPONSE, response || responseText);
746
+ }
747
+ }
748
+
749
+ /**
750
+ * Video upload error.
751
+ */
752
+
753
+ function _videoUploadError () {
754
+ _throwError(BAD_RESPONSE, this.response || this.responseText || this.responseXML);
755
+ }
756
+
757
+ /**
758
+ * Video upload progress.
759
+ */
760
+
761
+ function _videoUploadProgress (e) {
762
+ if (e.lengthComputable) {
763
+ var complete = (e.loaded / e.total * 100 | 0);
764
+ _setProgressMessage(editor.language.translate('Uploading'), complete);
765
+ }
766
+ }
767
+
768
+ /**
769
+ * Video upload aborted.
770
+ */
771
+ function _videoUploadAborted () {
772
+ editor.edit.on();
773
+ hideProgressBar(true);
774
+ }
775
+
776
+ function _addVideo (link, data, loadCallback) {
777
+
778
+ // Build video data string.
779
+ var data_str = '';
780
+ var attr;
781
+
782
+ if (data && typeof data != 'undefined') {
783
+ for (attr in data) {
784
+ if (data.hasOwnProperty(attr)) {
785
+ if (attr != 'link') {
786
+ data_str += ' data-' + attr + '="' + data[attr] + '"';
787
+ }
788
+ }
789
+ }
790
+ }
791
+
792
+ var width = editor.opts.videoDefaultWidth;
793
+
794
+ if (width && width != 'auto') {
795
+ width = width + 'px';
796
+ }
797
+
798
+ // Create video object and set the load event.
799
+ var $video = $('<span contenteditable="false" draggable="true" class="fr-video fr-dv' + (editor.opts.videoDefaultDisplay[0]) + (editor.opts.videoDefaultAlign != 'center' ? ' fr-fv' + editor.opts.videoDefaultAlign[0] : '') + '"><video src="' + link + '" ' + data_str + (width ? ' style="width: ' + width + ';" ' : '') + ' controls>' + editor.language.translate('Your browser does not support HTML5 video.') + '</video></span>');
800
+ $video.toggleClass('fr-draggable', editor.opts.videoMove);
801
+
802
+ // Make sure we have focus.
803
+ // Call the event.
804
+ editor.edit.on();
805
+ editor.events.focus(true);
806
+ editor.selection.restore();
807
+
808
+ editor.undo.saveStep();
809
+
810
+ // Insert marker and then replace it with the video.
811
+ if (editor.opts.videoSplitHTML) {
812
+ editor.markers.split();
813
+ }
814
+ else {
815
+ editor.markers.insert();
816
+ }
817
+
818
+ editor.html.wrap();
819
+ var $marker = editor.$el.find('.fr-marker');
820
+
821
+ // Do not insert video inside emoticon.
822
+ if (editor.node.isLastSibling($marker) && $marker.parent().hasClass('fr-deletable')) {
823
+
824
+ $marker.insertAfter($marker.parent());
825
+ }
826
+
827
+ $marker.replaceWith($video);
828
+
829
+ editor.selection.clear();
830
+
831
+ if ($video.find('video').get(0).readyState > $video.find('video').get(0).HAVE_FUTURE_DATA || editor.helpers.isIOS()) {
832
+ loadCallback.call($video.find('video').get(0));
833
+ }
834
+ else {
835
+ $video.find('video').on('canplaythrough load', loadCallback);
836
+ }
837
+
838
+ return $video;
839
+ }
840
+
841
+ /**
842
+ * Mouse down to start resize.
843
+ */
844
+ function _handlerMousedown (e) {
845
+
846
+ // Check if resizer belongs to current instance.
847
+ if (!editor.core.sameInstance($video_resizer)) return true;
848
+
849
+ e.preventDefault();
850
+ e.stopPropagation();
851
+
852
+ var c_x = e.pageX || (e.originalEvent.touches ? e.originalEvent.touches[0].pageX : null);
853
+ var c_y = e.pageY || (e.originalEvent.touches ? e.originalEvent.touches[0].pageY : null);
854
+
855
+ if (!c_x || !c_y) {
856
+
857
+ return false;
858
+ }
859
+
860
+ // Only on mousedown. This function could be called from keydown on accessibility.
861
+ if (e.type == 'mousedown') {
862
+
863
+ // See if the entire editor is inside iframe to adjust starting offsets.
864
+ var oel = editor.$oel.get(0);
865
+ var doc = oel.ownerDocument;
866
+ var win = doc.defaultView || doc.parentWindow;
867
+ var editor_inside_iframe = false;
868
+
869
+ try {
870
+ editor_inside_iframe = (win.location != win.parent.location && !(win.$ && win.$.FE));
871
+ }
872
+ catch (ex) {
873
+ }
874
+
875
+ if (editor_inside_iframe && win.frameElement) {
876
+ c_x += editor.helpers.getPX($(win.frameElement).offset().left) + win.frameElement.clientLeft;
877
+
878
+ // Override c_y with clientY attribute.
879
+ c_y = e.clientY + editor.helpers.getPX($(win.frameElement).offset().top) + win.frameElement.clientTop;
880
+ }
881
+ }
882
+
883
+ if (!editor.undo.canDo()) editor.undo.saveStep();
884
+
885
+ $handler = $(this);
886
+ $handler.data('start-x', c_x);
887
+ $handler.data('start-y', c_y);
888
+ $overlay.show();
889
+ editor.popups.hideAll();
890
+
891
+ _unmarkExit();
892
+ }
893
+
894
+ /**
895
+ * Do resize.
896
+ */
897
+ function _handlerMousemove (e) {
898
+
899
+ // Check if resizer belongs to current instance.
900
+ if (!editor.core.sameInstance($video_resizer)) return true;
901
+
902
+ if ($handler) {
903
+ e.preventDefault()
904
+
905
+ var c_x = e.pageX || (e.originalEvent.touches ? e.originalEvent.touches[0].pageX : null);
906
+ var c_y = e.pageY || (e.originalEvent.touches ? e.originalEvent.touches[0].pageY : null);
907
+
908
+ if (!c_x || !c_y) {
909
+
910
+ return false;
911
+ }
912
+
913
+ var s_x = $handler.data('start-x');
914
+ var s_y = $handler.data('start-y');
915
+
916
+ $handler.data('start-x', c_x);
917
+ $handler.data('start-y', c_y);
918
+
919
+ var diff_x = c_x - s_x;
920
+ var diff_y = c_y - s_y;
921
+
922
+ var $video_obj = $current_video.find('iframe, embed, video');
923
+ var width = $video_obj.width();
924
+ var height = $video_obj.height();
925
+
926
+ if ($handler.hasClass('fr-hnw') || $handler.hasClass('fr-hsw')) {
927
+ diff_x = 0 - diff_x;
928
+ }
929
+
930
+ if ($handler.hasClass('fr-hnw') || $handler.hasClass('fr-hne')) {
931
+ diff_y = 0 - diff_y;
932
+ }
933
+
934
+ $video_obj.css('width', width + diff_x);
935
+ $video_obj.css('height', height + diff_y);
936
+ $video_obj.removeAttr('width');
937
+ $video_obj.removeAttr('height');
938
+
939
+ _repositionResizer();
940
+ }
941
+ }
942
+
943
+ /**
944
+ * Stop resize.
945
+ */
946
+ function _handlerMouseup (e) {
947
+
948
+ // Check if resizer belongs to current instance.
949
+ if (!editor.core.sameInstance($video_resizer)) return true;
950
+
951
+ if ($handler && $current_video) {
952
+ if (e) e.stopPropagation();
953
+ $handler = null;
954
+ $overlay.hide();
955
+ _repositionResizer();
956
+ _showEditPopup();
957
+
958
+ editor.undo.saveStep();
959
+ }
960
+ }
961
+
962
+ /**
963
+ * Create resize handler.
964
+ */
965
+ function _getHandler (pos) {
966
+
967
+ return '<div class="fr-handler fr-h' + pos + '"></div>';
968
+ }
969
+
970
+ function _resizeVideo (e, initPageX, direction, step) {
971
+ e.pageX = initPageX;
972
+ e.pageY = initPageX;
973
+ _handlerMousedown.call(this, e);
974
+ e.pageX = e.pageX + direction * Math.floor(Math.pow(1.1, step));
975
+ e.pageY = e.pageY + direction * Math.floor(Math.pow(1.1, step));
976
+ _handlerMousemove.call(this, e);
977
+ _handlerMouseup.call(this, e);
978
+
979
+ return ++step;
980
+ }
981
+
982
+ /**
983
+ * Init video resizer.
984
+ */
985
+ function _initResizer () {
986
+ var doc;
987
+
988
+ // No shared video resizer.
989
+ if (!editor.shared.$video_resizer) {
990
+
991
+ // Create shared video resizer.
992
+ editor.shared.$video_resizer = $('<div class="fr-video-resizer"></div>');
993
+ $video_resizer = editor.shared.$video_resizer;
994
+
995
+ // Bind mousedown event shared.
996
+ editor.events.$on($video_resizer, 'mousedown', function (e) {
997
+ e.stopPropagation();
998
+ }, true);
999
+
1000
+ // video resize is enabled.
1001
+ if (editor.opts.videoResize) {
1002
+ $video_resizer.append(_getHandler('nw') + _getHandler('ne') + _getHandler('sw') + _getHandler('se'));
1003
+
1004
+ // Add video resizer overlay and set it.
1005
+ editor.shared.$vid_overlay = $('<div class="fr-video-overlay"></div>');
1006
+ $overlay = editor.shared.$vid_overlay;
1007
+ doc = $video_resizer.get(0).ownerDocument;
1008
+ $(doc).find('body:first').append($overlay);
1009
+ }
1010
+ }
1011
+ else {
1012
+ $video_resizer = editor.shared.$video_resizer;
1013
+ $overlay = editor.shared.$vid_overlay;
1014
+
1015
+ editor.events.on('destroy', function () {
1016
+ $video_resizer.removeClass('fr-active').appendTo($('body:first'));
1017
+ }, true);
1018
+ }
1019
+
1020
+ // Shared destroy.
1021
+ editor.events.on('shared.destroy', function () {
1022
+ $video_resizer.html('').removeData().remove();
1023
+ $video_resizer = null;
1024
+
1025
+ if (editor.opts.videoResize) {
1026
+ $overlay.remove();
1027
+ $overlay = null;
1028
+ }
1029
+ }, true);
1030
+
1031
+ // Window resize. Exit from edit.
1032
+ if (!editor.helpers.isMobile()) {
1033
+ editor.events.$on($(editor.o_win), 'resize.video', function () {
1034
+ _exitEdit(true);
1035
+ });
1036
+ }
1037
+
1038
+ // video resize is enabled.
1039
+ if (editor.opts.videoResize) {
1040
+ doc = $video_resizer.get(0).ownerDocument;
1041
+
1042
+ editor.events.$on($video_resizer, editor._mousedown, '.fr-handler', _handlerMousedown);
1043
+ editor.events.$on($(doc), editor._mousemove, _handlerMousemove);
1044
+ editor.events.$on($(doc.defaultView || doc.parentWindow), editor._mouseup, _handlerMouseup);
1045
+
1046
+ editor.events.$on($overlay, 'mouseleave', _handlerMouseup);
1047
+
1048
+
1049
+ // Accessibility.
1050
+
1051
+ // Used for keys holing.
1052
+ var step = 1;
1053
+ var prevKey = null;
1054
+ var prevTimestamp = 0;
1055
+
1056
+ // Keydown event.
1057
+ editor.events.on('keydown', function (e) {
1058
+ if ($current_video) {
1059
+ var ctrlKey = navigator.userAgent.indexOf('Mac OS X') != -1 ? e.metaKey : e.ctrlKey;
1060
+ var keycode = e.which;
1061
+
1062
+ if (keycode !== prevKey || e.timeStamp - prevTimestamp > 200) {
1063
+ step = 1;
1064
+
1065
+ // Reset step. Known browser issue: Keyup does not trigger when ctrl is pressed.
1066
+ }
1067
+
1068
+ // Increase video size.
1069
+ if ((keycode == $.FE.KEYCODE.EQUALS || (editor.browser.mozilla && keycode == $.FE.KEYCODE.FF_EQUALS)) && ctrlKey && !e.altKey) {
1070
+ step = _resizeVideo.call(this, e, 1, 1, step);
1071
+ }
1072
+
1073
+ // Decrease video size.
1074
+ else if ((keycode == $.FE.KEYCODE.HYPHEN || (editor.browser.mozilla && keycode == $.FE.KEYCODE.FF_HYPHEN)) && ctrlKey && !e.altKey) {
1075
+ step = _resizeVideo.call(this, e, 2, -1, step);
1076
+ }
1077
+
1078
+ // Save key code.
1079
+ prevKey = keycode;
1080
+
1081
+ // Save timestamp.
1082
+ prevTimestamp = e.timeStamp;
1083
+ }
1084
+ });
1085
+
1086
+ // Reset the step on key up event.
1087
+ editor.events.on('keyup', function () {
1088
+ step = 1;
1089
+ });
1090
+ }
1091
+ }
1092
+
1093
+ /**
1094
+ * Keep videos in sync when content changed.
1095
+ */
1096
+ var videos;
1097
+
1098
+ function _syncVideos () {
1099
+
1100
+ // Get current videos.
1101
+ var c_videos = Array.prototype.slice.call(editor.el.querySelectorAll('video, .fr-video > *'));
1102
+
1103
+ // Current videos src.
1104
+ var video_srcs = [];
1105
+ var i;
1106
+
1107
+ for (i = 0; i < c_videos.length; i++) {
1108
+ video_srcs.push(c_videos[i].getAttribute('src'));
1109
+
1110
+ $(c_videos[i]).toggleClass('fr-draggable', editor.opts.videoMove);
1111
+
1112
+ if (c_videos[i].getAttribute('class') === '') c_videos[i].removeAttribute('class');
1113
+
1114
+ if (c_videos[i].getAttribute('style') === '') c_videos[i].removeAttribute('style');
1115
+ }
1116
+
1117
+ // Loop previous videos and check their src.
1118
+ if (videos) {
1119
+ for (i = 0; i < videos.length; i++) {
1120
+ if (video_srcs.indexOf(videos[i].getAttribute('src')) < 0) {
1121
+ editor.events.trigger('video.removed', [$(videos[i])]);
1122
+ }
1123
+ }
1124
+ }
1125
+
1126
+ // Current videos are the old ones.
1127
+ videos = c_videos;
1128
+ }
1129
+
1130
+ /**
1131
+ * Reposition resizer.
1132
+ */
1133
+ function _repositionResizer () {
1134
+ if (!$video_resizer) _initResizer();
1135
+
1136
+ (editor.$wp || editor.$sc).append($video_resizer);
1137
+ $video_resizer.data('instance', editor);
1138
+
1139
+ var $video_obj = $current_video.find('iframe, embed, video');
1140
+
1141
+ $video_resizer
1142
+ .css('top', (editor.opts.iframe ? $video_obj.offset().top - 1 : $video_obj.offset().top - editor.$wp.offset().top - 1) + editor.$wp.scrollTop())
1143
+ .css('left', (editor.opts.iframe ? $video_obj.offset().left - 1 : $video_obj.offset().left - editor.$wp.offset().left - 1) + editor.$wp.scrollLeft())
1144
+ .css('width', $video_obj.get(0).getBoundingClientRect().width)
1145
+ .css('height', $video_obj.get(0).getBoundingClientRect().height)
1146
+ .addClass('fr-active');
1147
+ }
1148
+
1149
+ /**
1150
+ * Edit video.
1151
+ */
1152
+ var touchScroll;
1153
+
1154
+ function _edit (e) {
1155
+ if (e && e.type == 'touchend' && touchScroll) {
1156
+
1157
+ return true;
1158
+ }
1159
+
1160
+ if (e && editor.edit.isDisabled()) {
1161
+ e.stopPropagation();
1162
+ e.preventDefault();
1163
+
1164
+ return false;
1165
+ }
1166
+
1167
+ if (editor.edit.isDisabled()) {
1168
+
1169
+ return false;
1170
+ }
1171
+
1172
+ // Hide resizer for other instances.
1173
+ for (var i = 0; i < $.FE.INSTANCES.length; i++) {
1174
+ if ($.FE.INSTANCES[i] != editor) {
1175
+ $.FE.INSTANCES[i].events.trigger('video.hideResizer');
1176
+ }
1177
+ }
1178
+
1179
+ editor.toolbar.disable();
1180
+
1181
+ // Hide keyboard.
1182
+ if (editor.helpers.isMobile()) {
1183
+ editor.events.disableBlur();
1184
+ editor.$el.blur();
1185
+ editor.events.enableBlur();
1186
+ }
1187
+
1188
+ // Unselect all other videos.
1189
+ editor.$el.find('.fr-video.fr-active').removeClass('fr-active');
1190
+
1191
+ $current_video = $(this);
1192
+ $current_video.addClass('fr-active');
1193
+
1194
+ if (editor.opts.iframe) {
1195
+ editor.size.syncIframe();
1196
+ }
1197
+
1198
+ _selectVideo()
1199
+ _repositionResizer();
1200
+ _showEditPopup();
1201
+
1202
+ editor.selection.clear();
1203
+ editor.button.bulkRefresh();
1204
+
1205
+ editor.events.trigger('image.hideResizer');
1206
+ }
1207
+
1208
+ /**
1209
+ * Exit edit.
1210
+ */
1211
+ function _exitEdit (force_exit) {
1212
+ if ($current_video && (_canExit() || force_exit === true)) {
1213
+ $video_resizer.removeClass('fr-active');
1214
+
1215
+ editor.toolbar.enable();
1216
+
1217
+ $current_video.removeClass('fr-active');
1218
+ $current_video = null;
1219
+
1220
+ _unmarkExit();
1221
+ }
1222
+ }
1223
+
1224
+ editor.shared.vid_exit_flag = false;
1225
+
1226
+ function _markExit () {
1227
+ editor.shared.vid_exit_flag = true;
1228
+ }
1229
+
1230
+ function _unmarkExit () {
1231
+ editor.shared.vid_exit_flag = false;
1232
+ }
1233
+
1234
+ function _canExit () {
1235
+
1236
+ return editor.shared.vid_exit_flag;
1237
+ }
1238
+
1239
+ function _drop (e) {
1240
+
1241
+ // Check if we are dropping files.
1242
+ var dt = e.originalEvent.dataTransfer;
1243
+
1244
+ if (dt && dt.files && dt.files.length) {
1245
+ var vid = dt.files[0];
1246
+
1247
+ if (vid && vid.type && vid.type.indexOf('video') !== -1) {
1248
+ if (!editor.opts.videoUpload) {
1249
+ e.preventDefault();
1250
+ e.stopPropagation();
1251
+
1252
+ return false;
1253
+ }
1254
+
1255
+
1256
+ editor.markers.remove();
1257
+ editor.markers.insertAtPoint(e.originalEvent);
1258
+ editor.$el.find('.fr-marker').replaceWith($.FE.MARKERS);
1259
+
1260
+ // Hide popups.
1261
+ editor.popups.hideAll();
1262
+
1263
+ // Show the video insert popup.
1264
+ var $popup = editor.popups.get('video.insert');
1265
+
1266
+ if (!$popup) $popup = _initInsertPopup();
1267
+ editor.popups.setContainer('video.insert', editor.$sc);
1268
+ editor.popups.show('video.insert', e.originalEvent.pageX, e.originalEvent.pageY);
1269
+ showProgressBar();
1270
+
1271
+ // Dropped file is an video that we allow.
1272
+ if (editor.opts.videoAllowedTypes.indexOf(vid.type.replace(/video\//g, '')) >= 0) {
1273
+
1274
+ // Upload videos.
1275
+ upload(dt.files);
1276
+ }
1277
+ else {
1278
+ _throwError(BAD_FILE_TYPE);
1279
+ }
1280
+
1281
+ // Cancel anything else.
1282
+ e.preventDefault();
1283
+ e.stopPropagation();
1284
+
1285
+ return false;
1286
+ }
1287
+ }
1288
+ }
1289
+
1290
+ /**
1291
+ * Do video upload.
1292
+ */
1293
+ function upload (videos) {
1294
+
1295
+ // Make sure we have what to upload.
1296
+ if (typeof videos != 'undefined' && videos.length > 0) {
1297
+
1298
+ // Check if we should cancel the video upload.
1299
+ if (editor.events.trigger('video.beforeUpload', [videos]) === false) {
1300
+
1301
+ return false;
1302
+ }
1303
+
1304
+ var video = videos[0];
1305
+
1306
+ // Check video max size.
1307
+ if (video.size > editor.opts.videoMaxSize) {
1308
+ _throwError(MAX_SIZE_EXCEEDED);
1309
+
1310
+ return false;
1311
+ }
1312
+
1313
+ // Check video types.
1314
+ if (editor.opts.videoAllowedTypes.indexOf(video.type.replace(/video\//g, '')) < 0) {
1315
+ _throwError(BAD_FILE_TYPE);
1316
+
1317
+ return false;
1318
+ }
1319
+
1320
+ // Create form Data.
1321
+ var form_data;
1322
+
1323
+ if (editor.drag_support.formdata) {
1324
+ form_data = editor.drag_support.formdata ? new FormData() : null;
1325
+ }
1326
+
1327
+ // Prepare form data for request.
1328
+ if (form_data) {
1329
+ var key;
1330
+
1331
+ // Upload to S3.
1332
+ if (editor.opts.videoUploadToS3 !== false) {
1333
+ form_data.append('key', editor.opts.videoUploadToS3.keyStart + (new Date()).getTime() + '-' + (video.name || 'untitled'));
1334
+ form_data.append('success_action_status', '201');
1335
+ form_data.append('X-Requested-With', 'xhr');
1336
+ form_data.append('Content-Type', video.type);
1337
+
1338
+ for (key in editor.opts.videoUploadToS3.params) {
1339
+ if (editor.opts.videoUploadToS3.params.hasOwnProperty(key)) {
1340
+ form_data.append(key, editor.opts.videoUploadToS3.params[key]);
1341
+ }
1342
+ }
1343
+ }
1344
+
1345
+ // Add upload params.
1346
+ for (key in editor.opts.videoUploadParams) {
1347
+ if (editor.opts.videoUploadParams.hasOwnProperty(key)) {
1348
+ form_data.append(key, editor.opts.videoUploadParams[key]);
1349
+ }
1350
+ }
1351
+
1352
+ // Set the video in the request.
1353
+ form_data.append(editor.opts.videoUploadParam, video);
1354
+
1355
+ // Create XHR request.
1356
+ var url = editor.opts.videoUploadURL;
1357
+
1358
+ if (editor.opts.videoUploadToS3) {
1359
+ if (editor.opts.videoUploadToS3.uploadURL) {
1360
+ url = editor.opts.videoUploadToS3.uploadURL;
1361
+ }
1362
+ else {
1363
+ url = 'https://' + editor.opts.videoUploadToS3.region + '.amazonaws.com/' + editor.opts.videoUploadToS3.bucket;
1364
+ }
1365
+ }
1366
+
1367
+ var xhr = editor.core.getXHR(url, editor.opts.videoUploadMethod);
1368
+
1369
+ // Set upload events.
1370
+ xhr.onload = function () {
1371
+ _videoUploaded.call(xhr, $current_video);
1372
+ };
1373
+ xhr.onerror = _videoUploadError;
1374
+ xhr.upload.onprogress = _videoUploadProgress;
1375
+ xhr.onabort = _videoUploadAborted;
1376
+
1377
+ showProgressBar();
1378
+ editor.events.disableBlur();
1379
+ editor.edit.off();
1380
+ editor.events.enableBlur();
1381
+
1382
+ var $popup = editor.popups.get('video.insert');
1383
+
1384
+ if ($popup) {
1385
+ $popup.off('abortUpload').on('abortUpload', function () {
1386
+ if (xhr.readyState != 4) {
1387
+ xhr.abort();
1388
+ }
1389
+ })
1390
+ }
1391
+
1392
+ // Send data.
1393
+ xhr.send(form_data);
1394
+ }
1395
+ }
1396
+ }
1397
+
1398
+ /**
1399
+ * Video drop inside the upload zone.
1400
+ */
1401
+
1402
+ function _bindInsertEvents ($popup) {
1403
+
1404
+ // Drag over the dropable area.
1405
+ editor.events.$on($popup, 'dragover dragenter', '.fr-video-upload-layer', function () {
1406
+ $(this).addClass('fr-drop');
1407
+
1408
+ return false;
1409
+ }, true);
1410
+
1411
+ // Drag end.
1412
+ editor.events.$on($popup, 'dragleave dragend', '.fr-video-upload-layer', function () {
1413
+ $(this).removeClass('fr-drop');
1414
+
1415
+ return false;
1416
+ }, true);
1417
+
1418
+ // Drop.
1419
+ editor.events.$on($popup, 'drop', '.fr-video-upload-layer', function (e) {
1420
+ e.preventDefault();
1421
+ e.stopPropagation();
1422
+
1423
+ $(this).removeClass('fr-drop');
1424
+
1425
+ var dt = e.originalEvent.dataTransfer;
1426
+
1427
+ if (dt && dt.files) {
1428
+ var inst = $popup.data('instance') || editor;
1429
+ inst.events.disableBlur();
1430
+ inst.video.upload(dt.files);
1431
+ inst.events.enableBlur();
1432
+ }
1433
+ }, true);
1434
+
1435
+ if (editor.helpers.isIOS()) {
1436
+ editor.events.$on($popup, 'touchstart', '.fr-video-upload-layer input[type="file"]', function () {
1437
+ $(this).trigger('click');
1438
+ }, true);
1439
+ }
1440
+
1441
+ editor.events.$on($popup, 'change', '.fr-video-upload-layer input[type="file"]', function () {
1442
+ if (this.files) {
1443
+ var inst = $popup.data('instance') || editor;
1444
+ inst.events.disableBlur();
1445
+ $popup.find('input:focus').blur();
1446
+ inst.events.enableBlur();
1447
+ inst.video.upload(this.files);
1448
+ }
1449
+
1450
+ // Else IE 9 case.
1451
+ // Chrome fix.
1452
+ $(this).val('');
1453
+ }, true);
1454
+ }
1455
+
1456
+ /**
1457
+ * Init the video events.
1458
+ */
1459
+ function _initEvents () {
1460
+
1461
+ // Drop inside the editor.
1462
+ editor.events.on('drop', _drop, true);
1463
+
1464
+ editor.events.on('mousedown window.mousedown', _markExit);
1465
+ editor.events.on('window.touchmove', _unmarkExit);
1466
+ editor.events.on('mouseup window.mouseup', _exitEdit);
1467
+
1468
+ editor.events.on('commands.mousedown', function ($btn) {
1469
+ if ($btn.parents('.fr-toolbar').length > 0) {
1470
+ _exitEdit();
1471
+ }
1472
+ });
1473
+
1474
+ editor.events.on('video.hideResizer commands.undo commands.redo element.dropped', function () {
1475
+ _exitEdit(true);
1476
+ });
1477
+ }
1478
+
1479
+ /**
1480
+ * Throw a video error.
1481
+ */
1482
+
1483
+ function _throwError (code, response) {
1484
+ editor.edit.on();
1485
+
1486
+ if ($current_video) $current_video.find('video').addClass('fr-error');
1487
+ _showErrorMessage(editor.language.translate('Something went wrong. Please try again.'));
1488
+
1489
+ editor.events.trigger('video.error', [{
1490
+ code: code,
1491
+ message: error_messages[code]
1492
+ },
1493
+ response
1494
+ ]);
1495
+ }
1496
+
1497
+ /**
1498
+ * Init the video edit popup.
1499
+ */
1500
+ function _initEditPopup () {
1501
+
1502
+ // Video buttons.
1503
+ var video_buttons = '';
1504
+
1505
+ if (editor.opts.videoEditButtons.length > 0) {
1506
+ video_buttons += '<div class="fr-buttons">';
1507
+ video_buttons += editor.button.buildList(editor.opts.videoEditButtons);
1508
+ video_buttons += '</div>';
1509
+
1510
+ var template = {
1511
+ buttons: video_buttons
1512
+ }
1513
+
1514
+ var $popup = editor.popups.create('video.edit', template);
1515
+
1516
+ editor.events.$on(editor.$wp, 'scroll.video-edit', function () {
1517
+ if ($current_video && editor.popups.isVisible('video.edit')) {
1518
+
1519
+ editor.events.disableBlur();
1520
+ _editVideo($current_video);
1521
+ }
1522
+ });
1523
+
1524
+ return $popup;
1525
+ }
1526
+
1527
+ return false;
1528
+ }
1529
+
1530
+ /**
1531
+ * Refresh the size popup.
1532
+ */
1533
+ function _refreshSizePopup () {
1534
+ if ($current_video) {
1535
+ var $popup = editor.popups.get('video.size');
1536
+ var $video_obj = $current_video.find('iframe, embed, video')
1537
+ $popup.find('input[name="width"]').val($video_obj.get(0).style.width || $video_obj.attr('width')).trigger('change');
1538
+ $popup.find('input[name="height"]').val($video_obj.get(0).style.height || $video_obj.attr('height')).trigger('change');
1539
+ }
1540
+ }
1541
+
1542
+ /**
1543
+ * Show the size popup.
1544
+ */
1545
+ function showSizePopup () {
1546
+ var $popup = editor.popups.get('video.size');
1547
+
1548
+ if (!$popup) $popup = _initSizePopup();
1549
+ hideProgressBar();
1550
+ editor.popups.refresh('video.size');
1551
+ editor.popups.setContainer('video.size', editor.$sc);
1552
+ var $video_obj = $current_video.find('iframe, embed, video')
1553
+ var left = $video_obj.offset().left + $video_obj.width() / 2;
1554
+ var top = $video_obj.offset().top + $video_obj.height();
1555
+
1556
+ editor.popups.show('video.size', left, top, $video_obj.height());
1557
+ }
1558
+
1559
+ /**
1560
+ * Init the video upload popup.
1561
+ */
1562
+ function _initSizePopup (delayed) {
1563
+ if (delayed) {
1564
+ editor.popups.onRefresh('video.size', _refreshSizePopup);
1565
+
1566
+ return true;
1567
+ }
1568
+
1569
+ // Video buttons.
1570
+ var video_buttons = '';
1571
+ video_buttons = '<div class="fr-buttons">' + editor.button.buildList(editor.opts.videoSizeButtons) + '</div>';
1572
+
1573
+ // Size layer.
1574
+ var size_layer = '';
1575
+ size_layer = '<div class="fr-video-size-layer fr-layer fr-active" id="fr-video-size-layer-' + editor.id + '"><div class="fr-video-group"><div class="fr-input-line"><input id="fr-video-size-layer-width-' + editor.id + '" type="text" name="width" placeholder="' + editor.language.translate('Width') + '" tabIndex="1"></div><div class="fr-input-line"><input id="fr-video-size-layer-height-' + editor.id + '" type="text" name="height" placeholder="' + editor.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">' + editor.language.translate('Update') + '</button></div></div>';
1576
+
1577
+ var template = {
1578
+ buttons: video_buttons,
1579
+ size_layer: size_layer
1580
+ }
1581
+
1582
+ // Set the template in the popup.
1583
+ var $popup = editor.popups.create('video.size', template);
1584
+
1585
+ editor.events.$on(editor.$wp, 'scroll', function () {
1586
+ if ($current_video && editor.popups.isVisible('video.size')) {
1587
+
1588
+ editor.events.disableBlur();
1589
+ _editVideo($current_video);
1590
+ }
1591
+ });
1592
+
1593
+ return $popup;
1594
+ }
1595
+
1596
+ /**
1597
+ * Get video alignment.
1598
+ */
1599
+ function getAlign ($video) {
1600
+ if (typeof $video == 'undefined') $video = $current_video;
1601
+
1602
+ if ($video) {
1603
+
1604
+ // Video has left class.
1605
+ if ($video.hasClass('fr-fvl')) {
1606
+
1607
+ return 'left';
1608
+ }
1609
+
1610
+ // Video has right class.
1611
+ else if ($video.hasClass('fr-fvr')) {
1612
+
1613
+ return 'right';
1614
+ }
1615
+
1616
+ // Video has display class set.
1617
+ else if ($video.hasClass('fr-dvb') || $video.hasClass('fr-dvi')) {
1618
+
1619
+ return 'center';
1620
+ }
1621
+ else {
1622
+
1623
+ // Video has display block.
1624
+ if ($video.css('display') == 'block') {
1625
+
1626
+ // Margin left is 0.
1627
+ // Margin right is auto.
1628
+ if ($video.css('text-algin') == 'left') {
1629
+ return 'left';
1630
+ }
1631
+
1632
+ // Margin left is auto.
1633
+ // Margin right is 0.
1634
+ else if ($video.css('text-align') == 'right') {
1635
+ return 'right';
1636
+ }
1637
+ }
1638
+
1639
+ // Display inline.
1640
+ else {
1641
+
1642
+ // Float left.
1643
+ if ($video.css('float') == 'left') {
1644
+ return 'left';
1645
+ }
1646
+
1647
+ // Float right.
1648
+ else if ($video.css('float') == 'right') {
1649
+ return 'right';
1650
+ }
1651
+ }
1652
+ }
1653
+ }
1654
+
1655
+ return 'center';
1656
+ }
1657
+
1658
+ /**
1659
+ * Align video.
1660
+ */
1661
+ function align (val) {
1662
+ $current_video.removeClass('fr-fvr fr-fvl');
1663
+
1664
+ // Easy case. Use classes.
1665
+ if (!editor.opts.htmlUntouched && editor.opts.useClasses) {
1666
+ if (val == 'left') {
1667
+ $current_video.addClass('fr-fvl');
1668
+ }
1669
+ else if (val == 'right') {
1670
+ $current_video.addClass('fr-fvr');
1671
+ }
1672
+ }
1673
+ else {
1674
+ _setStyle($current_video, getDisplay(), val);
1675
+ }
1676
+
1677
+ _selectVideo()
1678
+ _repositionResizer();
1679
+ _showEditPopup();
1680
+ editor.selection.clear();
1681
+ }
1682
+
1683
+ /**
1684
+ * Refresh the align icon.
1685
+ */
1686
+ function refreshAlign ($btn) {
1687
+ if (!$current_video) return false;
1688
+
1689
+ $btn.find('> *:first').replaceWith(editor.icon.create('video-align-' + getAlign()));
1690
+ }
1691
+
1692
+ /**
1693
+ * Refresh the align option from the dropdown.
1694
+ */
1695
+ function refreshAlignOnShow ($btn, $dropdown) {
1696
+ if ($current_video) {
1697
+ $dropdown.find('.fr-command[data-param1="' + getAlign() + '"]').addClass('fr-active').attr('aria-selected', true);
1698
+ }
1699
+ }
1700
+
1701
+ /**
1702
+ * Get video display.
1703
+ */
1704
+ function getDisplay ($video) {
1705
+ if (typeof $video == 'undefined') $video = $current_video;
1706
+
1707
+ // Set float to none.
1708
+ var flt = $video.css('float');
1709
+ $video.css('float', 'none');
1710
+
1711
+ // Video has display block.
1712
+ if ($video.css('display') == 'block') {
1713
+
1714
+ // Set float to the initial value.
1715
+ $video.css('float', '');
1716
+
1717
+ if ($video.css('float') != flt) $video.css('float', flt);
1718
+
1719
+ return 'block';
1720
+ }
1721
+
1722
+ // Display inline.
1723
+ else {
1724
+
1725
+ // Set float.
1726
+ $video.css('float', '');
1727
+
1728
+ if ($video.css('float') != flt) $video.css('float', flt);
1729
+
1730
+ return 'inline';
1731
+ }
1732
+
1733
+ return 'inline';
1734
+ }
1735
+
1736
+
1737
+ /**
1738
+ * Set video display.
1739
+ */
1740
+ function display (val) {
1741
+ $current_video.removeClass('fr-dvi fr-dvb');
1742
+
1743
+ // Easy case. Use classes.
1744
+ if (!editor.opts.htmlUntouched && editor.opts.useClasses) {
1745
+ if (val == 'inline') {
1746
+ $current_video.addClass('fr-dvi');
1747
+ }
1748
+ else if (val == 'block') {
1749
+ $current_video.addClass('fr-dvb');
1750
+ }
1751
+ }
1752
+ else {
1753
+ _setStyle($current_video, val, getAlign());
1754
+ }
1755
+
1756
+ _selectVideo()
1757
+ _repositionResizer();
1758
+ _showEditPopup();
1759
+ editor.selection.clear();
1760
+ }
1761
+
1762
+ /**
1763
+ * Refresh the video display selected option.
1764
+ */
1765
+ function refreshDisplayOnShow ($btn, $dropdown) {
1766
+ if ($current_video) {
1767
+ $dropdown.find('.fr-command[data-param1="' + getDisplay() + '"]').addClass('fr-active').attr('aria-selected', true);
1768
+ }
1769
+ }
1770
+
1771
+ /**
1772
+ * Show the replace popup.
1773
+ */
1774
+
1775
+ function replace () {
1776
+ var $popup = editor.popups.get('video.insert');
1777
+
1778
+ if (!$popup) $popup = _initInsertPopup();
1779
+
1780
+ if (!editor.popups.isVisible('video.insert')) {
1781
+ hideProgressBar();
1782
+ editor.popups.refresh('video.insert');
1783
+ editor.popups.setContainer('video.insert', editor.$sc);
1784
+ }
1785
+
1786
+ var left = $current_video.offset().left + $current_video.width() / 2;
1787
+ var top = $current_video.offset().top + $current_video.height();
1788
+
1789
+ editor.popups.show('video.insert', left, top, $current_video.outerHeight());
1790
+ }
1791
+
1792
+ /**
1793
+ * Remove current selected video.
1794
+ */
1795
+ function remove () {
1796
+ if ($current_video) {
1797
+ if (editor.events.trigger('video.beforeRemove', [$current_video]) !== false) {
1798
+ var $video = $current_video;
1799
+ editor.popups.hideAll();
1800
+ _exitEdit(true);
1801
+
1802
+ editor.selection.setBefore($video.get(0)) || editor.selection.setAfter($video.get(0));
1803
+ $video.remove();
1804
+ editor.selection.restore();
1805
+
1806
+ editor.html.fillEmptyBlocks();
1807
+
1808
+ editor.events.trigger('video.removed', [$video]);
1809
+ }
1810
+ }
1811
+ }
1812
+
1813
+ /**
1814
+ * Hide image upload popup.
1815
+ */
1816
+
1817
+ function _hideInsertPopup () {
1818
+ hideProgressBar();
1819
+ }
1820
+
1821
+ function _setStyle ($video, _display, _align) {
1822
+ if (!editor.opts.htmlUntouched && editor.opts.useClasses) {
1823
+ $video.removeClass('fr-fvl fr-fvr fr-dvb fr-dvi');
1824
+ $video.addClass('fr-fv' + _align[0] + ' fr-dv' + _display[0]);
1825
+ }
1826
+ else {
1827
+ if (_display == 'inline') {
1828
+ $video.css({
1829
+ display: 'inline-block'
1830
+ })
1831
+
1832
+ if (_align == 'center') {
1833
+ $video.css({
1834
+ 'float': 'none'
1835
+ })
1836
+ }
1837
+ else if (_align == 'left') {
1838
+ $video.css({
1839
+ 'float': 'left'
1840
+ })
1841
+ }
1842
+ else {
1843
+ $video.css({
1844
+ 'float': 'right'
1845
+ })
1846
+ }
1847
+ }
1848
+ else {
1849
+ $video.css({
1850
+ display: 'block',
1851
+ clear: 'both'
1852
+ })
1853
+
1854
+ if (_align == 'left') {
1855
+ $video.css({
1856
+ textAlign: 'left'
1857
+ })
1858
+ }
1859
+ else if (_align == 'right') {
1860
+ $video.css({
1861
+ textAlign: 'right'
1862
+ })
1863
+ }
1864
+ else {
1865
+ $video.css({
1866
+ textAlign: 'center'
1867
+ })
1868
+ }
1869
+ }
1870
+ }
1871
+ }
1872
+
1873
+ /**
1874
+ * Convert style to classes.
1875
+ */
1876
+ function _convertStyleToClasses ($video) {
1877
+ if (!$video.hasClass('fr-dvi') && !$video.hasClass('fr-dvb')) {
1878
+ $video.addClass('fr-fv' + getAlign($video)[0]);
1879
+ $video.addClass('fr-dv' + getDisplay($video)[0]);
1880
+ }
1881
+ }
1882
+
1883
+ /**
1884
+ * Convert classes to style.
1885
+ */
1886
+ function _convertClassesToStyle ($video) {
1887
+ var d = $video.hasClass('fr-dvb') ? 'block' : $video.hasClass('fr-dvi') ? 'inline' : null;
1888
+ var a = $video.hasClass('fr-fvl') ? 'left' : $video.hasClass('fr-fvr') ? 'right' : getAlign($video);
1889
+
1890
+ _setStyle($video, d, a);
1891
+
1892
+ $video.removeClass('fr-dvb fr-dvi fr-fvr fr-fvl');
1893
+ }
1894
+
1895
+ /**
1896
+ * Refresh video list.
1897
+ */
1898
+ function _refreshVideoList () {
1899
+
1900
+ // Find possible candidates that are not wrapped.
1901
+ editor.$el.find('video').filter(function () {
1902
+
1903
+ return $(this).parents('span.fr-video').length === 0;
1904
+ }).wrap('<span class="fr-video" contenteditable="false"></span>');
1905
+
1906
+ editor.$el.find('embed, iframe').filter(function () {
1907
+ if (editor.browser.safari && this.getAttribute('src')) {
1908
+ this.setAttribute('src', this.src);
1909
+ }
1910
+
1911
+ if ($(this).parents('span.fr-video').length > 0) return false;
1912
+
1913
+ var link = $(this).attr('src');
1914
+
1915
+ for (var i = 0; i < $.FE.VIDEO_PROVIDERS.length; i++) {
1916
+ var vp = $.FE.VIDEO_PROVIDERS[i];
1917
+
1918
+ // Check if video provider is allowed.
1919
+ if (vp.test_regex.test(link) && (new RegExp(editor.opts.videoAllowedProviders.join('|'))).test(vp.provider)) {
1920
+
1921
+ return true;
1922
+ }
1923
+ }
1924
+
1925
+ return false;
1926
+ }).map(function () {
1927
+ return $(this).parents('object').length === 0 ? this : $(this).parents('object').get(0);
1928
+ }).wrap('<span class="fr-video" contenteditable="false"></span>');
1929
+
1930
+ var videos = editor.$el.find('span.fr-video, video');
1931
+
1932
+ for (var i = 0; i < videos.length; i++) {
1933
+ var $video = $(videos[i]);
1934
+
1935
+ if (!editor.opts.htmlUntouched && editor.opts.useClasses) {
1936
+ _convertStyleToClasses($video);
1937
+
1938
+ if (!editor.opts.videoTextNear) {
1939
+ $video.removeClass('fr-dvi').addClass('fr-dvb');
1940
+ }
1941
+ }
1942
+ else if (!editor.opts.htmlUntouched && !editor.opts.useClasses) {
1943
+ _convertClassesToStyle($video);
1944
+ }
1945
+ }
1946
+
1947
+ videos.toggleClass('fr-draggable', editor.opts.videoMove);
1948
+ }
1949
+
1950
+ function _init () {
1951
+ _initEvents();
1952
+
1953
+ if (editor.helpers.isMobile()) {
1954
+ editor.events.$on(editor.$el, 'touchstart', 'span.fr-video', function () {
1955
+ touchScroll = false;
1956
+ })
1957
+
1958
+ editor.events.$on(editor.$el, 'touchmove', function () {
1959
+ touchScroll = true;
1960
+ });
1961
+ }
1962
+
1963
+ editor.events.on('html.set', _refreshVideoList);
1964
+ _refreshVideoList();
1965
+
1966
+ editor.events.$on(editor.$el, 'mousedown', 'span.fr-video', function (e) {
1967
+ e.stopPropagation();
1968
+ })
1969
+ editor.events.$on(editor.$el, 'click touchend', 'span.fr-video', function (e) {
1970
+ if ($(this).parents('[contenteditable]:not(.fr-element):not(.fr-img-caption):not(body):first').attr('contenteditable') == 'false') return true;
1971
+
1972
+ _edit.call(this, e);
1973
+ });
1974
+
1975
+ editor.events.on('keydown', function (e) {
1976
+ var key_code = e.which;
1977
+
1978
+ if ($current_video && (key_code == $.FE.KEYCODE.BACKSPACE || key_code == $.FE.KEYCODE.DELETE)) {
1979
+ e.preventDefault();
1980
+ remove();
1981
+ editor.undo.saveStep();
1982
+
1983
+ return false;
1984
+ }
1985
+
1986
+ if ($current_video && key_code == $.FE.KEYCODE.ESC) {
1987
+ _exitEdit(true);
1988
+ e.preventDefault();
1989
+
1990
+ return false;
1991
+ }
1992
+
1993
+ if ($current_video && key_code != $.FE.KEYCODE.F10 && !editor.keys.isBrowserAction(e)) {
1994
+ e.preventDefault();
1995
+
1996
+ return false;
1997
+ }
1998
+ }, true);
1999
+
2000
+ // ESC from accessibility.
2001
+ editor.events.on('toolbar.esc', function () {
2002
+ if ($current_video) {
2003
+ editor.events.disableBlur();
2004
+ editor.events.focus();
2005
+
2006
+ return false;
2007
+ }
2008
+ }, true);
2009
+
2010
+ // focusEditor from accessibility.
2011
+ editor.events.on('toolbar.focusEditor', function () {
2012
+ if ($current_video) {
2013
+
2014
+ return false;
2015
+ }
2016
+ }, true);
2017
+
2018
+ // Make sure we don't leave empty tags.
2019
+ editor.events.on('keydown', function () {
2020
+ editor.$el.find('span.fr-video:empty').remove();
2021
+ })
2022
+
2023
+ if (editor.$wp) {
2024
+ _syncVideos();
2025
+ editor.events.on('contentChanged', _syncVideos);
2026
+ }
2027
+
2028
+ _initInsertPopup(true);
2029
+ _initSizePopup(true);
2030
+ }
2031
+
2032
+ /**
2033
+ * Place selection around current video.
2034
+ */
2035
+ function _selectVideo () {
2036
+ if ($current_video) {
2037
+ editor.selection.clear();
2038
+ var range = editor.doc.createRange();
2039
+ range.selectNode($current_video.get(0));
2040
+ var selection = editor.selection.get();
2041
+ selection.addRange(range);
2042
+ }
2043
+ }
2044
+
2045
+ /**
2046
+ * Get back to the video main popup.
2047
+ */
2048
+ function back () {
2049
+ if ($current_video) {
2050
+ editor.events.disableBlur();
2051
+ $current_video.trigger('click');
2052
+ }
2053
+ else {
2054
+ editor.events.disableBlur();
2055
+ editor.selection.restore();
2056
+ editor.events.enableBlur();
2057
+
2058
+ editor.popups.hide('video.insert');
2059
+ editor.toolbar.showInline();
2060
+ }
2061
+ }
2062
+
2063
+ /**
2064
+ * Set size based on the current video size.
2065
+ */
2066
+ function setSize (width, height) {
2067
+ if ($current_video) {
2068
+ var $popup = editor.popups.get('video.size');
2069
+ var $video_obj = $current_video.find('iframe, embed, video');
2070
+ $video_obj.css('width', width || $popup.find('input[name="width"]').val());
2071
+ $video_obj.css('height', height || $popup.find('input[name="height"]').val());
2072
+
2073
+ if ($video_obj.get(0).style.width) $video_obj.removeAttr('width');
2074
+
2075
+ if ($video_obj.get(0).style.height) $video_obj.removeAttr('height');
2076
+
2077
+ $popup.find('input:focus').blur();
2078
+ setTimeout(function () {
2079
+ $current_video.trigger('click');
2080
+ }, editor.helpers.isAndroid() ? 50 : 0);
2081
+ }
2082
+ }
2083
+
2084
+ function get () {
2085
+
2086
+ return $current_video;
2087
+ }
2088
+
2089
+ return {
2090
+ _init: _init,
2091
+ showInsertPopup: showInsertPopup,
2092
+ showLayer: showLayer,
2093
+ refreshByURLButton: refreshByURLButton,
2094
+ refreshEmbedButton: refreshEmbedButton,
2095
+ refreshUploadButton: refreshUploadButton,
2096
+ upload: upload,
2097
+ insertByURL: insertByURL,
2098
+ insertEmbed: insertEmbed,
2099
+ insert: insert,
2100
+ align: align,
2101
+ refreshAlign: refreshAlign,
2102
+ refreshAlignOnShow: refreshAlignOnShow,
2103
+ display: display,
2104
+ refreshDisplayOnShow: refreshDisplayOnShow,
2105
+ remove: remove,
2106
+ hideProgressBar: hideProgressBar,
2107
+ showSizePopup: showSizePopup,
2108
+ replace: replace,
2109
+ back: back,
2110
+ setSize: setSize,
2111
+ get: get
2112
+ }
2113
+ }
2114
+
2115
+ // Register the font size command.
2116
+ $.FE.RegisterCommand('insertVideo', {
2117
+ title: 'Insert Video',
2118
+ undo: false,
2119
+ focus: true,
2120
+ refreshAfterCallback: false,
2121
+ popup: true,
2122
+ callback: function () {
2123
+ if (!this.popups.isVisible('video.insert')) {
2124
+ this.video.showInsertPopup();
2125
+ }
2126
+ else {
2127
+ if (this.$el.find('.fr-marker').length) {
2128
+ this.events.disableBlur();
2129
+ this.selection.restore();
2130
+ }
2131
+ this.popups.hide('video.insert');
2132
+ }
2133
+ },
2134
+ plugin: 'video'
2135
+ })
2136
+
2137
+ // Add the font size icon.
2138
+ $.FE.DefineIcon('insertVideo', {
2139
+ NAME: 'video-camera',
2140
+ FA5NAME: 'camera'
2141
+ });
2142
+
2143
+ // Video by URL button inside the insert video popup.
2144
+ $.FE.DefineIcon('videoByURL', { NAME: 'link' });
2145
+ $.FE.RegisterCommand('videoByURL', {
2146
+ title: 'By URL',
2147
+ undo: false,
2148
+ focus: false,
2149
+ toggle: true,
2150
+ callback: function () {
2151
+ this.video.showLayer('video-by-url');
2152
+ },
2153
+ refresh: function ($btn) {
2154
+ this.video.refreshByURLButton($btn);
2155
+ }
2156
+ })
2157
+
2158
+ // Video embed button inside the insert video popup.
2159
+ $.FE.DefineIcon('videoEmbed', { NAME: 'code' });
2160
+ $.FE.RegisterCommand('videoEmbed', {
2161
+ title: 'Embedded Code',
2162
+ undo: false,
2163
+ focus: false,
2164
+ toggle: true,
2165
+ callback: function () {
2166
+ this.video.showLayer('video-embed');
2167
+ },
2168
+ refresh: function ($btn) {
2169
+ this.video.refreshEmbedButton($btn);
2170
+ }
2171
+ })
2172
+
2173
+ // Video upload button inside the insert video popup.
2174
+ $.FE.DefineIcon('videoUpload', { NAME: 'upload' });
2175
+ $.FE.RegisterCommand('videoUpload', {
2176
+ title: 'Upload Video',
2177
+ undo: false,
2178
+ focus: false,
2179
+ toggle: true,
2180
+ callback: function () {
2181
+ this.video.showLayer('video-upload');
2182
+ },
2183
+ refresh: function ($btn) {
2184
+ this.video.refreshUploadButton($btn);
2185
+ }
2186
+ })
2187
+
2188
+ $.FE.RegisterCommand('videoInsertByURL', {
2189
+ undo: true,
2190
+ focus: true,
2191
+ callback: function () {
2192
+ this.video.insertByURL();
2193
+ }
2194
+ })
2195
+
2196
+ $.FE.RegisterCommand('videoInsertEmbed', {
2197
+ undo: true,
2198
+ focus: true,
2199
+ callback: function () {
2200
+ this.video.insertEmbed();
2201
+ }
2202
+ })
2203
+
2204
+ // Video display.
2205
+ $.FE.DefineIcon('videoDisplay', { NAME: 'star' })
2206
+ $.FE.RegisterCommand('videoDisplay', {
2207
+ title: 'Display',
2208
+ type: 'dropdown',
2209
+ options: {
2210
+ inline: 'Inline',
2211
+ block: 'Break Text'
2212
+ },
2213
+ callback: function (cmd, val) {
2214
+ this.video.display(val);
2215
+ },
2216
+ refresh: function ($btn) {
2217
+ if (!this.opts.videoTextNear) $btn.addClass('fr-hidden');
2218
+ },
2219
+ refreshOnShow: function ($btn, $dropdown) {
2220
+ this.video.refreshDisplayOnShow($btn, $dropdown);
2221
+ }
2222
+ })
2223
+
2224
+ // Video align.
2225
+ $.FE.DefineIcon('video-align', { NAME: 'align-left' });
2226
+ $.FE.DefineIcon('video-align-left', { NAME: 'align-left' });
2227
+ $.FE.DefineIcon('video-align-right', { NAME: 'align-right' });
2228
+ $.FE.DefineIcon('video-align-center', { NAME: 'align-justify' });
2229
+
2230
+ // Video align.
2231
+ $.FE.DefineIcon('videoAlign', { NAME: 'align-center' })
2232
+ $.FE.RegisterCommand('videoAlign', {
2233
+ type: 'dropdown',
2234
+ title: 'Align',
2235
+ options: {
2236
+ left: 'Align Left',
2237
+ center: 'None',
2238
+ right: 'Align Right'
2239
+ },
2240
+ html: function () {
2241
+ var c = '<ul class="fr-dropdown-list" role="presentation">';
2242
+ var options = $.FE.COMMANDS.videoAlign.options;
2243
+
2244
+ for (var val in options) {
2245
+ if (options.hasOwnProperty(val)) {
2246
+ c += '<li role="presentation"><a class="fr-command fr-title" tabIndex="-1" role="option" data-cmd="videoAlign" data-param1="' + val + '" title="' + this.language.translate(options[val]) + '">' + this.icon.create('video-align-' + val) + '<span class="fr-sr-only">' + this.language.translate(options[val]) + '</span></a></li>';
2247
+ }
2248
+ }
2249
+ c += '</ul>';
2250
+
2251
+ return c;
2252
+ },
2253
+ callback: function (cmd, val) {
2254
+ this.video.align(val);
2255
+ },
2256
+ refresh: function ($btn) {
2257
+ this.video.refreshAlign($btn);
2258
+ },
2259
+ refreshOnShow: function ($btn, $dropdown) {
2260
+ this.video.refreshAlignOnShow($btn, $dropdown);
2261
+ }
2262
+ })
2263
+
2264
+ // Video replace.
2265
+ $.FE.DefineIcon('videoReplace', {
2266
+ NAME: 'exchange'
2267
+ })
2268
+ $.FE.RegisterCommand('videoReplace', {
2269
+ title: 'Replace',
2270
+ undo: false,
2271
+ focus: false,
2272
+ popup: true,
2273
+ refreshAfterCallback: false,
2274
+ callback: function () {
2275
+ this.video.replace();
2276
+ }
2277
+ })
2278
+
2279
+ // Video remove.
2280
+ $.FE.DefineIcon('videoRemove', { NAME: 'trash' })
2281
+ $.FE.RegisterCommand('videoRemove', {
2282
+ title: 'Remove',
2283
+ callback: function () {
2284
+ this.video.remove();
2285
+ }
2286
+ })
2287
+
2288
+ // Video size.
2289
+ $.FE.DefineIcon('videoSize', { NAME: 'arrows-alt' })
2290
+ $.FE.RegisterCommand('videoSize', {
2291
+ undo: false,
2292
+ focus: false,
2293
+ popup: true,
2294
+ title: 'Change Size',
2295
+ callback: function () {
2296
+ this.video.showSizePopup();
2297
+ }
2298
+ });
2299
+
2300
+ // Video back.
2301
+ $.FE.DefineIcon('videoBack', { NAME: 'arrow-left' });
2302
+ $.FE.RegisterCommand('videoBack', {
2303
+ title: 'Back',
2304
+ undo: false,
2305
+ focus: false,
2306
+ back: true,
2307
+ callback: function () {
2308
+ this.video.back();
2309
+ },
2310
+ refresh: function ($btn) {
2311
+ var $current_video = this.video.get();
2312
+
2313
+ if (!$current_video && !this.opts.toolbarInline) {
2314
+ $btn.addClass('fr-hidden');
2315
+ $btn.next('.fr-separator').addClass('fr-hidden');
2316
+ }
2317
+ else {
2318
+ $btn.removeClass('fr-hidden');
2319
+ $btn.next('.fr-separator').removeClass('fr-hidden');
2320
+ }
2321
+ }
2322
+ });
2323
+
2324
+ $.FE.RegisterCommand('videoDismissError', {
2325
+ title: 'OK',
2326
+ undo: false,
2327
+ callback: function () {
2328
+ this.video.hideProgressBar(true);
2329
+ }
2330
+ })
2331
+
2332
+ $.FE.RegisterCommand('videoSetSize', {
2333
+ undo: true,
2334
+ focus: false,
2335
+ title: 'Update',
2336
+ refreshAfterCallback: false,
2337
+ callback: function () {
2338
+ this.video.setSize();
2339
+ }
2340
+ })
2341
+
2342
+ }));