Fixes #36254.

git-svn-id: https://develop.svn.wordpress.org/trunk@37000 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Andrew Ozz 2016-03-15 21:37:22 +00:00
parent 6bc7b7c066
commit 22e01b6274
17 changed files with 900 additions and 604 deletions

View File

@ -433,9 +433,9 @@ tinymce.PluginManager.add('lists', function(editor) {
return true;
}
if (sibling && sibling.nodeName == 'LI' && isListNode(li.lastChild)) {
/*if (sibling && sibling.nodeName == 'LI' && isListNode(li.lastChild)) {
return false;
}
}*/
sibling = li.previousSibling;
if (sibling && sibling.nodeName == 'LI') {
@ -695,11 +695,15 @@ tinymce.PluginManager.add('lists', function(editor) {
}
nonEmptyBlocks = editor.schema.getNonEmptyElements();
walker = new tinymce.dom.TreeWalker(rng.startContainer, editor.getBody());
if (node.nodeType == 1) {
node = tinymce.dom.RangeUtils.getNode(node, offset);
}
walker = new tinymce.dom.TreeWalker(node, editor.getBody());
// Delete at <li>|<br></li> then jump over the bogus br
if (isForward) {
if (isBogusBr(tinymce.dom.RangeUtils.getNode(rng.startContainer, rng.startOffset))) {
if (isBogusBr(node)) {
walker.next();
}
}

File diff suppressed because one or more lines are too long

View File

@ -797,14 +797,14 @@ tinymce.ThemeManager.add('modern', function(editor) {
]});
}
if (settings.readonly) {
panel.find('*').disabled(true);
}
editor.fire('BeforeRenderUI');
editor.on('SwitchMode', switchMode());
panel.renderBefore(args.targetNode).reflow();
if (settings.readonly) {
editor.setMode('readonly');
}
if (settings.width) {
tinymce.DOM.setStyle(panel.getEl(), 'width', settings.width);
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -18,7 +18,7 @@ $wp_db_version = 36686;
*
* @global string $tinymce_version
*/
$tinymce_version = '4307-20160302';
$tinymce_version = '4308-20160315';
/**
* Holds the required PHP version

View File

@ -1475,6 +1475,36 @@ ModuleLoader.require([
);
});
test('Indent second second li with next sibling to nested li', function() {
editor.getBody().innerHTML = trimBrs(
'<ul>' +
'<li>a</li>' +
'<li>b' +
'<ul>' +
'<li>c</li>' +
'</ul>' +
'</li>' +
'<li>d</li>' +
'</ul>'
);
editor.focus();
Utils.setSelection('ul > li:nth-child(2)', 1);
execCommand('Indent');
equal(editor.getContent(),
'<ul>' +
'<li>a' +
'<ul>' +
'<li>b</li>' +
'<li>c</li>' +
'</ul>' +
'</li>' +
'<li>d</li>' +
'</ul>'
);
});
// Backspace
test('Backspace at beginning of single LI in UL', function() {
@ -2076,6 +2106,23 @@ ModuleLoader.require([
equal(editor.selection.getNode().nodeName, 'LI');
});
test('Delete at BR before text in LI', function() {
editor.getBody().innerHTML = (
'<ul>' +
'<li>1</li>' +
'<li>2<br></li>' +
'<li>3</li>' +
'</ul>'
);
editor.focus();
editor.selection.setCursorLocation(editor.$('li')[1], 1);
editor.plugins.lists.backspaceDelete(false);
equal(editor.getContent(), '<ul><li>1</li><li>2</li><li>3</li></ul>');
equal(editor.selection.getNode().nodeName, 'LI');
});
test('Remove UL in inline body element contained in LI', function() {
inlineEditor.setContent('<ul><li>a</li></ul>');
inlineEditor.selection.setCursorLocation();

View File

@ -547,7 +547,7 @@ test('paste data image with paste_data_images: true', function() {
editor.setContent('');
editor.execCommand('mceInsertClipboardContent', false, {content: '<img src="data:image/gif;base64,R0lGODlhAQABAPAAAP8REf///yH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==">'});
equal(editor.getContent(), '<p><img src="data:image/gif;base64,R0lGODlhAQABAPAAAP8REf///yH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="" /></p>');
equal(editor.getContent(), '<p><img src="data:image/gif;base64,R0lGODlhAQABAPAAAP8REf///yH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" /></p>');
});
test('paste pre process text (event)', function() {

View File

@ -60,6 +60,32 @@ test('mceInsertContent before HR', function() {
equal(getContent(), '<p>x</p><hr />');
});
test('mceInsertContent HR at end of H1', function() {
editor.setContent('<h1>abc</h1>');
Utils.setSelection('h1', 3);
editor.execCommand('mceInsertContent', false, '<hr>');
equal(editor.selection.getNode(), editor.getBody().lastChild);
equal(editor.selection.getNode().nodeName, 'H1');
equal(getContent(), '<h1>abc</h1><hr /><h1>\u00a0</h1>');
});
test('mceInsertContent HR at end of H1 with P sibling', function() {
editor.setContent('<h1>abc</h1><p>def</p>');
Utils.setSelection('h1', 3);
editor.execCommand('mceInsertContent', false, '<hr>');
equal(editor.selection.getNode(), editor.getBody().lastChild);
equal(editor.selection.getNode().nodeName, 'P');
equal(getContent(), '<h1>abc</h1><hr /><p>def</p>');
});
test('mceInsertContent HR at end of H1 with P sibling', function() {
editor.setContent('<h1>abc</h1><p>def</p>');
Utils.setSelection('h1', 3);
editor.execCommand('mceInsertContent', false, '<table><tr><td></td></tr></table>');
equal(editor.selection.getNode().nodeName, 'TD');
equal(getContent(), '<h1>abc</h1><table><tbody><tr><td>\u00a0</td></tr></tbody></table><p>def</p>');
});
test('mceInsertContent - p inside whole p', function() {
var rng;
@ -211,7 +237,7 @@ test('mceInsertContent - image inside p', function() {
rng.setEnd(editor.dom.select('p')[0].firstChild, 1);
editor.selection.setRng(rng);
editor.execCommand('mceInsertContent', false, '<img src="about:blank" />');
equal(editor.getContent(), '<p><img src="about:blank" alt="" /></p>');
equal(editor.getContent(), '<p><img src="about:blank" /></p>');
rng = Utils.normalizeRng(editor.selection.getRng(true));
ok(rng.collapsed);
equal(rng.startContainer.nodeName, 'P');
@ -418,12 +444,12 @@ test('Formatting commands (xhtmlTextStyles)', function() {
editor.setContent('test 123');
editor.execCommand('SelectAll');
editor.execCommand('FontName',false,'Arial');
editor.execCommand('FontName', false, 'Arial');
equal(editor.getContent(), '<p><span style="font-family: ' + Utils.fontFace('Arial') + ';">test 123</span></p>');
editor.setContent('test 123');
editor.execCommand('SelectAll');
editor.execCommand('FontSize',false,'7');
editor.execCommand('FontSize', false, '7');
equal(editor.getContent(), '<p><span style="font-size: xx-large;">test 123</span></p>');
editor.setContent('test 123');
@ -493,17 +519,17 @@ test('Formatting commands (alignInline)', function() {
editor.setContent('<img src="tinymce/ui/img/raster.gif" />');
editor.selection.select(editor.dom.select('img')[0]);
editor.execCommand('JustifyLeft');
equal(editor.getContent(), '<p><img style="float: left;" src="tinymce/ui/img/raster.gif" alt="" /></p>');
equal(editor.getContent(), '<p><img style="float: left;" src="tinymce/ui/img/raster.gif" /></p>');
editor.setContent('<img src="tinymce/ui/img/raster.gif" />');
editor.selection.select(editor.dom.select('img')[0]);
editor.execCommand('JustifyCenter');
equal(editor.getContent(), '<p><img style="margin-right: auto; margin-left: auto; display: block;" src="tinymce/ui/img/raster.gif" alt="" /></p>');
equal(editor.getContent(), '<p><img style="margin-right: auto; margin-left: auto; display: block;" src="tinymce/ui/img/raster.gif" /></p>');
editor.setContent('<img src="tinymce/ui/img/raster.gif" />');
editor.selection.select(editor.dom.select('img')[0]);
editor.execCommand('JustifyRight');
equal(editor.getContent(), '<p><img style="float: right;" src="tinymce/ui/img/raster.gif" alt="" /></p>');
equal(editor.getContent(), '<p><img style="float: right;" src="tinymce/ui/img/raster.gif" /></p>');
});
test('mceBlockQuote', function() {
@ -619,7 +645,7 @@ test('mceInsertLink (link floated img)', function() {
editor.setContent('<p><img style="float: right;" src="about:blank" /></p>');
editor.execCommand('SelectAll');
editor.execCommand('mceInsertLink', false, 'link');
equal(editor.getContent(), '<p><a href="link"><img style="float: right;" src="about:blank" alt="" /></a></p>');
equal(editor.getContent(), '<p><a href="link"><img style="float: right;" src="about:blank" /></a></p>');
});
test('mceInsertLink (link adjacent text)', function() {
@ -797,5 +823,5 @@ test('InsertLineBreak', function() {
editor.setContent('<p>123</p>');
Utils.setSelection('p', 3);
editor.execCommand('InsertLineBreak');
equal(Utils.cleanHtml(editor.getBody().innerHTML), (tinymce.isIE && tinymce.Env.ie < 11) ? '<p>123<br></p>': '<p>123<br><br></p>');
equal(Utils.cleanHtml(editor.getBody().innerHTML), (tinymce.isIE && tinymce.Env.ie < 11) ? '<p>123<br></p>' : '<p>123<br><br></p>');
});

View File

@ -106,15 +106,37 @@ test('overrideDefaults', function() {
tinymce.overrideDefaults({
test: 42,
base_url: "http://www.tinymce.com/base/",
suffix: "x"
suffix: "x",
external_plugins: {
"plugina": "//domain/plugina.js",
"pluginb": "//domain/pluginb.js"
}
});
strictEqual(tinymce.baseURI.path, "/base");
strictEqual(tinymce.baseURL, "http://www.tinymce.com/base");
strictEqual(tinymce.suffix, "x");
strictEqual(new tinymce.Editor('ed', {}, tinymce).settings.test, 42);
strictEqual(new tinymce.Editor('ed1', {}, tinymce).settings.test, 42);
deepEqual(new tinymce.Editor('ed2', {
external_plugins: {
"plugina": "//domain/plugina2.js",
"pluginc": "//domain/pluginc.js"
}
}, tinymce).settings.external_plugins, {
"plugina": "//domain/plugina2.js",
"pluginb": "//domain/pluginb.js",
"pluginc": "//domain/pluginc.js"
});
deepEqual(new tinymce.Editor('ed3', {}, tinymce).settings.external_plugins, {
"plugina": "//domain/plugina.js",
"pluginb": "//domain/pluginb.js"
});
tinymce.baseURI = oldBaseURI;
tinymce.baseURL = oldBaseUrl;
tinymce.suffix = oldSuffix;
});
tinymce.overrideDefaults({});
});

View File

@ -66,8 +66,8 @@ ModuleLoader.require([
var blobInfo = result[0].blobInfo;
QUnit.equal("data:" + blobInfo.blob().type + ";base64," + blobInfo.base64(), testBlobDataUri);
QUnit.equal(Utils.normalizeHtml(editor.getBody().innerHTML), '<p><img alt="" src="' + blobInfo.blobUri() + '" /></p>');
QUnit.equal('<p><img src="data:' + blobInfo.blob().type + ';base64,' + blobInfo.base64() + '" alt="" /></p>', editor.getContent());
QUnit.equal(Utils.normalizeHtml(editor.getBody().innerHTML), '<p><img src="' + blobInfo.blobUri() + '" /></p>');
QUnit.equal('<p><img src="data:' + blobInfo.blob().type + ';base64,' + blobInfo.base64() + '" /></p>', editor.getContent());
QUnit.strictEqual(editor.editorUpload.blobCache.get(blobInfo.id()), blobInfo);
}).then(QUnit.start);
});
@ -78,7 +78,7 @@ ModuleLoader.require([
function assertResult(result) {
QUnit.strictEqual(result[0].status, true);
QUnit.ok(result[0].element.src.indexOf(uploadedBlobInfo.id() + '.png') !== -1);
QUnit.equal('<p><img src="' + uploadedBlobInfo.filename() + '" alt="" /></p>', editor.getContent());
QUnit.equal('<p><img src="' + uploadedBlobInfo.filename() + '" /></p>', editor.getContent());
return result;
}
@ -185,6 +185,6 @@ ModuleLoader.require([
test('Retain blobs not in blob cache', function() {
editor.getBody().innerHTML = '<img src="blob:http%3A//host/f8d1e462-8646-485f-87c5-f9bcee5873c6">';
QUnit.equal('<p><img src="blob:http%3A//host/f8d1e462-8646-485f-87c5-f9bcee5873c6" alt="" /></p>', editor.getContent());
QUnit.equal('<p><img src="blob:http%3A//host/f8d1e462-8646-485f-87c5-f9bcee5873c6" /></p>', editor.getContent());
});
});

View File

@ -57,45 +57,45 @@ test('Enter before text after EM', function() {
});
test('Enter before first IMG in P', function() {
editor.setContent('<p><img alt="" src="about:blank" /></p>');
editor.setContent('<p><img src="about:blank" /></p>');
editor.selection.setCursorLocation(editor.getBody().firstChild, 0);
Utils.pressEnter();
equal(editor.getContent(), '<p>\u00a0</p><p><img src="about:blank" alt="" /></p>');
equal(editor.getContent(), '<p>\u00a0</p><p><img src="about:blank" /></p>');
});
test('Enter before first wrapped IMG in P', function() {
editor.setContent('<p><b><img alt="" src="about:blank" /></b></p>');
editor.setContent('<p><b><img src="about:blank" /></b></p>');
editor.selection.setCursorLocation(editor.getBody().firstChild.firstChild, 0);
Utils.pressEnter();
equal(editor.getBody().firstChild.innerHTML, (tinymce.isIE && tinymce.Env.ie < 11) ? '' : '<br data-mce-bogus="1">');
equal(editor.getContent(), '<p>\u00a0</p><p><b><img src=\"about:blank\" alt=\"\" /></b></p>');
equal(editor.getContent(), '<p>\u00a0</p><p><b><img src="about:blank" /></b></p>');
});
test('Enter before last IMG in P with text', function() {
editor.setContent('<p>abc<img alt="" src="about:blank" /></p>');
editor.setContent('<p>abc<img src="about:blank" /></p>');
editor.selection.setCursorLocation(editor.getBody().firstChild, 1);
Utils.pressEnter();
equal(editor.getContent(), '<p>abc</p><p><img src="about:blank" alt="" /></p>');
equal(editor.getContent(), '<p>abc</p><p><img src="about:blank" /></p>');
var rng = editor.selection.getRng(true);
equal(rng.startContainer.nodeName, 'P');
equal(rng.startContainer.childNodes[rng.startOffset].nodeName, 'IMG');
});
test('Enter before last IMG in P with IMG sibling', function() {
editor.setContent('<p><img src="about:blank" alt="" /><img src="about:blank" alt="" /></p>');
editor.setContent('<p><img src="about:blank" /><img src="about:blank" /></p>');
editor.selection.setCursorLocation(editor.getBody().firstChild, 1);
Utils.pressEnter();
equal(editor.getContent(), '<p><img src="about:blank" alt="" /></p><p><img src="about:blank" alt="" /></p>');
equal(editor.getContent(), '<p><img src="about:blank" /></p><p><img src="about:blank" /></p>');
var rng = editor.selection.getRng(true);
equal(rng.startContainer.nodeName, 'P');
equal(rng.startContainer.childNodes[rng.startOffset].nodeName, 'IMG');
});
test('Enter after last IMG in P', function() {
editor.setContent('<p>abc<img alt="" src="about:blank" /></p>');
editor.setContent('<p>abc<img src="about:blank" /></p>');
editor.selection.setCursorLocation(editor.getBody().firstChild, 2);
Utils.pressEnter();
equal(editor.getContent(), '<p>abc<img src="about:blank" alt="" /></p><p>\u00a0</p>');
equal(editor.getContent(), '<p>abc<img src="about:blank" /></p><p>\u00a0</p>');
});
test('Enter before last INPUT in P with text', function() {

View File

@ -15,7 +15,7 @@ module("tinymce.Formatter - Apply", {
disable_nodechange: true,
entities: 'raw',
valid_styles: {
'*': 'color,font-size,font-family,background-color,font-weight,font-style,text-decoration,float,margin,margin-top,margin-right,margin-bottom,margin-left,display'
'*': 'color,font-size,font-family,background-color,font-weight,font-style,text-decoration,float,margin,margin-top,margin-right,margin-bottom,margin-left,display,text-align'
},
init_instance_callback: function(ed) {
window.editor = ed;
@ -36,7 +36,7 @@ module("tinymce.Formatter - Apply", {
disable_nodechange: true,
entities: 'raw',
valid_styles: {
'*': 'color,font-size,font-family,background-color,font-weight,font-style,text-decoration,float,margin,margin-top,margin-right,margin-bottom,margin-left,display'
'*': 'color,font-size,font-family,background-color,font-weight,font-style,text-decoration,float,margin,margin-top,margin-right,margin-bottom,margin-left,display,text-align'
},
init_instance_callback: function(ed) {
window.inlineEditor = ed;
@ -1535,6 +1535,56 @@ test('Align specified table element with collapsed: false and selection collapse
equal(getContent(), '<table style="float: right;"><tbody><tr><td>a</td></tr></tbody></table>');
});
test('Align nested table cell to same as parent', function() {
editor.setContent(
'<table>' +
'<tbody>' +
'<tr>' +
'<td style="text-align: right;">a' +
'<table>' +
'<tbody>' +
'<tr>' +
'<td><b>b</b></td>' +
'</tr>' +
'</tbody>' +
'</table>' +
'</td>' +
'</tr>' +
'</tbody>' +
'</table>'
);
Utils.setSelection('b', 0);
editor.formatter.register('format', {
selector: 'td',
styles: {
'text-align': 'right'
}
});
editor.formatter.apply('format', {}, editor.$('td td')[0]);
equal(
getContent(),
'<table>' +
'<tbody>' +
'<tr>' +
'<td style="text-align: right;">a' +
'<table>' +
'<tbody>' +
'<tr>' +
'<td style="text-align: right;"><b>b</b></td>' +
'</tr>' +
'</tbody>' +
'</table>' +
'</td>' +
'</tr>' +
'</tbody>' +
'</table>'
);
});
test('Apply ID format to around existing bookmark node', function() {
editor.getBody().innerHTML = '<p>a<span id="b" data-mce-type="bookmark"></span>b</p>';
@ -1640,4 +1690,19 @@ asyncTest('Bug #7412 - valid_styles affects the Bold and Italic buttons, althoug
equal(getContent(), '<p>1 <strong><span style="text-decoration: underline;">1234</span></strong> 1</p>');
}
});
});
});
test('Format selection from with end at beginning of block', function(){
editor.setContent("<div id='a'>one</div><div id='b'>two</div>");
editor.focus();
Utils.setSelection('#a', 0, '#b', 0);
editor.execCommand('formatBlock', false, 'h1');
equal(getContent(), '<h1 id="a">one</h1>\n<div id="b">two</div>');
});
test('Format selection over fragments', function(){
editor.setContent("<strong>a</strong>bc<em>d</em>");
Utils.setSelection('strong', 1, 'em', 0);
editor.formatter.apply('underline');
equal(getContent(), '<p><strong>a</strong><span style="text-decoration: underline;">bc</span><em>d</em></p>');
});

View File

@ -44,7 +44,7 @@ test('Schema rules', function() {
ser = new tinymce.dom.Serializer({invalid_elements : 'hr,br'});
DOM.setHTML('test', '<img src="tinymce/ui/img/raster.gif" data-mce-src="tinymce/ui/img/raster.gif" /><hr /><br />');
equal(ser.serialize(DOM.get('test')), '<div id="test"><img src="tinymce/ui/img/raster.gif" alt="" /></div>');
equal(ser.serialize(DOM.get('test')), '<div id="test"><img src="tinymce/ui/img/raster.gif" /></div>');
});
test('Entity encoding', function() {

View File

@ -76,7 +76,7 @@
parser = new tinymce.html.DomParser({}, new tinymce.html.Schema({invalid_elements : 'hr,br'}));
root = parser.parse('\n<hr />\n<br />\n<div>\n<hr />\n<br />\n<img src="file.gif" data-mce-src="file.gif" />\n<hr />\n<br />\n</div>\n<hr />\n<br />\n');
equal(serializer.serialize(root), '<div><img src="file.gif" data-mce-src="file.gif" alt="" /></div>', 'Whitespace where SaxParser will produce multiple whitespace nodes');
equal(serializer.serialize(root), '<div><img src="file.gif" data-mce-src="file.gif" /></div>', 'Whitespace where SaxParser will produce multiple whitespace nodes');
deepEqual(countNodes(root), {body:1, div:1, img:1}, 'Whitespace where SaxParser will produce multiple whitespace nodes (count)');
});

View File

@ -6,7 +6,7 @@ test('Basic serialization', function() {
expect(6);
equal(serializer.serialize(new tinymce.html.DomParser().parse('text<text&')), 'text&lt;text&amp;');
equal(serializer.serialize(new tinymce.html.DomParser().parse('<B>text</B><IMG src="1.gif">')), '<strong>text</strong><img src="1.gif" alt="" />');
equal(serializer.serialize(new tinymce.html.DomParser().parse('<B>text</B><IMG src="1.gif">')), '<strong>text</strong><img src="1.gif" />');
equal(serializer.serialize(new tinymce.html.DomParser().parse('<!-- comment -->')), '<!-- comment -->');
equal(serializer.serialize(new tinymce.html.DomParser().parse('<![CDATA[cdata]]>')), '<![CDATA[cdata]]>');
equal(serializer.serialize(new tinymce.html.DomParser().parse('<?xml attr="value" ?>')), '<?xml attr="value" ?>');