Skip to content

Commit

Permalink
Merge branch 'master' into 4.12.x
Browse files Browse the repository at this point in the history
  • Loading branch information
nmielnik committed Jun 15, 2015
2 parents 3532d5c + a912cd2 commit f7cfc85
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 3 deletions.
43 changes: 42 additions & 1 deletion spec/selection.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ describe('Selection TestCase', function () {
var exportedSelection = editor.exportSelection();
expect(exportedSelection.emptyBlocksIndex).toEqual(undefined);
});

it('should not export a position indicating the cursor is after an empty paragraph ' +
'(in a complicated markup with selection on the element)', function () {
this.el.innerHTML = '<p><span>www.google.com</span></p><p><br /></p>' +
Expand Down Expand Up @@ -228,7 +229,47 @@ describe('Selection TestCase', function () {
expect(Util.isDescendant(editor.elements[0].querySelector('i'), innerElement, true)).toBe(true, 'nested inline elment inside block element after empty block element');
});

it('should import not import a selection beyond any block elements that have text, even when emptyBlocksIndex indicates it should ', function () {
['br', 'img'].forEach(function (tagName) {
it('should not import a selection into focusing on the element \'' + tagName + '\' that cannot have children', function () {
this.el.innerHTML = '<p>Hello</p><p><' + tagName + ' /></p><p>World<p>';
var editor = this.newMediumEditor('.editor', {
buttons: ['italic', 'underline', 'strikethrough']
});
editor.importSelection({
'start': 5,
'end': 5,
'emptyBlocksIndex': 1
});

var innerElement = window.getSelection().getRangeAt(0).startContainer;
expect(innerElement.nodeName.toLowerCase()).toBe('p', 'focused element nodeName');
expect(innerElement).toBe(window.getSelection().getRangeAt(0).endContainer);
expect(innerElement.previousSibling.nodeName.toLowerCase()).toBe('p', 'previous sibling name');
expect(innerElement.nextSibling.nodeName.toLowerCase()).toBe('p', 'next sibling name');
});
});

it('should not import a selection into focusing on an empty element in a table', function () {
this.el.innerHTML = '<p>Hello</p><table><colgroup><col /></colgroup>' +
'<thead><tr><th>Head</th></tr></thead>' +
'<tbody><tr><td>Body</td></tr></tbody></table><p>World<p>';
var editor = this.newMediumEditor('.editor', {
buttons: ['italic', 'underline', 'strikethrough']
});
editor.importSelection({
'start': 5,
'end': 5,
'emptyBlocksIndex': 1
});

var innerElement = window.getSelection().getRangeAt(0).startContainer;
// The behavior varies from browser to browser for this case, some select TH, some #textNode
expect(Util.isDescendant(editor.elements[0].querySelector('th'), innerElement, true))
.toBe(true, 'expect selection to be of TH or a descendant');
expect(innerElement).toBe(window.getSelection().getRangeAt(0).endContainer);
});

it('should not import a selection beyond any block elements that have text, even when emptyBlocksIndex indicates it should ', function () {
this.el.innerHTML = '<p><span>www.google.com</span></p><h1><br /></h1><h2>Not Empty</h2><p><b><i>Whatever</i></b></p>';
var editor = this.newMediumEditor('.editor', {
buttons: ['italic', 'underline', 'strikethrough']
Expand Down
2 changes: 1 addition & 1 deletion src/js/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -1014,7 +1014,7 @@ function MediumEditor(elements, options) {

// We're selecting a high-level block node, so make sure the cursor gets moved into the deepest
// element at the beginning of the block
range.setStart(Util.getFirstLeafNode(targetNode), 0);
range.setStart(Util.getFirstSelectableLeafNode(targetNode), 0);
range.collapse(true);
}

Expand Down
14 changes: 13 additions & 1 deletion src/js/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -672,10 +672,22 @@ var Util;
});
},

getFirstLeafNode: function (element) {
getFirstSelectableLeafNode: function (element) {
while (element && element.firstChild) {
element = element.firstChild;
}
var emptyElements = ['br', 'col', 'colgroup', 'hr', 'img', 'input', 'source', 'wbr'];
while (emptyElements.indexOf(element.nodeName.toLowerCase()) !== -1) {
// We don't want to set the selection to an element that can't have children, this messes up Gecko.
element = element.parentNode;
}
// Selecting at the beginning of a table doesn't work in PhantomJS.
if (element.nodeName.toLowerCase() === 'table') {
var firstCell = element.querySelector('th, td');
if (firstCell) {
element = firstCell;
}
}
return element;
},

Expand Down

0 comments on commit f7cfc85

Please sign in to comment.