diff --git a/spec/paste.spec.js b/spec/paste.spec.js index d05d10bb9..90cd65bea 100644 --- a/spec/paste.spec.js +++ b/spec/paste.spec.js @@ -184,6 +184,30 @@ describe('Pasting content', function () { }); + it('should trigger editablePaste', function () { + var editorEl = this.el, + editor = this.newMediumEditor('.editor', { + paste: { + forcePlainText: false, + cleanPastedHTML: true + } + }), + spy = jasmine.createSpy('handler'); + + editor.subscribe('editablePaste', spy); + + // move caret to editor + editorEl.innerHTML = ' '; + + selectElementContentsAndFire(editorEl); + + expect(spy).not.toHaveBeenCalled(); + var evt = prepareEvent(editorEl, 'paste'); + firePreparedEvent(evt, editorEl, 'paste'); + jasmine.clock().tick(1); + expect(spy).toHaveBeenCalledWith({ currentTarget: this.el, target: this.el }, this.el); + }); + it('should filter multi-line rich-text pastes when "insertHTML" command is not supported', function () { var editor = this.newMediumEditor('.editor', { paste: { @@ -287,6 +311,48 @@ describe('Pasting content', function () { expect(pasteHandler.handlePasteBinPaste).toHaveBeenCalledWith(evt); }); + it('should fire editablePaste event when pasting', function () { + var editor = this.newMediumEditor('.editor', { + paste: { + forcePlainText: false, + cleanPastedHTML: true + } + }), + spy = jasmine.createSpy('handler'); + + editor.subscribe('editablePaste', spy); + + selectElementContentsAndFire(editor.elements[0].firstChild); + expect(spy).not.toHaveBeenCalled(); + + fireEvent(this.el, 'keydown', { + keyCode: MediumEditor.util.keyCode.V, + ctrlKey: true, + metaKey: true + }); + + var contentEditables = document.body.querySelectorAll('[contentEditable=true]'); + expect(contentEditables.length).toBe(2); + + var evt = { + type: 'paste', + defaultPrevented: false, + preventDefault: function () {}, + clipboardData: { + types: ['text/plain', 'text/html'], + getData: function () { + // do we need to return different results for the different types? text/plain, text/html + return 'pasted content'; + } + } + }, + pasteExtension = editor.getExtensionByName('paste'); + + pasteExtension.handlePasteBinPaste(evt); + jasmine.clock().tick(1); + expect(spy).toHaveBeenCalledWith({ currentTarget: editor.elements[0], target: editor.elements[0] }, editor.elements[0]); + }); + it('should do nothing if default was prevented on paste event of the paste-bin', function () { var editor = this.newMediumEditor('.editor', { paste: { diff --git a/src/js/events.js b/src/js/events.js index c55013064..a46735c7e 100644 --- a/src/js/events.js +++ b/src/js/events.js @@ -542,7 +542,7 @@ }, handlePaste: function (event) { - this.triggerCustomEvent('editablePaste', event, event.currentTarget); + this.triggerCustomEvent('editablePaste', { currentTarget: event.currentTarget, target: event.target }, event.currentTarget); }, handleKeydown: function (event) { diff --git a/src/js/extensions/paste.js b/src/js/extensions/paste.js index 4c768b1c9..bc8bf7bb2 100644 --- a/src/js/extensions/paste.js +++ b/src/js/extensions/paste.js @@ -224,6 +224,12 @@ event.preventDefault(); this.removePasteBin(); this.doPaste(pastedHTML, pastedPlain, editable); + + // The event handling code listens for paste on the editable element + // in order to trigger the editablePaste event. Since this paste event + // is happening on the pastebin, the event handling code never knows about it + // So, we have to trigger editablePaste manually + this.trigger('editablePaste', { currentTarget: editable, target: editable }, editable); return; } @@ -241,6 +247,12 @@ // Handle the paste with the html from the paste bin this.doPaste(pastedHTML, pastedPlain, editable); + + // The event handling code listens for paste on the editable element + // in order to trigger the editablePaste event. Since this paste event + // is happening on the pastebin, the event handling code never knows about it + // So, we have to trigger editablePaste manually + this.trigger('editablePaste', { currentTarget: editable, target: editable }, editable); }.bind(this), 0); },