diff options
Diffstat (limited to 'addons/website/static/lib/summernote/src/js/EventHandler.js')
| -rw-r--r-- | addons/website/static/lib/summernote/src/js/EventHandler.js | 771 |
1 files changed, 0 insertions, 771 deletions
diff --git a/addons/website/static/lib/summernote/src/js/EventHandler.js b/addons/website/static/lib/summernote/src/js/EventHandler.js deleted file mode 100644 index 9d5174c6fe6..00000000000 --- a/addons/website/static/lib/summernote/src/js/EventHandler.js +++ /dev/null @@ -1,771 +0,0 @@ -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; -}); |
