-
Notifications
You must be signed in to change notification settings - Fork 40
T/1002: Introduce Position#getCommonAncestor( otherPosition ) and Range#getCommonAncestor() #1005
Conversation
…etCommonAncestor()` methods for `view` and `model`.
src/model/position.js
Outdated
* of these two positions must be identical. | ||
* | ||
* @param {module:engine/model/position~Position} position The second position. | ||
* @returns {module:engine/model/node~Node|null} Node that contains both positions. |
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.
DocumentFragment is not a node. So the correct notation is Element|DF
.
src/model/position.js
Outdated
return null; | ||
} | ||
|
||
const ancestorsA = this.getAncestors(); |
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 liked the previous implementation more. The one which reused getCommonPath()
. It was shorter and more readable.
Let me guess – you decided to skip it because DF doesn't implement getNodeByPath()
? ;) Why not borrowing it from Element
for DF
?
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.
You are right :D
If it does not a problem, I could do it as you said.
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.
It will make a lot of sense to unify the APIs of Element and DF, so it's definitely good to add this method there.
src/model/range.js
Outdated
@@ -446,6 +446,15 @@ export default class Range { | |||
} | |||
|
|||
/** | |||
* Returns a {@link module:engine/model/node~Node} which is a common ancestor for both positions. | |||
* | |||
* @returns {module:engine/model/node~Node|null} |
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.
Again, wrong type.
src/view/position.js
Outdated
* @returns {module:engine/view/node~Node|null} | ||
*/ | ||
getCommonAncestor( position ) { | ||
const ancestorsA = this.getAncestors(); |
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.
getAncestors()
accept options.includeNode
so will this work in such a case: <p>x{y}z</p>
? For such positions the text node should be returned. And for such <p>[x]</p>
the element.
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.
The second issue – you didn't pass options.parentFirst
too so how can you iterate from i==0
(leafs)? What if one ancestors array is longer than the other?
src/view/position.js
Outdated
* Returns a {@link module:engine/view/node~Node} which is a common ancestor for both positions. | ||
* | ||
* @param {module:engine/view/position~Position} position | ||
* @returns {module:engine/view/node~Node|null} |
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.
In this case it should be DF|Node
because here we can also get text nodes.
@@ -844,4 +844,46 @@ describe( 'Position', () => { | |||
).to.throw( CKEditorError, /model-position-fromjson-no-root/ ); | |||
} ); | |||
} ); | |||
|
|||
describe( 'getCommonAncestor()', () => { |
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.
All tests use the same length of paths.
@@ -519,4 +519,43 @@ describe( 'Position', () => { | |||
document.destroy(); | |||
} ); | |||
} ); | |||
|
|||
describe( 'getCommonAncestor()', () => { |
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.
Here you use positions on the same depts as well.
src/model/position.js
Outdated
|
||
const node = this.root.getNodeByPath( this.getCommonPath( position ) ); | ||
|
||
if ( node.is( 'text' ) ) { |
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 is something I expected from this method's model implementation. But I wonder what other think. Is "text node" a position's ancestor?
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.
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.
Let's add a comment here saying that "Although paths can indicate a text node, text node is not an ancestor of a position."
tests/view/position.js
Outdated
test( fPosition, zPosition, li1 ); | ||
} ); | ||
|
||
it( 'works when one positions is nested deeper than the other', () => { |
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.
"when one position"
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.
or rather "one of the positions"
@@ -519,4 +519,69 @@ describe( 'Position', () => { | |||
document.destroy(); | |||
} ); | |||
} ); | |||
|
|||
describe( 'getCommonAncestor()', () => { |
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.
There's just a single test with positions in text nodes and it uses a 0
offset. Please add more, with better offsets (ones which have a chance to break something).
Suggested merge commit message (convention)
Feature: Introduced
Position#getCommonAncestor( position )
andRange#getCommonAncestor()
methods forview
andmodel
. Closes ckeditor/ckeditor5#4105.