From 19f3098f2bbd4740b4e9ac67b40c2a58201fc386 Mon Sep 17 00:00:00 2001 From: Spocke Date: Thu, 23 Feb 2017 10:30:59 +0100 Subject: [PATCH 01/26] TINY-931: backported TINY-924, TINY-929 --- changelog.txt | 3 +++ js/tinymce/classes/dom/Selection.js | 17 +++++++++++++++-- js/tinymce/classes/util/Quirks.js | 10 +++------- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/changelog.txt b/changelog.txt index b552a37f76f..7cac058a15a 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,6 @@ +Version 4.5.4 (2017-02-23) + Fixed bug where setBaseAndExtend would throw exceptions on Chrome 58 when selecting images. + Fixed bug where deleting partially selected contents could remove all contents in some edge cases on WebKit. Version 4.5.3 (2017-02-01) Added keyboard navigation for menu buttons when the menu is in focus. Added api to the list plugin for setting custom classes/attributes on lists. diff --git a/js/tinymce/classes/dom/Selection.js b/js/tinymce/classes/dom/Selection.js index 70bba9dcf88..76f657d90c9 100644 --- a/js/tinymce/classes/dom/Selection.js +++ b/js/tinymce/classes/dom/Selection.js @@ -641,13 +641,26 @@ define("tinymce/dom/Selection", [ self.selectedRange = sel.rangeCount > 0 ? sel.getRangeAt(0) : null; } - // WebKit egde case selecting images works better using setBaseAndExtent + // WebKit egde case selecting images works better using setBaseAndExtent when the image is floated if (!rng.collapsed && rng.startContainer == rng.endContainer && sel.setBaseAndExtent && !Env.ie) { if (rng.endOffset - rng.startOffset < 2) { if (rng.startContainer.hasChildNodes()) { node = rng.startContainer.childNodes[rng.startOffset]; if (node && node.tagName == 'IMG') { - self.getSel().setBaseAndExtent(node, 0, node, 1); + sel.setBaseAndExtent( + rng.startContainer, + rng.startOffset, + rng.endContainer, + rng.endOffset + ); + + // Since the setBaseAndExtent is fixed in more recent Blink versions we + // need to detect if it's doing the wrong thing and falling back to the + // crazy incorrect behavior api call since that seems to be the only way + // to get it to work on Safari WebKit as of 2017-02-23 + if (sel.anchorNode !== rng.startContainer) { + sel.setBaseAndExtent(node, 0, node, 1); + } } } } diff --git a/js/tinymce/classes/util/Quirks.js b/js/tinymce/classes/util/Quirks.js index d9f6083bbd2..7fb1c9f98ae 100644 --- a/js/tinymce/classes/util/Quirks.js +++ b/js/tinymce/classes/util/Quirks.js @@ -960,10 +960,9 @@ define("tinymce/util/Quirks", [ // Workaround for bug, http://bugs.webkit.org/show_bug.cgi?id=12250 // WebKit can't even do simple things like selecting an image - // Needs to be the setBaseAndExtend or it will fail to select floated images if (/^(IMG|HR)$/.test(target.nodeName) && dom.getContentEditableParent(target) !== "false") { e.preventDefault(); - selection.getSel().setBaseAndExtent(target, 0, target, 1); + selection.select(target); editor.nodeChanged(); } @@ -1675,9 +1674,6 @@ define("tinymce/util/Quirks", [ * prevent empty paragraphs from being produced at beginning/end of contents. */ function emptyEditorOnDeleteEverything() { - var deepEqual = function (a, b) { - return a.getNode() === b.getNode() || a.isEqual(b); - }; function isEverythingSelected(editor) { var caretWalker = new CaretWalker(editor.getBody()); var rng = editor.selection.getRng(); @@ -1687,8 +1683,8 @@ define("tinymce/util/Quirks", [ var next = caretWalker.next(endCaretPos); return !editor.selection.isCollapsed() && - (!prev || (prev.isAtStart() && deepEqual(startCaretPos, prev) === false)) && - (!next || (next.isAtEnd() && deepEqual(startCaretPos, next) === false)); + (!prev || (prev.isAtStart() && startCaretPos.isEqual(prev))) && + (!next || (next.isAtEnd() && startCaretPos.isEqual(next))); } // Type over case delete and insert this won't cover typeover with a IME but at least it covers the common case From 2e9d3b9104345a8406f2364ed7269ad4ff3efcb5 Mon Sep 17 00:00:00 2001 From: Mattias Wikstrom Date: Thu, 23 Feb 2017 13:39:44 +0100 Subject: [PATCH 02/26] 4.5.x: updated package.json for 4.5.4 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 90859126979..791d0ee5a43 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tinymce", - "version": "4.5.3", + "version": "4.5.4", "repository": { "type": "git", "url": "https://github.com/tinymce/tinymce.git" From d96283d3def83c75a38864adcb6cc63e606894eb Mon Sep 17 00:00:00 2001 From: Mattias Wikstrom Date: Thu, 23 Feb 2017 14:42:55 +0100 Subject: [PATCH 03/26] 4.5.x: add validateVersion grunt task --- Gruntfile.js | 2 +- tools/tasks/validateVersion.js | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 tools/tasks/validateVersion.js diff --git a/Gruntfile.js b/Gruntfile.js index 8ce247419c1..a88ef277288 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -781,5 +781,5 @@ module.exports = function(grunt) { grunt.registerTask("lint", ["eslint"]); grunt.registerTask("minify", ["amdlc", "uglify", "skin", "less"]); grunt.registerTask("test", ["qunit"]); - grunt.registerTask("default", ["lint", "minify", "subgrunt", "test", "clean:release", "moxiezip", "nugetpack", "version"]); + grunt.registerTask("default", ["lint", "minify", "subgrunt", "test", "validateVersion", "clean:release", "moxiezip", "nugetpack", "version"]); }; diff --git a/tools/tasks/validateVersion.js b/tools/tasks/validateVersion.js new file mode 100644 index 00000000000..714a166c5a7 --- /dev/null +++ b/tools/tasks/validateVersion.js @@ -0,0 +1,20 @@ +/* eslint-env node */ + +var fs = require('fs'); +var path = require('path'); +var package = require(path.join(__dirname, '../../package.json')); + +module.exports = function (grunt) { + grunt.registerTask("validateVersion", "Check that version number in changelog and package.json match", function () { + var changelog = fs.readFileSync(path.join(__dirname, '../../changelog.txt')); + var changelogVersion = /Version ([0-9.]+)/.exec(changelog)[1]; + + if (package.version !== changelogVersion) { + grunt.fail.fatal( + 'Latest changelog version ' + changelogVersion + + ' and package.json version ' + package.version + + ' does not match.' + ); + } + }); +}; From f2dc7124833578d4c6b54f66ab3097c8ca66619a Mon Sep 17 00:00:00 2001 From: Davit Barbakadze Date: Thu, 2 Mar 2017 22:12:00 +0400 Subject: [PATCH 04/26] GH-3519: prioritize fontSize rule only after the node has been cleaned up --- js/tinymce/classes/Formatter.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/js/tinymce/classes/Formatter.js b/js/tinymce/classes/Formatter.js index c6b0d31f9d9..22973ced3a1 100644 --- a/js/tinymce/classes/Formatter.js +++ b/js/tinymce/classes/Formatter.js @@ -689,15 +689,6 @@ define("tinymce/Formatter", [ return; } - // fontSize defines the line height for the whole branch of nested style wrappers, - // therefore it should be set on the outermost wrapper - if (!isBlock(node) && !getStyle(node, 'fontSize')) { - var styleNode = matchNestedWrapper(node, hasStyle('fontSize')); - if (styleNode) { - apply('fontsize', {value: getStyle(styleNode, 'fontSize')}, node); - } - } - if (format.inline || format.wrapper) { // Merges the current node with it's children of similar type to reduce the number of elements if (!format.exact && childCount === 1) { @@ -737,6 +728,15 @@ define("tinymce/Formatter", [ }); } + // fontSize defines the line height for the whole branch of nested style wrappers, + // therefore it should be set on the outermost wrapper + if (!isBlock(node) && !getStyle(node, 'fontSize')) { + var styleNode = matchNestedWrapper(node, hasStyle('fontSize')); + if (styleNode) { + apply('fontsize', {value: getStyle(styleNode, 'fontSize')}, node); + } + } + // Merge next and previous siblings if they are similar texttext becomes texttext if (node && format.merge_siblings !== false) { node = mergeSiblings(getNonWhiteSpaceSibling(node), node); From 424c77aa7319e24c3cd3120427fecf79051955bd Mon Sep 17 00:00:00 2001 From: Davit Barbakadze Date: Thu, 2 Mar 2017 22:13:06 +0400 Subject: [PATCH 05/26] GH-3519: add test --- tests/tinymce/Formatter_apply.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/tinymce/Formatter_apply.js b/tests/tinymce/Formatter_apply.js index 4aead97a7e2..5a9ffa9a7b0 100644 --- a/tests/tinymce/Formatter_apply.js +++ b/tests/tinymce/Formatter_apply.js @@ -1779,3 +1779,10 @@ test("TINY-865: Font size removed when changing background color", function() { editor.formatter.apply('hilitecolor', {value: '#ffff00'}); equal(getContent(), '

a b c

'); }); + +test("GH-3519: Font family selection does not work after changing font size", function() { + editor.getBody().innerHTML = '

text

'; + Utils.setSelection('span', 0, 'span', 4); + editor.formatter.apply('fontname', {value: "verdana"}); + equal(getContent(), '

text

'); +}); From bbb3271ff64817ffe9491baf286d3efcc98abdb1 Mon Sep 17 00:00:00 2001 From: Davit Barbakadze Date: Thu, 2 Mar 2017 22:13:36 +0400 Subject: [PATCH 06/26] GH-3519: add test for TINY-935 --- tests/tinymce/Formatter_apply.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/tinymce/Formatter_apply.js b/tests/tinymce/Formatter_apply.js index 5a9ffa9a7b0..dc4ebc3e35b 100644 --- a/tests/tinymce/Formatter_apply.js +++ b/tests/tinymce/Formatter_apply.js @@ -1780,6 +1780,13 @@ test("TINY-865: Font size removed when changing background color", function() { equal(getContent(), '

a b c

'); }); +test("TINY-935: Text color, then size, then change color wraps span doesn't change color", function() { + editor.getBody().innerHTML = '

text

'; + Utils.setSelection('span', 0, 'span', 4); + editor.formatter.apply('forecolor', {value: '#ff0000'}); + equal(getContent(), '

text

'); +}); + test("GH-3519: Font family selection does not work after changing font size", function() { editor.getBody().innerHTML = '

text

'; Utils.setSelection('span', 0, 'span', 4); From c2702a3a5c5143d4d1b9e15192626956275edff8 Mon Sep 17 00:00:00 2001 From: Davit Barbakadze Date: Thu, 2 Mar 2017 22:15:52 +0400 Subject: [PATCH 07/26] GH-3519: adapt old tests (according to the current logic that's how they are expected to be) --- tests/tinymce/Formatter_apply.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/tinymce/Formatter_apply.js b/tests/tinymce/Formatter_apply.js index dc4ebc3e35b..7a60a70e593 100644 --- a/tests/tinymce/Formatter_apply.js +++ b/tests/tinymce/Formatter_apply.js @@ -1738,7 +1738,7 @@ test("Wrapper with fontSize should retain priority within a branch of nested inl editor.formatter.apply('underline'); editor.formatter.apply('forecolor', {value: '#ff0000'}); - equal(getContent(), '

abc

'); + equal(getContent(), '

abc

'); }); test("Child wrapper having the same format as the immediate parent, shouldn't be removed if it also has other formats merged", function() { @@ -1776,8 +1776,8 @@ test("TINY-671: Background color on nested font size bug", function() { test("TINY-865: Font size removed when changing background color", function() { editor.getBody().innerHTML = '

a b c

'; Utils.setSelection('span span:nth-child(2)', 0, 'span span:nth-child(2)', 1); - editor.formatter.apply('hilitecolor', {value: '#ffff00'}); - equal(getContent(), '

a b c

'); + editor.formatter.apply('hilitecolor', {value: '#ff0000'}); + equal(getContent(), '

a b c

'); }); test("TINY-935: Text color, then size, then change color wraps span doesn't change color", function() { From 3e6643b5bb43d26c47c6ae07caaf1b6b50eb3f14 Mon Sep 17 00:00:00 2001 From: Mattias Wikstrom Date: Tue, 7 Mar 2017 14:21:35 +0100 Subject: [PATCH 08/26] 4.5.x: Changelog and version bump for 4.5.5 release --- changelog.txt | 4 +++- package.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/changelog.txt b/changelog.txt index 7cac058a15a..1d0c37c4ae4 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,5 @@ +Version 4.5.5 (2017-03-07) + Fixed text formatting bug with fontsize could not be changed after changing the text color. Version 4.5.4 (2017-02-23) Fixed bug where setBaseAndExtend would throw exceptions on Chrome 58 when selecting images. Fixed bug where deleting partially selected contents could remove all contents in some edge cases on WebKit. @@ -107,7 +109,7 @@ Version 4.5.0 (2016-11-23) Fixed various api documentation issues and typos. Removed layer plugin since it wasn't really ported from 3.x and there doesn't seem to be much use for it. Removed moxieplayer.swf from the media plugin since it wasn't used by the media plugin. - Removed format state from the advlist plugin to be more consistent with common word processors. + Removed format state from the advlist plugin to be more consistent with common word processors. Version 4.4.3 (2016-09-01) Fixed bug where copy would produce an exception on Chrome. Fixed bug where deleting lists on IE 11 would merge in correct text nodes. diff --git a/package.json b/package.json index 791d0ee5a43..7cbbbef4062 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tinymce", - "version": "4.5.4", + "version": "4.5.5", "repository": { "type": "git", "url": "https://github.com/tinymce/tinymce.git" From 518a3bff9a5b5922e647db7b0b2d000d4d4c752f Mon Sep 17 00:00:00 2001 From: Spocke Date: Mon, 20 Mar 2017 11:15:02 +0100 Subject: [PATCH 09/26] TINY-955: fixed image selection on chrome --- js/tinymce/classes/dom/Selection.js | 2 +- tests/tinymce/dom/Selection.js | 43 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/js/tinymce/classes/dom/Selection.js b/js/tinymce/classes/dom/Selection.js index 76f657d90c9..0465e606170 100644 --- a/js/tinymce/classes/dom/Selection.js +++ b/js/tinymce/classes/dom/Selection.js @@ -658,7 +658,7 @@ define("tinymce/dom/Selection", [ // need to detect if it's doing the wrong thing and falling back to the // crazy incorrect behavior api call since that seems to be the only way // to get it to work on Safari WebKit as of 2017-02-23 - if (sel.anchorNode !== rng.startContainer) { + if (sel.anchorNode !== rng.startContainer || sel.focusNode !== rng.endContainer) { sel.setBaseAndExtent(node, 0, node, 1); } } diff --git a/tests/tinymce/dom/Selection.js b/tests/tinymce/dom/Selection.js index 581f065fe5f..20f4e863ada 100644 --- a/tests/tinymce/dom/Selection.js +++ b/tests/tinymce/dom/Selection.js @@ -1094,5 +1094,48 @@ ModuleLoader.require([ editor.selection.win = win; }); + + test('image selection webkit bug', function() { + var testImageSelection = function (inputHtml, expectedContainerName, expectedOffset) { + editor.setContent(inputHtml); + editor.selection.select(editor.dom.select('img')[0]); + + var rng = editor.selection.getRng(true); + equal(rng.startContainer.nodeName, 'P'); + equal(rng.startOffset, expectedOffset); + equal(rng.startContainer.nodeName, 'P'); + equal(rng.endOffset, expectedOffset + 1); + equal(editor.selection.getNode().nodeName, 'IMG'); + equal(editor.selection.getStart().nodeName, 'IMG'); + equal(editor.selection.getEnd().nodeName, 'IMG'); + + var nativeRng = editor.selection.getSel().getRangeAt(0); + equal(nativeRng.startContainer.nodeName, 'P'); + equal(nativeRng.startOffset, expectedOffset); + equal(nativeRng.startContainer.nodeName, 'P'); + equal(nativeRng.endOffset, expectedOffset + 1); + }; + + testImageSelection('

', 'P', 0); + testImageSelection('

abc

', 'P', 0); + testImageSelection('

abc

', 'P', 1); + testImageSelection('

abcdef

', 'P', 1); + testImageSelection('

', 'P', 0); + testImageSelection('

abc

', 'P', 0); + testImageSelection('

abc

', 'P', 1); + testImageSelection('

abcdef

', 'P', 1); + testImageSelection('

', 'P', 0); + testImageSelection('

abc

', 'P', 0); + testImageSelection('

abc

', 'P', 1); + testImageSelection('

abcdef

', 'P', 1); + testImageSelection('

', 'P', 0); + testImageSelection('

abc

', 'P', 0); + testImageSelection('

abc

', 'P', 1); + testImageSelection('

abcdef

', 'P', 1); + testImageSelection('

', 'P', 0); + testImageSelection('

abc

', 'P', 0); + testImageSelection('

abc

', 'P', 1); + testImageSelection('

abcdef

', 'P', 1); + }); }); From e308e071dd5a6ea48706131c15a4af8e1fee974f Mon Sep 17 00:00:00 2001 From: Spocke Date: Thu, 30 Mar 2017 13:31:05 +0200 Subject: [PATCH 10/26] updated changelog --- changelog.txt | 4 +++- package.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/changelog.txt b/changelog.txt index 1d0c37c4ae4..b41b988f291 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,7 @@ +Version 4.5.6 (2017-03-30) + Fixed bug where it wasn't possible to select floated images in some cases. Version 4.5.5 (2017-03-07) - Fixed text formatting bug with fontsize could not be changed after changing the text color. + Fixed text formatting bug with fontsize could not be changed after changing the text color. Version 4.5.4 (2017-02-23) Fixed bug where setBaseAndExtend would throw exceptions on Chrome 58 when selecting images. Fixed bug where deleting partially selected contents could remove all contents in some edge cases on WebKit. diff --git a/package.json b/package.json index 7cbbbef4062..d6d8fe407ec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tinymce", - "version": "4.5.5", + "version": "4.5.6", "repository": { "type": "git", "url": "https://github.com/tinymce/tinymce.git" From 0b45f7da96aa509b876c37cecb8eb8daf0d843e6 Mon Sep 17 00:00:00 2001 From: Davit Barbakadze Date: Mon, 24 Apr 2017 13:17:04 +0400 Subject: [PATCH 11/26] TINY-996, paste: trim html in case-insensitive manner --- js/tinymce/plugins/paste/classes/Utils.js | 2 +- tests/plugins/paste.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/js/tinymce/plugins/paste/classes/Utils.js b/js/tinymce/plugins/paste/classes/Utils.js index bb196e9cf80..3bb12ed2f16 100644 --- a/js/tinymce/plugins/paste/classes/Utils.js +++ b/js/tinymce/plugins/paste/classes/Utils.js @@ -112,7 +112,7 @@ define("tinymce/pasteplugin/Utils", [ } html = filter(html, [ - /^[\s\S]*]*>\s*|\s*<\/body[^>]*>[\s\S]*$/g, // Remove anything but the contents within the BODY element + /^[\s\S]*]*>\s*|\s*<\/body[^>]*>[\s\S]*$/ig, // Remove anything but the contents within the BODY element /|/g, // Inner fragments (tables from excel on mac) [/( ?)\u00a0<\/span>( ?)/g, trimSpaces], /
/g, diff --git a/tests/plugins/paste.js b/tests/plugins/paste.js index 9ff1eb6305a..139cd0173c4 100644 --- a/tests/plugins/paste.js +++ b/tests/plugins/paste.js @@ -679,6 +679,7 @@ test('trim html from clipboard fragments', function() { equal(tinymce.pasteplugin.Utils.trimHtml('a\n\n\nb\n\n\nc'), '\nb\n'); equal(tinymce.pasteplugin.Utils.trimHtml('abc'), 'abc'); equal(tinymce.pasteplugin.Utils.trimHtml('abc'), 'b'); + equal(tinymce.pasteplugin.Utils.trimHtml('ab'), 'b'); equal(tinymce.pasteplugin.Utils.trimHtml('a\u00a0<\/span>b'), 'a b'); equal(tinymce.pasteplugin.Utils.trimHtml('\u00a0<\/span>b'), ' b'); equal(tinymce.pasteplugin.Utils.trimHtml('a\u00a0<\/span>'), 'a '); From 84c41b376029aa32f802a633704ce42fef3aecd4 Mon Sep 17 00:00:00 2001 From: Spocke Date: Mon, 24 Apr 2017 10:54:02 +0200 Subject: [PATCH 12/26] backported TINY-991 --- changelog.txt | 2 ++ js/tinymce/classes/SelectionOverrides.js | 21 +++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/changelog.txt b/changelog.txt index b41b988f291..38831392e97 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,5 @@ +Version 4.5.7 (2017-04-25) + Fixed bug with selection around inline contenteditable false would get collapsed incorrectly. Version 4.5.6 (2017-03-30) Fixed bug where it wasn't possible to select floated images in some cases. Version 4.5.5 (2017-03-07) diff --git a/js/tinymce/classes/SelectionOverrides.js b/js/tinymce/classes/SelectionOverrides.js index eda6c4efb03..34106bde745 100644 --- a/js/tinymce/classes/SelectionOverrides.js +++ b/js/tinymce/classes/SelectionOverrides.js @@ -521,11 +521,12 @@ define("tinymce/SelectionOverrides", [ var down = curry(moveV, 1, LineWalker.downUntil); function override(evt, moveFn) { - var range = moveFn(getRange()); - - if (range && !evt.isDefaultPrevented()) { - evt.preventDefault(); - setRange(range); + if (evt.isDefaultPrevented() === false) { + var range = moveFn(getRange()); + if (range) { + evt.preventDefault(); + setRange(range); + } } } @@ -862,8 +863,16 @@ define("tinymce/SelectionOverrides", [ ); } + function isWithinCaretContainer(node) { + return ( + CaretContainer.isCaretContainer(node) || + CaretContainer.startsWithCaretContainer(node) || + CaretContainer.endsWithCaretContainer(node) + ); + } + function isRangeInCaretContainer(rng) { - return CaretContainer.isCaretContainer(rng.startContainer) || CaretContainer.isCaretContainer(rng.endContainer); + return isWithinCaretContainer(rng.startContainer) || isWithinCaretContainer(rng.endContainer); } function setContentEditableSelection(range) { From 6b72aacc3bb6b9de86e05965c4d9e34956999e56 Mon Sep 17 00:00:00 2001 From: Spocke Date: Mon, 24 Apr 2017 14:18:24 +0200 Subject: [PATCH 13/26] updated changelog --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index 38831392e97..c316222fe8a 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,6 @@ Version 4.5.7 (2017-04-25) Fixed bug with selection around inline contenteditable false would get collapsed incorrectly. + Fixed bug where pasting on Microsoft Edge 40+ would produce clipboard fragment headers. Version 4.5.6 (2017-03-30) Fixed bug where it wasn't possible to select floated images in some cases. Version 4.5.5 (2017-03-07) From 943f420414412a2b50456b0b1602ed2c15f158f2 Mon Sep 17 00:00:00 2001 From: Spocke Date: Mon, 24 Apr 2017 14:23:52 +0200 Subject: [PATCH 14/26] bumped package.json version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d6d8fe407ec..0ad288b45f7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tinymce", - "version": "4.5.6", + "version": "4.5.7", "repository": { "type": "git", "url": "https://github.com/tinymce/tinymce.git" From 3be9ae5f668dd4d02bfe611099cff5dfadddfe67 Mon Sep 17 00:00:00 2001 From: Spocke Date: Tue, 25 Apr 2017 14:34:41 +0200 Subject: [PATCH 15/26] TINY-996: trimmed at fragment bondaries --- js/tinymce/plugins/paste/classes/Utils.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/js/tinymce/plugins/paste/classes/Utils.js b/js/tinymce/plugins/paste/classes/Utils.js index 3bb12ed2f16..2d0233dfa98 100644 --- a/js/tinymce/plugins/paste/classes/Utils.js +++ b/js/tinymce/plugins/paste/classes/Utils.js @@ -94,6 +94,21 @@ define("tinymce/pasteplugin/Utils", [ return text; } + var getInnerFragment = function (html) { + var startFragment = ''; + var endFragment = ''; + var startPos = html.indexOf(startFragment); + if (startPos !== -1) { + var fragmentHtml = html.substr(startPos + startFragment.length); + var endPos = fragmentHtml.indexOf(endFragment); + if (endPos !== -1 && /^<\/(p|h[1-6]|li)>/i.test(fragmentHtml.substr(endPos + endFragment.length, 5))) { + return fragmentHtml.substr(0, endPos); + } + } + + return html; + }; + /** * Trims the specified HTML by removing all WebKit fragments, all elements wrapping the body trailing BR elements etc. * @@ -111,7 +126,7 @@ define("tinymce/pasteplugin/Utils", [ return '\u00a0'; } - html = filter(html, [ + html = filter(getInnerFragment(html), [ /^[\s\S]*]*>\s*|\s*<\/body[^>]*>[\s\S]*$/ig, // Remove anything but the contents within the BODY element /|/g, // Inner fragments (tables from excel on mac) [/( ?)\u00a0<\/span>( ?)/g, trimSpaces], From 3ec71dfbdbf209c903e6f01e1de0cb73e1372ad5 Mon Sep 17 00:00:00 2001 From: Davit Barbakadze Date: Tue, 23 May 2017 14:40:21 +0400 Subject: [PATCH 16/26] TINY-926: blobUriToBlob() might fail if image doesn't exist or is inaccessible. --- js/tinymce/classes/file/Conversions.js | 46 +++++++++++++++++--------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/js/tinymce/classes/file/Conversions.js b/js/tinymce/classes/file/Conversions.js index 13effd66e37..9f73c7ea29a 100644 --- a/js/tinymce/classes/file/Conversions.js +++ b/js/tinymce/classes/file/Conversions.js @@ -18,21 +18,37 @@ define("tinymce/file/Conversions", [ "tinymce/util/Promise" ], function(Promise) { function blobUriToBlob(url) { - return new Promise(function(resolve) { - var xhr = new XMLHttpRequest(); - - xhr.open('GET', url, true); - xhr.responseType = 'blob'; - - xhr.onload = function() { - if (this.status == 200) { - resolve(this.response); - } - }; - - xhr.send(); - }); - } + return new Promise(function (resolve, reject) { + + var rejectWithError = function () { + reject("Cannot convert " + url + " to Blob. Resource might not exist or is inaccessible."); + }; + + try { + var xhr = new XMLHttpRequest(); + + xhr.open('GET', url, true); + xhr.responseType = 'blob'; + + xhr.onload = function () { + if (this.status == 200) { + resolve(this.response); + } else { + // IE11 makes it into onload but responds with status 500 + rejectWithError(); + } + }; + + // Chrome fires an error event instead of the exception + // Also there seems to be no way to intercept the message that is logged to the console + xhr.onerror = rejectWithError; + + xhr.send(); + } catch (ex) { + rejectWithError(); + } + }); + } function parseDataUri(uri) { var type, matches; From 96e2eb53fa8e90ba56d0c1d9f17a61a4118152bd Mon Sep 17 00:00:00 2001 From: Davit Barbakadze Date: Tue, 23 May 2017 14:51:11 +0400 Subject: [PATCH 17/26] TINY-926, ErrorReporter: expose generic displayError() --- js/tinymce/classes/ErrorReporter.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/tinymce/classes/ErrorReporter.js b/js/tinymce/classes/ErrorReporter.js index a589b4c8719..b1fd00ce097 100644 --- a/js/tinymce/classes/ErrorReporter.js +++ b/js/tinymce/classes/ErrorReporter.js @@ -64,6 +64,7 @@ define("tinymce/ErrorReporter", [ return { pluginLoadError: pluginLoadError, - uploadError: uploadError + uploadError: uploadError, + displayError: displayError }; }); \ No newline at end of file From fb20a9efd3466944f770d119f74629d1dfbddae9 Mon Sep 17 00:00:00 2001 From: Davit Barbakadze Date: Tue, 23 May 2017 14:57:08 +0400 Subject: [PATCH 18/26] TINY-926, ImageScanner/EditorUpload: take into account that conversion might fail in findAll() --- js/tinymce/classes/EditorUpload.js | 10 ++++++++++ js/tinymce/classes/file/ImageScanner.js | 10 +++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/js/tinymce/classes/EditorUpload.js b/js/tinymce/classes/EditorUpload.js index ce62d75af0c..8e580928735 100644 --- a/js/tinymce/classes/EditorUpload.js +++ b/js/tinymce/classes/EditorUpload.js @@ -152,6 +152,16 @@ define("tinymce/EditorUpload", [ } return imageScanner.findAll(editor.getBody(), isValidDataUriImage).then(aliveGuard(function(result) { + result = Arr.filter(result, function (resultItem) { + // ImageScanner internally converts images that it finds, but it may fail to do so if image source is inaccessible. + // In such case resultItem will contain appropriate text error message, instead of image data. + if (typeof resultItem === 'string') { + ErrorReporter.displayError(editor, resultItem); + return false; + } + return true; + }); + Arr.each(result, function(resultItem) { replaceUrlInUndoStack(resultItem.image.src, resultItem.blobInfo.blobUri()); resultItem.image.src = resultItem.blobInfo.blobUri(); diff --git a/js/tinymce/classes/file/ImageScanner.js b/js/tinymce/classes/file/ImageScanner.js index d005bd9ba82..3b04fe518eb 100644 --- a/js/tinymce/classes/file/ImageScanner.js +++ b/js/tinymce/classes/file/ImageScanner.js @@ -33,7 +33,7 @@ define("tinymce/file/ImageScanner", [ function findAll(elm, predicate) { var images, promises; - function imageToBlobInfo(img, resolve) { + function imageToBlobInfo(img, resolve, reject) { var base64, blobInfo; if (img.src.indexOf('blob:') === 0) { @@ -56,6 +56,8 @@ define("tinymce/file/ImageScanner", [ blobInfo: blobInfo }); }); + }, function (err) { + reject(err); }); } @@ -81,6 +83,8 @@ define("tinymce/file/ImageScanner", [ image: img, blobInfo: blobInfo }); + }, function (err) { + reject(err); }); } } @@ -135,8 +139,8 @@ define("tinymce/file/ImageScanner", [ }); } - newPromise = new Promise(function(resolve) { - imageToBlobInfo(img, resolve); + newPromise = new Promise(function(resolve, reject) { + imageToBlobInfo(img, resolve, reject); }).then(function(result) { delete cachedPromises[result.image.src]; return result; From 42a7f538ebdff5a3dca4de1af41cabab1c6b6a93 Mon Sep 17 00:00:00 2001 From: Davit Barbakadze Date: Tue, 23 May 2017 14:58:40 +0400 Subject: [PATCH 19/26] TINY-926, EditorUpload: editorUpload might not be initialized yet --- js/tinymce/classes/EditorUpload.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/tinymce/classes/EditorUpload.js b/js/tinymce/classes/EditorUpload.js index 8e580928735..c926c888c56 100644 --- a/js/tinymce/classes/EditorUpload.js +++ b/js/tinymce/classes/EditorUpload.js @@ -190,7 +190,7 @@ define("tinymce/EditorUpload", [ if (!blobInfo) { blobInfo = Arr.reduce(editor.editorManager.editors, function(result, editor) { - return result || editor.editorUpload.blobCache.getByUri(blobUri); + return result || editor.editorUpload && editor.editorUpload.blobCache.getByUri(blobUri); }, null); } From 8d6c898ae9315b85d8604186ced5b6e56e92e2bc Mon Sep 17 00:00:00 2001 From: Davit Barbakadze Date: Tue, 23 May 2017 14:59:31 +0400 Subject: [PATCH 20/26] TINY-926, ImageScanner: cached promises might also fail --- js/tinymce/classes/file/ImageScanner.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/js/tinymce/classes/file/ImageScanner.js b/js/tinymce/classes/file/ImageScanner.js index 3b04fe518eb..c04742ede1b 100644 --- a/js/tinymce/classes/file/ImageScanner.js +++ b/js/tinymce/classes/file/ImageScanner.js @@ -131,6 +131,10 @@ define("tinymce/file/ImageScanner", [ // We need to wrap it and resolve with the actual image return new Promise(function(resolve) { cachedPromises[img.src].then(function(imageInfo) { + if (typeof imageInfo === 'string') { // error apparently + return imageInfo; + } + resolve({ image: img, blobInfo: imageInfo.blobInfo From 106f8a993ef424d3be5c5a982ca2de1b788564fb Mon Sep 17 00:00:00 2001 From: Davit Barbakadze Date: Tue, 23 May 2017 15:09:14 +0400 Subject: [PATCH 21/26] TINY-926: add tests --- tests/tinymce/file/Conversions.js | 14 ++++++++++++++ tests/tinymce/file/ImageScanner.js | 8 ++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/tests/tinymce/file/Conversions.js b/tests/tinymce/file/Conversions.js index 05a066e224c..48b86c6eb5e 100644 --- a/tests/tinymce/file/Conversions.js +++ b/tests/tinymce/file/Conversions.js @@ -14,4 +14,18 @@ ModuleLoader.require(["tinymce/file/Conversions"], function(Conversions) { QUnit.equal(dataUri, "data:text/plain;base64,SGVsbG8sIFdvcmxkIQ=="); }).then(QUnit.start); }); + + + QUnit.asyncTest("uriToBlob", function () { + var invalidBlobUriSrc = "blob:70BE8432-BA4D-4787-9AB9-86563351FBF7"; + + Conversions.uriToBlob(invalidBlobUriSrc).then(function () { + equal(true, false, "Conversion should fail."); + QUnit.start(); + })['catch'](function (error) { + equal(typeof error, 'string'); + equal(error.indexOf(invalidBlobUriSrc) !== -1, true); + QUnit.start(); + }); + }); }); \ No newline at end of file diff --git a/tests/tinymce/file/ImageScanner.js b/tests/tinymce/file/ImageScanner.js index f3fa7fabf55..c539af3ef54 100644 --- a/tests/tinymce/file/ImageScanner.js +++ b/tests/tinymce/file/ImageScanner.js @@ -15,6 +15,8 @@ ModuleLoader.require([ var base64Src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw=='; var blobUriSrc; + var invalidBlobUriSrc = "blob:70BE8432-BA4D-4787-9AB9-86563351FBF7"; + Conversions.uriToBlob(base64Src).then(function(blob) { blobUriSrc = URL.createObjectURL(blob); @@ -29,13 +31,15 @@ ModuleLoader.require([ '' + '' + '' + - '' + '' + + '' ); imageScanner.findAll(document.getElementById('view')).then(function(result) { QUnit.start(); var blobInfo = result[0].blobInfo; - equal(result.length, 2); + equal(result.length, 3); + equal(typeof result[result.length - 1], 'string', "Last item is not the image, but error message."); equal('data:image/gif;base64,' + blobInfo.base64(), base64Src); strictEqual(result[0].image, document.getElementById('view').firstChild); }); From ba8b68ca37a749852c87cf0099b80391b12a032e Mon Sep 17 00:00:00 2001 From: Davit Barbakadze Date: Tue, 8 Aug 2017 09:40:12 +0400 Subject: [PATCH 22/26] TINY-1160, Quirks: all IEs require bodyHeight fix (not only IE >= 11) --- js/tinymce/classes/util/Quirks.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/tinymce/classes/util/Quirks.js b/js/tinymce/classes/util/Quirks.js index 7fb1c9f98ae..6c2a2c16cc6 100644 --- a/js/tinymce/classes/util/Quirks.js +++ b/js/tinymce/classes/util/Quirks.js @@ -1471,7 +1471,7 @@ define("tinymce/util/Quirks", [ * object it's not possible anymore. So we need to hack in a ungly CSS to force the * body to be at least 150px. If the user clicks the HTML element out side this 150px region * we simply move the focus into the first paragraph. Not ideal since you loose the - * positioning of the caret but goot enough for most cases. + * positioning of the caret but good enough for most cases. */ function bodyHeight() { if (!editor.inline) { @@ -1759,11 +1759,11 @@ define("tinymce/util/Quirks", [ } if (Env.ie >= 11) { - bodyHeight(); disableBackspaceIntoATable(); } if (Env.ie) { + bodyHeight(); selectAll(); disableAutoUrlDetect(); ieInternalDragAndDrop(); From caf7bfce3225088301f49bd80db36be83d45037a Mon Sep 17 00:00:00 2001 From: Davit Barbakadze Date: Tue, 8 Aug 2017 08:05:26 +0400 Subject: [PATCH 23/26] TINY-1160: let the HTML tag occupy whole editable area and show text cursor (instead of the default one) --- js/tinymce/skins/lightgray/Content.less | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/js/tinymce/skins/lightgray/Content.less b/js/tinymce/skins/lightgray/Content.less index 17aab6dbebd..de39a3d12f8 100644 --- a/js/tinymce/skins/lightgray/Content.less +++ b/js/tinymce/skins/lightgray/Content.less @@ -3,6 +3,11 @@ @font-family: Verdana, Arial, Helvetica, sans-serif; @font-size: 14px; +html { + height: 100%; + cursor: text; +} + body { background-color: #FFFFFF; color: #000000; From a5a6098a7bd71fea50631ddbbeeca204705449c2 Mon Sep 17 00:00:00 2001 From: Mattias Wikstrom Date: Mon, 2 Oct 2017 13:45:47 +0200 Subject: [PATCH 24/26] TINY-1185: backport "fix" for edge paste bug --- js/tinymce/plugins/paste/classes/Clipboard.js | 8 ++++++-- js/tinymce/plugins/paste/classes/Utils.js | 7 ++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/js/tinymce/plugins/paste/classes/Clipboard.js b/js/tinymce/plugins/paste/classes/Clipboard.js index c41f2c8e3ed..6320433c70b 100644 --- a/js/tinymce/plugins/paste/classes/Clipboard.js +++ b/js/tinymce/plugins/paste/classes/Clipboard.js @@ -31,10 +31,11 @@ define("tinymce/pasteplugin/Clipboard", [ "tinymce/Env", "tinymce/dom/RangeUtils", "tinymce/util/VK", + "tinymce/util/Tools", "tinymce/pasteplugin/Utils", "tinymce/pasteplugin/SmartPaste", "tinymce/util/Delay" -], function(Env, RangeUtils, VK, Utils, SmartPaste, Delay) { +], function(Env, RangeUtils, VK, Tools, Utils, SmartPaste, Delay) { return function(editor) { var self = this, pasteBinElm, lastRng, keyboardPasteTimeStamp = 0, draggingInternally = false; var pasteBinDefaultContent = '%MCEPASTEBIN%', keyboardPastePlainTextState; @@ -321,7 +322,10 @@ define("tinymce/pasteplugin/Clipboard", [ * @return {Object} Object with mime types and data for those mime types. */ function getClipboardContent(clipboardEvent) { - return getDataTransferItems(clipboardEvent.clipboardData || editor.getDoc().dataTransfer); + var content = getDataTransferItems(clipboardEvent.clipboardData || editor.getDoc().dataTransfer); + + // Edge 15 has a broken HTML Clipboard API see https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/11877517/ + return Utils.isMsEdge() ? Tools.extend(content, {'text/html': ''}) : content; } function hasHtmlOrText(content) { diff --git a/js/tinymce/plugins/paste/classes/Utils.js b/js/tinymce/plugins/paste/classes/Utils.js index 2d0233dfa98..caefcc4dde3 100644 --- a/js/tinymce/plugins/paste/classes/Utils.js +++ b/js/tinymce/plugins/paste/classes/Utils.js @@ -146,10 +146,15 @@ define("tinymce/pasteplugin/Utils", [ }; } + var isMsEdge = function () { + return navigator.userAgent.indexOf(' Edge/') !== -1; + }; + return { filter: filter, innerText: innerText, trimHtml: trimHtml, - createIdGenerator: createIdGenerator + createIdGenerator: createIdGenerator, + isMsEdge: isMsEdge }; }); From f3129f22ecb1253902f4b56009a0fda907456e91 Mon Sep 17 00:00:00 2001 From: Spocke Date: Thu, 5 Oct 2017 10:21:43 +0200 Subject: [PATCH 25/26] TINY-1287: updated changelog and bumped version --- changelog.txt | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index c316222fe8a..89791043cc9 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,7 @@ +Version 4.5.8 (2017-10-05) + Fixed bug where paste on Edge wouldn't paste UTF characters since Microsoft didn't implement the html5 clipboard api correctly. + Fixed bug where it was hard to focus the editor on IE 10 since the body element didn't have full height. + Fixed bug where malformed blob urls wouldn't be handled correctly by the editor. Version 4.5.7 (2017-04-25) Fixed bug with selection around inline contenteditable false would get collapsed incorrectly. Fixed bug where pasting on Microsoft Edge 40+ would produce clipboard fragment headers. diff --git a/package.json b/package.json index 0ad288b45f7..30d76df91e7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tinymce", - "version": "4.5.7", + "version": "4.5.8", "repository": { "type": "git", "url": "https://github.com/tinymce/tinymce.git" From f81d69084d334037b781cc528218e45ea1de48df Mon Sep 17 00:00:00 2001 From: Spocke Date: Thu, 5 Oct 2017 10:31:34 +0200 Subject: [PATCH 26/26] TINY-1287: fixed whitespace issue --- changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index 89791043cc9..70a4c754cf5 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,7 +1,7 @@ Version 4.5.8 (2017-10-05) Fixed bug where paste on Edge wouldn't paste UTF characters since Microsoft didn't implement the html5 clipboard api correctly. Fixed bug where it was hard to focus the editor on IE 10 since the body element didn't have full height. - Fixed bug where malformed blob urls wouldn't be handled correctly by the editor. + Fixed bug where malformed blob urls wouldn't be handled correctly by the editor. Version 4.5.7 (2017-04-25) Fixed bug with selection around inline contenteditable false would get collapsed incorrectly. Fixed bug where pasting on Microsoft Edge 40+ would produce clipboard fragment headers.