-
Notifications
You must be signed in to change notification settings - Fork 675
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix selection after mousedown if contenteditable div contains only one new line char (#2365) #2426
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -110,24 +110,24 @@ 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; | ||
|
||
if (!childrenLength && isVisibleTextNode(el)) | ||
if (!childrenLength && checkTextNodeVisibility(el, onlyVisible)) | ||
return el; | ||
|
||
for (var i = 0; i < childrenLength; i++) { | ||
curNode = children[i]; | ||
isNotContentEditableElement = domUtils.isElementNode(curNode) && !domUtils.isContentEditableElement(curNode); | ||
|
||
if (isVisibleTextNode(curNode)) | ||
if (checkTextNodeVisibility(curNode, onlyVisible)) | ||
return curNode; | ||
else if (domUtils.isRenderedNode(curNode) && hasVisibleChildren(curNode) && !isNotContentEditableElement) { | ||
child = getFirstVisibleTextNode(curNode); | ||
child = getFirstTextNode(curNode, onlyVisible); | ||
|
||
if (child) | ||
return child; | ||
|
@@ -137,6 +137,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); | ||
|
@@ -210,8 +214,15 @@ export function isInvisibleTextNode (node) { | |
return firstVisibleIndex === nodeValue.length && lastVisibleIndex === 0; | ||
} | ||
|
||
function checkTextNodeVisibility (node, onlyVisible) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For me it seems little awkward that method named |
||
if (!domUtils.isTextNode(node)) | ||
return false; | ||
|
||
return !onlyVisible || !isInvisibleTextNode(node); | ||
} | ||
|
||
function isVisibleTextNode (node) { | ||
return domUtils.isTextNode(node) && !isInvisibleTextNode(node); | ||
return checkTextNodeVisibility(node, true); | ||
} | ||
|
||
function isSkippableNode (node) { | ||
|
@@ -532,17 +543,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(); | ||
var lastVisibleTextChild = domUtils.isTextNode(el) ? el : getLastTextNode(el, true); | ||
|
||
if (lastVisibleTextChild) { | ||
range.selectNodeContents(lastVisibleTextChild); | ||
if (!lastVisibleTextChild || isResetAnchorOffsetRequired(lastVisibleTextChild, el)) | ||
return 0; | ||
|
||
return calculatePositionByNodeAndOffset(el, { node: lastVisibleTextChild, offset: range.endOffset }); | ||
var curDocument = domUtils.findDocument(el); | ||
var range = curDocument.createRange(); | ||
|
||
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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please add a blank line |
||
if (arrayUtils.indexOf(whiteSpacePreStyles, styleUtils.get(el, 'white-space')) > -1) | ||
return true; | ||
} | ||
|
||
return 0; | ||
return false; | ||
} | ||
|
||
function getContentEditableNodes (target) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we don't need this function anymore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is used in several places.
I think it's more convenient to write
getFirstVisibleTextNode()
instead ofgetFirstTextNode(true)