summaryrefslogtreecommitdiff
path: root/addons/web_editor/static/lib/summernote/src/js/EventHandler.js
diff options
context:
space:
mode:
authorChristophe Matthieu <chm@odoo.com>2015-03-04 14:32:33 +0100
committerChristophe Matthieu <chm@odoo.com>2015-07-10 17:00:13 +0200
commitcebc73ebf9aa2bd6d8026473344af16726effec1 (patch)
tree55a8de23a6cf7f551aeabf58195e7ba8e1c76686 /addons/web_editor/static/lib/summernote/src/js/EventHandler.js
parentc1f39d0ca74486de714ea85f56b6924a9a520757 (diff)
[IMP] web_editor: move summernote & nearest lib from website
Diffstat (limited to 'addons/web_editor/static/lib/summernote/src/js/EventHandler.js')
-rw-r--r--addons/web_editor/static/lib/summernote/src/js/EventHandler.js771
1 files changed, 771 insertions, 0 deletions
diff --git a/addons/web_editor/static/lib/summernote/src/js/EventHandler.js b/addons/web_editor/static/lib/summernote/src/js/EventHandler.js
new file mode 100644
index 00000000000..9d5174c6fe6
--- /dev/null
+++ b/addons/web_editor/static/lib/summernote/src/js/EventHandler.js
@@ -0,0 +1,771 @@
+define([
+ 'summernote/core/agent', 'summernote/core/dom', 'summernote/core/async', 'summernote/core/key', 'summernote/core/list', 'summernote/core/range',
+ 'summernote/editing/Style', 'summernote/editing/Editor', 'summernote/editing/History',
+ 'summernote/module/Toolbar', 'summernote/module/Popover', 'summernote/module/Handle', 'summernote/module/Dialog'
+], function (agent, dom, async, key, list, range,
+ Style, Editor, History,
+ Toolbar, Popover, Handle, Dialog) {
+
+ var CodeMirror;
+ if (agent.hasCodeMirror) {
+ if (agent.isSupportAmd) {
+ require(['CodeMirror'], function (cm) {
+ CodeMirror = cm;
+ });
+ } else {
+ CodeMirror = window.CodeMirror;
+ }
+ }
+
+ /**
+ * EventHandler
+ */
+ var EventHandler = function () {
+ var $window = $(window);
+ var $document = $(document);
+ var $scrollbar = $('html, body');
+
+ var editor = new Editor();
+ var toolbar = new Toolbar(), popover = new Popover();
+ var handle = new Handle(), dialog = new Dialog();
+
+ this.getEditor = function () {
+ return editor;
+ };
+
+ /**
+ * returns makeLayoutInfo from editor's descendant node.
+ *
+ * @param {Node} descendant
+ * @returns {Object}
+ */
+ var makeLayoutInfo = function (descendant) {
+ var $target = $(descendant).closest('.note-editor, .note-air-editor, .note-air-layout');
+
+ if (!$target.length) { return null; }
+
+ var $editor;
+ if ($target.is('.note-editor, .note-air-editor')) {
+ $editor = $target;
+ } else {
+ $editor = $('[data-note-id="' + list.last($target.attr('id')) + '"]');
+ }
+
+ return dom.buildLayoutInfo($editor);
+ };
+
+ /**
+ * insert Images from file array.
+ *
+ * @param {Object} layoutInfo
+ * @param {File[]} files
+ */
+ var insertImages = function (layoutInfo, files) {
+ var $editor = layoutInfo.editor(),
+ $editable = layoutInfo.editable();
+
+ var callbacks = $editable.data('callbacks');
+ var options = $editor.data('options');
+
+ // If onImageUpload options setted
+ if (callbacks.onImageUpload) {
+ callbacks.onImageUpload(files, editor, $editable);
+ // else insert Image as dataURL
+ } else {
+ $.each(files, function (idx, file) {
+ var filename = file.name;
+ if (options.maximumImageFileSize && options.maximumImageFileSize < file.size) {
+ if (callbacks.onImageUploadError) {
+ callbacks.onImageUploadError(options.langInfo.image.maximumFileSizeError);
+ } else {
+ alert(options.langInfo.image.maximumFileSizeError);
+ }
+ } else {
+ async.readFileAsDataURL(file).then(function (sDataURL) {
+ editor.insertImage($editable, sDataURL, filename);
+ }).fail(function () {
+ if (callbacks.onImageUploadError) {
+ callbacks.onImageUploadError();
+ }
+ });
+ }
+ });
+ }
+ };
+
+ var commands = {
+ /**
+ * @param {Object} layoutInfo
+ */
+ showLinkDialog: function (layoutInfo) {
+ var $editor = layoutInfo.editor(),
+ $dialog = layoutInfo.dialog(),
+ $editable = layoutInfo.editable(),
+ linkInfo = editor.getLinkInfo($editable);
+
+ var options = $editor.data('options');
+
+ editor.saveRange($editable);
+ dialog.showLinkDialog($editable, $dialog, linkInfo).then(function (linkInfo) {
+ editor.restoreRange($editable);
+ editor.createLink($editable, linkInfo, options);
+ // hide popover after creating link
+ popover.hide(layoutInfo.popover());
+ }).fail(function () {
+ editor.restoreRange($editable);
+ });
+ },
+
+ /**
+ * @param {Object} layoutInfo
+ */
+ showImageDialog: function (layoutInfo) {
+ var $dialog = layoutInfo.dialog(),
+ $editable = layoutInfo.editable();
+
+ editor.saveRange($editable);
+ dialog.showImageDialog($editable, $dialog).then(function (data) {
+ editor.restoreRange($editable);
+
+ if (typeof data === 'string') {
+ // image url
+ editor.insertImage($editable, data);
+ } else {
+ // array of files
+ insertImages(layoutInfo, data);
+ }
+ }).fail(function () {
+ editor.restoreRange($editable);
+ });
+ },
+
+ /**
+ * @param {Object} layoutInfo
+ */
+ showHelpDialog: function (layoutInfo) {
+ var $dialog = layoutInfo.dialog(),
+ $editable = layoutInfo.editable();
+
+ editor.saveRange($editable, true);
+ dialog.showHelpDialog($editable, $dialog).then(function () {
+ editor.restoreRange($editable);
+ });
+ },
+
+ fullscreen: function (layoutInfo) {
+ var $editor = layoutInfo.editor(),
+ $toolbar = layoutInfo.toolbar(),
+ $editable = layoutInfo.editable(),
+ $codable = layoutInfo.codable();
+
+ var resize = function (size) {
+ $editable.css('height', size.h);
+ $codable.css('height', size.h);
+ if ($codable.data('cmeditor')) {
+ $codable.data('cmeditor').setsize(null, size.h);
+ }
+ };
+
+ $editor.toggleClass('fullscreen');
+ var isFullscreen = $editor.hasClass('fullscreen');
+ if (isFullscreen) {
+ $editable.data('orgheight', $editable.css('height'));
+
+ $window.on('resize', function () {
+ resize({
+ h: $window.height() - $toolbar.outerHeight()
+ });
+ }).trigger('resize');
+
+ $scrollbar.css('overflow', 'hidden');
+ } else {
+ $window.off('resize');
+ resize({
+ h: $editable.data('orgheight')
+ });
+ $scrollbar.css('overflow', 'visible');
+ }
+
+ toolbar.updateFullscreen($toolbar, isFullscreen);
+ },
+
+ codeview: function (layoutInfo) {
+ var $editor = layoutInfo.editor(),
+ $toolbar = layoutInfo.toolbar(),
+ $editable = layoutInfo.editable(),
+ $codable = layoutInfo.codable(),
+ $popover = layoutInfo.popover(),
+ $handle = layoutInfo.handle();
+
+ var options = $editor.data('options');
+
+ var cmEditor, server;
+
+ $editor.toggleClass('codeview');
+
+ var isCodeview = $editor.hasClass('codeview');
+ if (isCodeview) {
+ $codable.val(dom.html($editable, true));
+ $codable.height($editable.height());
+ toolbar.deactivate($toolbar);
+ popover.hide($popover);
+ handle.hide($handle);
+ $codable.focus();
+
+ // activate CodeMirror as codable
+ if (agent.hasCodeMirror) {
+ cmEditor = CodeMirror.fromTextArea($codable[0], options.codemirror);
+
+ // CodeMirror TernServer
+ if (options.codemirror.tern) {
+ server = new CodeMirror.TernServer(options.codemirror.tern);
+ cmEditor.ternServer = server;
+ cmEditor.on('cursorActivity', function (cm) {
+ server.updateArgHints(cm);
+ });
+ }
+
+ // CodeMirror hasn't Padding.
+ cmEditor.setSize(null, $editable.outerHeight());
+ $codable.data('cmEditor', cmEditor);
+ }
+ } else {
+ // deactivate CodeMirror as codable
+ if (agent.hasCodeMirror) {
+ cmEditor = $codable.data('cmEditor');
+ $codable.val(cmEditor.getValue());
+ cmEditor.toTextArea();
+ }
+
+ $editable.html(dom.value($codable) || dom.emptyPara);
+ $editable.height(options.height ? $codable.height() : 'auto');
+
+ toolbar.activate($toolbar);
+ $editable.focus();
+ }
+
+ toolbar.updateCodeview(layoutInfo.toolbar(), isCodeview);
+ }
+ };
+
+ this.commands = commands; // odoo change for overwrite
+ this.editor = editor; // odoo change for overwrite
+ this.toolbar = toolbar; // odoo change for overwrite
+ this.popover = popover; // odoo change for overwrite
+ this.handle = handle; // odoo change for overwrite
+ this.dialog = dialog; // odoo change for overwrite
+
+ var hMousedown = function (event) {
+ //preventDefault Selection for FF, IE8+
+ if (dom.isImg(event.target)) {
+ event.preventDefault();
+ range.createFromNode(event.target).select();
+ }
+ };
+
+ var hToolbarAndPopoverUpdate = function (event) {
+ // delay for range after mouseup
+ setTimeout(function () {
+ var layoutInfo = makeLayoutInfo(event.target);
+ var $editable = layoutInfo.editable();
+ editor.saveRange($editable);
+ var styleInfo = editor.currentStyle();
+ if (!styleInfo) { return; }
+
+ var isAirMode = layoutInfo.editor().data('options').airMode;
+ if (!isAirMode) {
+ toolbar.update(layoutInfo.toolbar(), styleInfo);
+ }
+
+ popover.update(layoutInfo.popover(), styleInfo, isAirMode);
+ handle.update(layoutInfo.handle(), styleInfo, isAirMode);
+ }, 0);
+ };
+
+ var hScroll = function (event) {
+ var layoutInfo = makeLayoutInfo(event.currentTarget || event.target);
+ //hide popover and handle when scrolled
+ popover.hide(layoutInfo.popover());
+ handle.hide(layoutInfo.handle());
+ };
+
+ /**
+ * paste clipboard image
+ *
+ * @param {Event} event
+ */
+ var hPasteClipboardImage = function (event) {
+ var clipboardData = event.originalEvent.clipboardData;
+ var layoutInfo = makeLayoutInfo(event.currentTarget || event.target);
+ var $editable = layoutInfo.editable();
+
+ if (!clipboardData || !clipboardData.items || !clipboardData.items.length) {
+ var callbacks = $editable.data('callbacks');
+ // only can run if it has onImageUpload method
+ if (!callbacks.onImageUpload) {
+ return;
+ }
+
+ // save cursor
+ editor.saveNode($editable);
+ editor.saveRange($editable);
+
+ $editable.html('');
+
+ setTimeout(function () {
+ var $img = $editable.find('img');
+ var datauri = $img[0].src;
+
+ var data = atob(datauri.split(',')[1]);
+ var array = new Uint8Array(data.length);
+ for (var i = 0; i < data.length; i++) {
+ array[i] = data.charCodeAt(i);
+ }
+
+ var blob = new Blob([array], { type : 'image/png'});
+ blob.name = 'clipboard.png';
+
+ editor.restoreNode($editable);
+ editor.restoreRange($editable);
+ insertImages(layoutInfo, [blob]);
+
+ editor.afterCommand($editable);
+ }, 0);
+
+ return;
+ }
+
+ var item = list.head(clipboardData.items);
+ var isClipboardImage = item.kind === 'file' && item.type.indexOf('image/') !== -1;
+
+ if (isClipboardImage) {
+ insertImages(layoutInfo, [item.getAsFile()]);
+ }
+
+ editor.afterCommand($editable);
+ };
+
+ /**
+ * `mousedown` event handler on $handle
+ * - controlSizing: resize image
+ *
+ * @param {MouseEvent} event
+ */
+ var hHandleMousedown = function (event) {
+ if (dom.isControlSizing(event.target)) {
+ event.preventDefault();
+ event.stopPropagation();
+
+ var layoutInfo = makeLayoutInfo(event.target),
+ $handle = layoutInfo.handle(), $popover = layoutInfo.popover(),
+ $editable = layoutInfo.editable(),
+ $editor = layoutInfo.editor();
+
+ var target = $handle.find('.note-control-selection').data('target'),
+ $target = $(target), posStart = $target.offset(),
+ scrollTop = $document.scrollTop();
+
+ var isAirMode = $editor.data('options').airMode;
+
+ $document.on('mousemove', function (event) {
+ editor.resizeTo({
+ x: event.clientX - posStart.left,
+ y: event.clientY - (posStart.top - scrollTop)
+ }, $target, !event.shiftKey);
+
+ handle.update($handle, {image: target}, isAirMode);
+ popover.update($popover, {image: target}, isAirMode);
+ }).one('mouseup', function () {
+ $document.off('mousemove');
+ editor.afterCommand($editable);
+ });
+
+ if (!$target.data('ratio')) { // original ratio.
+ $target.data('ratio', $target.height() / $target.width());
+ }
+ }
+ };
+
+ var hToolbarAndPopoverMousedown = function (event) {
+ // prevent default event when insertTable (FF, Webkit)
+ var $btn = $(event.target).closest('[data-event]');
+ if ($btn.length) {
+ event.preventDefault();
+ }
+ };
+
+ var hToolbarAndPopoverClick = function (event) {
+ var $btn = $(event.target).closest('[data-event]');
+
+ if ($btn.length) {
+ var eventName = $btn.attr('data-event'),
+ value = $btn.attr('data-value'),
+ hide = $btn.attr('data-hide');
+
+ var layoutInfo = makeLayoutInfo(event.target);
+
+ var $editable = layoutInfo.editable();
+ editor.restoreRange($editable);
+
+ // before command: detect control selection element($target)
+ var $target;
+ if ($.inArray(eventName, ['resize', 'floatMe', 'removeMedia', 'imageShape']) !== -1) {
+ var $selection = layoutInfo.handle().find('.note-control-selection');
+ $target = $($selection.data('target'));
+ }
+
+ // If requested, hide the popover when the button is clicked.
+ // Useful for things like showHelpDialog.
+ if (hide) {
+ $btn.parents('.popover').hide();
+ }
+
+ if ($.isFunction($.summernote.pluginEvents[eventName])) {
+ $.summernote.pluginEvents[eventName](event, editor, layoutInfo, value);
+ } else if (editor[eventName]) { // on command
+ $editable.trigger('focus');
+ editor[eventName]($editable, value, $target);
+ event.preventDefault();
+ } else if (commands[eventName]) {
+ commands[eventName].call(this, layoutInfo);
+ event.preventDefault();
+ }
+
+ // after command
+ if ($.inArray(eventName, ['backColor', 'foreColor']) !== -1) {
+ var options = layoutInfo.editor().data('options', options);
+ var module = options.airMode ? popover : toolbar;
+ module.updateRecentColor(list.head($btn), eventName, value);
+ }
+
+ hToolbarAndPopoverUpdate(event);
+ }
+ };
+
+ var EDITABLE_PADDING = 24;
+ /**
+ * `mousedown` event handler on statusbar
+ *
+ * @param {MouseEvent} event
+ */
+ var hStatusbarMousedown = function (event) {
+ event.preventDefault();
+ event.stopPropagation();
+
+ var layoutInfo = makeLayoutInfo(event.target);
+ var $editable = layoutInfo.editable();
+ var nEditableTop = $editable.offset().top - $document.scrollTop();
+ var options = layoutInfo.editor().data('options');
+
+ $document.on('mousemove', function (event) {
+ var nHeight = event.clientY - (nEditableTop + EDITABLE_PADDING);
+
+ nHeight = (options.minHeight > 0) ? Math.max(nHeight, options.minHeight) : nHeight;
+ nHeight = (options.maxHeight > 0) ? Math.min(nHeight, options.maxHeight) : nHeight;
+
+ $editable.height(nHeight);
+ }).one('mouseup', function () {
+ $document.off('mousemove');
+ });
+ };
+
+ var PX_PER_EM = 18;
+ var hDimensionPickerMove = function (event, options) {
+ var $picker = $(event.target.parentNode); // target is mousecatcher
+ var $dimensionDisplay = $picker.next();
+ var $catcher = $picker.find('.note-dimension-picker-mousecatcher');
+ var $highlighted = $picker.find('.note-dimension-picker-highlighted');
+ var $unhighlighted = $picker.find('.note-dimension-picker-unhighlighted');
+
+ var posOffset;
+ // HTML5 with jQuery - e.offsetX is undefined in Firefox
+ if (event.offsetX === undefined) {
+ var posCatcher = $(event.target).offset();
+ posOffset = {
+ x: event.pageX - posCatcher.left,
+ y: event.pageY - posCatcher.top
+ };
+ } else {
+ posOffset = {
+ x: event.offsetX,
+ y: event.offsetY
+ };
+ }
+
+ var dim = {
+ c: Math.ceil(posOffset.x / PX_PER_EM) || 1,
+ r: Math.ceil(posOffset.y / PX_PER_EM) || 1
+ };
+
+ $highlighted.css({ width: dim.c + 'em', height: dim.r + 'em' });
+ $catcher.attr('data-value', dim.c + 'x' + dim.r);
+
+ if (3 < dim.c && dim.c < options.insertTableMaxSize.col) {
+ $unhighlighted.css({ width: dim.c + 1 + 'em'});
+ }
+
+ if (3 < dim.r && dim.r < options.insertTableMaxSize.row) {
+ $unhighlighted.css({ height: dim.r + 1 + 'em'});
+ }
+
+ $dimensionDisplay.html(dim.c + ' x ' + dim.r);
+ };
+
+ /**
+ * Drag and Drop Events
+ *
+ * @param {Object} layoutInfo - layout Informations
+ * @param {Object} options
+ */
+ var handleDragAndDropEvent = function (layoutInfo, options) {
+ if (options.disableDragAndDrop) {
+ // prevent default drop event
+ $document.on('drop', function (e) {
+ e.preventDefault();
+ });
+ } else {
+ attachDragAndDropEvent(layoutInfo, options);
+ }
+ };
+
+ /**
+ * attach Drag and Drop Events
+ *
+ * @param {Object} layoutInfo - layout Informations
+ * @param {Object} options
+ */
+ var attachDragAndDropEvent = function (layoutInfo, options) {
+ var collection = $(),
+ $dropzone = layoutInfo.dropzone,
+ $dropzoneMessage = layoutInfo.dropzone.find('.note-dropzone-message');
+
+ // show dropzone on dragenter when dragging a object to document.
+ $document.on('dragenter', function (e) {
+ var isCodeview = layoutInfo.editor.hasClass('codeview');
+ if (!isCodeview && !collection.length) {
+ layoutInfo.editor.addClass('dragover');
+ $dropzone.width(layoutInfo.editor.width());
+ $dropzone.height(layoutInfo.editor.height());
+ $dropzoneMessage.text(options.langInfo.image.dragImageHere);
+ }
+ collection = collection.add(e.target);
+ }).on('dragleave', function (e) {
+ collection = collection.not(e.target);
+ if (!collection.length) {
+ layoutInfo.editor.removeClass('dragover');
+ }
+ }).on('drop', function () {
+ collection = $();
+ layoutInfo.editor.removeClass('dragover');
+ });
+
+ // change dropzone's message on hover.
+ $dropzone.on('dragenter', function () {
+ $dropzone.addClass('hover');
+ $dropzoneMessage.text(options.langInfo.image.dropImage);
+ }).on('dragleave', function () {
+ $dropzone.removeClass('hover');
+ $dropzoneMessage.text(options.langInfo.image.dragImageHere);
+ });
+
+ // attach dropImage
+ $dropzone.on('drop', function (event) {
+ event.preventDefault();
+
+ var dataTransfer = event.originalEvent.dataTransfer;
+ var text = dataTransfer.getData('text/plain');
+ var layoutInfo = makeLayoutInfo(event.currentTarget || event.target);
+ layoutInfo.editable().focus();
+ if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {
+ insertImages(layoutInfo, dataTransfer.files);
+ } else if (text) {
+ editor.insertText(layoutInfo.editable(), text);
+ }
+ }).on('dragover', false); // prevent default dragover event
+ };
+
+
+ /**
+ * bind KeyMap on keydown
+ *
+ * @param {Object} layoutInfo
+ * @param {Object} keyMap
+ */
+ this.bindKeyMap = function (layoutInfo, keyMap) {
+ var $editor = layoutInfo.editor;
+ var $editable = layoutInfo.editable;
+
+ layoutInfo = makeLayoutInfo($editable);
+
+ $editable.on('keydown', function (event) {
+ var aKey = [];
+
+ // modifier
+ if (event.metaKey) { aKey.push('CMD'); }
+ if (event.ctrlKey && !event.altKey) { aKey.push('CTRL'); }
+ if (event.shiftKey) { aKey.push('SHIFT'); }
+
+ // keycode
+ var keyName = key.nameFromCode[event.keyCode];
+ if (keyName) { aKey.push(keyName); }
+
+ var eventName = keyMap[aKey.join('+')];
+
+ // odoo change: add visible event to overwrite the browser comportment
+ var keycode = event.keyCode;
+ if (!eventName &&
+ !event.ctrlKey && !event.metaKey && ( // special code/command
+ (keycode > 47 && keycode < 58) || // number keys
+ keycode == 32 || keycode == 13 || // spacebar & return
+ (keycode > 64 && keycode < 91) || // letter keys
+ (keycode > 95 && keycode < 112) || // numpad keys
+ (keycode > 185 && keycode < 193) || // ;=,-./` (in order)
+ (keycode > 218 && keycode < 223))) { // [\]' (in order))
+ eventName = 'visible';
+ } else if (!keycode) {
+ editor.restoreRange($editable);
+ }
+
+ if (eventName) {
+ if ($.summernote.pluginEvents[eventName]) {
+ var plugin = $.summernote.pluginEvents[eventName];
+ if ($.isFunction(plugin)) {
+ plugin(event, editor, layoutInfo);
+ }
+ } else if (editor[eventName]) {
+ editor[eventName]($editable, $editor.data('options'));
+ event.preventDefault();
+ } else if (commands[eventName]) {
+ commands[eventName].call(this, layoutInfo);
+ event.preventDefault();
+ }
+ if (keycode) {
+ editor.saveRange($editable);
+ }
+ } else if (key.isEdit(event.keyCode)) {
+ editor.afterCommand($editable);
+ }
+ });
+ };
+
+ /**
+ * attach eventhandler
+ *
+ * @param {Object} layoutInfo - layout Informations
+ * @param {Object} options - user options include custom event handlers
+ * @param {Function} options.enter - enter key handler
+ */
+ this.attach = function (layoutInfo, options) {
+ // handlers for editable
+ if (options.shortcuts) {
+ this.bindKeyMap(layoutInfo, options.keyMap[agent.isMac ? 'mac' : 'pc']);
+ }
+ layoutInfo.editable.on('mousedown', hMousedown);
+ layoutInfo.editable.on('keyup mouseup', hToolbarAndPopoverUpdate);
+ layoutInfo.editable.on('scroll', hScroll);
+ layoutInfo.editable.on('paste', hPasteClipboardImage);
+
+ // handler for handle and popover
+ layoutInfo.handle.on('mousedown', hHandleMousedown);
+ layoutInfo.popover.on('click', hToolbarAndPopoverClick);
+ layoutInfo.popover.on('mousedown', hToolbarAndPopoverMousedown);
+
+ // handlers for frame mode (toolbar, statusbar)
+ if (!options.airMode) {
+ // handler for drag and drop
+ handleDragAndDropEvent(layoutInfo, options);
+
+ // handler for toolbar
+ layoutInfo.toolbar.on('click', hToolbarAndPopoverClick);
+ layoutInfo.toolbar.on('mousedown', hToolbarAndPopoverMousedown);
+
+ // handler for statusbar
+ if (!options.disableResizeEditor) {
+ layoutInfo.statusbar.on('mousedown', hStatusbarMousedown);
+ }
+ }
+
+ // handler for table dimension
+ var $catcherContainer = options.airMode ? layoutInfo.popover :
+ layoutInfo.toolbar;
+ var $catcher = $catcherContainer.find('.note-dimension-picker-mousecatcher');
+ $catcher.css({
+ width: options.insertTableMaxSize.col + 'em',
+ height: options.insertTableMaxSize.row + 'em'
+ }).on('mousemove', function (event) {
+ hDimensionPickerMove(event, options);
+ });
+
+ // save options on editor
+ layoutInfo.editor.data('options', options);
+
+ // ret styleWithCSS for backColor / foreColor clearing with 'inherit'.
+ if (!agent.isMSIE) {
+ // protect FF Error: NS_ERROR_FAILURE: Failure
+ setTimeout(function () {
+ document.execCommand('styleWithCSS', 0, options.styleWithSpan);
+ }, 0);
+ }
+
+ // History
+ var history = new History(layoutInfo.editable);
+ layoutInfo.editable.data('NoteHistory', history);
+
+ // basic event callbacks (lowercase)
+ // enter, focus, blur, keyup, keydown
+ if (options.onenter) {
+ layoutInfo.editable.keypress(function (event) {
+ if (event.keyCode === key.ENTER) { options.onenter(event); }
+ });
+ }
+
+ if (options.onfocus) { layoutInfo.editable.focus(options.onfocus); }
+ if (options.onblur) { layoutInfo.editable.blur(options.onblur); }
+ if (options.onkeyup) { layoutInfo.editable.keyup(options.onkeyup); }
+ if (options.onkeydown) { layoutInfo.editable.keydown(options.onkeydown); }
+ if (options.onpaste) { layoutInfo.editable.on('paste', options.onpaste); }
+
+ // callbacks for advanced features (camel)
+ if (options.onToolbarClick) { layoutInfo.toolbar.click(options.onToolbarClick); }
+ if (options.onChange) {
+ var hChange = function () {
+ editor.triggerOnChange(layoutInfo.editable);
+ };
+
+ if (agent.isMSIE) {
+ var sDomEvents = 'DOMCharacterDataModified DOMSubtreeModified DOMNodeInserted';
+ layoutInfo.editable.on(sDomEvents, hChange);
+ } else {
+ layoutInfo.editable.on('input', hChange);
+ }
+ }
+
+ // All editor status will be saved on editable with jquery's data
+ // for support multiple editor with singleton object.
+ layoutInfo.editable.data('callbacks', {
+ onChange: options.onChange,
+ onAutoSave: options.onAutoSave,
+ onImageUpload: options.onImageUpload,
+ onImageUploadError: options.onImageUploadError,
+ onFileUpload: options.onFileUpload,
+ onFileUploadError: options.onFileUpload
+ });
+ };
+
+ this.detach = function (layoutInfo, options) {
+ layoutInfo.editable.off();
+
+ layoutInfo.popover.off();
+ layoutInfo.handle.off();
+ layoutInfo.dialog.off();
+
+ if (!options.airMode) {
+ layoutInfo.dropzone.off();
+ layoutInfo.toolbar.off();
+ layoutInfo.statusbar.off();
+ }
+ };
+ };
+
+ return EventHandler;
+});