xmt_froala 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +2 -0
- data/app/assets/javascripts/xmt_froala.js +31 -0
- data/app/assets/stylesheets/xmt_froala.css +17 -0
- data/app/controllers/xmt_froala/application_controller.rb +5 -0
- data/app/controllers/xmt_froala/assets_controller.rb +94 -0
- data/app/models/xmt_froala/asset_uploader.rb +107 -0
- data/app/models/xmt_froala/file_uploader.rb +10 -0
- data/app/models/xmt_froala/flash_uploader.rb +10 -0
- data/app/models/xmt_froala/image_uploader.rb +10 -0
- data/app/models/xmt_froala/media_uploader.rb +10 -0
- data/config/routes.rb +6 -0
- data/lib/generators/xmt_froala/install/USAGE +10 -0
- data/lib/generators/xmt_froala/install/install_generator.rb +23 -0
- data/lib/generators/xmt_froala/install/templates/application.js +17 -0
- data/lib/generators/xmt_froala/install/templates/xmt_froala.rb +29 -0
- data/lib/generators/xmt_froala/migration/USAGE +14 -0
- data/lib/generators/xmt_froala/migration/migration_generator.rb +36 -0
- data/lib/generators/xmt_froala/migration/templates/migration/migration.rb +18 -0
- data/lib/generators/xmt_froala/migration/templates/models/active_record/xmt_froala/asset.rb +14 -0
- data/lib/generators/xmt_froala/migration/templates/models/active_record/xmt_froala/file.rb +3 -0
- data/lib/generators/xmt_froala/migration/templates/models/active_record/xmt_froala/flash.rb +3 -0
- data/lib/generators/xmt_froala/migration/templates/models/active_record/xmt_froala/image.rb +3 -0
- data/lib/generators/xmt_froala/migration/templates/models/active_record/xmt_froala/media.rb +3 -0
- data/lib/generators/xmt_froala/migration/templates/models/mongoid/xmt_froala/asset.rb +27 -0
- data/lib/generators/xmt_froala/migration/templates/models/mongoid/xmt_froala/file.rb +3 -0
- data/lib/generators/xmt_froala/migration/templates/models/mongoid/xmt_froala/flash.rb +3 -0
- data/lib/generators/xmt_froala/migration/templates/models/mongoid/xmt_froala/image.rb +3 -0
- data/lib/generators/xmt_froala/migration/templates/models/mongoid/xmt_froala/media.rb +3 -0
- data/lib/tasks/xmt_froala_tasks.rake +9 -0
- data/lib/xmt_froala.rb +65 -0
- data/lib/xmt_froala/active_record.rb +14 -0
- data/lib/xmt_froala/engine.rb +32 -0
- data/lib/xmt_froala/formtastic.rb +12 -0
- data/lib/xmt_froala/helper.rb +105 -0
- data/lib/xmt_froala/simple_form.rb +11 -0
- data/lib/xmt_froala/version.rb +3 -0
- data/vendor/assets/javascripts/xmt_froala/froala_editor.js +0 -0
- data/vendor/assets/javascripts/xmt_froala/languages/ar.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/bs.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/cs.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/da.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/de.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/en_ca.js +262 -0
- data/vendor/assets/javascripts/xmt_froala/languages/en_gb.js +262 -0
- data/vendor/assets/javascripts/xmt_froala/languages/es.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/et.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/fa.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/fi.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/fr.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/he.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/hr.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/hu.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/id.js +319 -0
- data/vendor/assets/javascripts/xmt_froala/languages/it.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/ja.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/ko.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/me.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/nb.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/nl.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/pl.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/pt_br.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/pt_pt.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/ro.js +319 -0
- data/vendor/assets/javascripts/xmt_froala/languages/ru.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/sk.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/sr.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/sv.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/th.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/tr.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/uk.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/languages/vi.js +258 -0
- data/vendor/assets/javascripts/xmt_froala/languages/zh_cn.js +320 -0
- data/vendor/assets/javascripts/xmt_froala/languages/zh_tw.js +318 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/align.js +139 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/align.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/char_counter.js +154 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/char_counter.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/code_beautifier.js +3270 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/code_beautifier.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/code_view.js +393 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/code_view.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/colors.js +492 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/colors.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/draggable.js +459 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/draggable.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/emoticons.js +509 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/emoticons.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/entities.js +121 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/entities.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/file.js +736 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/file.min.js +239 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/font_family.js +182 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/font_family.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/font_size.js +118 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/font_size.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/forms.js +430 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/forms.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/fullscreen.js +274 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/fullscreen.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/help.js +216 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/help.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/image.js +3323 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/image.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/image_manager.js +1056 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/image_manager.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/inline_style.js +94 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/inline_style.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/line_breaker.js +537 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/line_breaker.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/link.js +1157 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/link.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/lists.js +462 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/lists.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/paragraph_format.js +290 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/paragraph_format.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/paragraph_style.js +144 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/paragraph_style.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/plain_paste.js +96 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/print.js +137 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/print.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/quick_format.js +89 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/quick_insert.js +478 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/quick_insert.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/quote.js +141 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/quote.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/save.js +189 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/save.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/special_characters.js +781 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/special_characters.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/table.js +4194 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/table.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/url.js +194 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/url.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/video.js +2342 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/video.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/word_paste.js +1403 -0
- data/vendor/assets/javascripts/xmt_froala/plugins/word_paste.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/third_party/embedly.js +543 -0
- data/vendor/assets/javascripts/xmt_froala/third_party/embedly.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/third_party/image_aviary.js +163 -0
- data/vendor/assets/javascripts/xmt_froala/third_party/image_aviary.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/third_party/spell_checker.js +222 -0
- data/vendor/assets/javascripts/xmt_froala/third_party/spell_checker.min.js +7 -0
- data/vendor/assets/javascripts/xmt_froala/xmt_froala.js +15172 -0
- data/vendor/assets/stylesheets/xmt_froala/css/font-awesome.css +2546 -0
- data/vendor/assets/stylesheets/xmt_froala/css/froala_editor.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/froala_editor.pkgd.css +2902 -0
- data/vendor/assets/stylesheets/xmt_froala/css/froala_editor.pkgd.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/froala_style.css +413 -0
- data/vendor/assets/stylesheets/xmt_froala/css/froala_style.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/char_counter.css +57 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/char_counter.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/code_view.css +112 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/code_view.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/colors.css +155 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/colors.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/draggable.css +43 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/draggable.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/emoticons.css +42 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/emoticons.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/file.css +146 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/file.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/fullscreen.css +28 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/fullscreen.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/help.css +52 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/help.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/image.css +244 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/image.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/image_manager.css +266 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/image_manager.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/line_breaker.css +37 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/line_breaker.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/quick_insert.css +70 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/quick_insert.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/special_characters.css +51 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/special_characters.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/table.css +181 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/table.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/video.css +231 -0
- data/vendor/assets/stylesheets/xmt_froala/css/plugins/video.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/themes/dark.css +1281 -0
- data/vendor/assets/stylesheets/xmt_froala/css/themes/dark.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/themes/gray.css +1281 -0
- data/vendor/assets/stylesheets/xmt_froala/css/themes/gray.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/themes/red.css +1281 -0
- data/vendor/assets/stylesheets/xmt_froala/css/themes/red.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/themes/royal.css +1281 -0
- data/vendor/assets/stylesheets/xmt_froala/css/themes/royal.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/third_party/embedly.css +64 -0
- data/vendor/assets/stylesheets/xmt_froala/css/third_party/embedly.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/third_party/spell_checker.css +72 -0
- data/vendor/assets/stylesheets/xmt_froala/css/third_party/spell_checker.min.css +7 -0
- data/vendor/assets/stylesheets/xmt_froala/css/xmt_froala.css +1423 -0
- data/vendor/assets/stylesheets/xmt_froala/fonts/FontAwesome.otf +0 -0
- data/vendor/assets/stylesheets/xmt_froala/fonts/fontawesome-webfont.eot +0 -0
- data/vendor/assets/stylesheets/xmt_froala/fonts/fontawesome-webfont.svg +2671 -0
- data/vendor/assets/stylesheets/xmt_froala/fonts/fontawesome-webfont.ttf +0 -0
- data/vendor/assets/stylesheets/xmt_froala/fonts/fontawesome-webfont.woff +0 -0
- data/vendor/assets/stylesheets/xmt_froala/fonts/fontawesome-webfont.woff2 +0 -0
- 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(o){"function"==typeof define&&define.amd?define(["jquery"],o):"object"==typeof module&&module.exports?module.exports=function(e,t){return t===undefined&&(t="undefined"!=typeof window?require("jquery"):require("jquery")(e)),o(t)}:o(window.jQuery)}(function(c){c.FE.PLUGINS.fullscreen=function(o){var t,r,s,n;function i(){return o.$box.hasClass("fr-fullscreen")}function e(){if(o.helpers.isIOS()&&o.core.hasFocus())return o.$el.blur(),setTimeout(a,250),!1;t=o.helpers.scrollTop(),o.$box.toggleClass("fr-fullscreen"),c("body:first").toggleClass("fr-fullscreen"),o.helpers.isMobile()&&(o.$tb.data("parent",o.$tb.parent()),o.$tb.prependTo(o.$box),o.$tb.data("sticky-dummy")&&o.$tb.after(o.$tb.data("sticky-dummy"))),r=o.opts.height,s=o.opts.heightMax,n=o.opts.zIndex,o.position.refresh(),o.opts.height=o.o_win.innerHeight-(o.opts.toolbarInline?0:o.$tb.outerHeight()),o.opts.zIndex=2147483641,o.opts.heightMax=null,o.size.refresh(),o.opts.toolbarInline&&o.toolbar.showInline();for(var e=o.$box.parent();!e.is("body:first");)e.data("z-index",e.css("z-index")).data("overflow",e.css("overflow")).css("z-index","2147483640").css("overflow","visible"),e=e.parent();o.opts.toolbarContainer&&o.$box.prepend(o.$tb),o.events.trigger("charCounter.update"),o.events.trigger("codeView.update"),o.$win.trigger("scroll")}function l(){if(o.helpers.isIOS()&&o.core.hasFocus())return o.$el.blur(),setTimeout(a,250),!1;o.$box.toggleClass("fr-fullscreen"),c("body:first").toggleClass("fr-fullscreen"),o.$tb.prependTo(o.$tb.data("parent")),o.$tb.data("sticky-dummy")&&o.$tb.after(o.$tb.data("sticky-dummy")),o.opts.height=r,o.opts.heightMax=s,o.opts.zIndex=n,o.size.refresh(),c(o.o_win).scrollTop(t),o.opts.toolbarInline&&o.toolbar.showInline(),o.events.trigger("charCounter.update"),o.opts.toolbarSticky&&o.opts.toolbarStickyOffset&&(o.opts.toolbarBottom?o.$tb.css("bottom",o.opts.toolbarStickyOffset).data("bottom",o.opts.toolbarStickyOffset):o.$tb.css("top",o.opts.toolbarStickyOffset).data("top",o.opts.toolbarStickyOffset));for(var e=o.$box.parent();!e.is("body:first");)e.data("z-index")&&(e.css("z-index",""),e.css("z-index")!=e.data("z-index")&&e.css("z-index",e.data("z-index")),e.removeData("z-index")),e.data("overflow")?(e.css("overflow",""),e.css("overflow")!=e.data("overflow")&&e.css("overflow",e.data("overflow"))):e.css("overflow",""),e.removeData("overflow"),e=e.parent();o.opts.toolbarContainer&&c(o.opts.toolbarContainer).append(o.$tb),c(o.o_win).trigger("scroll"),o.events.trigger("codeView.update")}function a(){i()?l():e(),f(o.$tb.find('.fr-command[data-cmd="fullscreen"]'))}function f(e){var t=i();e.toggleClass("fr-active",t).attr("aria-pressed",t),e.find("> *:not(.fr-sr-only)").replaceWith(t?o.icon.create("fullscreenCompress"):o.icon.create("fullscreen"))}return{_init:function(){if(!o.$wp)return!1;o.events.$on(c(o.o_win),"resize",function(){i()&&(l(),e())}),o.events.on("toolbar.hide",function(){if(i()&&o.helpers.isMobile())return!1}),o.events.on("position.refresh",function(){if(o.helpers.isIOS())return!i()}),o.events.on("destroy",function(){i()&&l()},!0)},toggle:a,refresh:f,isActive:i}},c.FE.RegisterCommand("fullscreen",{title:"Fullscreen",undo:!1,focus:!1,accessibilityFocus:!0,forcedRefresh:!0,toggle:!0,callback:function(){this.fullscreen.toggle()},refresh:function(e){this.fullscreen.refresh(e)},plugin:"fullscreen"}),c.FE.DefineIcon("fullscreen",{NAME:"expand"}),c.FE.DefineIcon("fullscreenCompress",{NAME:"compress"})});
|
|
@@ -0,0 +1,216 @@
|
|
|
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 defaults.
|
|
37
|
+
$.extend($.FE.DEFAULTS, {
|
|
38
|
+
helpSets: [
|
|
39
|
+
{
|
|
40
|
+
title: 'Inline Editor',
|
|
41
|
+
commands: [
|
|
42
|
+
{ val: 'OSkeyE', desc: 'Show the editor' }
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
title: 'Common actions',
|
|
47
|
+
commands: [
|
|
48
|
+
{ val: 'OSkeyC', desc: 'Copy' },
|
|
49
|
+
{ val: 'OSkeyX', desc: 'Cut' },
|
|
50
|
+
{ val: 'OSkeyV', desc: 'Paste' },
|
|
51
|
+
{ val: 'OSkeyZ', desc: 'Undo' },
|
|
52
|
+
{ val: 'OSkeyShift+Z', desc: 'Redo' },
|
|
53
|
+
{ val: 'OSkeyK', desc: 'Insert Link' },
|
|
54
|
+
{ val: 'OSkeyP', desc: 'Insert Image' }
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
title: 'Basic Formatting',
|
|
59
|
+
commands: [
|
|
60
|
+
{ val: 'OSkeyA', desc: 'Select All' },
|
|
61
|
+
{ val: 'OSkeyB', desc: 'Bold' },
|
|
62
|
+
{ val: 'OSkeyI', desc: 'Italic' },
|
|
63
|
+
{ val: 'OSkeyU', desc: 'Underline' },
|
|
64
|
+
{ val: 'OSkeyS', desc: 'Strikethrough' },
|
|
65
|
+
{ val: 'OSkey]', desc: 'Increase Indent' },
|
|
66
|
+
{ val: 'OSkey[', desc: 'Decrease Indent' }
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
title: 'Quote',
|
|
71
|
+
commands: [
|
|
72
|
+
{ val: 'OSkey\'', desc: 'Increase quote level' },
|
|
73
|
+
{ val: 'OSkeyShift+\'', desc: 'Decrease quote level' }
|
|
74
|
+
]
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
title: 'Image / Video',
|
|
78
|
+
commands: [
|
|
79
|
+
{ val: 'OSkey+', desc: 'Resize larger' },
|
|
80
|
+
{ val: 'OSkey-', desc: 'Resize smaller' }
|
|
81
|
+
]
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
title: 'Table',
|
|
85
|
+
commands: [
|
|
86
|
+
{ val: 'Alt+Space', desc: 'Select table cell' },
|
|
87
|
+
{ val: 'Shift+Left/Right arrow', desc: 'Extend selection one cell' },
|
|
88
|
+
{ val: 'Shift+Up/Down arrow', desc: 'Extend selection one row' }
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
title: 'Navigation',
|
|
93
|
+
commands: [
|
|
94
|
+
{ val: 'OSkey/', desc: 'Shortcuts' },
|
|
95
|
+
{ val: 'Alt+F10', desc: 'Focus popup / toolbar' },
|
|
96
|
+
{ val: 'Esc', desc: 'Return focus to previous position' }
|
|
97
|
+
]
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
$.FE.PLUGINS.help = function (editor) {
|
|
103
|
+
var $modal;
|
|
104
|
+
var modal_id = 'help';
|
|
105
|
+
|
|
106
|
+
var $head;
|
|
107
|
+
var $body;
|
|
108
|
+
|
|
109
|
+
/*
|
|
110
|
+
* Init Help.
|
|
111
|
+
*/
|
|
112
|
+
function _init () {
|
|
113
|
+
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/*
|
|
117
|
+
* Build html body.
|
|
118
|
+
*/
|
|
119
|
+
function _buildBody () {
|
|
120
|
+
|
|
121
|
+
// Begin body.
|
|
122
|
+
var body = '<div class="fr-help-modal">';
|
|
123
|
+
|
|
124
|
+
for (var i = 0; i < editor.opts.helpSets.length; i++) {
|
|
125
|
+
var set = editor.opts.helpSets[i];
|
|
126
|
+
|
|
127
|
+
// Set shortcuts table.
|
|
128
|
+
// Begin Table.
|
|
129
|
+
var group = '<table>';
|
|
130
|
+
|
|
131
|
+
// Set title.
|
|
132
|
+
group += '<thead><tr><th>' + editor.language.translate(set.title) + '</th></tr></thead>';
|
|
133
|
+
group += '<tbody>';
|
|
134
|
+
|
|
135
|
+
// Build commands table.
|
|
136
|
+
for (var j = 0; j < set.commands.length; j++) {
|
|
137
|
+
var command = set.commands[j];
|
|
138
|
+
group += '<tr>';
|
|
139
|
+
|
|
140
|
+
group += '<td>' + editor.language.translate(command.desc) + '</td>';
|
|
141
|
+
group += '<td>' + command.val.replace('OSkey', editor.helpers.isMac() ? '⌘' : 'Ctrl+') + '</td>';
|
|
142
|
+
|
|
143
|
+
group += '</tr>';
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// End table.
|
|
147
|
+
group += '</tbody></table>';
|
|
148
|
+
|
|
149
|
+
// Append group to body.
|
|
150
|
+
body += group;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// End body.
|
|
154
|
+
body += '</div>';
|
|
155
|
+
|
|
156
|
+
return body;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/*
|
|
160
|
+
* Show help.
|
|
161
|
+
*/
|
|
162
|
+
function show () {
|
|
163
|
+
if (!$modal) {
|
|
164
|
+
var head = '<h4>' + editor.language.translate('Shortcuts') + '</h4>';
|
|
165
|
+
var body = _buildBody();
|
|
166
|
+
|
|
167
|
+
var modalHash = editor.modals.create(modal_id, head, body);
|
|
168
|
+
$modal = modalHash.$modal;
|
|
169
|
+
$head = modalHash.$head;
|
|
170
|
+
$body = modalHash.$body;
|
|
171
|
+
|
|
172
|
+
// Resize help modal on window resize.
|
|
173
|
+
editor.events.$on($(editor.o_win), 'resize', function () {
|
|
174
|
+
editor.modals.resize(modal_id);
|
|
175
|
+
})
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Show modal.
|
|
179
|
+
editor.modals.show(modal_id);
|
|
180
|
+
|
|
181
|
+
// Modal may not fit window size.
|
|
182
|
+
editor.modals.resize(modal_id);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/*
|
|
186
|
+
* Hide help.
|
|
187
|
+
*/
|
|
188
|
+
function hide () {
|
|
189
|
+
editor.modals.hide(modal_id);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return {
|
|
193
|
+
_init: _init,
|
|
194
|
+
show: show,
|
|
195
|
+
hide: hide
|
|
196
|
+
};
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
$.FroalaEditor.DefineIcon('help', { NAME: 'question' })
|
|
200
|
+
|
|
201
|
+
$.FE.RegisterShortcut($.FE.KEYCODE.SLASH, 'help', null, '/');
|
|
202
|
+
|
|
203
|
+
$.FE.RegisterCommand('help', {
|
|
204
|
+
title: 'Help',
|
|
205
|
+
icon: 'help',
|
|
206
|
+
undo: false,
|
|
207
|
+
focus: false,
|
|
208
|
+
modal: true,
|
|
209
|
+
callback: function () {
|
|
210
|
+
this.help.show();
|
|
211
|
+
},
|
|
212
|
+
plugin: 'help',
|
|
213
|
+
showOnMobile: false
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
}));
|
|
@@ -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(l){"function"==typeof define&&define.amd?define(["jquery"],l):"object"==typeof module&&module.exports?module.exports=function(e,t){return t===undefined&&(t="undefined"!=typeof window?require("jquery"):require("jquery")(e)),l(t)}:l(window.jQuery)}(function(n){n.extend(n.FE.DEFAULTS,{helpSets:[{title:"Inline Editor",commands:[{val:"OSkeyE",desc:"Show the editor"}]},{title:"Common actions",commands:[{val:"OSkeyC",desc:"Copy"},{val:"OSkeyX",desc:"Cut"},{val:"OSkeyV",desc:"Paste"},{val:"OSkeyZ",desc:"Undo"},{val:"OSkeyShift+Z",desc:"Redo"},{val:"OSkeyK",desc:"Insert Link"},{val:"OSkeyP",desc:"Insert Image"}]},{title:"Basic Formatting",commands:[{val:"OSkeyA",desc:"Select All"},{val:"OSkeyB",desc:"Bold"},{val:"OSkeyI",desc:"Italic"},{val:"OSkeyU",desc:"Underline"},{val:"OSkeyS",desc:"Strikethrough"},{val:"OSkey]",desc:"Increase Indent"},{val:"OSkey[",desc:"Decrease Indent"}]},{title:"Quote",commands:[{val:"OSkey'",desc:"Increase quote level"},{val:"OSkeyShift+'",desc:"Decrease quote level"}]},{title:"Image / Video",commands:[{val:"OSkey+",desc:"Resize larger"},{val:"OSkey-",desc:"Resize smaller"}]},{title:"Table",commands:[{val:"Alt+Space",desc:"Select table cell"},{val:"Shift+Left/Right arrow",desc:"Extend selection one cell"},{val:"Shift+Up/Down arrow",desc:"Extend selection one row"}]},{title:"Navigation",commands:[{val:"OSkey/",desc:"Shortcuts"},{val:"Alt+F10",desc:"Focus popup / toolbar"},{val:"Esc",desc:"Return focus to previous position"}]}]}),n.FE.PLUGINS.help=function(s){var o,a="help";return{_init:function(){},show:function(){if(!o){var e="<h4>"+s.language.translate("Shortcuts")+"</h4>",t=function(){for(var e='<div class="fr-help-modal">',t=0;t<s.opts.helpSets.length;t++){var l=s.opts.helpSets[t],o="<table>";o+="<thead><tr><th>"+s.language.translate(l.title)+"</th></tr></thead>",o+="<tbody>";for(var a=0;a<l.commands.length;a++){var n=l.commands[a];o+="<tr>",o+="<td>"+s.language.translate(n.desc)+"</td>",o+="<td>"+n.val.replace("OSkey",s.helpers.isMac()?"⌘":"Ctrl+")+"</td>",o+="</tr>"}e+=o+="</tbody></table>"}return e+="</div>"}(),l=s.modals.create(a,e,t);o=l.$modal,l.$head,l.$body,s.events.$on(n(s.o_win),"resize",function(){s.modals.resize(a)})}s.modals.show(a),s.modals.resize(a)},hide:function(){s.modals.hide(a)}}},n.FroalaEditor.DefineIcon("help",{NAME:"question"}),n.FE.RegisterShortcut(n.FE.KEYCODE.SLASH,"help",null,"/"),n.FE.RegisterCommand("help",{title:"Help",icon:"help",undo:!1,focus:!1,modal:!0,callback:function(){this.help.show()},plugin:"help",showOnMobile:!1})});
|
|
@@ -0,0 +1,3323 @@
|
|
|
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
|
+
|
|
37
|
+
$.extend($.FE.POPUP_TEMPLATES, {
|
|
38
|
+
'image.insert': '[_BUTTONS_][_UPLOAD_LAYER_][_BY_URL_LAYER_][_PROGRESS_BAR_]',
|
|
39
|
+
'image.edit': '[_BUTTONS_]',
|
|
40
|
+
'image.alt': '[_BUTTONS_][_ALT_LAYER_]',
|
|
41
|
+
'image.size': '[_BUTTONS_][_SIZE_LAYER_]'
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
$.extend($.FE.DEFAULTS, {
|
|
45
|
+
imageInsertButtons: ['imageBack', '|', 'imageUpload', 'imageByURL'],
|
|
46
|
+
imageEditButtons: ['imageReplace', 'imageAlign', 'imageCaption', 'imageRemove', '|', 'imageLink', 'linkOpen', 'linkEdit', 'linkRemove', '-', 'imageDisplay', 'imageStyle', 'imageAlt', 'imageSize'],
|
|
47
|
+
imageAltButtons: ['imageBack', '|'],
|
|
48
|
+
imageSizeButtons: ['imageBack', '|'],
|
|
49
|
+
imageUpload: true,
|
|
50
|
+
imageUploadURL: 'https://i.froala.com/upload',
|
|
51
|
+
imageCORSProxy: 'https://cors-anywhere.froala.com',
|
|
52
|
+
imageUploadRemoteUrls: true,
|
|
53
|
+
imageUploadParam: 'file',
|
|
54
|
+
imageUploadParams: {},
|
|
55
|
+
imageUploadToS3: false,
|
|
56
|
+
imageUploadMethod: 'POST',
|
|
57
|
+
imageMaxSize: 10 * 1024 * 1024,
|
|
58
|
+
imageAllowedTypes: ['jpeg', 'jpg', 'png', 'gif'],
|
|
59
|
+
imageResize: true,
|
|
60
|
+
imageResizeWithPercent: false,
|
|
61
|
+
imageRoundPercent: false,
|
|
62
|
+
imageDefaultWidth: 300,
|
|
63
|
+
imageDefaultAlign: 'center',
|
|
64
|
+
imageDefaultDisplay: 'block',
|
|
65
|
+
imageSplitHTML: false,
|
|
66
|
+
imageStyles: {
|
|
67
|
+
'fr-rounded': 'Rounded',
|
|
68
|
+
'fr-bordered': 'Bordered',
|
|
69
|
+
'fr-shadow': 'Shadow'
|
|
70
|
+
},
|
|
71
|
+
imageMove: true,
|
|
72
|
+
imageMultipleStyles: true,
|
|
73
|
+
imageTextNear: true,
|
|
74
|
+
imagePaste: true,
|
|
75
|
+
imagePasteProcess: false,
|
|
76
|
+
imageMinWidth: 16,
|
|
77
|
+
imageOutputSize: false,
|
|
78
|
+
imageDefaultMargin: 5
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
$.FE.PLUGINS.image = function (editor) {
|
|
82
|
+
var $current_image;
|
|
83
|
+
var $image_resizer;
|
|
84
|
+
var $handler;
|
|
85
|
+
var $overlay;
|
|
86
|
+
var mousedown = false;
|
|
87
|
+
|
|
88
|
+
var BAD_LINK = 1;
|
|
89
|
+
var MISSING_LINK = 2;
|
|
90
|
+
var ERROR_DURING_UPLOAD = 3;
|
|
91
|
+
var BAD_RESPONSE = 4;
|
|
92
|
+
var MAX_SIZE_EXCEEDED = 5;
|
|
93
|
+
var BAD_FILE_TYPE = 6;
|
|
94
|
+
var NO_CORS_IE = 7;
|
|
95
|
+
var CORRUPTED_IMAGE = 8;
|
|
96
|
+
|
|
97
|
+
var error_messages = {};
|
|
98
|
+
error_messages[BAD_LINK] = 'Image cannot be loaded from the passed link.',
|
|
99
|
+
error_messages[MISSING_LINK] = 'No link in upload response.',
|
|
100
|
+
error_messages[ERROR_DURING_UPLOAD] = 'Error during file upload.',
|
|
101
|
+
error_messages[BAD_RESPONSE] = 'Parsing response failed.',
|
|
102
|
+
error_messages[MAX_SIZE_EXCEEDED] = 'File is too large.',
|
|
103
|
+
error_messages[BAD_FILE_TYPE] = 'Image file type is invalid.',
|
|
104
|
+
error_messages[NO_CORS_IE] = 'Files can be uploaded only to same domain in IE 8 and IE 9.'
|
|
105
|
+
error_messages[CORRUPTED_IMAGE] = 'Image file is corrupted.'
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Refresh the image insert popup.
|
|
109
|
+
*/
|
|
110
|
+
|
|
111
|
+
function _refreshInsertPopup() {
|
|
112
|
+
var $popup = editor.popups.get('image.insert');
|
|
113
|
+
|
|
114
|
+
var $url_input = $popup.find('.fr-image-by-url-layer input');
|
|
115
|
+
$url_input.val('');
|
|
116
|
+
|
|
117
|
+
if ($current_image) {
|
|
118
|
+
$url_input.val($current_image.attr('src'));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
$url_input.trigger('change');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Show the image upload popup.
|
|
126
|
+
*/
|
|
127
|
+
|
|
128
|
+
function showInsertPopup() {
|
|
129
|
+
var $btn = editor.$tb.find('.fr-command[data-cmd="insertImage"]');
|
|
130
|
+
|
|
131
|
+
var $popup = editor.popups.get('image.insert');
|
|
132
|
+
|
|
133
|
+
if (!$popup) $popup = _initInsertPopup();
|
|
134
|
+
hideProgressBar();
|
|
135
|
+
|
|
136
|
+
if (!$popup.hasClass('fr-active')) {
|
|
137
|
+
editor.popups.refresh('image.insert');
|
|
138
|
+
editor.popups.setContainer('image.insert', editor.$tb);
|
|
139
|
+
|
|
140
|
+
if ($btn.is(':visible')) {
|
|
141
|
+
var left = $btn.offset().left + $btn.outerWidth() / 2;
|
|
142
|
+
var top = $btn.offset().top + (editor.opts.toolbarBottom ? 10 : $btn.outerHeight() - 10);
|
|
143
|
+
editor.popups.show('image.insert', left, top, $btn.outerHeight());
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
editor.position.forSelection($popup);
|
|
147
|
+
editor.popups.show('image.insert');
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Show the image edit popup.
|
|
154
|
+
*/
|
|
155
|
+
|
|
156
|
+
function _showEditPopup() {
|
|
157
|
+
var $popup = editor.popups.get('image.edit');
|
|
158
|
+
|
|
159
|
+
if (!$popup) $popup = _initEditPopup();
|
|
160
|
+
|
|
161
|
+
if ($popup) {
|
|
162
|
+
var $el = getEl();
|
|
163
|
+
|
|
164
|
+
if (hasCaption()) {
|
|
165
|
+
$el = $el.find('.fr-img-wrap');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
editor.popups.setContainer('image.edit', editor.$sc);
|
|
169
|
+
editor.popups.refresh('image.edit');
|
|
170
|
+
var left = $el.offset().left + $el.outerWidth() / 2;
|
|
171
|
+
var top = $el.offset().top + $el.outerHeight();
|
|
172
|
+
|
|
173
|
+
editor.popups.show('image.edit', left, top, $el.outerHeight());
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Hide image upload popup.
|
|
179
|
+
*/
|
|
180
|
+
|
|
181
|
+
function _hideInsertPopup() {
|
|
182
|
+
hideProgressBar();
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Convert style to classes.
|
|
187
|
+
*/
|
|
188
|
+
function _convertStyleToClasses($img) {
|
|
189
|
+
if ($img.parents('.fr-img-caption').length > 0) {
|
|
190
|
+
$img = $img.parents('.fr-img-caption:first');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (!$img.hasClass('fr-dii') && !$img.hasClass('fr-dib')) {
|
|
194
|
+
$img.addClass('fr-fi' + getAlign($img)[0]);
|
|
195
|
+
$img.addClass('fr-di' + getDisplay($img)[0]);
|
|
196
|
+
|
|
197
|
+
// Reset inline style.
|
|
198
|
+
$img.css('margin', '');
|
|
199
|
+
$img.css('float', '');
|
|
200
|
+
$img.css('display', '');
|
|
201
|
+
$img.css('z-index', '');
|
|
202
|
+
$img.css('position', '');
|
|
203
|
+
$img.css('overflow', '');
|
|
204
|
+
$img.css('vertical-align', '');
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Convert classes to style.
|
|
210
|
+
*/
|
|
211
|
+
function _convertClassesToStyle($img) {
|
|
212
|
+
if ($img.parents('.fr-img-caption').length > 0) {
|
|
213
|
+
$img = $img.parents('.fr-img-caption:first');
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
var d = $img.hasClass('fr-dib') ? 'block' : $img.hasClass('fr-dii') ? 'inline' : null;
|
|
217
|
+
var a = $img.hasClass('fr-fil') ? 'left' : $img.hasClass('fr-fir') ? 'right' : getAlign($img);
|
|
218
|
+
|
|
219
|
+
_setStyle($img, d, a);
|
|
220
|
+
|
|
221
|
+
$img.removeClass('fr-dib fr-dii fr-fir fr-fil');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Refresh the image list.
|
|
226
|
+
*/
|
|
227
|
+
function _refreshImageList() {
|
|
228
|
+
var images = editor.el.tagName == 'IMG' ? [editor.el] : editor.el.querySelectorAll('img');
|
|
229
|
+
|
|
230
|
+
for (var i = 0; i < images.length; i++) {
|
|
231
|
+
var $img = $(images[i]);
|
|
232
|
+
|
|
233
|
+
if (!editor.opts.htmlUntouched && editor.opts.useClasses) {
|
|
234
|
+
if (editor.opts.imageDefaultAlign || editor.opts.imageDefaultDisplay) {
|
|
235
|
+
_convertStyleToClasses($img);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Do not allow text near image.
|
|
239
|
+
if (!editor.opts.imageTextNear) {
|
|
240
|
+
if ($img.parents('.fr-img-caption').length > 0) {
|
|
241
|
+
$img.parents('.fr-img-caption:first').removeClass('fr-dii').addClass('fr-dib');
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
$img.removeClass('fr-dii').addClass('fr-dib');
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
else if (!editor.opts.htmlUntouched && !editor.opts.useClasses) {
|
|
249
|
+
if (editor.opts.imageDefaultAlign || editor.opts.imageDefaultDisplay) {
|
|
250
|
+
_convertClassesToStyle($img);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (editor.opts.iframe) {
|
|
255
|
+
$img.on('load', editor.size.syncIframe);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Keep images in sync when content changed.
|
|
262
|
+
*/
|
|
263
|
+
var images;
|
|
264
|
+
|
|
265
|
+
function _syncImages(loaded) {
|
|
266
|
+
|
|
267
|
+
if (typeof loaded === 'undefined') loaded = true;
|
|
268
|
+
|
|
269
|
+
// Get current images.
|
|
270
|
+
var c_images = Array.prototype.slice.call(editor.el.querySelectorAll('img'));
|
|
271
|
+
|
|
272
|
+
// Current images src.
|
|
273
|
+
var image_srcs = [];
|
|
274
|
+
var i;
|
|
275
|
+
|
|
276
|
+
for (i = 0; i < c_images.length; i++) {
|
|
277
|
+
image_srcs.push(c_images[i].getAttribute('src'));
|
|
278
|
+
|
|
279
|
+
$(c_images[i]).toggleClass('fr-draggable', editor.opts.imageMove);
|
|
280
|
+
|
|
281
|
+
if (c_images[i].getAttribute('class') === '') c_images[i].removeAttribute('class');
|
|
282
|
+
|
|
283
|
+
if (c_images[i].getAttribute('style') === '') c_images[i].removeAttribute('style');
|
|
284
|
+
|
|
285
|
+
if (c_images[i].parentNode && c_images[i].parentNode.parentNode && editor.node.hasClass(c_images[i].parentNode.parentNode, 'fr-img-caption')) {
|
|
286
|
+
var p_node = c_images[i].parentNode.parentNode;
|
|
287
|
+
|
|
288
|
+
if (!editor.browser.mozilla) {
|
|
289
|
+
p_node.setAttribute('contenteditable', false);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
p_node.setAttribute('draggable', false);
|
|
293
|
+
p_node.classList.add('fr-draggable');
|
|
294
|
+
|
|
295
|
+
var n_node = c_images[i].nextSibling;
|
|
296
|
+
|
|
297
|
+
if (n_node) {
|
|
298
|
+
n_node.setAttribute('contenteditable', true);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Loop previous images and check their src.
|
|
304
|
+
if (images) {
|
|
305
|
+
for (i = 0; i < images.length; i++) {
|
|
306
|
+
if (image_srcs.indexOf(images[i].getAttribute('src')) < 0) {
|
|
307
|
+
editor.events.trigger('image.removed', [$(images[i])]);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Loop new images and see which were not int the old ones.
|
|
313
|
+
if (images && loaded) {
|
|
314
|
+
var old_images_srcs = [];
|
|
315
|
+
|
|
316
|
+
for (i = 0; i < images.length; i++) {
|
|
317
|
+
old_images_srcs.push(images[i].getAttribute('src'));
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
for (i = 0; i < c_images.length; i++) {
|
|
321
|
+
if (old_images_srcs.indexOf(c_images[i].getAttribute('src')) < 0) {
|
|
322
|
+
editor.events.trigger('image.loaded', [$(c_images[i])]);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Current images are the old ones.
|
|
328
|
+
images = c_images;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Reposition resizer.
|
|
333
|
+
*/
|
|
334
|
+
|
|
335
|
+
function _repositionResizer() {
|
|
336
|
+
if (!$image_resizer) _initImageResizer();
|
|
337
|
+
|
|
338
|
+
if (!$current_image) return false;
|
|
339
|
+
|
|
340
|
+
var $container = editor.$wp || editor.$sc;
|
|
341
|
+
|
|
342
|
+
$container.append($image_resizer);
|
|
343
|
+
$image_resizer.data('instance', editor);
|
|
344
|
+
|
|
345
|
+
var wrap_correction_top = $container.scrollTop() - (($container.css('position') != 'static' ? $container.offset().top : 0));
|
|
346
|
+
var wrap_correction_left = $container.scrollLeft() - (($container.css('position') != 'static' ? $container.offset().left : 0));
|
|
347
|
+
|
|
348
|
+
wrap_correction_left -= editor.helpers.getPX($container.css('border-left-width'));
|
|
349
|
+
wrap_correction_top -= editor.helpers.getPX($container.css('border-top-width'));
|
|
350
|
+
|
|
351
|
+
if (editor.$el.is('img') && editor.$sc.is('body')) {
|
|
352
|
+
wrap_correction_top = 0;
|
|
353
|
+
wrap_correction_left = 0;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
var $el = getEl();
|
|
357
|
+
|
|
358
|
+
if (hasCaption()) {
|
|
359
|
+
$el = $el.find('.fr-img-wrap');
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
$image_resizer
|
|
363
|
+
.css('top', (editor.opts.iframe ? $el.offset().top : $el.offset().top + wrap_correction_top) - 1)
|
|
364
|
+
.css('left', (editor.opts.iframe ? $el.offset().left : $el.offset().left + wrap_correction_left) - 1)
|
|
365
|
+
.css('width', $el.get(0).getBoundingClientRect().width)
|
|
366
|
+
.css('height', $el.get(0).getBoundingClientRect().height)
|
|
367
|
+
.addClass('fr-active');
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Create resize handler.
|
|
372
|
+
*/
|
|
373
|
+
|
|
374
|
+
function _getHandler(pos) {
|
|
375
|
+
|
|
376
|
+
return '<div class="fr-handler fr-h' + pos + '"></div>';
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Set the image with
|
|
381
|
+
*/
|
|
382
|
+
function _setWidth(width) {
|
|
383
|
+
if (hasCaption()) {
|
|
384
|
+
$current_image.parents('.fr-img-caption').css('width', width);
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
$current_image.css('width', width);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Mouse down to start resize.
|
|
393
|
+
*/
|
|
394
|
+
function _handlerMousedown(e) {
|
|
395
|
+
// Check if resizer belongs to current instance.
|
|
396
|
+
if (!editor.core.sameInstance($image_resizer)) return true;
|
|
397
|
+
|
|
398
|
+
e.preventDefault();
|
|
399
|
+
e.stopPropagation();
|
|
400
|
+
|
|
401
|
+
if (editor.$el.find('img.fr-error').left) return false;
|
|
402
|
+
|
|
403
|
+
if (!editor.undo.canDo()) editor.undo.saveStep();
|
|
404
|
+
|
|
405
|
+
// Get offset.
|
|
406
|
+
var start_x = e.pageX || e.originalEvent.touches[0].pageX;
|
|
407
|
+
|
|
408
|
+
// Only on mousedown. This function could be called from keydown on accessibility.
|
|
409
|
+
if (e.type == 'mousedown') {
|
|
410
|
+
// See if the entire editor is inside iframe to adjust starting offset.
|
|
411
|
+
var oel = editor.$oel.get(0);
|
|
412
|
+
var doc = oel.ownerDocument;
|
|
413
|
+
var win = doc.defaultView || doc.parentWindow;
|
|
414
|
+
var editor_inside_iframe = false;
|
|
415
|
+
|
|
416
|
+
try {
|
|
417
|
+
editor_inside_iframe = (win.location != win.parent.location && !(win.$ && win.$.FE));
|
|
418
|
+
}
|
|
419
|
+
catch (ex) {}
|
|
420
|
+
|
|
421
|
+
if (editor_inside_iframe && win.frameElement) {
|
|
422
|
+
start_x += editor.helpers.getPX($(win.frameElement).offset().left) + win.frameElement.clientLeft;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
$handler = $(this);
|
|
427
|
+
$handler.data('start-x', start_x);
|
|
428
|
+
$handler.data('start-width', $current_image.width());
|
|
429
|
+
$handler.data('start-height', $current_image.height());
|
|
430
|
+
|
|
431
|
+
// Set current width.
|
|
432
|
+
var width = $current_image.width();
|
|
433
|
+
|
|
434
|
+
// Update width value if resizing with percent.
|
|
435
|
+
if (editor.opts.imageResizeWithPercent) {
|
|
436
|
+
var p_node = $current_image.parentsUntil(editor.$el, editor.html.blockTagsQuery()).get(0) || editor.el;
|
|
437
|
+
width = (width / $(p_node).outerWidth() * 100).toFixed(2) + '%';
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// Set the image width.
|
|
441
|
+
_setWidth(width);
|
|
442
|
+
|
|
443
|
+
$overlay.show();
|
|
444
|
+
|
|
445
|
+
editor.popups.hideAll();
|
|
446
|
+
|
|
447
|
+
_unmarkExit();
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Do resize.
|
|
452
|
+
*/
|
|
453
|
+
function _handlerMousemove(e) {
|
|
454
|
+
// Check if resizer belongs to current instance.
|
|
455
|
+
if (!editor.core.sameInstance($image_resizer)) return true;
|
|
456
|
+
var real_image_size;
|
|
457
|
+
|
|
458
|
+
if ($handler && $current_image) {
|
|
459
|
+
e.preventDefault()
|
|
460
|
+
|
|
461
|
+
if (editor.$el.find('img.fr-error').left) return false;
|
|
462
|
+
|
|
463
|
+
var c_x = e.pageX || (e.originalEvent.touches ? e.originalEvent.touches[0].pageX : null);
|
|
464
|
+
|
|
465
|
+
if (!c_x) return false;
|
|
466
|
+
|
|
467
|
+
var s_x = $handler.data('start-x');
|
|
468
|
+
var diff_x = c_x - s_x;
|
|
469
|
+
var width = $handler.data('start-width');
|
|
470
|
+
|
|
471
|
+
if ($handler.hasClass('fr-hnw') || $handler.hasClass('fr-hsw')) {
|
|
472
|
+
diff_x = 0 - diff_x;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
if (editor.opts.imageResizeWithPercent) {
|
|
476
|
+
var p_node = $current_image.parentsUntil(editor.$el, editor.html.blockTagsQuery()).get(0) || editor.el;
|
|
477
|
+
width = ((width + diff_x) / $(p_node).outerWidth() * 100).toFixed(2);
|
|
478
|
+
|
|
479
|
+
if (editor.opts.imageRoundPercent) width = Math.round(width);
|
|
480
|
+
|
|
481
|
+
// Set the image width.
|
|
482
|
+
_setWidth(width + '%')
|
|
483
|
+
|
|
484
|
+
// Get the real image width after resize.
|
|
485
|
+
if (hasCaption()) {
|
|
486
|
+
real_image_size = (editor.helpers.getPX($current_image.parents('.fr-img-caption').css('width')) / $(p_node).outerWidth() * 100).toFixed(2);
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
real_image_size = (editor.helpers.getPX($current_image.css('width')) / $(p_node).outerWidth() * 100).toFixed(2);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// If the width is not contained within editor use the real image size.
|
|
493
|
+
if (real_image_size !== width && !editor.opts.imageRoundPercent) {
|
|
494
|
+
_setWidth(real_image_size + '%')
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
$current_image.css('height', '').removeAttr('height');
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
else {
|
|
501
|
+
if (width + diff_x >= editor.opts.imageMinWidth) {
|
|
502
|
+
// Set width for image parent node as well.
|
|
503
|
+
_setWidth(width + diff_x)
|
|
504
|
+
|
|
505
|
+
// Get the real image width after resize.
|
|
506
|
+
if (hasCaption()) {
|
|
507
|
+
real_image_size = editor.helpers.getPX($current_image.parents('.fr-img-caption').css('width'));
|
|
508
|
+
}
|
|
509
|
+
else {
|
|
510
|
+
real_image_size = editor.helpers.getPX($current_image.css('width'));
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// If the width is not contained within editor use the real image size.
|
|
515
|
+
if (real_image_size !== width + diff_x) {
|
|
516
|
+
_setWidth(real_image_size)
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// https://github.com/froala/wysiwyg-editor/issues/1963.
|
|
520
|
+
if (($current_image.attr('style') || '').match(/(^height:)|(; *height:)/) || $current_image.attr('height')) {
|
|
521
|
+
$current_image.css('height', $handler.data('start-height') * $current_image.width() / $handler.data('start-width'));
|
|
522
|
+
$current_image.removeAttr('height');
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
_repositionResizer();
|
|
527
|
+
|
|
528
|
+
editor.events.trigger('image.resize', [get()]);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Stop resize.
|
|
534
|
+
*/
|
|
535
|
+
|
|
536
|
+
function _handlerMouseup(e) {
|
|
537
|
+
|
|
538
|
+
// Check if resizer belongs to current instance.
|
|
539
|
+
if (!editor.core.sameInstance($image_resizer)) return true;
|
|
540
|
+
|
|
541
|
+
if ($handler && $current_image) {
|
|
542
|
+
if (e) e.stopPropagation();
|
|
543
|
+
|
|
544
|
+
if (editor.$el.find('img.fr-error').left) return false;
|
|
545
|
+
|
|
546
|
+
$handler = null;
|
|
547
|
+
$overlay.hide();
|
|
548
|
+
_repositionResizer();
|
|
549
|
+
_showEditPopup();
|
|
550
|
+
|
|
551
|
+
editor.undo.saveStep();
|
|
552
|
+
|
|
553
|
+
editor.events.trigger('image.resizeEnd', [get()]);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Throw an image error.
|
|
559
|
+
*/
|
|
560
|
+
|
|
561
|
+
function _throwError(code, response, $img) {
|
|
562
|
+
editor.edit.on();
|
|
563
|
+
|
|
564
|
+
if ($current_image) $current_image.addClass('fr-error');
|
|
565
|
+
_showErrorMessage(editor.language.translate('Something went wrong. Please try again.'));
|
|
566
|
+
|
|
567
|
+
// Remove image if it exists.
|
|
568
|
+
if (!$current_image && $img) remove($img);
|
|
569
|
+
|
|
570
|
+
editor.events.trigger('image.error', [{
|
|
571
|
+
code: code,
|
|
572
|
+
message: error_messages[code]
|
|
573
|
+
},
|
|
574
|
+
response,
|
|
575
|
+
$img
|
|
576
|
+
]);
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Init the image edit popup.
|
|
581
|
+
*/
|
|
582
|
+
|
|
583
|
+
function _initEditPopup(delayed) {
|
|
584
|
+
if (delayed) {
|
|
585
|
+
if (editor.$wp) {
|
|
586
|
+
editor.events.$on(editor.$wp, 'scroll', function () {
|
|
587
|
+
if ($current_image && editor.popups.isVisible('image.edit')) {
|
|
588
|
+
editor.events.disableBlur();
|
|
589
|
+
_editImg($current_image);
|
|
590
|
+
}
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
return true;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// Image buttons.
|
|
598
|
+
var image_buttons = '';
|
|
599
|
+
|
|
600
|
+
if (editor.opts.imageEditButtons.length > 0) {
|
|
601
|
+
image_buttons += '<div class="fr-buttons">';
|
|
602
|
+
image_buttons += editor.button.buildList(editor.opts.imageEditButtons);
|
|
603
|
+
image_buttons += '</div>';
|
|
604
|
+
|
|
605
|
+
var template = {
|
|
606
|
+
buttons: image_buttons
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
var $popup = editor.popups.create('image.edit', template);
|
|
610
|
+
|
|
611
|
+
return $popup;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
return false;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* Show progress bar.
|
|
619
|
+
*/
|
|
620
|
+
|
|
621
|
+
function showProgressBar(no_message) {
|
|
622
|
+
var $popup = editor.popups.get('image.insert');
|
|
623
|
+
|
|
624
|
+
if (!$popup) $popup = _initInsertPopup();
|
|
625
|
+
|
|
626
|
+
$popup.find('.fr-layer.fr-active').removeClass('fr-active').addClass('fr-pactive');
|
|
627
|
+
$popup.find('.fr-image-progress-bar-layer').addClass('fr-active');
|
|
628
|
+
$popup.find('.fr-buttons').hide();
|
|
629
|
+
|
|
630
|
+
if ($current_image) {
|
|
631
|
+
var $el = getEl();
|
|
632
|
+
|
|
633
|
+
editor.popups.setContainer('image.insert', editor.$sc);
|
|
634
|
+
var left = $el.offset().left + $el.width() / 2;
|
|
635
|
+
var top = $el.offset().top + $el.height();
|
|
636
|
+
|
|
637
|
+
editor.popups.show('image.insert', left, top, $el.outerHeight());
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
if (typeof no_message == 'undefined') {
|
|
641
|
+
_setProgressMessage(editor.language.translate('Uploading'), 0);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Hide progress bar.
|
|
647
|
+
*/
|
|
648
|
+
function hideProgressBar(dismiss) {
|
|
649
|
+
var $popup = editor.popups.get('image.insert');
|
|
650
|
+
|
|
651
|
+
if ($popup) {
|
|
652
|
+
$popup.find('.fr-layer.fr-pactive').addClass('fr-active').removeClass('fr-pactive');
|
|
653
|
+
$popup.find('.fr-image-progress-bar-layer').removeClass('fr-active');
|
|
654
|
+
$popup.find('.fr-buttons').show();
|
|
655
|
+
|
|
656
|
+
// Dismiss error message.
|
|
657
|
+
if (dismiss || editor.$el.find('img.fr-error').length) {
|
|
658
|
+
editor.events.focus();
|
|
659
|
+
|
|
660
|
+
if (editor.$el.find('img.fr-error').length) {
|
|
661
|
+
editor.$el.find('img.fr-error').remove();
|
|
662
|
+
editor.undo.saveStep();
|
|
663
|
+
editor.undo.run();
|
|
664
|
+
editor.undo.dropRedo();
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
if (!editor.$wp && $current_image) {
|
|
668
|
+
var $img = $current_image;
|
|
669
|
+
_exitEdit(true);
|
|
670
|
+
editor.selection.setAfter($img.get(0));
|
|
671
|
+
editor.selection.restore();
|
|
672
|
+
}
|
|
673
|
+
editor.popups.hide('image.insert');
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* Set a progress message.
|
|
680
|
+
*/
|
|
681
|
+
|
|
682
|
+
function _setProgressMessage(message, progress) {
|
|
683
|
+
var $popup = editor.popups.get('image.insert');
|
|
684
|
+
|
|
685
|
+
if ($popup) {
|
|
686
|
+
var $layer = $popup.find('.fr-image-progress-bar-layer');
|
|
687
|
+
$layer.find('h3').text(message + (progress ? ' ' + progress + '%' : ''));
|
|
688
|
+
|
|
689
|
+
$layer.removeClass('fr-error');
|
|
690
|
+
|
|
691
|
+
if (progress) {
|
|
692
|
+
$layer.find('div').removeClass('fr-indeterminate');
|
|
693
|
+
$layer.find('div > span').css('width', progress + '%');
|
|
694
|
+
}
|
|
695
|
+
else {
|
|
696
|
+
$layer.find('div').addClass('fr-indeterminate');
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
/**
|
|
702
|
+
* Show error message to the user.
|
|
703
|
+
*/
|
|
704
|
+
|
|
705
|
+
function _showErrorMessage(message) {
|
|
706
|
+
showProgressBar();
|
|
707
|
+
var $popup = editor.popups.get('image.insert');
|
|
708
|
+
var $layer = $popup.find('.fr-image-progress-bar-layer');
|
|
709
|
+
$layer.addClass('fr-error');
|
|
710
|
+
var $message_header = $layer.find('h3');
|
|
711
|
+
$message_header.text(message);
|
|
712
|
+
editor.events.disableBlur();
|
|
713
|
+
$message_header.focus();
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* Insert image using URL callback.
|
|
718
|
+
*/
|
|
719
|
+
|
|
720
|
+
function insertByURL() {
|
|
721
|
+
var $popup = editor.popups.get('image.insert');
|
|
722
|
+
var $input = $popup.find('.fr-image-by-url-layer input');
|
|
723
|
+
|
|
724
|
+
if ($input.val().length > 0) {
|
|
725
|
+
showProgressBar();
|
|
726
|
+
_setProgressMessage(editor.language.translate('Loading image'));
|
|
727
|
+
|
|
728
|
+
var img_url = $input.val();
|
|
729
|
+
|
|
730
|
+
// Upload images if we should upload them.
|
|
731
|
+
if (editor.opts.imageUploadRemoteUrls && editor.opts.imageCORSProxy && editor.opts.imageUpload) {
|
|
732
|
+
var xhr = new XMLHttpRequest();
|
|
733
|
+
xhr.onload = function () {
|
|
734
|
+
|
|
735
|
+
if (this.status == 200) {
|
|
736
|
+
|
|
737
|
+
upload([new Blob([this.response], {
|
|
738
|
+
type: this.response.type || 'image/png'
|
|
739
|
+
})], $current_image);
|
|
740
|
+
}
|
|
741
|
+
else {
|
|
742
|
+
_throwError(BAD_LINK);
|
|
743
|
+
}
|
|
744
|
+
};
|
|
745
|
+
|
|
746
|
+
// If image couldn't be uploaded, insert as it is.
|
|
747
|
+
xhr.onerror = function () {
|
|
748
|
+
insert(img_url, true, [], $current_image);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
xhr.open('GET', editor.opts.imageCORSProxy + '/' + img_url, true);
|
|
752
|
+
xhr.responseType = 'blob';
|
|
753
|
+
|
|
754
|
+
xhr.send();
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
else {
|
|
758
|
+
insert(img_url, true, [], $current_image);
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
$input.val('');
|
|
762
|
+
$input.blur();
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
function _editImg($img) {
|
|
767
|
+
_edit.call($img.get(0));
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
function _loadedCallback() {
|
|
771
|
+
var $img = $(this);
|
|
772
|
+
|
|
773
|
+
editor.popups.hide('image.insert');
|
|
774
|
+
|
|
775
|
+
$img.removeClass('fr-uploading');
|
|
776
|
+
|
|
777
|
+
// Select the image.
|
|
778
|
+
if ($img.next().is('br')) {
|
|
779
|
+
$img.next().remove();
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
_editImg($img);
|
|
783
|
+
|
|
784
|
+
editor.events.trigger('image.loaded', [$img]);
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* Insert image into the editor.
|
|
789
|
+
*/
|
|
790
|
+
|
|
791
|
+
function insert(link, sanitize, data, $existing_img, response) {
|
|
792
|
+
editor.edit.off();
|
|
793
|
+
_setProgressMessage(editor.language.translate('Loading image'));
|
|
794
|
+
|
|
795
|
+
if (sanitize) link = editor.helpers.sanitizeURL(link);
|
|
796
|
+
|
|
797
|
+
var image = new Image();
|
|
798
|
+
|
|
799
|
+
image.onload = function () {
|
|
800
|
+
var $img;
|
|
801
|
+
var attr;
|
|
802
|
+
|
|
803
|
+
if ($existing_img) {
|
|
804
|
+
if (!editor.undo.canDo() && !$existing_img.hasClass('fr-uploading')) editor.undo.saveStep();
|
|
805
|
+
|
|
806
|
+
var old_src = $existing_img.data('fr-old-src');
|
|
807
|
+
|
|
808
|
+
if ($existing_img.data('fr-image-pasted')) {
|
|
809
|
+
old_src = null;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
if (editor.$wp) {
|
|
813
|
+
|
|
814
|
+
// Clone existing image.
|
|
815
|
+
$img = $existing_img.clone()
|
|
816
|
+
.removeData('fr-old-src')
|
|
817
|
+
.removeClass('fr-uploading')
|
|
818
|
+
.removeAttr('data-fr-image-pasted');
|
|
819
|
+
|
|
820
|
+
// Remove load event.
|
|
821
|
+
$img.off('load');
|
|
822
|
+
|
|
823
|
+
// Set new SRC.
|
|
824
|
+
if (old_src) $existing_img.attr('src', old_src);
|
|
825
|
+
|
|
826
|
+
// Replace existing image with its clone.
|
|
827
|
+
$existing_img.replaceWith($img);
|
|
828
|
+
|
|
829
|
+
}
|
|
830
|
+
else {
|
|
831
|
+
$img = $existing_img;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
// Remove old data.
|
|
835
|
+
var atts = $img.get(0).attributes;
|
|
836
|
+
|
|
837
|
+
for (var i = 0; i < atts.length; i++) {
|
|
838
|
+
var att = atts[i];
|
|
839
|
+
|
|
840
|
+
if (att.nodeName.indexOf('data-') === 0) {
|
|
841
|
+
$img.removeAttr(att.nodeName);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
// Set new data.
|
|
846
|
+
if (typeof data != 'undefined') {
|
|
847
|
+
for (attr in data) {
|
|
848
|
+
if (data.hasOwnProperty(attr)) {
|
|
849
|
+
if (attr != 'link') {
|
|
850
|
+
$img.attr('data-' + attr, data[attr]);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
$img.on('load', _loadedCallback);
|
|
857
|
+
$img.attr('src', link);
|
|
858
|
+
editor.edit.on();
|
|
859
|
+
_syncImages(false);
|
|
860
|
+
editor.undo.saveStep();
|
|
861
|
+
|
|
862
|
+
// Cursor will not appear if we don't make blur.
|
|
863
|
+
editor.events.disableBlur();
|
|
864
|
+
editor.$el.blur();
|
|
865
|
+
editor.events.trigger(old_src ? 'image.replaced' : 'image.inserted', [$img, response]);
|
|
866
|
+
}
|
|
867
|
+
else {
|
|
868
|
+
$img = _addImage(link, data, _loadedCallback);
|
|
869
|
+
_syncImages(false);
|
|
870
|
+
editor.undo.saveStep();
|
|
871
|
+
|
|
872
|
+
// Cursor will not appear if we don't make blur.
|
|
873
|
+
editor.$el.blur();
|
|
874
|
+
editor.events.trigger('image.inserted', [$img, response]);
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
image.onerror = function () {
|
|
879
|
+
_throwError(BAD_LINK);
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
showProgressBar(editor.language.translate('Loading image'));
|
|
883
|
+
|
|
884
|
+
image.src = link;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
/**
|
|
888
|
+
* Parse image response.
|
|
889
|
+
*/
|
|
890
|
+
|
|
891
|
+
function _parseResponse(response) {
|
|
892
|
+
try {
|
|
893
|
+
if (editor.events.trigger('image.uploaded', [response], true) === false) {
|
|
894
|
+
editor.edit.on();
|
|
895
|
+
|
|
896
|
+
return false;
|
|
897
|
+
}
|
|
898
|
+
var resp = JSON.parse(response);
|
|
899
|
+
|
|
900
|
+
if (resp.link) {
|
|
901
|
+
|
|
902
|
+
return resp;
|
|
903
|
+
}
|
|
904
|
+
else {
|
|
905
|
+
|
|
906
|
+
// No link in upload request.
|
|
907
|
+
_throwError(MISSING_LINK, response);
|
|
908
|
+
|
|
909
|
+
return false;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
catch (ex) {
|
|
913
|
+
|
|
914
|
+
// Bad response.
|
|
915
|
+
_throwError(BAD_RESPONSE, response);
|
|
916
|
+
|
|
917
|
+
return false;
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
/**
|
|
922
|
+
* Parse image response.
|
|
923
|
+
*/
|
|
924
|
+
|
|
925
|
+
function _parseXMLResponse(response) {
|
|
926
|
+
try {
|
|
927
|
+
var link = $(response).find('Location').text();
|
|
928
|
+
var key = $(response).find('Key').text();
|
|
929
|
+
|
|
930
|
+
if (editor.events.trigger('image.uploadedToS3', [link, key, response], true) === false) {
|
|
931
|
+
editor.edit.on();
|
|
932
|
+
|
|
933
|
+
return false;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
return link;
|
|
937
|
+
}
|
|
938
|
+
catch (ex) {
|
|
939
|
+
|
|
940
|
+
// Bad response.
|
|
941
|
+
_throwError(BAD_RESPONSE, response);
|
|
942
|
+
|
|
943
|
+
return false;
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
/**
|
|
948
|
+
* Image was uploaded to the server and we have a response.
|
|
949
|
+
*/
|
|
950
|
+
|
|
951
|
+
function _imageUploaded($img) {
|
|
952
|
+
_setProgressMessage(editor.language.translate('Loading image'));
|
|
953
|
+
var status = this.status;
|
|
954
|
+
var response = this.response;
|
|
955
|
+
var responseXML = this.responseXML;
|
|
956
|
+
var responseText = this.responseText;
|
|
957
|
+
|
|
958
|
+
try {
|
|
959
|
+
if (editor.opts.imageUploadToS3) {
|
|
960
|
+
if (status == 201) {
|
|
961
|
+
var link = _parseXMLResponse(responseXML);
|
|
962
|
+
|
|
963
|
+
if (link) {
|
|
964
|
+
insert(link, false, [], $img, response || responseXML);
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
else {
|
|
968
|
+
_throwError(BAD_RESPONSE, response || responseXML, $img);
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
else {
|
|
972
|
+
if (status >= 200 && status < 300) {
|
|
973
|
+
var resp = _parseResponse(responseText);
|
|
974
|
+
|
|
975
|
+
if (resp) {
|
|
976
|
+
insert(resp.link, false, resp, $img, response || responseText);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
else {
|
|
980
|
+
_throwError(ERROR_DURING_UPLOAD, response || responseText, $img);
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
catch (ex) {
|
|
985
|
+
|
|
986
|
+
// Bad response.
|
|
987
|
+
_throwError(BAD_RESPONSE, response || responseText, $img);
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
/**
|
|
992
|
+
* Image upload error.
|
|
993
|
+
*/
|
|
994
|
+
|
|
995
|
+
function _imageUploadError() {
|
|
996
|
+
_throwError(BAD_RESPONSE, this.response || this.responseText || this.responseXML);
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
/**
|
|
1000
|
+
* Image upload progress.
|
|
1001
|
+
*/
|
|
1002
|
+
|
|
1003
|
+
function _imageUploadProgress(e) {
|
|
1004
|
+
if (e.lengthComputable) {
|
|
1005
|
+
var complete = (e.loaded / e.total * 100 | 0);
|
|
1006
|
+
_setProgressMessage(editor.language.translate('Uploading'), complete);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
function _addImage(link, data, loadCallback) {
|
|
1011
|
+
|
|
1012
|
+
// Build image data string.
|
|
1013
|
+
var data_str = '';
|
|
1014
|
+
var attr;
|
|
1015
|
+
|
|
1016
|
+
if (data && typeof data != 'undefined') {
|
|
1017
|
+
for (attr in data) {
|
|
1018
|
+
if (data.hasOwnProperty(attr)) {
|
|
1019
|
+
if (attr != 'link') {
|
|
1020
|
+
data_str += ' data-' + attr + '="' + data[attr] + '"';
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
var width = editor.opts.imageDefaultWidth;
|
|
1027
|
+
|
|
1028
|
+
if (width && width != 'auto') {
|
|
1029
|
+
width = width + (editor.opts.imageResizeWithPercent ? '%' : 'px');
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
// Create image object and set the load event.
|
|
1033
|
+
var $img = $('<img src="' + link + '"' + data_str + (width ? ' style="width: ' + width + ';"' : '') + '>');
|
|
1034
|
+
_setStyle($img, editor.opts.imageDefaultDisplay, editor.opts.imageDefaultAlign);
|
|
1035
|
+
|
|
1036
|
+
$img.on('load', loadCallback);
|
|
1037
|
+
$img.on('error', function () {
|
|
1038
|
+
$(this).addClass('fr-error');
|
|
1039
|
+
_throwError(CORRUPTED_IMAGE);
|
|
1040
|
+
})
|
|
1041
|
+
|
|
1042
|
+
// Make sure we have focus.
|
|
1043
|
+
// Call the event.
|
|
1044
|
+
editor.edit.on();
|
|
1045
|
+
editor.events.focus(true);
|
|
1046
|
+
editor.selection.restore();
|
|
1047
|
+
editor.undo.saveStep();
|
|
1048
|
+
|
|
1049
|
+
// Insert marker and then replace it with the image.
|
|
1050
|
+
if (editor.opts.imageSplitHTML) {
|
|
1051
|
+
editor.markers.split();
|
|
1052
|
+
}
|
|
1053
|
+
else {
|
|
1054
|
+
editor.markers.insert();
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
editor.html.wrap();
|
|
1058
|
+
var $marker = editor.$el.find('.fr-marker');
|
|
1059
|
+
|
|
1060
|
+
if ($marker.length) {
|
|
1061
|
+
|
|
1062
|
+
// Do not insert image in HR.
|
|
1063
|
+
if ($marker.parent().is('hr')) {
|
|
1064
|
+
$marker.parent().after($marker);
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
// Do not insert image inside emoticon.
|
|
1068
|
+
if (editor.node.isLastSibling($marker) && $marker.parent().hasClass('fr-deletable')) {
|
|
1069
|
+
|
|
1070
|
+
$marker.insertAfter($marker.parent());
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
$marker.replaceWith($img);
|
|
1074
|
+
}
|
|
1075
|
+
else {
|
|
1076
|
+
editor.$el.append($img);
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
editor.selection.clear();
|
|
1080
|
+
|
|
1081
|
+
return $img;
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
/**
|
|
1085
|
+
* Image upload aborted.
|
|
1086
|
+
*/
|
|
1087
|
+
function _imageUploadAborted() {
|
|
1088
|
+
editor.edit.on();
|
|
1089
|
+
hideProgressBar(true);
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
/**
|
|
1093
|
+
* Start the uploading process.
|
|
1094
|
+
*/
|
|
1095
|
+
function _startUpload(xhr, form_data, image, $image_placeholder) {
|
|
1096
|
+
function _sendRequest() {
|
|
1097
|
+
var $img = $(this);
|
|
1098
|
+
$img.off('load');
|
|
1099
|
+
$img.addClass('fr-uploading');
|
|
1100
|
+
|
|
1101
|
+
if ($img.next().is('br')) {
|
|
1102
|
+
$img.next().remove();
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
editor.placeholder.refresh();
|
|
1106
|
+
|
|
1107
|
+
// Select the image.
|
|
1108
|
+
_editImg($img);
|
|
1109
|
+
_repositionResizer();
|
|
1110
|
+
showProgressBar();
|
|
1111
|
+
editor.edit.off();
|
|
1112
|
+
|
|
1113
|
+
// Set upload events.
|
|
1114
|
+
xhr.onload = function () {
|
|
1115
|
+
_imageUploaded.call(xhr, $img);
|
|
1116
|
+
};
|
|
1117
|
+
xhr.onerror = _imageUploadError;
|
|
1118
|
+
xhr.upload.onprogress = _imageUploadProgress;
|
|
1119
|
+
xhr.onabort = _imageUploadAborted;
|
|
1120
|
+
|
|
1121
|
+
// Set abort event.
|
|
1122
|
+
$img.off('abortUpload').on('abortUpload', function () {
|
|
1123
|
+
if (xhr.readyState != 4) {
|
|
1124
|
+
xhr.abort();
|
|
1125
|
+
}
|
|
1126
|
+
});
|
|
1127
|
+
|
|
1128
|
+
// Send data.
|
|
1129
|
+
xhr.send(form_data);
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
var reader = new FileReader();
|
|
1133
|
+
var $img;
|
|
1134
|
+
|
|
1135
|
+
reader.addEventListener('load', function () {
|
|
1136
|
+
var link = reader.result;
|
|
1137
|
+
|
|
1138
|
+
if (reader.result.indexOf('svg+xml') < 0) {
|
|
1139
|
+
|
|
1140
|
+
// Convert image to local blob.
|
|
1141
|
+
var binary = atob(reader.result.split(',')[1]);
|
|
1142
|
+
var array = [];
|
|
1143
|
+
|
|
1144
|
+
for (var i = 0; i < binary.length; i++) {
|
|
1145
|
+
array.push(binary.charCodeAt(i));
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
// Get local image link.
|
|
1149
|
+
link = window.URL.createObjectURL(new Blob([new Uint8Array(array)], {
|
|
1150
|
+
type: 'image/jpeg'
|
|
1151
|
+
}));
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
// No image.
|
|
1155
|
+
if (!$image_placeholder) {
|
|
1156
|
+
$img = _addImage(link, null, _sendRequest);
|
|
1157
|
+
}
|
|
1158
|
+
else {
|
|
1159
|
+
$image_placeholder.on('load', _sendRequest);
|
|
1160
|
+
$image_placeholder.one('error', function () {
|
|
1161
|
+
$image_placeholder.off('load');
|
|
1162
|
+
$image_placeholder.attr('src', $image_placeholder.data('fr-old-src'));
|
|
1163
|
+
_throwError(CORRUPTED_IMAGE);
|
|
1164
|
+
})
|
|
1165
|
+
editor.edit.on();
|
|
1166
|
+
editor.undo.saveStep();
|
|
1167
|
+
$image_placeholder.data('fr-old-src', $image_placeholder.attr('src'));
|
|
1168
|
+
$image_placeholder.attr('src', link);
|
|
1169
|
+
}
|
|
1170
|
+
}, false);
|
|
1171
|
+
|
|
1172
|
+
reader.readAsDataURL(image);
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
/**
|
|
1176
|
+
* Do image upload.
|
|
1177
|
+
*/
|
|
1178
|
+
|
|
1179
|
+
function upload(images, $image_placeholder) {
|
|
1180
|
+
|
|
1181
|
+
// Make sure we have what to upload.
|
|
1182
|
+
if (typeof images != 'undefined' && images.length > 0) {
|
|
1183
|
+
|
|
1184
|
+
// Check if we should cancel the image upload.
|
|
1185
|
+
if (editor.events.trigger('image.beforeUpload', [images, $image_placeholder]) === false) {
|
|
1186
|
+
|
|
1187
|
+
return false;
|
|
1188
|
+
}
|
|
1189
|
+
var image = images[0];
|
|
1190
|
+
|
|
1191
|
+
// Check if there is image name set.
|
|
1192
|
+
if (!image.name) {
|
|
1193
|
+
image.name = (new Date()).getTime() + '.' + (image.type || 'image/jpeg').replace(/image\//g, '')
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
// Check image max size.
|
|
1197
|
+
if (image.size > editor.opts.imageMaxSize) {
|
|
1198
|
+
_throwError(MAX_SIZE_EXCEEDED);
|
|
1199
|
+
|
|
1200
|
+
return false;
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
// Check image types.
|
|
1204
|
+
if (editor.opts.imageAllowedTypes.indexOf(image.type.replace(/image\//g, '')) < 0) {
|
|
1205
|
+
_throwError(BAD_FILE_TYPE);
|
|
1206
|
+
|
|
1207
|
+
return false;
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
// Create form Data.
|
|
1211
|
+
var form_data;
|
|
1212
|
+
|
|
1213
|
+
if (editor.drag_support.formdata) {
|
|
1214
|
+
form_data = editor.drag_support.formdata ? new FormData() : null;
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
// Prepare form data for request.
|
|
1218
|
+
if (form_data) {
|
|
1219
|
+
var key;
|
|
1220
|
+
|
|
1221
|
+
// Upload to S3.
|
|
1222
|
+
if (editor.opts.imageUploadToS3 !== false) {
|
|
1223
|
+
form_data.append('key', editor.opts.imageUploadToS3.keyStart + (new Date()).getTime() + '-' + (image.name || 'untitled'));
|
|
1224
|
+
form_data.append('success_action_status', '201');
|
|
1225
|
+
form_data.append('X-Requested-With', 'xhr');
|
|
1226
|
+
form_data.append('Content-Type', image.type);
|
|
1227
|
+
|
|
1228
|
+
for (key in editor.opts.imageUploadToS3.params) {
|
|
1229
|
+
if (editor.opts.imageUploadToS3.params.hasOwnProperty(key)) {
|
|
1230
|
+
form_data.append(key, editor.opts.imageUploadToS3.params[key]);
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
// Add upload params.
|
|
1236
|
+
for (key in editor.opts.imageUploadParams) {
|
|
1237
|
+
if (editor.opts.imageUploadParams.hasOwnProperty(key)) {
|
|
1238
|
+
form_data.append(key, editor.opts.imageUploadParams[key]);
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
// Set the image in the request.
|
|
1243
|
+
form_data.append(editor.opts.imageUploadParam, image, image.name);
|
|
1244
|
+
|
|
1245
|
+
// Create XHR request.
|
|
1246
|
+
var url = editor.opts.imageUploadURL;
|
|
1247
|
+
|
|
1248
|
+
if (editor.opts.imageUploadToS3) {
|
|
1249
|
+
if (editor.opts.imageUploadToS3.uploadURL) {
|
|
1250
|
+
url = editor.opts.imageUploadToS3.uploadURL;
|
|
1251
|
+
}
|
|
1252
|
+
else {
|
|
1253
|
+
url = 'https://' + editor.opts.imageUploadToS3.region + '.amazonaws.com/' + editor.opts.imageUploadToS3.bucket;
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
var xhr = editor.core.getXHR(url, editor.opts.imageUploadMethod);
|
|
1257
|
+
_startUpload(xhr, form_data, image, $image_placeholder || $current_image);
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
/**
|
|
1263
|
+
* Image drop inside the upload zone.
|
|
1264
|
+
*/
|
|
1265
|
+
|
|
1266
|
+
function _bindInsertEvents($popup) {
|
|
1267
|
+
|
|
1268
|
+
// Drag over the dropable area.
|
|
1269
|
+
editor.events.$on($popup, 'dragover dragenter', '.fr-image-upload-layer', function () {
|
|
1270
|
+
$(this).addClass('fr-drop');
|
|
1271
|
+
|
|
1272
|
+
return false;
|
|
1273
|
+
}, true);
|
|
1274
|
+
|
|
1275
|
+
// Drag end.
|
|
1276
|
+
editor.events.$on($popup, 'dragleave dragend', '.fr-image-upload-layer', function () {
|
|
1277
|
+
$(this).removeClass('fr-drop');
|
|
1278
|
+
|
|
1279
|
+
return false;
|
|
1280
|
+
}, true);
|
|
1281
|
+
|
|
1282
|
+
// Drop.
|
|
1283
|
+
editor.events.$on($popup, 'drop', '.fr-image-upload-layer', function (e) {
|
|
1284
|
+
e.preventDefault();
|
|
1285
|
+
e.stopPropagation();
|
|
1286
|
+
$(this).removeClass('fr-drop');
|
|
1287
|
+
var dt = e.originalEvent.dataTransfer;
|
|
1288
|
+
|
|
1289
|
+
if (dt && dt.files) {
|
|
1290
|
+
var inst = $popup.data('instance') || editor;
|
|
1291
|
+
inst.events.disableBlur();
|
|
1292
|
+
inst.image.upload(dt.files);
|
|
1293
|
+
inst.events.enableBlur();
|
|
1294
|
+
}
|
|
1295
|
+
}, true);
|
|
1296
|
+
|
|
1297
|
+
if (editor.helpers.isIOS()) {
|
|
1298
|
+
editor.events.$on($popup, 'touchstart', '.fr-image-upload-layer input[type="file"]', function () {
|
|
1299
|
+
$(this).trigger('click');
|
|
1300
|
+
}, true);
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
editor.events.$on($popup, 'change', '.fr-image-upload-layer input[type="file"]', function () {
|
|
1304
|
+
if (this.files) {
|
|
1305
|
+
var inst = $popup.data('instance') || editor;
|
|
1306
|
+
|
|
1307
|
+
inst.events.disableBlur();
|
|
1308
|
+
$popup.find('input:focus').blur();
|
|
1309
|
+
inst.events.enableBlur();
|
|
1310
|
+
|
|
1311
|
+
inst.image.upload(this.files, $current_image);
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
// Else IE 9 case.
|
|
1315
|
+
// Chrome fix.
|
|
1316
|
+
$(this).val('');
|
|
1317
|
+
}, true);
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
function _beforeElementDrop($el) {
|
|
1321
|
+
if ($el.is('img') && $el.parents('.fr-img-caption').length > 0) {
|
|
1322
|
+
return $el.parents('.fr-img-caption');
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
function _drop(e) {
|
|
1327
|
+
|
|
1328
|
+
// Check if we are dropping files.
|
|
1329
|
+
var dt = e.originalEvent.dataTransfer;
|
|
1330
|
+
|
|
1331
|
+
if (dt && dt.files && dt.files.length) {
|
|
1332
|
+
var img = dt.files[0];
|
|
1333
|
+
|
|
1334
|
+
if (img && img.type && img.type.indexOf('image') !== -1 && editor.opts.imageAllowedTypes.indexOf(img.type.replace(/image\//g, '')) >= 0) {
|
|
1335
|
+
if (!editor.opts.imageUpload) {
|
|
1336
|
+
e.preventDefault();
|
|
1337
|
+
e.stopPropagation();
|
|
1338
|
+
|
|
1339
|
+
return false;
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
editor.markers.remove();
|
|
1343
|
+
editor.markers.insertAtPoint(e.originalEvent);
|
|
1344
|
+
|
|
1345
|
+
editor.$el.find('.fr-marker').replaceWith($.FE.MARKERS);
|
|
1346
|
+
|
|
1347
|
+
if (editor.$el.find('.fr-marker').length === 0) {
|
|
1348
|
+
editor.selection.setAtEnd(editor.el);
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
// Hide popups.
|
|
1352
|
+
editor.popups.hideAll();
|
|
1353
|
+
|
|
1354
|
+
// Show the image insert popup.
|
|
1355
|
+
var $popup = editor.popups.get('image.insert');
|
|
1356
|
+
|
|
1357
|
+
if (!$popup) $popup = _initInsertPopup();
|
|
1358
|
+
editor.popups.setContainer('image.insert', editor.$sc);
|
|
1359
|
+
|
|
1360
|
+
var left = e.originalEvent.pageX;
|
|
1361
|
+
var top = e.originalEvent.pageY;
|
|
1362
|
+
|
|
1363
|
+
if (editor.opts.iframe) {
|
|
1364
|
+
top += editor.$iframe.offset().top;
|
|
1365
|
+
left += editor.$iframe.offset().left;
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
editor.popups.show('image.insert', left, top);
|
|
1369
|
+
showProgressBar();
|
|
1370
|
+
|
|
1371
|
+
// Dropped file is an image that we allow.
|
|
1372
|
+
if (editor.opts.imageAllowedTypes.indexOf(img.type.replace(/image\//g, '')) >= 0) {
|
|
1373
|
+
|
|
1374
|
+
// Image might be selected.
|
|
1375
|
+
_exitEdit(true);
|
|
1376
|
+
|
|
1377
|
+
// Upload images.
|
|
1378
|
+
upload(dt.files);
|
|
1379
|
+
}
|
|
1380
|
+
else {
|
|
1381
|
+
_throwError(BAD_FILE_TYPE);
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
// Cancel anything else.
|
|
1385
|
+
e.preventDefault();
|
|
1386
|
+
e.stopPropagation();
|
|
1387
|
+
|
|
1388
|
+
return false;
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
function _initEvents() {
|
|
1394
|
+
|
|
1395
|
+
// Mouse down on image. It might start move.
|
|
1396
|
+
editor.events.$on(editor.$el, editor._mousedown, editor.el.tagName == 'IMG' ? null : 'img:not([contenteditable="false"])', function (e) {
|
|
1397
|
+
if ($(this).parents('[contenteditable]:not(.fr-element):not(.fr-img-caption):not(body):first').attr('contenteditable') == 'false') return true;
|
|
1398
|
+
|
|
1399
|
+
if (!editor.helpers.isMobile()) editor.selection.clear();
|
|
1400
|
+
|
|
1401
|
+
mousedown = true;
|
|
1402
|
+
|
|
1403
|
+
if (editor.popups.areVisible()) editor.events.disableBlur();
|
|
1404
|
+
|
|
1405
|
+
// Prevent the image resizing.
|
|
1406
|
+
if (editor.browser.msie) {
|
|
1407
|
+
editor.events.disableBlur();
|
|
1408
|
+
editor.$el.attr('contenteditable', false);
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
if (!editor.draggable && e.type != 'touchstart') e.preventDefault();
|
|
1412
|
+
|
|
1413
|
+
e.stopPropagation();
|
|
1414
|
+
});
|
|
1415
|
+
|
|
1416
|
+
// Mouse up on an image prevent move.
|
|
1417
|
+
editor.events.$on(editor.$el, editor._mouseup, editor.el.tagName == 'IMG' ? null : 'img:not([contenteditable="false"])', function (e) {
|
|
1418
|
+
if ($(this).parents('[contenteditable]:not(.fr-element):not(.fr-img-caption):not(body):first').attr('contenteditable') == 'false') return true;
|
|
1419
|
+
|
|
1420
|
+
if (mousedown) {
|
|
1421
|
+
mousedown = false;
|
|
1422
|
+
|
|
1423
|
+
// Remove moving class.
|
|
1424
|
+
e.stopPropagation();
|
|
1425
|
+
|
|
1426
|
+
if (editor.browser.msie) {
|
|
1427
|
+
editor.$el.attr('contenteditable', true);
|
|
1428
|
+
editor.events.enableBlur();
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
});
|
|
1432
|
+
|
|
1433
|
+
// Show image popup when it was selected.
|
|
1434
|
+
editor.events.on('keyup', function (e) {
|
|
1435
|
+
if (e.shiftKey && editor.selection.text().replace(/\n/g, '') === '' && editor.keys.isArrow(e.which)) {
|
|
1436
|
+
var s_el = editor.selection.element();
|
|
1437
|
+
var e_el = editor.selection.endElement();
|
|
1438
|
+
|
|
1439
|
+
if (s_el && s_el.tagName == 'IMG') {
|
|
1440
|
+
_editImg($(s_el));
|
|
1441
|
+
}
|
|
1442
|
+
else if (e_el && e_el.tagName == 'IMG') {
|
|
1443
|
+
_editImg($(e_el));
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
}, true);
|
|
1447
|
+
|
|
1448
|
+
// Drop inside the editor.
|
|
1449
|
+
editor.events.on('drop', _drop);
|
|
1450
|
+
editor.events.on('element.beforeDrop', _beforeElementDrop);
|
|
1451
|
+
|
|
1452
|
+
editor.events.on('mousedown window.mousedown', _markExit);
|
|
1453
|
+
editor.events.on('window.touchmove', _unmarkExit);
|
|
1454
|
+
|
|
1455
|
+
editor.events.on('mouseup window.mouseup', function () {
|
|
1456
|
+
if ($current_image) {
|
|
1457
|
+
_exitEdit();
|
|
1458
|
+
|
|
1459
|
+
return false;
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
_unmarkExit();
|
|
1463
|
+
});
|
|
1464
|
+
editor.events.on('commands.mousedown', function ($btn) {
|
|
1465
|
+
if ($btn.parents('.fr-toolbar').length > 0) {
|
|
1466
|
+
_exitEdit();
|
|
1467
|
+
}
|
|
1468
|
+
});
|
|
1469
|
+
|
|
1470
|
+
editor.events.on('blur image.hideResizer commands.undo commands.redo element.dropped', function () {
|
|
1471
|
+
mousedown = false;
|
|
1472
|
+
_exitEdit(true);
|
|
1473
|
+
});
|
|
1474
|
+
|
|
1475
|
+
editor.events.on('modals.hide', function () {
|
|
1476
|
+
if ($current_image) {
|
|
1477
|
+
_selectImage();
|
|
1478
|
+
editor.selection.clear();
|
|
1479
|
+
}
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
/**
|
|
1484
|
+
* Init the image upload popup.
|
|
1485
|
+
*/
|
|
1486
|
+
|
|
1487
|
+
function _initInsertPopup(delayed) {
|
|
1488
|
+
if (delayed) {
|
|
1489
|
+
editor.popups.onRefresh('image.insert', _refreshInsertPopup);
|
|
1490
|
+
editor.popups.onHide('image.insert', _hideInsertPopup);
|
|
1491
|
+
|
|
1492
|
+
return true;
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
var active;
|
|
1496
|
+
|
|
1497
|
+
// Image buttons.
|
|
1498
|
+
var image_buttons = '';
|
|
1499
|
+
|
|
1500
|
+
if (!editor.opts.imageUpload) {
|
|
1501
|
+
editor.opts.imageInsertButtons.splice(editor.opts.imageInsertButtons.indexOf('imageUpload'), 1);
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
if (editor.opts.imageInsertButtons.length > 1) {
|
|
1505
|
+
image_buttons = '<div class="fr-buttons">' + editor.button.buildList(editor.opts.imageInsertButtons) + '</div>';
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
var uploadIndex = editor.opts.imageInsertButtons.indexOf('imageUpload');
|
|
1509
|
+
var urlIndex = editor.opts.imageInsertButtons.indexOf('imageByURL');
|
|
1510
|
+
|
|
1511
|
+
// Image upload layer.
|
|
1512
|
+
var upload_layer = '';
|
|
1513
|
+
|
|
1514
|
+
if (uploadIndex >= 0) {
|
|
1515
|
+
active = ' fr-active';
|
|
1516
|
+
|
|
1517
|
+
if (urlIndex >= 0 && uploadIndex > urlIndex) {
|
|
1518
|
+
active = '';
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
upload_layer = '<div class="fr-image-upload-layer' + active + ' fr-layer" id="fr-image-upload-layer-' + editor.id + '"><strong>' + editor.language.translate('Drop image') + '</strong><br>(' + editor.language.translate('or click') + ')<div class="fr-form"><input type="file" accept="image/' + editor.opts.imageAllowedTypes.join(', image/').toLowerCase() + '" tabIndex="-1" aria-labelledby="fr-image-upload-layer-' + editor.id + '" role="button"></div></div>'
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
// Image by url layer.
|
|
1525
|
+
var by_url_layer = '';
|
|
1526
|
+
|
|
1527
|
+
if (urlIndex >= 0) {
|
|
1528
|
+
active = ' fr-active';
|
|
1529
|
+
|
|
1530
|
+
if (uploadIndex >= 0 && urlIndex > uploadIndex) {
|
|
1531
|
+
active = '';
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
by_url_layer = '<div class="fr-image-by-url-layer' + active + ' fr-layer" id="fr-image-by-url-layer-' + editor.id + '"><div class="fr-input-line"><input id="fr-image-by-url-layer-text-' + editor.id + '" type="text" placeholder="http://" tabIndex="1" aria-required="true"></div><div class="fr-action-buttons"><button type="button" class="fr-command fr-submit" data-cmd="imageInsertByURL" tabIndex="2" role="button">' + editor.language.translate('Insert') + '</button></div></div>'
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
// Progress bar.
|
|
1538
|
+
var progress_bar_layer = '<div class="fr-image-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="imageDismissError" tabIndex="2" role="button">OK</button></div></div>';
|
|
1539
|
+
|
|
1540
|
+
var template = {
|
|
1541
|
+
buttons: image_buttons,
|
|
1542
|
+
upload_layer: upload_layer,
|
|
1543
|
+
by_url_layer: by_url_layer,
|
|
1544
|
+
progress_bar: progress_bar_layer
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
// Set the template in the popup.
|
|
1548
|
+
var $popup = editor.popups.create('image.insert', template);
|
|
1549
|
+
|
|
1550
|
+
if (editor.$wp) {
|
|
1551
|
+
editor.events.$on(editor.$wp, 'scroll', function () {
|
|
1552
|
+
if ($current_image && editor.popups.isVisible('image.insert')) {
|
|
1553
|
+
replace();
|
|
1554
|
+
}
|
|
1555
|
+
});
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1558
|
+
_bindInsertEvents($popup);
|
|
1559
|
+
|
|
1560
|
+
return $popup;
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
/**
|
|
1564
|
+
* Refresh the ALT popup.
|
|
1565
|
+
*/
|
|
1566
|
+
|
|
1567
|
+
function _refreshAltPopup() {
|
|
1568
|
+
if ($current_image) {
|
|
1569
|
+
var $popup = editor.popups.get('image.alt');
|
|
1570
|
+
$popup.find('input').val($current_image.attr('alt') || '').trigger('change');
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
/**
|
|
1575
|
+
* Show the ALT popup.
|
|
1576
|
+
*/
|
|
1577
|
+
|
|
1578
|
+
function showAltPopup() {
|
|
1579
|
+
var $popup = editor.popups.get('image.alt');
|
|
1580
|
+
|
|
1581
|
+
if (!$popup) $popup = _initAltPopup();
|
|
1582
|
+
hideProgressBar();
|
|
1583
|
+
editor.popups.refresh('image.alt');
|
|
1584
|
+
editor.popups.setContainer('image.alt', editor.$sc);
|
|
1585
|
+
|
|
1586
|
+
var $el = getEl();
|
|
1587
|
+
|
|
1588
|
+
if (hasCaption()) {
|
|
1589
|
+
$el = $el.find('.fr-img-wrap');
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
var left = $el.offset().left + $el.outerWidth() / 2;
|
|
1593
|
+
var top = $el.offset().top + $el.outerHeight();
|
|
1594
|
+
|
|
1595
|
+
editor.popups.show('image.alt', left, top, $el.outerHeight());
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
/**
|
|
1599
|
+
* Init the image upload popup.
|
|
1600
|
+
*/
|
|
1601
|
+
|
|
1602
|
+
function _initAltPopup(delayed) {
|
|
1603
|
+
if (delayed) {
|
|
1604
|
+
editor.popups.onRefresh('image.alt', _refreshAltPopup);
|
|
1605
|
+
|
|
1606
|
+
return true;
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1609
|
+
// Image buttons.
|
|
1610
|
+
var image_buttons = '';
|
|
1611
|
+
image_buttons = '<div class="fr-buttons">' + editor.button.buildList(editor.opts.imageAltButtons) + '</div>';
|
|
1612
|
+
|
|
1613
|
+
// Image by url layer.
|
|
1614
|
+
var alt_layer = '';
|
|
1615
|
+
alt_layer = '<div class="fr-image-alt-layer fr-layer fr-active" id="fr-image-alt-layer-' + editor.id + '"><div class="fr-input-line"><input id="fr-image-alt-layer-text-' + editor.id + '" type="text" placeholder="' + editor.language.translate('Alternate Text') + '" tabIndex="1"></div><div class="fr-action-buttons"><button type="button" class="fr-command fr-submit" data-cmd="imageSetAlt" tabIndex="2" role="button">' + editor.language.translate('Update') + '</button></div></div>'
|
|
1616
|
+
|
|
1617
|
+
var template = {
|
|
1618
|
+
buttons: image_buttons,
|
|
1619
|
+
alt_layer: alt_layer
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1622
|
+
// Set the template in the popup.
|
|
1623
|
+
var $popup = editor.popups.create('image.alt', template);
|
|
1624
|
+
|
|
1625
|
+
if (editor.$wp) {
|
|
1626
|
+
editor.events.$on(editor.$wp, 'scroll.image-alt', function () {
|
|
1627
|
+
if ($current_image && editor.popups.isVisible('image.alt')) {
|
|
1628
|
+
showAltPopup();
|
|
1629
|
+
}
|
|
1630
|
+
});
|
|
1631
|
+
}
|
|
1632
|
+
|
|
1633
|
+
return $popup;
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1636
|
+
/**
|
|
1637
|
+
* Set ALT based on the values from the popup.
|
|
1638
|
+
*/
|
|
1639
|
+
|
|
1640
|
+
function setAlt(alt) {
|
|
1641
|
+
if ($current_image) {
|
|
1642
|
+
var $popup = editor.popups.get('image.alt');
|
|
1643
|
+
$current_image.attr('alt', alt || $popup.find('input').val() || '');
|
|
1644
|
+
$popup.find('input:focus').blur();
|
|
1645
|
+
_editImg($current_image);
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1649
|
+
/**
|
|
1650
|
+
* Refresh the size popup.
|
|
1651
|
+
*/
|
|
1652
|
+
|
|
1653
|
+
function _refreshSizePopup() {
|
|
1654
|
+
if ($current_image) {
|
|
1655
|
+
var $popup = editor.popups.get('image.size');
|
|
1656
|
+
$popup.find('input[name="width"]').val($current_image.get(0).style.width).trigger('change');
|
|
1657
|
+
$popup.find('input[name="height"]').val($current_image.get(0).style.height).trigger('change');
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
/**
|
|
1662
|
+
* Show the size popup.
|
|
1663
|
+
*/
|
|
1664
|
+
|
|
1665
|
+
function showSizePopup() {
|
|
1666
|
+
var $popup = editor.popups.get('image.size');
|
|
1667
|
+
|
|
1668
|
+
if (!$popup) $popup = _initSizePopup();
|
|
1669
|
+
hideProgressBar();
|
|
1670
|
+
editor.popups.refresh('image.size');
|
|
1671
|
+
editor.popups.setContainer('image.size', editor.$sc);
|
|
1672
|
+
|
|
1673
|
+
var $el = getEl();
|
|
1674
|
+
|
|
1675
|
+
if (hasCaption()) {
|
|
1676
|
+
$el = $el.find('.fr-img-wrap');
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
var left = $el.offset().left + $el.outerWidth() / 2;
|
|
1680
|
+
var top = $el.offset().top + $el.outerHeight();
|
|
1681
|
+
|
|
1682
|
+
editor.popups.show('image.size', left, top, $el.outerHeight());
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1685
|
+
/**
|
|
1686
|
+
* Init the image upload popup.
|
|
1687
|
+
*/
|
|
1688
|
+
|
|
1689
|
+
function _initSizePopup(delayed) {
|
|
1690
|
+
if (delayed) {
|
|
1691
|
+
editor.popups.onRefresh('image.size', _refreshSizePopup);
|
|
1692
|
+
|
|
1693
|
+
return true;
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
// Image buttons.
|
|
1697
|
+
var image_buttons = '';
|
|
1698
|
+
image_buttons = '<div class="fr-buttons">' + editor.button.buildList(editor.opts.imageSizeButtons) + '</div>';
|
|
1699
|
+
|
|
1700
|
+
// Size layer.
|
|
1701
|
+
var size_layer = '';
|
|
1702
|
+
size_layer = '<div class="fr-image-size-layer fr-layer fr-active" id="fr-image-size-layer-' + editor.id + '"><div class="fr-image-group"><div class="fr-input-line"><input id="fr-image-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-image-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="imageSetSize" tabIndex="2" role="button">' + editor.language.translate('Update') + '</button></div></div>'
|
|
1703
|
+
|
|
1704
|
+
var template = {
|
|
1705
|
+
buttons: image_buttons,
|
|
1706
|
+
size_layer: size_layer
|
|
1707
|
+
};
|
|
1708
|
+
|
|
1709
|
+
// Set the template in the popup.
|
|
1710
|
+
var $popup = editor.popups.create('image.size', template);
|
|
1711
|
+
|
|
1712
|
+
if (editor.$wp) {
|
|
1713
|
+
editor.events.$on(editor.$wp, 'scroll.image-size', function () {
|
|
1714
|
+
if ($current_image && editor.popups.isVisible('image.size')) {
|
|
1715
|
+
showSizePopup();
|
|
1716
|
+
}
|
|
1717
|
+
});
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
return $popup;
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
/**
|
|
1724
|
+
* Set size based on the current image size.
|
|
1725
|
+
*/
|
|
1726
|
+
|
|
1727
|
+
function setSize(width, height) {
|
|
1728
|
+
if ($current_image) {
|
|
1729
|
+
var $popup = editor.popups.get('image.size');
|
|
1730
|
+
width = width || $popup.find('input[name="width"]').val() || '';
|
|
1731
|
+
height = height || $popup.find('input[name="height"]').val() || '';
|
|
1732
|
+
var regex = /^[\d]+((px)|%)*$/g;
|
|
1733
|
+
|
|
1734
|
+
$current_image.removeAttr('width').removeAttr('height');
|
|
1735
|
+
|
|
1736
|
+
if (width.match(regex)) $current_image.css('width', width);
|
|
1737
|
+
else $current_image.css('width', '');
|
|
1738
|
+
|
|
1739
|
+
if (height.match(regex)) $current_image.css('height', height);
|
|
1740
|
+
else $current_image.css('height', '');
|
|
1741
|
+
|
|
1742
|
+
if (hasCaption()) {
|
|
1743
|
+
$current_image.parent().removeAttr('width').removeAttr('height');
|
|
1744
|
+
|
|
1745
|
+
if (width.match(regex)) $current_image.parent().css('width', width);
|
|
1746
|
+
else $current_image.parent().css('width', '');
|
|
1747
|
+
|
|
1748
|
+
if (height.match(regex)) $current_image.parent().css('height', height);
|
|
1749
|
+
else $current_image.parent().css('height', '');
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
$popup.find('input:focus').blur();
|
|
1753
|
+
_editImg($current_image);
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
|
|
1757
|
+
/**
|
|
1758
|
+
* Show the image upload layer.
|
|
1759
|
+
*/
|
|
1760
|
+
|
|
1761
|
+
function showLayer(name) {
|
|
1762
|
+
var $popup = editor.popups.get('image.insert');
|
|
1763
|
+
|
|
1764
|
+
var left;
|
|
1765
|
+
var top;
|
|
1766
|
+
|
|
1767
|
+
// Click on the button from the toolbar without image selected.
|
|
1768
|
+
if (!$current_image && !editor.opts.toolbarInline) {
|
|
1769
|
+
var $btn = editor.$tb.find('.fr-command[data-cmd="insertImage"]');
|
|
1770
|
+
left = $btn.offset().left + $btn.outerWidth() / 2;
|
|
1771
|
+
top = $btn.offset().top + (editor.opts.toolbarBottom ? 10 : $btn.outerHeight() - 10);
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
// Image is selected.
|
|
1775
|
+
else if ($current_image) {
|
|
1776
|
+
|
|
1777
|
+
var $el = getEl();
|
|
1778
|
+
|
|
1779
|
+
if (hasCaption()) {
|
|
1780
|
+
$el = $el.find('.fr-img-wrap');
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1783
|
+
// Set the top to the bottom of the image.
|
|
1784
|
+
top = $el.offset().top + $el.outerHeight();
|
|
1785
|
+
left = $el.offset().left + $el.outerWidth() / 2;
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1788
|
+
// Image is selected and we are in inline mode.
|
|
1789
|
+
if (!$current_image && editor.opts.toolbarInline) {
|
|
1790
|
+
|
|
1791
|
+
// Set top to the popup top.
|
|
1792
|
+
top = $popup.offset().top - editor.helpers.getPX($popup.css('margin-top'));
|
|
1793
|
+
|
|
1794
|
+
// If the popup is above apply height correction.
|
|
1795
|
+
if ($popup.hasClass('fr-above')) {
|
|
1796
|
+
top += $popup.outerHeight();
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
// Show the new layer.
|
|
1801
|
+
$popup.find('.fr-layer').removeClass('fr-active');
|
|
1802
|
+
$popup.find('.fr-' + name + '-layer').addClass('fr-active');
|
|
1803
|
+
|
|
1804
|
+
editor.popups.show('image.insert', left, top, ($current_image ? $current_image.outerHeight() : 0));
|
|
1805
|
+
editor.accessibility.focusPopup($popup);
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
/**
|
|
1809
|
+
* Refresh the upload image button.
|
|
1810
|
+
*/
|
|
1811
|
+
|
|
1812
|
+
function refreshUploadButton($btn) {
|
|
1813
|
+
var $popup = editor.popups.get('image.insert');
|
|
1814
|
+
|
|
1815
|
+
if ($popup.find('.fr-image-upload-layer').hasClass('fr-active')) {
|
|
1816
|
+
$btn.addClass('fr-active').attr('aria-pressed', true);
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
/**
|
|
1821
|
+
* Refresh the insert by url button.
|
|
1822
|
+
*/
|
|
1823
|
+
|
|
1824
|
+
function refreshByURLButton($btn) {
|
|
1825
|
+
var $popup = editor.popups.get('image.insert');
|
|
1826
|
+
|
|
1827
|
+
if ($popup.find('.fr-image-by-url-layer').hasClass('fr-active')) {
|
|
1828
|
+
$btn.addClass('fr-active').attr('aria-pressed', true);
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
function _resizeImage(e, initPageX, direction, step) {
|
|
1833
|
+
e.pageX = initPageX;
|
|
1834
|
+
_handlerMousedown.call(this, e);
|
|
1835
|
+
e.pageX = e.pageX + direction * Math.floor(Math.pow(1.1, step));
|
|
1836
|
+
_handlerMousemove.call(this, e);
|
|
1837
|
+
_handlerMouseup.call(this, e);
|
|
1838
|
+
|
|
1839
|
+
return ++step;
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
/**
|
|
1843
|
+
* Init image resizer.
|
|
1844
|
+
*/
|
|
1845
|
+
function _initImageResizer() {
|
|
1846
|
+
var doc;
|
|
1847
|
+
|
|
1848
|
+
// No shared image resizer.
|
|
1849
|
+
if (!editor.shared.$image_resizer) {
|
|
1850
|
+
|
|
1851
|
+
// Create shared image resizer.
|
|
1852
|
+
editor.shared.$image_resizer = $('<div class="fr-image-resizer"></div>');
|
|
1853
|
+
$image_resizer = editor.shared.$image_resizer;
|
|
1854
|
+
|
|
1855
|
+
// Bind mousedown event shared.
|
|
1856
|
+
editor.events.$on($image_resizer, 'mousedown', function (e) {
|
|
1857
|
+
e.stopPropagation();
|
|
1858
|
+
}, true);
|
|
1859
|
+
|
|
1860
|
+
// Image resize is enabled.
|
|
1861
|
+
if (editor.opts.imageResize) {
|
|
1862
|
+
$image_resizer.append(_getHandler('nw') + _getHandler('ne') + _getHandler('sw') + _getHandler('se'));
|
|
1863
|
+
|
|
1864
|
+
// Add image resizer overlay and set it.
|
|
1865
|
+
editor.shared.$img_overlay = $('<div class="fr-image-overlay"></div>');
|
|
1866
|
+
$overlay = editor.shared.$img_overlay;
|
|
1867
|
+
doc = $image_resizer.get(0).ownerDocument;
|
|
1868
|
+
$(doc).find('body:first').append($overlay);
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
else {
|
|
1872
|
+
$image_resizer = editor.shared.$image_resizer;
|
|
1873
|
+
$overlay = editor.shared.$img_overlay;
|
|
1874
|
+
|
|
1875
|
+
editor.events.on('destroy', function () {
|
|
1876
|
+
$image_resizer.removeClass('fr-active').appendTo($('body:first'));
|
|
1877
|
+
}, true);
|
|
1878
|
+
}
|
|
1879
|
+
|
|
1880
|
+
// Shared destroy.
|
|
1881
|
+
editor.events.on('shared.destroy', function () {
|
|
1882
|
+
$image_resizer.html('').removeData().remove();
|
|
1883
|
+
$image_resizer = null;
|
|
1884
|
+
|
|
1885
|
+
if (editor.opts.imageResize) {
|
|
1886
|
+
$overlay.remove();
|
|
1887
|
+
$overlay = null;
|
|
1888
|
+
}
|
|
1889
|
+
}, true);
|
|
1890
|
+
|
|
1891
|
+
// Window resize. Exit from edit.
|
|
1892
|
+
if (!editor.helpers.isMobile()) {
|
|
1893
|
+
editor.events.$on($(editor.o_win), 'resize', function () {
|
|
1894
|
+
if ($current_image && !$current_image.hasClass('fr-uploading')) {
|
|
1895
|
+
_exitEdit(true);
|
|
1896
|
+
}
|
|
1897
|
+
else if ($current_image) {
|
|
1898
|
+
_repositionResizer();
|
|
1899
|
+
replace();
|
|
1900
|
+
showProgressBar(false);
|
|
1901
|
+
}
|
|
1902
|
+
});
|
|
1903
|
+
}
|
|
1904
|
+
|
|
1905
|
+
// Image resize is enabled.
|
|
1906
|
+
if (editor.opts.imageResize) {
|
|
1907
|
+
doc = $image_resizer.get(0).ownerDocument;
|
|
1908
|
+
editor.events.$on($image_resizer, editor._mousedown, '.fr-handler', _handlerMousedown);
|
|
1909
|
+
editor.events.$on($(doc), editor._mousemove, _handlerMousemove);
|
|
1910
|
+
editor.events.$on($(doc.defaultView || doc.parentWindow), editor._mouseup, _handlerMouseup);
|
|
1911
|
+
editor.events.$on($overlay, 'mouseleave', _handlerMouseup);
|
|
1912
|
+
|
|
1913
|
+
// Accessibility.
|
|
1914
|
+
|
|
1915
|
+
// Used for keys holing.
|
|
1916
|
+
var step = 1;
|
|
1917
|
+
var prevKey = null;
|
|
1918
|
+
var prevTimestamp = 0;
|
|
1919
|
+
|
|
1920
|
+
// Keydown event.
|
|
1921
|
+
editor.events.on('keydown', function (e) {
|
|
1922
|
+
if ($current_image) {
|
|
1923
|
+
var ctrlKey = navigator.userAgent.indexOf('Mac OS X') != -1 ? e.metaKey : e.ctrlKey;
|
|
1924
|
+
var keycode = e.which;
|
|
1925
|
+
|
|
1926
|
+
if (keycode !== prevKey || e.timeStamp - prevTimestamp > 200) {
|
|
1927
|
+
step = 1;
|
|
1928
|
+
|
|
1929
|
+
// Reset step. Known browser issue: Keyup does not trigger when ctrl is pressed.
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
// Increase image size.
|
|
1933
|
+
if ((keycode == $.FE.KEYCODE.EQUALS || (editor.browser.mozilla && keycode == $.FE.KEYCODE.FF_EQUALS)) && ctrlKey && !e.altKey) {
|
|
1934
|
+
step = _resizeImage.call(this, e, 1, 1, step);
|
|
1935
|
+
}
|
|
1936
|
+
|
|
1937
|
+
// Decrease image size.
|
|
1938
|
+
else if ((keycode == $.FE.KEYCODE.HYPHEN || (editor.browser.mozilla && keycode == $.FE.KEYCODE.FF_HYPHEN)) && ctrlKey && !e.altKey) {
|
|
1939
|
+
step = _resizeImage.call(this, e, 2, -1, step);
|
|
1940
|
+
}
|
|
1941
|
+
else if (!editor.keys.ctrlKey(e) && keycode == $.FE.KEYCODE.ENTER) {
|
|
1942
|
+
$current_image.before('<br>');
|
|
1943
|
+
_editImg($current_image);
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
// Save key code.
|
|
1947
|
+
prevKey = keycode;
|
|
1948
|
+
|
|
1949
|
+
// Save timestamp.
|
|
1950
|
+
prevTimestamp = e.timeStamp;
|
|
1951
|
+
}
|
|
1952
|
+
}, true);
|
|
1953
|
+
|
|
1954
|
+
// Reset the step on key up event.
|
|
1955
|
+
editor.events.on('keyup', function () {
|
|
1956
|
+
step = 1;
|
|
1957
|
+
});
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
/**
|
|
1962
|
+
* Remove the current image.
|
|
1963
|
+
*/
|
|
1964
|
+
function remove($img) {
|
|
1965
|
+
$img = $img || getEl();
|
|
1966
|
+
|
|
1967
|
+
if ($img) {
|
|
1968
|
+
if (editor.events.trigger('image.beforeRemove', [$img]) !== false) {
|
|
1969
|
+
editor.popups.hideAll();
|
|
1970
|
+
_selectImage();
|
|
1971
|
+
_exitEdit(true);
|
|
1972
|
+
|
|
1973
|
+
if (!editor.undo.canDo()) editor.undo.saveStep();
|
|
1974
|
+
|
|
1975
|
+
if ($img.get(0) == editor.el) {
|
|
1976
|
+
$img.removeAttr('src');
|
|
1977
|
+
}
|
|
1978
|
+
else {
|
|
1979
|
+
if ($img.get(0).parentNode.tagName == 'A') {
|
|
1980
|
+
editor.selection.setBefore($img.get(0).parentNode) || editor.selection.setAfter($img.get(0).parentNode) || $img.parent().after($.FE.MARKERS);
|
|
1981
|
+
$($img.get(0).parentNode).remove();
|
|
1982
|
+
}
|
|
1983
|
+
else {
|
|
1984
|
+
editor.selection.setBefore($img.get(0)) || editor.selection.setAfter($img.get(0)) || $img.after($.FE.MARKERS);
|
|
1985
|
+
$img.remove();
|
|
1986
|
+
}
|
|
1987
|
+
|
|
1988
|
+
editor.html.fillEmptyBlocks();
|
|
1989
|
+
editor.selection.restore();
|
|
1990
|
+
}
|
|
1991
|
+
|
|
1992
|
+
editor.undo.saveStep();
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1997
|
+
function _editorKeydownHandler(e) {
|
|
1998
|
+
var key_code = e.which;
|
|
1999
|
+
|
|
2000
|
+
if ($current_image && (key_code == $.FE.KEYCODE.BACKSPACE || key_code == $.FE.KEYCODE.DELETE)) {
|
|
2001
|
+
e.preventDefault();
|
|
2002
|
+
e.stopPropagation();
|
|
2003
|
+
remove();
|
|
2004
|
+
|
|
2005
|
+
return false;
|
|
2006
|
+
}
|
|
2007
|
+
|
|
2008
|
+
else if ($current_image && key_code == $.FE.KEYCODE.ESC) {
|
|
2009
|
+
var $img = $current_image;
|
|
2010
|
+
_exitEdit(true);
|
|
2011
|
+
editor.selection.setAfter($img.get(0));
|
|
2012
|
+
editor.selection.restore();
|
|
2013
|
+
e.preventDefault();
|
|
2014
|
+
|
|
2015
|
+
return false;
|
|
2016
|
+
}
|
|
2017
|
+
|
|
2018
|
+
// Move cursor if left and right arrows are used.
|
|
2019
|
+
else if ($current_image && (key_code == $.FE.KEYCODE.ARROW_LEFT || key_code == $.FE.KEYCODE.ARROW_RIGHT)) {
|
|
2020
|
+
var img = $current_image.get(0);
|
|
2021
|
+
_exitEdit(true);
|
|
2022
|
+
|
|
2023
|
+
if (key_code == $.FE.KEYCODE.ARROW_LEFT) {
|
|
2024
|
+
editor.selection.setBefore(img);
|
|
2025
|
+
}
|
|
2026
|
+
else {
|
|
2027
|
+
editor.selection.setAfter(img);
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
editor.selection.restore();
|
|
2031
|
+
e.preventDefault();
|
|
2032
|
+
|
|
2033
|
+
return false;
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2036
|
+
else if ($current_image && key_code != $.FE.KEYCODE.F10 && !editor.keys.isBrowserAction(e)) {
|
|
2037
|
+
e.preventDefault();
|
|
2038
|
+
e.stopPropagation();
|
|
2039
|
+
|
|
2040
|
+
return false;
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
|
|
2044
|
+
/**
|
|
2045
|
+
* Do some cleanup on images.
|
|
2046
|
+
*/
|
|
2047
|
+
function _cleanOnGet(el) {
|
|
2048
|
+
|
|
2049
|
+
// Tag is image.
|
|
2050
|
+
if (el && el.tagName == 'IMG') {
|
|
2051
|
+
|
|
2052
|
+
// Remove element if it has class fr-uploading or fr-error.
|
|
2053
|
+
if (editor.node.hasClass(el, 'fr-uploading') || editor.node.hasClass(el, 'fr-error')) {
|
|
2054
|
+
el.parentNode.removeChild(el);
|
|
2055
|
+
}
|
|
2056
|
+
|
|
2057
|
+
// Remove class if it is draggable.
|
|
2058
|
+
else if (editor.node.hasClass(el, 'fr-draggable')) {
|
|
2059
|
+
el.classList.remove('fr-draggable');
|
|
2060
|
+
}
|
|
2061
|
+
|
|
2062
|
+
if (el.parentNode && el.parentNode.parentNode && editor.node.hasClass(el.parentNode.parentNode, 'fr-img-caption')) {
|
|
2063
|
+
var p_node = el.parentNode.parentNode;
|
|
2064
|
+
p_node.removeAttribute('contenteditable');
|
|
2065
|
+
p_node.removeAttribute('draggable');
|
|
2066
|
+
p_node.classList.remove('fr-draggable');
|
|
2067
|
+
|
|
2068
|
+
var n_node = el.nextSibling;
|
|
2069
|
+
|
|
2070
|
+
if (n_node) {
|
|
2071
|
+
n_node.removeAttribute('contenteditable');
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
|
|
2076
|
+
// Look for inner nodes that might be in a similar case.
|
|
2077
|
+
else if (el && el.nodeType == Node.ELEMENT_NODE) {
|
|
2078
|
+
var imgs = el.querySelectorAll('img.fr-uploading, img.fr-error, img.fr-draggable');
|
|
2079
|
+
|
|
2080
|
+
for (var i = 0; i < imgs.length; i++) {
|
|
2081
|
+
_cleanOnGet(imgs[i]);
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2086
|
+
/**
|
|
2087
|
+
* Initialization.
|
|
2088
|
+
*/
|
|
2089
|
+
function _init() {
|
|
2090
|
+
_initEvents();
|
|
2091
|
+
|
|
2092
|
+
// Init on image.
|
|
2093
|
+
if (editor.el.tagName == 'IMG') {
|
|
2094
|
+
editor.$el.addClass('fr-view');
|
|
2095
|
+
}
|
|
2096
|
+
|
|
2097
|
+
editor.events.$on(editor.$el, editor.helpers.isMobile() && !editor.helpers.isWindowsPhone() ? 'touchend' : 'click', editor.el.tagName == 'IMG' ? null : 'img:not([contenteditable="false"])', _edit);
|
|
2098
|
+
|
|
2099
|
+
if (editor.helpers.isMobile()) {
|
|
2100
|
+
editor.events.$on(editor.$el, 'touchstart', editor.el.tagName == 'IMG' ? null : 'img:not([contenteditable="false"])', function () {
|
|
2101
|
+
touchScroll = false;
|
|
2102
|
+
})
|
|
2103
|
+
|
|
2104
|
+
editor.events.$on(editor.$el, 'touchmove', function () {
|
|
2105
|
+
touchScroll = true;
|
|
2106
|
+
});
|
|
2107
|
+
}
|
|
2108
|
+
|
|
2109
|
+
if (editor.$wp) {
|
|
2110
|
+
editor.events.on('window.keydown keydown', _editorKeydownHandler, true)
|
|
2111
|
+
|
|
2112
|
+
editor.events.on('keyup', function (e) {
|
|
2113
|
+
if ($current_image && e.which == $.FE.KEYCODE.ENTER) {
|
|
2114
|
+
|
|
2115
|
+
return false;
|
|
2116
|
+
}
|
|
2117
|
+
}, true);
|
|
2118
|
+
}
|
|
2119
|
+
else {
|
|
2120
|
+
editor.events.$on(editor.$win, 'keydown', _editorKeydownHandler);
|
|
2121
|
+
}
|
|
2122
|
+
|
|
2123
|
+
// ESC from accessibility.
|
|
2124
|
+
editor.events.on('toolbar.esc', function () {
|
|
2125
|
+
if ($current_image) {
|
|
2126
|
+
if (editor.$wp) {
|
|
2127
|
+
editor.events.disableBlur();
|
|
2128
|
+
editor.events.focus();
|
|
2129
|
+
}
|
|
2130
|
+
else {
|
|
2131
|
+
var $img = $current_image;
|
|
2132
|
+
_exitEdit(true);
|
|
2133
|
+
editor.selection.setAfter($img.get(0));
|
|
2134
|
+
editor.selection.restore();
|
|
2135
|
+
}
|
|
2136
|
+
|
|
2137
|
+
return false;
|
|
2138
|
+
}
|
|
2139
|
+
}, true);
|
|
2140
|
+
|
|
2141
|
+
// focusEditor from accessibility.
|
|
2142
|
+
editor.events.on('toolbar.focusEditor', function () {
|
|
2143
|
+
if ($current_image) {
|
|
2144
|
+
|
|
2145
|
+
return false;
|
|
2146
|
+
}
|
|
2147
|
+
}, true);
|
|
2148
|
+
|
|
2149
|
+
// Copy/cut image.
|
|
2150
|
+
editor.events.on('window.cut window.copy', function (e) {
|
|
2151
|
+
// Do copy only if image.edit popups is visible and not focused.
|
|
2152
|
+
if ($current_image && editor.popups.isVisible('image.edit') && !editor.popups.get('image.edit').find(':focus').length) {
|
|
2153
|
+
|
|
2154
|
+
var $el = getEl();
|
|
2155
|
+
|
|
2156
|
+
if (hasCaption()) {
|
|
2157
|
+
$el.before($.FE.START_MARKER);
|
|
2158
|
+
$el.after($.FE.END_MARKER);
|
|
2159
|
+
editor.selection.restore();
|
|
2160
|
+
editor.paste.saveCopiedText($el.get(0).outerHTML, $el.text());
|
|
2161
|
+
}
|
|
2162
|
+
else {
|
|
2163
|
+
_selectImage();
|
|
2164
|
+
editor.paste.saveCopiedText($current_image.get(0).outerHTML, $current_image.attr('alt'));
|
|
2165
|
+
}
|
|
2166
|
+
|
|
2167
|
+
if (e.type == 'copy') {
|
|
2168
|
+
setTimeout(function () {
|
|
2169
|
+
_editImg($current_image);
|
|
2170
|
+
});
|
|
2171
|
+
}
|
|
2172
|
+
else {
|
|
2173
|
+
_exitEdit(true);
|
|
2174
|
+
editor.undo.saveStep();
|
|
2175
|
+
setTimeout(function () {
|
|
2176
|
+
editor.undo.saveStep();
|
|
2177
|
+
}, 0);
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
}, true);
|
|
2181
|
+
|
|
2182
|
+
// Fix IE copy not working when selection is collapsed.
|
|
2183
|
+
if (editor.browser.msie) {
|
|
2184
|
+
editor.events.on('keydown', function (e) {
|
|
2185
|
+
// Selection is collapsed and we have an image.
|
|
2186
|
+
if (!(editor.selection.isCollapsed() && $current_image)) return true;
|
|
2187
|
+
|
|
2188
|
+
var key_code = e.which;
|
|
2189
|
+
|
|
2190
|
+
// Copy.
|
|
2191
|
+
if (key_code == $.FE.KEYCODE.C && editor.keys.ctrlKey(e)) {
|
|
2192
|
+
editor.events.trigger('window.copy');
|
|
2193
|
+
}
|
|
2194
|
+
|
|
2195
|
+
// Cut.
|
|
2196
|
+
else if (key_code == $.FE.KEYCODE.X && editor.keys.ctrlKey(e)) {
|
|
2197
|
+
editor.events.trigger('window.cut');
|
|
2198
|
+
}
|
|
2199
|
+
});
|
|
2200
|
+
}
|
|
2201
|
+
|
|
2202
|
+
// Do not leave page while uploading.
|
|
2203
|
+
editor.events.$on($(editor.o_win), 'keydown', function (e) {
|
|
2204
|
+
var key_code = e.which;
|
|
2205
|
+
|
|
2206
|
+
if ($current_image && key_code == $.FE.KEYCODE.BACKSPACE) {
|
|
2207
|
+
e.preventDefault();
|
|
2208
|
+
|
|
2209
|
+
return false;
|
|
2210
|
+
}
|
|
2211
|
+
});
|
|
2212
|
+
|
|
2213
|
+
// Check if image is uploading to abort it.
|
|
2214
|
+
editor.events.$on(editor.$win, 'keydown', function (e) {
|
|
2215
|
+
var key_code = e.which;
|
|
2216
|
+
|
|
2217
|
+
if ($current_image && $current_image.hasClass('fr-uploading') && key_code == $.FE.KEYCODE.ESC) {
|
|
2218
|
+
$current_image.trigger('abortUpload');
|
|
2219
|
+
}
|
|
2220
|
+
});
|
|
2221
|
+
|
|
2222
|
+
editor.events.on('destroy', function () {
|
|
2223
|
+
if ($current_image && $current_image.hasClass('fr-uploading')) {
|
|
2224
|
+
$current_image.trigger('abortUpload');
|
|
2225
|
+
}
|
|
2226
|
+
});
|
|
2227
|
+
|
|
2228
|
+
editor.events.on('paste.before', _clipboardPaste);
|
|
2229
|
+
editor.events.on('paste.beforeCleanup', _clipboardPasteCleanup);
|
|
2230
|
+
editor.events.on('paste.after', _uploadPastedImages);
|
|
2231
|
+
editor.events.on('html.set', _refreshImageList);
|
|
2232
|
+
editor.events.on('html.inserted', _refreshImageList);
|
|
2233
|
+
_refreshImageList();
|
|
2234
|
+
|
|
2235
|
+
editor.events.on('destroy', function () {
|
|
2236
|
+
images = [];
|
|
2237
|
+
})
|
|
2238
|
+
|
|
2239
|
+
// Remove any fr-uploading / fr-error images.
|
|
2240
|
+
editor.events.on('html.processGet', _cleanOnGet);
|
|
2241
|
+
|
|
2242
|
+
if (editor.opts.imageOutputSize) {
|
|
2243
|
+
var imgs;
|
|
2244
|
+
|
|
2245
|
+
editor.events.on('html.beforeGet', function () {
|
|
2246
|
+
imgs = editor.el.querySelectorAll('img')
|
|
2247
|
+
for (var i = 0; i < imgs.length; i++) {
|
|
2248
|
+
var width = imgs[i].style.width || $(imgs[i]).width();
|
|
2249
|
+
var height = imgs[i].style.height || $(imgs[i]).height();
|
|
2250
|
+
|
|
2251
|
+
if (width) imgs[i].setAttribute('width', ('' + width).replace(/px/, ''));
|
|
2252
|
+
|
|
2253
|
+
if (height) imgs[i].setAttribute('height', ('' + height).replace(/px/, ''));
|
|
2254
|
+
}
|
|
2255
|
+
});
|
|
2256
|
+
}
|
|
2257
|
+
|
|
2258
|
+
if (editor.opts.iframe) {
|
|
2259
|
+
editor.events.on('image.loaded', editor.size.syncIframe);
|
|
2260
|
+
}
|
|
2261
|
+
|
|
2262
|
+
if (editor.$wp) {
|
|
2263
|
+
_syncImages();
|
|
2264
|
+
editor.events.on('contentChanged', _syncImages);
|
|
2265
|
+
}
|
|
2266
|
+
|
|
2267
|
+
editor.events.$on($(editor.o_win), 'orientationchange.image', function () {
|
|
2268
|
+
setTimeout(function () {
|
|
2269
|
+
if ($current_image) {
|
|
2270
|
+
_editImg($current_image);
|
|
2271
|
+
}
|
|
2272
|
+
}, 100);
|
|
2273
|
+
});
|
|
2274
|
+
|
|
2275
|
+
_initEditPopup(true);
|
|
2276
|
+
_initInsertPopup(true);
|
|
2277
|
+
_initSizePopup(true);
|
|
2278
|
+
_initAltPopup(true);
|
|
2279
|
+
|
|
2280
|
+
editor.events.on('node.remove', function ($node) {
|
|
2281
|
+
if ($node.get(0).tagName == 'IMG') {
|
|
2282
|
+
remove($node);
|
|
2283
|
+
|
|
2284
|
+
return false;
|
|
2285
|
+
}
|
|
2286
|
+
});
|
|
2287
|
+
}
|
|
2288
|
+
|
|
2289
|
+
function _processPastedImage(img) {
|
|
2290
|
+
if (editor.events.trigger('image.beforePasteUpload', [img]) === false) {
|
|
2291
|
+
|
|
2292
|
+
return false;
|
|
2293
|
+
}
|
|
2294
|
+
|
|
2295
|
+
// Show the progress bar.
|
|
2296
|
+
$current_image = $(img);
|
|
2297
|
+
_repositionResizer();
|
|
2298
|
+
_showEditPopup();
|
|
2299
|
+
replace();
|
|
2300
|
+
showProgressBar();
|
|
2301
|
+
|
|
2302
|
+
// Convert image to blob.
|
|
2303
|
+
var binary = atob($(img).attr('src').split(',')[1]);
|
|
2304
|
+
var array = [];
|
|
2305
|
+
|
|
2306
|
+
for (var i = 0; i < binary.length; i++) {
|
|
2307
|
+
array.push(binary.charCodeAt(i));
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2310
|
+
var upload_img = new Blob([new Uint8Array(array)], {
|
|
2311
|
+
type: $(img).attr('src').split(',')[0].replace(/data\:/g, '').replace(/;base64/g, '')
|
|
2312
|
+
});
|
|
2313
|
+
|
|
2314
|
+
upload([upload_img], $current_image);
|
|
2315
|
+
}
|
|
2316
|
+
|
|
2317
|
+
function _uploadPastedImages() {
|
|
2318
|
+
if (!editor.opts.imagePaste) {
|
|
2319
|
+
editor.$el.find('img[data-fr-image-pasted]').remove();
|
|
2320
|
+
}
|
|
2321
|
+
else {
|
|
2322
|
+
|
|
2323
|
+
// Safari won't work https://bugs.webkit.org/show_bug.cgi?id=49141
|
|
2324
|
+
editor.$el.find('img[data-fr-image-pasted]').each(function (index, img) {
|
|
2325
|
+
if (editor.opts.imagePasteProcess) {
|
|
2326
|
+
var width = editor.opts.imageDefaultWidth;
|
|
2327
|
+
|
|
2328
|
+
if (width && width != 'auto') {
|
|
2329
|
+
width = width + (editor.opts.imageResizeWithPercent ? '%' : 'px');
|
|
2330
|
+
}
|
|
2331
|
+
$(img)
|
|
2332
|
+
.css('width', width)
|
|
2333
|
+
.removeClass('fr-dii fr-dib fr-fir fr-fil')
|
|
2334
|
+
|
|
2335
|
+
_setStyle($(img), editor.opts.imageDefaultDisplay, editor.opts.imageDefaultAlign);
|
|
2336
|
+
}
|
|
2337
|
+
|
|
2338
|
+
// Data images.
|
|
2339
|
+
if (img.src.indexOf('data:') === 0) {
|
|
2340
|
+
_processPastedImage(img);
|
|
2341
|
+
}
|
|
2342
|
+
|
|
2343
|
+
// New way Safari is pasting images.
|
|
2344
|
+
else if (img.src.indexOf('blob:') === 0 || (img.src.indexOf('http') === 0 && editor.opts.imageUploadRemoteUrls && editor.opts.imageCORSProxy)) {
|
|
2345
|
+
var _img = new Image();
|
|
2346
|
+
_img.crossOrigin = 'Anonymous';
|
|
2347
|
+
_img.onload = function () {
|
|
2348
|
+
// Create canvas.
|
|
2349
|
+
var canvas = editor.o_doc.createElement('CANVAS');
|
|
2350
|
+
var context = canvas.getContext('2d');
|
|
2351
|
+
|
|
2352
|
+
// Set height.
|
|
2353
|
+
canvas.height = this.naturalHeight;
|
|
2354
|
+
canvas.width = this.naturalWidth;
|
|
2355
|
+
|
|
2356
|
+
// Draw image.
|
|
2357
|
+
context.drawImage(this, 0, 0);
|
|
2358
|
+
|
|
2359
|
+
// Update image and process it.
|
|
2360
|
+
img.src = canvas.toDataURL('image/png');
|
|
2361
|
+
_processPastedImage(img);
|
|
2362
|
+
};
|
|
2363
|
+
|
|
2364
|
+
_img.src = (img.src.indexOf('blob:') === 0 ? '' : (editor.opts.imageCORSProxy + '/')) + img.src;
|
|
2365
|
+
}
|
|
2366
|
+
|
|
2367
|
+
// Images without http (Safari ones.).
|
|
2368
|
+
else if (img.src.indexOf('http') !== 0 || img.src.indexOf('https://mail.google.com/mail') === 0) {
|
|
2369
|
+
editor.selection.save();
|
|
2370
|
+
$(img).remove();
|
|
2371
|
+
editor.selection.restore();
|
|
2372
|
+
}
|
|
2373
|
+
else {
|
|
2374
|
+
$(img).removeAttr('data-fr-image-pasted');
|
|
2375
|
+
}
|
|
2376
|
+
});
|
|
2377
|
+
}
|
|
2378
|
+
}
|
|
2379
|
+
|
|
2380
|
+
function _clipboardImageLoaded(e) {
|
|
2381
|
+
var result = e.target.result;
|
|
2382
|
+
|
|
2383
|
+
// Default width.
|
|
2384
|
+
var width = editor.opts.imageDefaultWidth;
|
|
2385
|
+
|
|
2386
|
+
if (width && width != 'auto') {
|
|
2387
|
+
width = width + (editor.opts.imageResizeWithPercent ? '%' : 'px');
|
|
2388
|
+
}
|
|
2389
|
+
|
|
2390
|
+
editor.undo.saveStep();
|
|
2391
|
+
|
|
2392
|
+
editor.html.insert('<img data-fr-image-pasted="true" src="' + result + '"' + (width ? ' style="width: ' + width + ';"' : '') + '>');
|
|
2393
|
+
|
|
2394
|
+
var $img = editor.$el.find('img[data-fr-image-pasted="true"]');
|
|
2395
|
+
|
|
2396
|
+
if ($img) {
|
|
2397
|
+
_setStyle($img, editor.opts.imageDefaultDisplay, editor.opts.imageDefaultAlign);
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2400
|
+
editor.events.trigger('paste.after');
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2403
|
+
function _processsClipboardPaste(file) {
|
|
2404
|
+
var reader = new FileReader();
|
|
2405
|
+
reader.onload = _clipboardImageLoaded;
|
|
2406
|
+
reader.readAsDataURL(file);
|
|
2407
|
+
}
|
|
2408
|
+
|
|
2409
|
+
function _clipboardPaste(e) {
|
|
2410
|
+
if (e && e.clipboardData && e.clipboardData.items) {
|
|
2411
|
+
|
|
2412
|
+
var file = null;
|
|
2413
|
+
|
|
2414
|
+
if (!e.clipboardData.getData('text/html') && !e.clipboardData.getData('text/rtf')) {
|
|
2415
|
+
for (var i = 0; i < e.clipboardData.items.length; i++) {
|
|
2416
|
+
file = e.clipboardData.items[i].getAsFile();
|
|
2417
|
+
|
|
2418
|
+
if (file) {
|
|
2419
|
+
break;
|
|
2420
|
+
}
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2423
|
+
else {
|
|
2424
|
+
file = e.clipboardData.items[0].getAsFile();
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2427
|
+
if (file) {
|
|
2428
|
+
_processsClipboardPaste(file);
|
|
2429
|
+
|
|
2430
|
+
return false;
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2434
|
+
|
|
2435
|
+
function _clipboardPasteCleanup(clipboard_html) {
|
|
2436
|
+
clipboard_html = clipboard_html.replace(/<img /gi, '<img data-fr-image-pasted="true" ');
|
|
2437
|
+
|
|
2438
|
+
return clipboard_html;
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2441
|
+
/**
|
|
2442
|
+
* Start edit.
|
|
2443
|
+
*/
|
|
2444
|
+
var touchScroll;
|
|
2445
|
+
|
|
2446
|
+
function _edit(e) {
|
|
2447
|
+
if ($(this).parents('[contenteditable]:not(.fr-element):not(.fr-img-caption):not(body):first').attr('contenteditable') == 'false') return true;
|
|
2448
|
+
|
|
2449
|
+
if (e && e.type == 'touchend' && touchScroll) {
|
|
2450
|
+
|
|
2451
|
+
return true;
|
|
2452
|
+
}
|
|
2453
|
+
|
|
2454
|
+
if (e && editor.edit.isDisabled()) {
|
|
2455
|
+
e.stopPropagation();
|
|
2456
|
+
e.preventDefault();
|
|
2457
|
+
|
|
2458
|
+
return false;
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
// Hide resizer for other instances.
|
|
2462
|
+
for (var i = 0; i < $.FE.INSTANCES.length; i++) {
|
|
2463
|
+
if ($.FE.INSTANCES[i] != editor) {
|
|
2464
|
+
$.FE.INSTANCES[i].events.trigger('image.hideResizer');
|
|
2465
|
+
}
|
|
2466
|
+
}
|
|
2467
|
+
|
|
2468
|
+
editor.toolbar.disable();
|
|
2469
|
+
|
|
2470
|
+
if (e) {
|
|
2471
|
+
e.stopPropagation();
|
|
2472
|
+
e.preventDefault();
|
|
2473
|
+
}
|
|
2474
|
+
|
|
2475
|
+
// Hide keyboard.
|
|
2476
|
+
if (editor.helpers.isMobile()) {
|
|
2477
|
+
editor.events.disableBlur();
|
|
2478
|
+
editor.$el.blur();
|
|
2479
|
+
editor.events.enableBlur();
|
|
2480
|
+
}
|
|
2481
|
+
|
|
2482
|
+
if (editor.opts.iframe) {
|
|
2483
|
+
editor.size.syncIframe();
|
|
2484
|
+
}
|
|
2485
|
+
|
|
2486
|
+
// Store current image.
|
|
2487
|
+
$current_image = $(this);
|
|
2488
|
+
|
|
2489
|
+
// Select image.
|
|
2490
|
+
_selectImage();
|
|
2491
|
+
|
|
2492
|
+
// Reposition resizer.
|
|
2493
|
+
_repositionResizer();
|
|
2494
|
+
_showEditPopup();
|
|
2495
|
+
|
|
2496
|
+
// Clear selection.
|
|
2497
|
+
if (!editor.browser.msie) {
|
|
2498
|
+
editor.selection.clear();
|
|
2499
|
+
}
|
|
2500
|
+
|
|
2501
|
+
// Fix for image remaining selected.
|
|
2502
|
+
if (editor.helpers.isIOS()) {
|
|
2503
|
+
editor.events.disableBlur();
|
|
2504
|
+
editor.$el.blur();
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
// Refresh buttons.
|
|
2508
|
+
editor.button.bulkRefresh();
|
|
2509
|
+
editor.events.trigger('video.hideResizer');
|
|
2510
|
+
}
|
|
2511
|
+
|
|
2512
|
+
/**
|
|
2513
|
+
* Exit edit.
|
|
2514
|
+
*/
|
|
2515
|
+
|
|
2516
|
+
function _exitEdit(force_exit) {
|
|
2517
|
+
if ($current_image && (_canExit() || force_exit === true)) {
|
|
2518
|
+
editor.toolbar.enable();
|
|
2519
|
+
$image_resizer.removeClass('fr-active');
|
|
2520
|
+
editor.popups.hide('image.edit');
|
|
2521
|
+
$current_image = null;
|
|
2522
|
+
_unmarkExit();
|
|
2523
|
+
|
|
2524
|
+
$handler = null;
|
|
2525
|
+
|
|
2526
|
+
if ($overlay) {
|
|
2527
|
+
$overlay.hide();
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
}
|
|
2531
|
+
|
|
2532
|
+
var img_exit_flag = false;
|
|
2533
|
+
|
|
2534
|
+
function _markExit() {
|
|
2535
|
+
img_exit_flag = true;
|
|
2536
|
+
}
|
|
2537
|
+
|
|
2538
|
+
function _unmarkExit() {
|
|
2539
|
+
img_exit_flag = false;
|
|
2540
|
+
}
|
|
2541
|
+
|
|
2542
|
+
function _canExit() {
|
|
2543
|
+
|
|
2544
|
+
return img_exit_flag;
|
|
2545
|
+
}
|
|
2546
|
+
|
|
2547
|
+
/**
|
|
2548
|
+
* Set style for image.
|
|
2549
|
+
*/
|
|
2550
|
+
function _setStyle($img, _display, _align) {
|
|
2551
|
+
|
|
2552
|
+
if (!editor.opts.htmlUntouched && editor.opts.useClasses) {
|
|
2553
|
+
$img.removeClass('fr-fil fr-fir fr-dib fr-dii');
|
|
2554
|
+
|
|
2555
|
+
if (_align) {
|
|
2556
|
+
$img.addClass('fr-fi' + _align[0]);
|
|
2557
|
+
}
|
|
2558
|
+
|
|
2559
|
+
if (_display) {
|
|
2560
|
+
$img.addClass('fr-di' + _display[0]);
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
else {
|
|
2564
|
+
if (_display == 'inline') {
|
|
2565
|
+
$img.css({
|
|
2566
|
+
display: 'inline-block',
|
|
2567
|
+
verticalAlign: 'bottom',
|
|
2568
|
+
margin: editor.opts.imageDefaultMargin
|
|
2569
|
+
})
|
|
2570
|
+
|
|
2571
|
+
if (_align == 'center') {
|
|
2572
|
+
$img.css({
|
|
2573
|
+
'float': 'none',
|
|
2574
|
+
marginBottom: '',
|
|
2575
|
+
marginTop: '',
|
|
2576
|
+
maxWidth: 'calc(100% - ' + (2 * editor.opts.imageDefaultMargin) + 'px)',
|
|
2577
|
+
textAlign: 'center'
|
|
2578
|
+
})
|
|
2579
|
+
}
|
|
2580
|
+
else if (_align == 'left') {
|
|
2581
|
+
$img.css({
|
|
2582
|
+
'float': 'left',
|
|
2583
|
+
marginLeft: 0,
|
|
2584
|
+
maxWidth: 'calc(100% - ' + editor.opts.imageDefaultMargin + 'px)',
|
|
2585
|
+
textAlign: 'left'
|
|
2586
|
+
})
|
|
2587
|
+
}
|
|
2588
|
+
else {
|
|
2589
|
+
$img.css({
|
|
2590
|
+
'float': 'right',
|
|
2591
|
+
marginRight: 0,
|
|
2592
|
+
maxWidth: 'calc(100% - ' + editor.opts.imageDefaultMargin + 'px)',
|
|
2593
|
+
textAlign: 'right'
|
|
2594
|
+
})
|
|
2595
|
+
}
|
|
2596
|
+
}
|
|
2597
|
+
else if (_display == 'block') {
|
|
2598
|
+
$img.css({
|
|
2599
|
+
display: 'block',
|
|
2600
|
+
'float': 'none',
|
|
2601
|
+
verticalAlign: 'top',
|
|
2602
|
+
margin: editor.opts.imageDefaultMargin + 'px auto',
|
|
2603
|
+
textAlign: 'center'
|
|
2604
|
+
})
|
|
2605
|
+
|
|
2606
|
+
if (_align == 'left') {
|
|
2607
|
+
$img.css({
|
|
2608
|
+
marginLeft: 0,
|
|
2609
|
+
textAlign: 'left'
|
|
2610
|
+
})
|
|
2611
|
+
}
|
|
2612
|
+
else if (_align == 'right') {
|
|
2613
|
+
$img.css({
|
|
2614
|
+
marginRight: 0,
|
|
2615
|
+
textAlign: 'right'
|
|
2616
|
+
})
|
|
2617
|
+
}
|
|
2618
|
+
}
|
|
2619
|
+
}
|
|
2620
|
+
}
|
|
2621
|
+
|
|
2622
|
+
/**
|
|
2623
|
+
* Align image.
|
|
2624
|
+
*/
|
|
2625
|
+
function align(val) {
|
|
2626
|
+
var $el = getEl();
|
|
2627
|
+
|
|
2628
|
+
$el.removeClass('fr-fir fr-fil');
|
|
2629
|
+
|
|
2630
|
+
// Easy case. Use classes.
|
|
2631
|
+
if (!editor.opts.htmlUntouched && editor.opts.useClasses) {
|
|
2632
|
+
if (val == 'left') {
|
|
2633
|
+
$el.addClass('fr-fil');
|
|
2634
|
+
}
|
|
2635
|
+
else if (val == 'right') {
|
|
2636
|
+
$el.addClass('fr-fir');
|
|
2637
|
+
}
|
|
2638
|
+
}
|
|
2639
|
+
else {
|
|
2640
|
+
_setStyle($el, getDisplay(), val);
|
|
2641
|
+
}
|
|
2642
|
+
|
|
2643
|
+
_selectImage();
|
|
2644
|
+
_repositionResizer();
|
|
2645
|
+
_showEditPopup();
|
|
2646
|
+
editor.selection.clear();
|
|
2647
|
+
}
|
|
2648
|
+
|
|
2649
|
+
/**
|
|
2650
|
+
* Get image alignment.
|
|
2651
|
+
*/
|
|
2652
|
+
function getAlign($img) {
|
|
2653
|
+
if (typeof $img == 'undefined') $img = getEl();
|
|
2654
|
+
|
|
2655
|
+
if ($img) {
|
|
2656
|
+
|
|
2657
|
+
// Image has left class.
|
|
2658
|
+
if ($img.hasClass('fr-fil')) {
|
|
2659
|
+
|
|
2660
|
+
return 'left';
|
|
2661
|
+
}
|
|
2662
|
+
|
|
2663
|
+
// Image has right class.
|
|
2664
|
+
else if ($img.hasClass('fr-fir')) {
|
|
2665
|
+
|
|
2666
|
+
return 'right';
|
|
2667
|
+
}
|
|
2668
|
+
|
|
2669
|
+
// Image has display class set.
|
|
2670
|
+
else if ($img.hasClass('fr-dib') || $img.hasClass('fr-dii')) {
|
|
2671
|
+
|
|
2672
|
+
return 'center';
|
|
2673
|
+
}
|
|
2674
|
+
else {
|
|
2675
|
+
// Set float to none.
|
|
2676
|
+
var flt = $img.css('float');
|
|
2677
|
+
|
|
2678
|
+
$img.css('float', 'none');
|
|
2679
|
+
|
|
2680
|
+
// Image has display block.
|
|
2681
|
+
if ($img.css('display') == 'block') {
|
|
2682
|
+
|
|
2683
|
+
// Set float to the initial value.
|
|
2684
|
+
$img.css('float', '');
|
|
2685
|
+
|
|
2686
|
+
if ($img.css('float') != flt) $img.css('float', flt);
|
|
2687
|
+
|
|
2688
|
+
// Margin left is 0.
|
|
2689
|
+
// Margin right is auto.
|
|
2690
|
+
if (parseInt($img.css('margin-left'), 10) === 0) {
|
|
2691
|
+
|
|
2692
|
+
return 'left';
|
|
2693
|
+
}
|
|
2694
|
+
|
|
2695
|
+
// Margin left is auto.
|
|
2696
|
+
// Margin right is 0.
|
|
2697
|
+
else if (parseInt($img.css('margin-right'), 10) === 0) {
|
|
2698
|
+
|
|
2699
|
+
return 'right';
|
|
2700
|
+
}
|
|
2701
|
+
}
|
|
2702
|
+
|
|
2703
|
+
// Display inline.
|
|
2704
|
+
else {
|
|
2705
|
+
|
|
2706
|
+
// Set float.
|
|
2707
|
+
$img.css('float', '');
|
|
2708
|
+
|
|
2709
|
+
if ($img.css('float') != flt) $img.css('float', flt);
|
|
2710
|
+
|
|
2711
|
+
// Float left.
|
|
2712
|
+
if ($img.css('float') == 'left') {
|
|
2713
|
+
|
|
2714
|
+
return 'left';
|
|
2715
|
+
}
|
|
2716
|
+
|
|
2717
|
+
// Float right.
|
|
2718
|
+
else if ($img.css('float') == 'right') {
|
|
2719
|
+
|
|
2720
|
+
return 'right';
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
}
|
|
2725
|
+
|
|
2726
|
+
return 'center';
|
|
2727
|
+
}
|
|
2728
|
+
|
|
2729
|
+
/**
|
|
2730
|
+
* Get image display.
|
|
2731
|
+
*/
|
|
2732
|
+
function getDisplay($img) {
|
|
2733
|
+
if (typeof $img == 'undefined') $img = getEl();
|
|
2734
|
+
|
|
2735
|
+
// Set float to none.
|
|
2736
|
+
var flt = $img.css('float');
|
|
2737
|
+
$img.css('float', 'none');
|
|
2738
|
+
|
|
2739
|
+
// Image has display block.
|
|
2740
|
+
if ($img.css('display') == 'block') {
|
|
2741
|
+
|
|
2742
|
+
// Set float to the initial value.
|
|
2743
|
+
$img.css('float', '');
|
|
2744
|
+
|
|
2745
|
+
if ($img.css('float') != flt) $img.css('float', flt);
|
|
2746
|
+
|
|
2747
|
+
return 'block';
|
|
2748
|
+
}
|
|
2749
|
+
|
|
2750
|
+
// Display inline.
|
|
2751
|
+
else {
|
|
2752
|
+
|
|
2753
|
+
// Set float.
|
|
2754
|
+
$img.css('float', '');
|
|
2755
|
+
|
|
2756
|
+
if ($img.css('float') != flt) $img.css('float', flt);
|
|
2757
|
+
|
|
2758
|
+
return 'inline';
|
|
2759
|
+
}
|
|
2760
|
+
|
|
2761
|
+
return 'inline';
|
|
2762
|
+
}
|
|
2763
|
+
|
|
2764
|
+
/**
|
|
2765
|
+
* Refresh the align icon.
|
|
2766
|
+
*/
|
|
2767
|
+
function refreshAlign($btn) {
|
|
2768
|
+
if ($current_image) {
|
|
2769
|
+
$btn.find('> *:first').replaceWith(editor.icon.create('image-align-' + getAlign()));
|
|
2770
|
+
}
|
|
2771
|
+
}
|
|
2772
|
+
|
|
2773
|
+
/**
|
|
2774
|
+
* Refresh the align option from the dropdown.
|
|
2775
|
+
*/
|
|
2776
|
+
|
|
2777
|
+
function refreshAlignOnShow($btn, $dropdown) {
|
|
2778
|
+
if ($current_image) {
|
|
2779
|
+
$dropdown.find('.fr-command[data-param1="' + getAlign() + '"]').addClass('fr-active').attr('aria-selected', true);
|
|
2780
|
+
}
|
|
2781
|
+
}
|
|
2782
|
+
|
|
2783
|
+
/**
|
|
2784
|
+
* Align image.
|
|
2785
|
+
*/
|
|
2786
|
+
|
|
2787
|
+
function display(val) {
|
|
2788
|
+
var $el = getEl();
|
|
2789
|
+
|
|
2790
|
+
$el.removeClass('fr-dii fr-dib');
|
|
2791
|
+
|
|
2792
|
+
// Easy case. Use classes.
|
|
2793
|
+
if (!editor.opts.htmlUntouched && editor.opts.useClasses) {
|
|
2794
|
+
if (val == 'inline') {
|
|
2795
|
+
$el.addClass('fr-dii');
|
|
2796
|
+
}
|
|
2797
|
+
else if (val == 'block') {
|
|
2798
|
+
$el.addClass('fr-dib');
|
|
2799
|
+
}
|
|
2800
|
+
}
|
|
2801
|
+
else {
|
|
2802
|
+
_setStyle($el, val, getAlign());
|
|
2803
|
+
}
|
|
2804
|
+
|
|
2805
|
+
_selectImage();
|
|
2806
|
+
_repositionResizer();
|
|
2807
|
+
_showEditPopup();
|
|
2808
|
+
editor.selection.clear();
|
|
2809
|
+
}
|
|
2810
|
+
|
|
2811
|
+
/**
|
|
2812
|
+
* Refresh the image display selected option.
|
|
2813
|
+
*/
|
|
2814
|
+
|
|
2815
|
+
function refreshDisplayOnShow($btn, $dropdown) {
|
|
2816
|
+
if ($current_image) {
|
|
2817
|
+
$dropdown.find('.fr-command[data-param1="' + getDisplay() + '"]').addClass('fr-active').attr('aria-selected', true);
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2821
|
+
/**
|
|
2822
|
+
* Show the replace popup.
|
|
2823
|
+
*/
|
|
2824
|
+
|
|
2825
|
+
function replace() {
|
|
2826
|
+
var $popup = editor.popups.get('image.insert');
|
|
2827
|
+
|
|
2828
|
+
if (!$popup) $popup = _initInsertPopup();
|
|
2829
|
+
|
|
2830
|
+
if (!editor.popups.isVisible('image.insert')) {
|
|
2831
|
+
hideProgressBar();
|
|
2832
|
+
editor.popups.refresh('image.insert');
|
|
2833
|
+
editor.popups.setContainer('image.insert', editor.$sc);
|
|
2834
|
+
}
|
|
2835
|
+
|
|
2836
|
+
var $el = getEl();
|
|
2837
|
+
|
|
2838
|
+
if (hasCaption()) {
|
|
2839
|
+
$el = $el.find('.fr-img-wrap');
|
|
2840
|
+
}
|
|
2841
|
+
|
|
2842
|
+
var left = $el.offset().left + $el.outerWidth() / 2;
|
|
2843
|
+
var top = $el.offset().top + $el.outerHeight();
|
|
2844
|
+
|
|
2845
|
+
editor.popups.show('image.insert', left, top, $el.outerHeight(true));
|
|
2846
|
+
}
|
|
2847
|
+
|
|
2848
|
+
/**
|
|
2849
|
+
* Place selection around current image.
|
|
2850
|
+
*/
|
|
2851
|
+
function _selectImage() {
|
|
2852
|
+
if ($current_image) {
|
|
2853
|
+
editor.events.disableBlur();
|
|
2854
|
+
editor.selection.clear();
|
|
2855
|
+
var range = editor.doc.createRange();
|
|
2856
|
+
range.selectNode($current_image.get(0));
|
|
2857
|
+
|
|
2858
|
+
// Collapse range in IE.
|
|
2859
|
+
if (editor.browser.msie) range.collapse(true);
|
|
2860
|
+
|
|
2861
|
+
var selection = editor.selection.get();
|
|
2862
|
+
selection.addRange(range);
|
|
2863
|
+
editor.events.enableBlur();
|
|
2864
|
+
}
|
|
2865
|
+
}
|
|
2866
|
+
|
|
2867
|
+
/**
|
|
2868
|
+
* Get back to the image main popup.
|
|
2869
|
+
*/
|
|
2870
|
+
function back() {
|
|
2871
|
+
if ($current_image) {
|
|
2872
|
+
editor.events.disableBlur();
|
|
2873
|
+
$('.fr-popup input:focus').blur();
|
|
2874
|
+
_editImg($current_image);
|
|
2875
|
+
}
|
|
2876
|
+
else {
|
|
2877
|
+
editor.events.disableBlur();
|
|
2878
|
+
editor.selection.restore();
|
|
2879
|
+
editor.events.enableBlur();
|
|
2880
|
+
|
|
2881
|
+
editor.popups.hide('image.insert');
|
|
2882
|
+
editor.toolbar.showInline();
|
|
2883
|
+
}
|
|
2884
|
+
}
|
|
2885
|
+
|
|
2886
|
+
/**
|
|
2887
|
+
* Get the current image.
|
|
2888
|
+
*/
|
|
2889
|
+
|
|
2890
|
+
function get() {
|
|
2891
|
+
|
|
2892
|
+
return $current_image;
|
|
2893
|
+
}
|
|
2894
|
+
|
|
2895
|
+
function getEl() {
|
|
2896
|
+
return hasCaption() ? $current_image.parents('.fr-img-caption:first') : $current_image;
|
|
2897
|
+
}
|
|
2898
|
+
|
|
2899
|
+
/**
|
|
2900
|
+
* Apply specific style.
|
|
2901
|
+
*/
|
|
2902
|
+
|
|
2903
|
+
function applyStyle(val, imageStyles, multipleStyles) {
|
|
2904
|
+
if (typeof imageStyles == 'undefined') imageStyles = editor.opts.imageStyles;
|
|
2905
|
+
|
|
2906
|
+
if (typeof multipleStyles == 'undefined') multipleStyles = editor.opts.imageMultipleStyles;
|
|
2907
|
+
|
|
2908
|
+
if (!$current_image) return false;
|
|
2909
|
+
|
|
2910
|
+
var $img = getEl();
|
|
2911
|
+
|
|
2912
|
+
// Remove multiple styles.
|
|
2913
|
+
if (!multipleStyles) {
|
|
2914
|
+
var styles = Object.keys(imageStyles);
|
|
2915
|
+
styles.splice(styles.indexOf(val), 1);
|
|
2916
|
+
$img.removeClass(styles.join(' '));
|
|
2917
|
+
}
|
|
2918
|
+
|
|
2919
|
+
if (typeof imageStyles[val] == 'object') {
|
|
2920
|
+
$img.removeAttr('style');
|
|
2921
|
+
$img.css(imageStyles[val].style);
|
|
2922
|
+
}
|
|
2923
|
+
else {
|
|
2924
|
+
$img.toggleClass(val);
|
|
2925
|
+
}
|
|
2926
|
+
|
|
2927
|
+
_editImg($current_image);
|
|
2928
|
+
}
|
|
2929
|
+
|
|
2930
|
+
function hasCaption() {
|
|
2931
|
+
if ($current_image) {
|
|
2932
|
+
return $current_image.parents('.fr-img-caption').length > 0;
|
|
2933
|
+
}
|
|
2934
|
+
|
|
2935
|
+
return false;
|
|
2936
|
+
}
|
|
2937
|
+
|
|
2938
|
+
function toggleCaption() {
|
|
2939
|
+
var $el;
|
|
2940
|
+
|
|
2941
|
+
if ($current_image && !hasCaption()) {
|
|
2942
|
+
$el = $current_image;
|
|
2943
|
+
|
|
2944
|
+
// Check if there is a link wrapping the image.
|
|
2945
|
+
if ($current_image.parent().is('a')) {
|
|
2946
|
+
$el = $current_image.parent();
|
|
2947
|
+
}
|
|
2948
|
+
|
|
2949
|
+
$el.wrap('<span ' + (!editor.browser.mozilla ? 'contenteditable="false"' : '') + 'class="fr-img-caption ' + $current_image.attr('class') + '" style="' + ($current_image.attr('style') ? $current_image.attr('style') + ' ' : '') + 'width: ' + $current_image.width() + 'px;" draggable="false"></span>');
|
|
2950
|
+
$el.wrap('<span class="fr-img-wrap"></span>');
|
|
2951
|
+
$el.after('<span class="fr-inner" contenteditable="true">' + $.FE.START_MARKER + 'Image caption' + $.FE.END_MARKER + '</span>');
|
|
2952
|
+
$current_image.removeAttr('class').removeAttr('style').removeAttr('width');
|
|
2953
|
+
|
|
2954
|
+
_exitEdit(true);
|
|
2955
|
+
|
|
2956
|
+
editor.selection.restore();
|
|
2957
|
+
}
|
|
2958
|
+
else {
|
|
2959
|
+
$el = getEl();
|
|
2960
|
+
$current_image.insertAfter($el);
|
|
2961
|
+
$current_image
|
|
2962
|
+
.attr('class', $el.attr('class').replace('fr-img-caption', ''))
|
|
2963
|
+
.attr('style', $el.attr('style'));
|
|
2964
|
+
$el.remove();
|
|
2965
|
+
|
|
2966
|
+
_editImg($current_image);
|
|
2967
|
+
}
|
|
2968
|
+
}
|
|
2969
|
+
|
|
2970
|
+
return {
|
|
2971
|
+
_init: _init,
|
|
2972
|
+
showInsertPopup: showInsertPopup,
|
|
2973
|
+
showLayer: showLayer,
|
|
2974
|
+
refreshUploadButton: refreshUploadButton,
|
|
2975
|
+
refreshByURLButton: refreshByURLButton,
|
|
2976
|
+
upload: upload,
|
|
2977
|
+
insertByURL: insertByURL,
|
|
2978
|
+
align: align,
|
|
2979
|
+
refreshAlign: refreshAlign,
|
|
2980
|
+
refreshAlignOnShow: refreshAlignOnShow,
|
|
2981
|
+
display: display,
|
|
2982
|
+
refreshDisplayOnShow: refreshDisplayOnShow,
|
|
2983
|
+
replace: replace,
|
|
2984
|
+
back: back,
|
|
2985
|
+
get: get,
|
|
2986
|
+
getEl: getEl,
|
|
2987
|
+
insert: insert,
|
|
2988
|
+
showProgressBar: showProgressBar,
|
|
2989
|
+
remove: remove,
|
|
2990
|
+
hideProgressBar: hideProgressBar,
|
|
2991
|
+
applyStyle: applyStyle,
|
|
2992
|
+
showAltPopup: showAltPopup,
|
|
2993
|
+
showSizePopup: showSizePopup,
|
|
2994
|
+
setAlt: setAlt,
|
|
2995
|
+
setSize: setSize,
|
|
2996
|
+
toggleCaption: toggleCaption,
|
|
2997
|
+
hasCaption: hasCaption,
|
|
2998
|
+
exitEdit: _exitEdit,
|
|
2999
|
+
edit: _editImg
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
|
|
3003
|
+
// Insert image button.
|
|
3004
|
+
$.FE.DefineIcon('insertImage', {
|
|
3005
|
+
NAME: 'image'
|
|
3006
|
+
});
|
|
3007
|
+
$.FE.RegisterShortcut($.FE.KEYCODE.P, 'insertImage', null, 'P');
|
|
3008
|
+
$.FE.RegisterCommand('insertImage', {
|
|
3009
|
+
title: 'Insert Image',
|
|
3010
|
+
undo: false,
|
|
3011
|
+
focus: true,
|
|
3012
|
+
refreshAfterCallback: false,
|
|
3013
|
+
popup: true,
|
|
3014
|
+
callback: function () {
|
|
3015
|
+
if (!this.popups.isVisible('image.insert')) {
|
|
3016
|
+
this.image.showInsertPopup();
|
|
3017
|
+
}
|
|
3018
|
+
else {
|
|
3019
|
+
if (this.$el.find('.fr-marker').length) {
|
|
3020
|
+
this.events.disableBlur();
|
|
3021
|
+
this.selection.restore();
|
|
3022
|
+
}
|
|
3023
|
+
this.popups.hide('image.insert');
|
|
3024
|
+
}
|
|
3025
|
+
},
|
|
3026
|
+
plugin: 'image'
|
|
3027
|
+
});
|
|
3028
|
+
|
|
3029
|
+
// Image upload button inside the insert image popup.
|
|
3030
|
+
$.FE.DefineIcon('imageUpload', {
|
|
3031
|
+
NAME: 'upload'
|
|
3032
|
+
});
|
|
3033
|
+
$.FE.RegisterCommand('imageUpload', {
|
|
3034
|
+
title: 'Upload Image',
|
|
3035
|
+
undo: false,
|
|
3036
|
+
focus: false,
|
|
3037
|
+
toggle: true,
|
|
3038
|
+
callback: function () {
|
|
3039
|
+
this.image.showLayer('image-upload');
|
|
3040
|
+
},
|
|
3041
|
+
refresh: function ($btn) {
|
|
3042
|
+
this.image.refreshUploadButton($btn);
|
|
3043
|
+
}
|
|
3044
|
+
});
|
|
3045
|
+
|
|
3046
|
+
// Image by URL button inside the insert image popup.
|
|
3047
|
+
$.FE.DefineIcon('imageByURL', {
|
|
3048
|
+
NAME: 'link'
|
|
3049
|
+
});
|
|
3050
|
+
$.FE.RegisterCommand('imageByURL', {
|
|
3051
|
+
title: 'By URL',
|
|
3052
|
+
undo: false,
|
|
3053
|
+
focus: false,
|
|
3054
|
+
toggle: true,
|
|
3055
|
+
callback: function () {
|
|
3056
|
+
this.image.showLayer('image-by-url');
|
|
3057
|
+
},
|
|
3058
|
+
refresh: function ($btn) {
|
|
3059
|
+
this.image.refreshByURLButton($btn);
|
|
3060
|
+
}
|
|
3061
|
+
})
|
|
3062
|
+
|
|
3063
|
+
// Insert image button inside the insert by URL layer.
|
|
3064
|
+
$.FE.RegisterCommand('imageInsertByURL', {
|
|
3065
|
+
title: 'Insert Image',
|
|
3066
|
+
undo: true,
|
|
3067
|
+
refreshAfterCallback: false,
|
|
3068
|
+
callback: function () {
|
|
3069
|
+
this.image.insertByURL();
|
|
3070
|
+
},
|
|
3071
|
+
refresh: function ($btn) {
|
|
3072
|
+
var $current_image = this.image.get();
|
|
3073
|
+
|
|
3074
|
+
if (!$current_image) {
|
|
3075
|
+
$btn.text(this.language.translate('Insert'));
|
|
3076
|
+
}
|
|
3077
|
+
else {
|
|
3078
|
+
$btn.text(this.language.translate('Replace'));
|
|
3079
|
+
}
|
|
3080
|
+
}
|
|
3081
|
+
})
|
|
3082
|
+
|
|
3083
|
+
// Image display.
|
|
3084
|
+
$.FE.DefineIcon('imageDisplay', {
|
|
3085
|
+
NAME: 'star'
|
|
3086
|
+
})
|
|
3087
|
+
$.FE.RegisterCommand('imageDisplay', {
|
|
3088
|
+
title: 'Display',
|
|
3089
|
+
type: 'dropdown',
|
|
3090
|
+
options: {
|
|
3091
|
+
inline: 'Inline',
|
|
3092
|
+
block: 'Break Text'
|
|
3093
|
+
},
|
|
3094
|
+
callback: function (cmd, val) {
|
|
3095
|
+
this.image.display(val);
|
|
3096
|
+
},
|
|
3097
|
+
refresh: function ($btn) {
|
|
3098
|
+
if (!this.opts.imageTextNear) $btn.addClass('fr-hidden');
|
|
3099
|
+
},
|
|
3100
|
+
refreshOnShow: function ($btn, $dropdown) {
|
|
3101
|
+
this.image.refreshDisplayOnShow($btn, $dropdown);
|
|
3102
|
+
}
|
|
3103
|
+
})
|
|
3104
|
+
|
|
3105
|
+
// Image align.
|
|
3106
|
+
$.FE.DefineIcon('image-align', {
|
|
3107
|
+
NAME: 'align-left'
|
|
3108
|
+
});
|
|
3109
|
+
$.FE.DefineIcon('image-align-left', {
|
|
3110
|
+
NAME: 'align-left'
|
|
3111
|
+
});
|
|
3112
|
+
$.FE.DefineIcon('image-align-right', {
|
|
3113
|
+
NAME: 'align-right'
|
|
3114
|
+
});
|
|
3115
|
+
$.FE.DefineIcon('image-align-center', {
|
|
3116
|
+
NAME: 'align-justify'
|
|
3117
|
+
});
|
|
3118
|
+
|
|
3119
|
+
$.FE.DefineIcon('imageAlign', {
|
|
3120
|
+
NAME: 'align-justify'
|
|
3121
|
+
})
|
|
3122
|
+
$.FE.RegisterCommand('imageAlign', {
|
|
3123
|
+
type: 'dropdown',
|
|
3124
|
+
title: 'Align',
|
|
3125
|
+
options: {
|
|
3126
|
+
left: 'Align Left',
|
|
3127
|
+
center: 'None',
|
|
3128
|
+
right: 'Align Right'
|
|
3129
|
+
},
|
|
3130
|
+
html: function () {
|
|
3131
|
+
var c = '<ul class="fr-dropdown-list" role="presentation">';
|
|
3132
|
+
var options = $.FE.COMMANDS.imageAlign.options;
|
|
3133
|
+
|
|
3134
|
+
for (var val in options) {
|
|
3135
|
+
if (options.hasOwnProperty(val)) {
|
|
3136
|
+
c += '<li role="presentation"><a class="fr-command fr-title" tabIndex="-1" role="option" data-cmd="imageAlign" data-param1="' + val + '" title="' + this.language.translate(options[val]) + '">' + this.icon.create('image-align-' + val) + '<span class="fr-sr-only">' + this.language.translate(options[val]) + '</span></a></li>';
|
|
3137
|
+
}
|
|
3138
|
+
}
|
|
3139
|
+
c += '</ul>';
|
|
3140
|
+
|
|
3141
|
+
return c;
|
|
3142
|
+
},
|
|
3143
|
+
callback: function (cmd, val) {
|
|
3144
|
+
this.image.align(val);
|
|
3145
|
+
},
|
|
3146
|
+
refresh: function ($btn) {
|
|
3147
|
+
this.image.refreshAlign($btn);
|
|
3148
|
+
},
|
|
3149
|
+
refreshOnShow: function ($btn, $dropdown) {
|
|
3150
|
+
this.image.refreshAlignOnShow($btn, $dropdown);
|
|
3151
|
+
}
|
|
3152
|
+
})
|
|
3153
|
+
|
|
3154
|
+
// Image replace.
|
|
3155
|
+
$.FE.DefineIcon('imageReplace', {
|
|
3156
|
+
NAME: 'exchange',
|
|
3157
|
+
FA5NAME: 'exchange-alt'
|
|
3158
|
+
})
|
|
3159
|
+
$.FE.RegisterCommand('imageReplace', {
|
|
3160
|
+
title: 'Replace',
|
|
3161
|
+
undo: false,
|
|
3162
|
+
focus: false,
|
|
3163
|
+
popup: true,
|
|
3164
|
+
refreshAfterCallback: false,
|
|
3165
|
+
callback: function () {
|
|
3166
|
+
this.image.replace();
|
|
3167
|
+
}
|
|
3168
|
+
})
|
|
3169
|
+
|
|
3170
|
+
// Image remove.
|
|
3171
|
+
$.FE.DefineIcon('imageRemove', {
|
|
3172
|
+
NAME: 'trash'
|
|
3173
|
+
})
|
|
3174
|
+
$.FE.RegisterCommand('imageRemove', {
|
|
3175
|
+
title: 'Remove',
|
|
3176
|
+
callback: function () {
|
|
3177
|
+
this.image.remove();
|
|
3178
|
+
}
|
|
3179
|
+
})
|
|
3180
|
+
|
|
3181
|
+
// Image back.
|
|
3182
|
+
$.FE.DefineIcon('imageBack', {
|
|
3183
|
+
NAME: 'arrow-left'
|
|
3184
|
+
});
|
|
3185
|
+
$.FE.RegisterCommand('imageBack', {
|
|
3186
|
+
title: 'Back',
|
|
3187
|
+
undo: false,
|
|
3188
|
+
focus: false,
|
|
3189
|
+
back: true,
|
|
3190
|
+
callback: function () {
|
|
3191
|
+
this.image.back();
|
|
3192
|
+
},
|
|
3193
|
+
refresh: function ($btn) {
|
|
3194
|
+
var $current_image = this.image.get();
|
|
3195
|
+
|
|
3196
|
+
if (!$current_image && !this.opts.toolbarInline) {
|
|
3197
|
+
$btn.addClass('fr-hidden');
|
|
3198
|
+
$btn.next('.fr-separator').addClass('fr-hidden');
|
|
3199
|
+
}
|
|
3200
|
+
else {
|
|
3201
|
+
$btn.removeClass('fr-hidden');
|
|
3202
|
+
$btn.next('.fr-separator').removeClass('fr-hidden');
|
|
3203
|
+
}
|
|
3204
|
+
}
|
|
3205
|
+
});
|
|
3206
|
+
|
|
3207
|
+
$.FE.RegisterCommand('imageDismissError', {
|
|
3208
|
+
title: 'OK',
|
|
3209
|
+
undo: false,
|
|
3210
|
+
callback: function () {
|
|
3211
|
+
this.image.hideProgressBar(true);
|
|
3212
|
+
}
|
|
3213
|
+
})
|
|
3214
|
+
|
|
3215
|
+
// Image styles.
|
|
3216
|
+
$.FE.DefineIcon('imageStyle', {
|
|
3217
|
+
NAME: 'magic'
|
|
3218
|
+
})
|
|
3219
|
+
$.FE.RegisterCommand('imageStyle', {
|
|
3220
|
+
title: 'Style',
|
|
3221
|
+
type: 'dropdown',
|
|
3222
|
+
html: function () {
|
|
3223
|
+
var c = '<ul class="fr-dropdown-list" role="presentation">';
|
|
3224
|
+
var options = this.opts.imageStyles;
|
|
3225
|
+
|
|
3226
|
+
for (var cls in options) {
|
|
3227
|
+
if (options.hasOwnProperty(cls)) {
|
|
3228
|
+
var val = options[cls];
|
|
3229
|
+
|
|
3230
|
+
if (typeof val == 'object') val = val.title;
|
|
3231
|
+
|
|
3232
|
+
c += '<li role="presentation"><a class="fr-command" tabIndex="-1" role="option" data-cmd="imageStyle" data-param1="' + cls + '">' + this.language.translate(val) + '</a></li>';
|
|
3233
|
+
}
|
|
3234
|
+
}
|
|
3235
|
+
c += '</ul>';
|
|
3236
|
+
|
|
3237
|
+
return c;
|
|
3238
|
+
},
|
|
3239
|
+
callback: function (cmd, val) {
|
|
3240
|
+
this.image.applyStyle(val);
|
|
3241
|
+
},
|
|
3242
|
+
refreshOnShow: function ($btn, $dropdown) {
|
|
3243
|
+
var $current_image = this.image.getEl();
|
|
3244
|
+
|
|
3245
|
+
if ($current_image) {
|
|
3246
|
+
$dropdown.find('.fr-command').each(function () {
|
|
3247
|
+
var cls = $(this).data('param1');
|
|
3248
|
+
var active = $current_image.hasClass(cls);
|
|
3249
|
+
$(this).toggleClass('fr-active', active).attr('aria-selected', active);
|
|
3250
|
+
})
|
|
3251
|
+
}
|
|
3252
|
+
}
|
|
3253
|
+
})
|
|
3254
|
+
|
|
3255
|
+
// Image alt.
|
|
3256
|
+
$.FE.DefineIcon('imageAlt', {
|
|
3257
|
+
NAME: 'info'
|
|
3258
|
+
})
|
|
3259
|
+
$.FE.RegisterCommand('imageAlt', {
|
|
3260
|
+
undo: false,
|
|
3261
|
+
focus: false,
|
|
3262
|
+
popup: true,
|
|
3263
|
+
title: 'Alternate Text',
|
|
3264
|
+
callback: function () {
|
|
3265
|
+
this.image.showAltPopup();
|
|
3266
|
+
}
|
|
3267
|
+
});
|
|
3268
|
+
|
|
3269
|
+
$.FE.RegisterCommand('imageSetAlt', {
|
|
3270
|
+
undo: true,
|
|
3271
|
+
focus: false,
|
|
3272
|
+
title: 'Update',
|
|
3273
|
+
refreshAfterCallback: false,
|
|
3274
|
+
callback: function () {
|
|
3275
|
+
this.image.setAlt();
|
|
3276
|
+
}
|
|
3277
|
+
});
|
|
3278
|
+
|
|
3279
|
+
// Image size.
|
|
3280
|
+
$.FE.DefineIcon('imageSize', {
|
|
3281
|
+
NAME: 'arrows-alt'
|
|
3282
|
+
})
|
|
3283
|
+
$.FE.RegisterCommand('imageSize', {
|
|
3284
|
+
undo: false,
|
|
3285
|
+
focus: false,
|
|
3286
|
+
popup: true,
|
|
3287
|
+
title: 'Change Size',
|
|
3288
|
+
callback: function () {
|
|
3289
|
+
this.image.showSizePopup();
|
|
3290
|
+
}
|
|
3291
|
+
});
|
|
3292
|
+
|
|
3293
|
+
$.FE.RegisterCommand('imageSetSize', {
|
|
3294
|
+
undo: true,
|
|
3295
|
+
focus: false,
|
|
3296
|
+
title: 'Update',
|
|
3297
|
+
refreshAfterCallback: false,
|
|
3298
|
+
callback: function () {
|
|
3299
|
+
this.image.setSize();
|
|
3300
|
+
}
|
|
3301
|
+
});
|
|
3302
|
+
|
|
3303
|
+
$.FE.DefineIcon('imageCaption', {
|
|
3304
|
+
NAME: 'commenting',
|
|
3305
|
+
FA5NAME: 'comment-alt'
|
|
3306
|
+
})
|
|
3307
|
+
|
|
3308
|
+
$.FE.RegisterCommand('imageCaption', {
|
|
3309
|
+
undo: true,
|
|
3310
|
+
focus: false,
|
|
3311
|
+
title: 'Image Caption',
|
|
3312
|
+
refreshAfterCallback: true,
|
|
3313
|
+
callback: function () {
|
|
3314
|
+
this.image.toggleCaption();
|
|
3315
|
+
},
|
|
3316
|
+
refresh: function ($btn) {
|
|
3317
|
+
if (this.image.get()) {
|
|
3318
|
+
$btn.toggleClass('fr-active', this.image.hasCaption());
|
|
3319
|
+
}
|
|
3320
|
+
}
|
|
3321
|
+
})
|
|
3322
|
+
|
|
3323
|
+
}));
|