Skip to content

Commit

Permalink
fix selection after mousedown if contenteditable div contains only on…
Browse files Browse the repository at this point in the history
…e new line char (#2365) (#2426)

* fix selection after mousedown if contenteditable div contains only one new line char (#2365)

* remove confusing function
  • Loading branch information
AlexKamaev authored May 28, 2018
1 parent 9c08371 commit 8274923
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 12 deletions.
46 changes: 36 additions & 10 deletions src/client/core/utils/content-editable.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,24 +110,25 @@ function isNodeAfterNodeBlockWithBreakLine (parent, node) {
return false;
}

export function getFirstVisibleTextNode (el) {
function getFirstTextNode (el, onlyVisible) {
var children = el.childNodes;
var childrenLength = domUtils.getChildNodesLength(children);
var curNode = null;
var child = null;
var isNotContentEditableElement = null;
var checkTextNode = onlyVisible ? isVisibleTextNode : domUtils.isTextNode;

if (!childrenLength && isVisibleTextNode(el))
if (!childrenLength && checkTextNode(el))
return el;

for (var i = 0; i < childrenLength; i++) {
curNode = children[i];
isNotContentEditableElement = domUtils.isElementNode(curNode) && !domUtils.isContentEditableElement(curNode);

if (isVisibleTextNode(curNode))
if (checkTextNode(curNode))
return curNode;
else if (domUtils.isRenderedNode(curNode) && hasVisibleChildren(curNode) && !isNotContentEditableElement) {
child = getFirstVisibleTextNode(curNode);
child = getFirstTextNode(curNode, onlyVisible);

if (child)
return child;
Expand All @@ -137,6 +138,10 @@ export function getFirstVisibleTextNode (el) {
return child;
}

export function getFirstVisibleTextNode (el) {
return getFirstTextNode(el, true);
}

export function getLastTextNode (el, onlyVisible) {
var children = el.childNodes;
var childrenLength = domUtils.getChildNodesLength(children);
Expand Down Expand Up @@ -533,16 +538,37 @@ export function getFirstVisiblePosition (el) {

export function getLastVisiblePosition (el) {
var lastVisibleTextChild = domUtils.isTextNode(el) ? el : getLastTextNode(el, true);
var curDocument = domUtils.findDocument(el);
var range = curDocument.createRange();

if (lastVisibleTextChild) {
range.selectNodeContents(lastVisibleTextChild);
if (!lastVisibleTextChild || isResetAnchorOffsetRequired(lastVisibleTextChild, el))
return 0;

var curDocument = domUtils.findDocument(el);
var range = curDocument.createRange();

return calculatePositionByNodeAndOffset(el, { node: lastVisibleTextChild, offset: range.endOffset });
range.selectNodeContents(lastVisibleTextChild);

return calculatePositionByNodeAndOffset(el, { node: lastVisibleTextChild, offset: range.endOffset });
}

function isResetAnchorOffsetRequired (lastVisibleTextChild, el) {
const firstVisibleTextChild = domUtils.isTextNode(el) ? el : getFirstTextNode(el, false);
const isSingleTextNode = lastVisibleTextChild === firstVisibleTextChild;
const isNewLineChar = lastVisibleTextChild.nodeValue === String.fromCharCode(10);

return isSingleTextNode && isNewLineChar && hasWhiteSpacePreStyle(lastVisibleTextChild, el);
}

function hasWhiteSpacePreStyle (el, container) {
const whiteSpacePreStyles = ['pre', 'pre-wrap', 'pre-line'];

while (el !== container) {
el = el.parentNode;

if (arrayUtils.indexOf(whiteSpacePreStyles, styleUtils.get(el, 'white-space')) > -1)
return true;
}

return 0;
return false;
}

function getContentEditableNodes (target) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
var hammerhead = window.getTestCafeModule('hammerhead');
var browserUtils = hammerhead.utils.browser;

var testCafeCore = window.getTestCafeModule('testCafeCore');
var domUtils = testCafeCore.get('./utils/dom');
var testCafeCore = window.getTestCafeModule('testCafeCore');
var domUtils = testCafeCore.get('./utils/dom');

var testCafeAutomation = window.getTestCafeModule('testCafeAutomation');
var TypeOptions = testCafeAutomation.get('../../test-run/commands/options').TypeOptions;
Expand Down Expand Up @@ -142,4 +142,48 @@ $(document).ready(function () {
});
});
}

asyncTest('selection after mousedown should ignore single new line character', function () {

function testWithWhiteSpaceStyle (whiteSpace) {
var editor = document.createElement('div');
var span = document.createElement('span');
var type = new TypeAutomation(editor, 'Hello World', {});

editor.className = TEST_ELEMENT_CLASS;
editor.style.whiteSpace = whiteSpace;
editor.contentEditable = true;
span.innerHTML = String.fromCharCode(10);

editor.appendChild(span);
document.body.appendChild(editor);

var onSelectionChange = function () {
equal(document.getSelection().anchorOffset, 0);
document.removeEventListener('selectionchange', onSelectionChange, true);
};

document.addEventListener('selectionchange', onSelectionChange, true);

return type
.run()
.then(function () {
equal(editor.textContent, 'Hello' + String.fromCharCode(160) + 'World\n', 'white-space: ' + whiteSpace);
removeTestElements();
document.getSelection().removeAllRanges();
return;
});
}

testWithWhiteSpaceStyle('pre')
.then(function () {
return testWithWhiteSpaceStyle('pre-wrap');
})
.then(function () {
return testWithWhiteSpaceStyle('pre-line');
})
.then(function () {
startNext();
});
});
});

0 comments on commit 8274923

Please sign in to comment.