Divec has uploaded a new change for review.
https://gerrit.wikimedia.org/r/222221
Change subject: Single function to apply DOM selections
......................................................................
Single function to apply DOM selections
Also fix reversed selection bug in onCopy
Bug: T104517
Change-Id: I33c8073592341d5b775e2839be0221662705a6df
---
M src/ce/ve.ce.Surface.js
M tests/ce/ve.ce.Surface.test.js
2 files changed, 223 insertions(+), 155 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/VisualEditor/VisualEditor
refs/changes/21/222221/1
diff --git a/src/ce/ve.ce.Surface.js b/src/ce/ve.ce.Surface.js
index c710a02..3a2664f 100644
--- a/src/ce/ve.ce.Surface.js
+++ b/src/ce/ve.ce.Surface.js
@@ -1588,7 +1588,7 @@
* @param {jQuery.Event} e Copy event
*/
ve.ce.Surface.prototype.onCopy = function ( e ) {
- var originalRange,
+ var originalSelection,
clipboardIndex, clipboardItem,
scrollTop, unsafeSelector, range, slice,
selection = this.getModel().getSelection(),
@@ -1668,10 +1668,16 @@
// If direct clipboard editing is not allowed, we must use the
pasteTarget to
// select the data we want to go in the clipboard
+ if ( this.getModel().getSelection() instanceof
ve.dm.LinearSelection ) {
+ // We have a selection in the document; preserve it so
it can restored
+ originalSelection = {
+ anchorNode: this.nativeSelection.anchorNode,
+ anchorOffset: this.nativeSelection.anchorOffset,
+ focusNode: this.nativeSelection.focusNode,
+ focusOffset: this.nativeSelection.focusOffset,
+ isCollapsed: this.nativeSelection.isCollapsed
+ };
- // If we have a range in the document, preserve it so it can
restored
- originalRange = this.getNativeRange();
- if ( originalRange ) {
// Save scroll position before changing focus to
"offscreen" paste target
scrollTop = this.$window.scrollTop();
@@ -1684,11 +1690,10 @@
setTimeout( function () {
// If the range was in $highlights (right-click
copy), don't restore it
- if ( !OO.ui.contains( view.$highlights[0],
originalRange.startContainer, true ) ) {
+ if ( !OO.ui.contains( view.$highlights[0],
originalSelection.focusNode, true ) ) {
// Change focus back
view.$documentNode[0].focus();
- view.nativeSelection.removeAllRanges();
- view.nativeSelection.addRange(
originalRange.cloneRange() );
+ view.showRangeSelection(
originalSelection );
// Restore scroll position
view.$window.scrollTop( scrollTop );
}
@@ -3768,7 +3773,7 @@
};
/**
- * Show selection
+ * Show DM selection
*
* @method
* @param {ve.dm.Selection} selection Selection to show
@@ -3788,80 +3793,141 @@
return;
}
- var endRange, oldRange, $node,
- range = selection.getRange(),
- rangeSelection = this.getRangeSelection( range ),
- nativeRange = this.getElementDocument().createRange();
+ this.showRangeSelection( this.getRangeSelection( selection.getRange() )
);
+};
- nativeRange.setStart( rangeSelection.start.node,
rangeSelection.start.offset );
- if ( rangeSelection.end ) {
- nativeRange.setEnd( rangeSelection.end.node,
rangeSelection.end.offset );
+/**
+ * Show native-selection-like object
+ *
+ * @param {Object} rangeSelection A native-selection-like object
+ * @param {Node} rangeSelection.anchorNode Anchor node to show
+ * @param {number} rangeSelection.anchorOffset Anchor offset to show
+ * @param {Node} rangeSelection.focusNode Focus node to show
+ * @param {number} rangeSelection.focusOffset Focus offset to show
+ * @param {boolean} rangeSelection.isCollapsed Are focus and anchor equal?
+ * @param {boolean} [rangeSelection.isBackwards] Is focus before anchor?
(Calculated if ommitted)
+ */
+ve.ce.Surface.prototype.showRangeSelection = function ( rangeSelection ) {
+ var range = document.createRange(),
+ sel = this.nativeSelection,
+ newSel = rangeSelection,
+ isBackwards = newSel.isBackwards;
+
+ /** Test whether the selection would change.
+ * TODO: this gives false positives, because an apparent change can be
normalized away
+ * by the browser e.g. "abc|<i>def" -> "abc<i>|def" in Chromium.
+ */
+ function isChanged() {
+ return sel.rangeCount === 0 ||
+ newSel.anchorNode !== sel.anchorNode ||
+ newSel.anchorOffset !== sel.anchorOffset ||
+ newSel.focusNode !== sel.focusNode ||
+ newSel.focusOffset !== sel.focusOffset;
}
- if ( rangeSelection.end && rangeSelection.isBackwards &&
this.nativeSelection.extend ) {
- endRange = nativeRange.cloneRange();
- endRange.collapse( false );
- this.nativeSelection.removeAllRanges();
- this.nativeSelection.addRange( endRange );
- try {
- this.nativeSelection.extend(
nativeRange.startContainer, nativeRange.startOffset );
- } catch ( e ) {
- // Firefox sometimes fails when nodes are different,
- // see
https://bugzilla.mozilla.org/show_bug.cgi?id=921444
- this.nativeSelection.addRange( nativeRange );
- }
- } else if ( !(
- this.nativeSelection.rangeCount > 0 &&
- ( oldRange = this.nativeSelection.getRangeAt( 0 ) ) &&
- oldRange.startContainer === nativeRange.startContainer &&
- oldRange.startOffset === nativeRange.startOffset &&
- oldRange.endContainer === nativeRange.endContainer &&
- oldRange.endOffset === nativeRange.endOffset
- ) ) {
- // Genuine selection change: apply it.
- // TODO: this is slightly too zealous, because a cursor
position at a node edge
- // can have more than one (container,offset) representation
- this.nativeSelection.removeAllRanges();
- this.nativeSelection.addRange( nativeRange );
- } else {
- // Not a selection change: don't needlessly reapply the same
selection.
+
+ if ( !isChanged() ) {
return;
}
+ if ( isBackwards === undefined ) {
+ isBackwards = !newSel.isCollapsed && ve.compareDocumentOrder(
+ newSel.focusNode,
+ newSel.focusOffset,
+ newSel.anchorNode,
+ newSel.anchorOffset
+ ) < 0;
+ }
+
+ if ( isBackwards ) {
+ if ( sel.extend ) {
+ range.setStart( newSel.anchorNode, newSel.anchorOffset
);
+ sel.removeAllRanges();
+ sel.addRange( range );
+ try {
+ sel.extend( newSel.focusNode,
newSel.focusOffset );
+ return;
+ } catch ( e ) {
+ // Firefox sometimes fails when nodes are
different
+ // see
https://bugzilla.mozilla.org/show_bug.cgi?id=921444
+ }
+ }
+ // Fallback: Apply the corresponding forward selection
+ newSel = this.flipRangeSelection( newSel );
+ if ( !isChanged() ) {
+ return;
+ }
+ }
+
+ // Forward selection
+ range.setStart( newSel.anchorNode, newSel.anchorOffset );
+ if ( !newSel.isCollapsed ) {
+ range.setEnd( newSel.focusNode, newSel.focusOffset );
+ }
+ sel.removeAllRanges();
+ sel.addRange( range );
+
// Setting a range doesn't give focus in all browsers so make sure this
happens
// Also set focus after range to prevent scrolling to top
- if ( !OO.ui.contains( this.getElementDocument().activeElement,
rangeSelection.start.node, true ) ) {
- $( rangeSelection.start.node ).closest(
'[contenteditable=true]' ).focus();
+ if ( !OO.ui.contains( this.getElementDocument().activeElement,
newSel.focusNode, true ) ) {
+ $( newSel.focusNode ).closest( '[contenteditable=true]'
).focus();
} else {
- $node = $( rangeSelection.start.node ).closest( '*' );
// Scroll the node into view
- OO.ui.Element.static.scrollIntoView( $node.get( 0 ) );
+ OO.ui.Element.static.scrollIntoView(
+ $( newSel.focusNode ).closest( '*' ).get( 0 )
+ );
}
};
/**
- * Get selection for a range.
+ * Get anchor and focus positions for a range.
*
* @method
* @param {ve.Range} range Range to get selection for
- * @returns {Object} Object containing start and end node/offset selections,
and an isBackwards flag.
+ * @returns {Object} The selection
+ * @returns.anchorNode {Node} The anchor node
+ * @returns.anchorOffset {number} The anchor offset
+ * @returns.focusNode {Node} The focus node
+ * @returns.focusOffset {number} The focus offset
+ * @returns.isCollapsed {boolean} True if the focus and anchor are in the same
place
+ * @returns.isBackwards {boolean} True if the focus is before the anchor
*/
ve.ce.Surface.prototype.getRangeSelection = function ( range ) {
- range = new ve.Range(
- this.getNearestCorrectOffset( range.from, -1 ),
- this.getNearestCorrectOffset( range.to, 1 )
- );
+ var anchor, focus;
- if ( !range.isCollapsed() ) {
- return {
- start: this.documentView.getNodeAndOffset( range.start
),
- end: this.documentView.getNodeAndOffset( range.end ),
- isBackwards: range.isBackwards()
- };
- } else {
- return {
- start: this.documentView.getNodeAndOffset( range.start )
- };
+ // Anchor/focus at the nearest correct position in the direction that
grows the selection
+ anchor = this.documentView.getNodeAndOffset(
+ this.getNearestCorrectOffset( range.from, range.isBackwards() ?
1 : -1 )
+ );
+ focus = this.documentView.getNodeAndOffset(
+ this.getNearestCorrectOffset( range.to, range.isBackwards() ?
-1 : 1 )
+ );
+ return {
+ anchorNode: anchor.node,
+ anchorOffset: anchor.offset,
+ focusNode: focus.node,
+ focusOffset: focus.offset,
+ isCollapsed: range.isCollapsed() && ( anchor.node ===
focus.node && anchor.offset === focus.offset ),
+ isBackwards: range.isBackwards()
+ };
+};
+
+/**
+ * Flips the selection if uncollapsed; otherwise returns it unchanged
+ *
+ * @param {Object} rangeSelection native-selection-like object
+ * @returns {Object} The selection with the anchor/focus swapped
+ */
+ve.ce.Surface.prototype.flipRangeSelection = function ( rangeSelection ) {
+ if ( rangeSelection.isCollapsed ) {
+ return rangeSelection;
}
+ return {
+ anchorNode: rangeSelection.focusNode,
+ anchorOffset: rangeSelection.focusOffset,
+ focusNode: rangeSelection.anchorNode,
+ focusOffset: rangeSelection.focusOffset,
+ isCollapsed: false
+ };
};
/**
@@ -3900,10 +3966,12 @@
nativeRange = document.createRange();
rangeSelection = this.getRangeSelection( range );
-
- nativeRange.setStart( rangeSelection.start.node,
rangeSelection.start.offset );
- if ( rangeSelection.end ) {
- nativeRange.setEnd( rangeSelection.end.node,
rangeSelection.end.offset );
+ if ( rangeSelection.isBackwards ) {
+ rangeSelection = this.flipRangeSelection( rangeSelection );
+ }
+ nativeRange.setStart( rangeSelection.anchorNode,
rangeSelection.anchorOffset );
+ if ( !rangeSelection.isCollapsed ) {
+ nativeRange.setEnd( rangeSelection.focusNode,
rangeSelection.focusOffset );
}
return nativeRange;
};
diff --git a/tests/ce/ve.ce.Surface.test.js b/tests/ce/ve.ce.Surface.test.js
index 366912f..9d3b2c1 100644
--- a/tests/ce/ve.ce.Surface.test.js
+++ b/tests/ce/ve.ce.Surface.test.js
@@ -1409,7 +1409,7 @@
} );
QUnit.test( 'getRangeSelection', function ( assert ) {
- var i, j, l, view, selection, expectedNode, internlListNode, node, msg,
+ var i, j, l, view, selection, expectedNode, internalListNode, node, msg,
expect = 0,
cases = [
{
@@ -1425,102 +1425,102 @@
'2<b>n</b>d' +
'</p>',
expected: [
- { startNode: 'Foo', startOffset: 0 },
- { startNode: 'Foo', startOffset: 0 },
- { startNode: 'Foo', startOffset: 1 },
- { startNode: 'Foo', startOffset: 2 },
- { startNode: 'Foo', startOffset: 3 },
+ { anchorNode: 'Foo', anchorOffset: 0 },
+ { anchorNode: 'Foo', anchorOffset: 0 },
+ { anchorNode: 'Foo', anchorOffset: 1 },
+ { anchorNode: 'Foo', anchorOffset: 2 },
+ { anchorNode: 'Foo', anchorOffset: 3 },
null, // Focusable
- { startNode: 'Whee', startOffset: 0 },
- { startNode: 'Whee', startOffset: 1 },
- { startNode: 'Whee', startOffset: 2 },
- { startNode: 'Whee', startOffset: 3 },
- { startNode: 'Whee', startOffset: 4 },
- { startNode: 'Whee', startOffset: 4,
endNode: '2', endOffset: 0 },
- { startNode: '2', startOffset: 0 },
- { startNode: '2', startOffset: 1 },
- { startNode: 'n', startOffset: 1 },
- { startNode: 'd', startOffset: 1 }
+ { anchorNode: 'Whee', anchorOffset: 0 },
+ { anchorNode: 'Whee', anchorOffset: 1 },
+ { anchorNode: 'Whee', anchorOffset: 2 },
+ { anchorNode: 'Whee', anchorOffset: 3 },
+ { anchorNode: 'Whee', anchorOffset: 4 },
+ { anchorNode: 'Whee', anchorOffset: 4,
focusNode: '2', focusOffset: 0 },
+ { anchorNode: '2', anchorOffset: 0 },
+ { anchorNode: '2', anchorOffset: 1 },
+ { anchorNode: 'n', anchorOffset: 1 },
+ { anchorNode: 'd', anchorOffset: 1 }
]
},
{
msg: 'Simple example doc',
html: ve.dm.example.html,
expected: [
- { startNode: 'a', startOffset: 0 },
- { startNode: 'a', startOffset: 0 },
- { startNode: 'a', startOffset: 1 },
- { startNode: 'b', startOffset: 1 },
- { startNode: 'c', startOffset: 1 },
- { startNode: 'c', startOffset: 1,
endNode: 'd', endOffset: 0 },
- { startNode: 'c', startOffset: 1,
endNode: 'd', endOffset: 0 },
- { startNode: 'c', startOffset: 1,
endNode: 'd', endOffset: 0 },
- { startNode: 'c', startOffset: 1,
endNode: 'd', endOffset: 0 },
- { startNode: 'c', startOffset: 1,
endNode: 'd', endOffset: 0 },
+ { anchorNode: 'a', anchorOffset: 0 },
+ { anchorNode: 'a', anchorOffset: 0 },
+ { anchorNode: 'a', anchorOffset: 1 },
+ { anchorNode: 'b', anchorOffset: 1 },
+ { anchorNode: 'c', anchorOffset: 1 },
+ { anchorNode: 'c', anchorOffset: 1,
focusNode: 'd', focusOffset: 0 },
+ { anchorNode: 'c', anchorOffset: 1,
focusNode: 'd', focusOffset: 0 },
+ { anchorNode: 'c', anchorOffset: 1,
focusNode: 'd', focusOffset: 0 },
+ { anchorNode: 'c', anchorOffset: 1,
focusNode: 'd', focusOffset: 0 },
+ { anchorNode: 'c', anchorOffset: 1,
focusNode: 'd', focusOffset: 0 },
// 10
- { startNode: 'd', startOffset: 0 },
- { startNode: 'd', startOffset: 1 },
- { startNode: 'd', startOffset: 1,
endNode: 'e', endOffset: 0 },
- { startNode: 'd', startOffset: 1,
endNode: 'e', endOffset: 0 },
- { startNode: 'd', startOffset: 1,
endNode: 'e', endOffset: 0 },
- { startNode: 'e', startOffset: 0 },
- { startNode: 'e', startOffset: 1 },
- { startNode: 'e', startOffset: 1,
endNode: 'f', endOffset: 0 },
- { startNode: 'e', startOffset: 1,
endNode: 'f', endOffset: 0 },
- { startNode: 'e', startOffset: 1,
endNode: 'f', endOffset: 0 },
+ { anchorNode: 'd', anchorOffset: 0 },
+ { anchorNode: 'd', anchorOffset: 1 },
+ { anchorNode: 'd', anchorOffset: 1,
focusNode: 'e', focusOffset: 0 },
+ { anchorNode: 'd', anchorOffset: 1,
focusNode: 'e', focusOffset: 0 },
+ { anchorNode: 'd', anchorOffset: 1,
focusNode: 'e', focusOffset: 0 },
+ { anchorNode: 'e', anchorOffset: 0 },
+ { anchorNode: 'e', anchorOffset: 1 },
+ { anchorNode: 'e', anchorOffset: 1,
focusNode: 'f', focusOffset: 0 },
+ { anchorNode: 'e', anchorOffset: 1,
focusNode: 'f', focusOffset: 0 },
+ { anchorNode: 'e', anchorOffset: 1,
focusNode: 'f', focusOffset: 0 },
// 20
- { startNode: 'f', startOffset: 0 },
- { startNode: 'f', startOffset: 1 },
- { startNode: 'f', startOffset: 1,
endNode: 'g', endOffset: 0 },
- { startNode: 'f', startOffset: 1,
endNode: 'g', endOffset: 0 },
- { startNode: 'f', startOffset: 1,
endNode: 'g', endOffset: 0 },
- { startNode: 'f', startOffset: 1,
endNode: 'g', endOffset: 0 },
- { startNode: 'f', startOffset: 1,
endNode: 'g', endOffset: 0 },
- { startNode: 'f', startOffset: 1,
endNode: 'g', endOffset: 0 },
- { startNode: 'f', startOffset: 1,
endNode: 'g', endOffset: 0 },
- { startNode: 'g', startOffset: 0 },
+ { anchorNode: 'f', anchorOffset: 0 },
+ { anchorNode: 'f', anchorOffset: 1 },
+ { anchorNode: 'f', anchorOffset: 1,
focusNode: 'g', focusOffset: 0 },
+ { anchorNode: 'f', anchorOffset: 1,
focusNode: 'g', focusOffset: 0 },
+ { anchorNode: 'f', anchorOffset: 1,
focusNode: 'g', focusOffset: 0 },
+ { anchorNode: 'f', anchorOffset: 1,
focusNode: 'g', focusOffset: 0 },
+ { anchorNode: 'f', anchorOffset: 1,
focusNode: 'g', focusOffset: 0 },
+ { anchorNode: 'f', anchorOffset: 1,
focusNode: 'g', focusOffset: 0 },
+ { anchorNode: 'f', anchorOffset: 1,
focusNode: 'g', focusOffset: 0 },
+ { anchorNode: 'g', anchorOffset: 0 },
// 30
- { startNode: 'g', startOffset: 1 },
- { startNode: 'g', startOffset: 1,
endNode: 'h', endOffset: 0 },
- { startNode: 'g', startOffset: 1,
endNode: 'h', endOffset: 0 },
- { startNode: 'g', startOffset: 1,
endNode: 'h', endOffset: 0 },
- { startNode: 'g', startOffset: 1,
endNode: 'h', endOffset: 0 },
- { startNode: 'g', startOffset: 1,
endNode: 'h', endOffset: 0 },
- { startNode: 'g', startOffset: 1,
endNode: 'h', endOffset: 0 },
- { startNode: 'g', startOffset: 1,
endNode: 'h', endOffset: 0 },
- { startNode: 'h', startOffset: 0 },
- { startNode: 'h', startOffset: 1 },
+ { anchorNode: 'g', anchorOffset: 1 },
+ { anchorNode: 'g', anchorOffset: 1,
focusNode: 'h', focusOffset: 0 },
+ { anchorNode: 'g', anchorOffset: 1,
focusNode: 'h', focusOffset: 0 },
+ { anchorNode: 'g', anchorOffset: 1,
focusNode: 'h', focusOffset: 0 },
+ { anchorNode: 'g', anchorOffset: 1,
focusNode: 'h', focusOffset: 0 },
+ { anchorNode: 'g', anchorOffset: 1,
focusNode: 'h', focusOffset: 0 },
+ { anchorNode: 'g', anchorOffset: 1,
focusNode: 'h', focusOffset: 0 },
+ { anchorNode: 'g', anchorOffset: 1,
focusNode: 'h', focusOffset: 0 },
+ { anchorNode: 'h', anchorOffset: 0 },
+ { anchorNode: 'h', anchorOffset: 1 },
// 40
null, // Focusable
- { startNode: 'i', startOffset: 0 },
- { startNode: 'i', startOffset: 1 },
- { startNode: 'i', startOffset: 1,
endNode: 'j', endOffset: 0 },
- { startNode: 'i', startOffset: 1,
endNode: 'j', endOffset: 0 },
- { startNode: 'i', startOffset: 1,
endNode: 'j', endOffset: 0 },
- { startNode: 'j', startOffset: 0 },
- { startNode: 'j', startOffset: 1 },
- { startNode: 'j', startOffset: 1,
endNode: 'k', endOffset: 0 },
- { startNode: 'j', startOffset: 1,
endNode: 'k', endOffset: 0 },
+ { anchorNode: 'i', anchorOffset: 0 },
+ { anchorNode: 'i', anchorOffset: 1 },
+ { anchorNode: 'i', anchorOffset: 1,
focusNode: 'j', focusOffset: 0 },
+ { anchorNode: 'i', anchorOffset: 1,
focusNode: 'j', focusOffset: 0 },
+ { anchorNode: 'i', anchorOffset: 1,
focusNode: 'j', focusOffset: 0 },
+ { anchorNode: 'j', anchorOffset: 0 },
+ { anchorNode: 'j', anchorOffset: 1 },
+ { anchorNode: 'j', anchorOffset: 1,
focusNode: 'k', focusOffset: 0 },
+ { anchorNode: 'j', anchorOffset: 1,
focusNode: 'k', focusOffset: 0 },
// 50
- { startNode: 'j', startOffset: 1,
endNode: 'k', endOffset: 0 },
- { startNode: 'k', startOffset: 0 },
- { startNode: 'k', startOffset: 1 },
- { startNode: 'k', startOffset: 1,
endNode: 'l', endOffset: 0 },
- { startNode: 'k', startOffset: 1,
endNode: 'l', endOffset: 0 },
- { startNode: 'k', startOffset: 1,
endNode: 'l', endOffset: 0 },
- { startNode: 'l', startOffset: 0 },
- { startNode: 'l', startOffset: 1 },
- { startNode: 'l', startOffset: 1,
endNode: 'm', endOffset: 0 },
- { startNode: 'm', startOffset: 0 },
+ { anchorNode: 'j', anchorOffset: 1,
focusNode: 'k', focusOffset: 0 },
+ { anchorNode: 'k', anchorOffset: 0 },
+ { anchorNode: 'k', anchorOffset: 1 },
+ { anchorNode: 'k', anchorOffset: 1,
focusNode: 'l', focusOffset: 0 },
+ { anchorNode: 'k', anchorOffset: 1,
focusNode: 'l', focusOffset: 0 },
+ { anchorNode: 'k', anchorOffset: 1,
focusNode: 'l', focusOffset: 0 },
+ { anchorNode: 'l', anchorOffset: 0 },
+ { anchorNode: 'l', anchorOffset: 1 },
+ { anchorNode: 'l', anchorOffset: 1,
focusNode: 'm', focusOffset: 0 },
+ { anchorNode: 'm', anchorOffset: 0 },
// 60
- { startNode: 'm', startOffset: 1 }
+ { anchorNode: 'm', anchorOffset: 1 }
]
}
];
for ( i = 0; i < cases.length; i++ ) {
for ( j = 0; j < cases[i].expected.length; j++ ) {
- expect += cases[i].expected[j] ? (
cases[i].expected[j].endNode ? 4 : 2 ) : 1;
+ expect += cases[i].expected[j] ? (
cases[i].expected[j].focusNode === undefined ? 2 : 4 ) : 1;
}
}
@@ -1528,25 +1528,25 @@
for ( i = 0; i < cases.length; i++ ) {
view = ve.test.utils.createSurfaceViewFromHtml( cases[i].html );
- internlListNode =
view.getModel().getDocument().getInternalList().getListNode();
- for ( j = 0, l = internlListNode.getOuterRange().start; j < l;
j++ ) {
+ internalListNode =
view.getModel().getDocument().getInternalList().getListNode();
+ for ( j = 0, l = internalListNode.getOuterRange().start; j < l;
j++ ) {
msg = ' at ' + j + ' in ' + cases[i].msg;
node =
view.getDocument().getDocumentNode().getNodeFromOffset( j );
if ( node.isFocusable() ) {
assert.strictEqual( null, cases[i].expected[j],
'Focusable node at ' + j );
} else {
selection = view.getRangeSelection( new
ve.Range( j ) );
- if ( selection.end ) {
- expectedNode = $( '<div>' ).html(
cases[i].expected[j].startNode )[0].childNodes[0];
- assert.equalDomElement(
selection.start.node, expectedNode, 'Start node ' + msg );
- assert.strictEqual(
selection.start.offset, cases[i].expected[j].startOffset, 'Start offfset ' +
msg );
- expectedNode = $( '<div>' ).html(
cases[i].expected[j].endNode )[0].childNodes[0];
- assert.equalDomElement(
selection.end.node, expectedNode, 'End node ' + msg );
- assert.strictEqual(
selection.end.offset, cases[i].expected[j].endOffset, 'End offfset ' + msg );
+ if ( selection.isCollapsed ) {
+ expectedNode = $( '<div>' ).html(
cases[i].expected[j].anchorNode )[0].childNodes[0];
+ assert.equalDomElement(
selection.anchorNode, expectedNode, 'Node ' + msg );
+ assert.strictEqual(
selection.anchorOffset, cases[i].expected[j].anchorOffset, 'Offset ' + msg );
} else {
- expectedNode = $( '<div>' ).html(
cases[i].expected[j].startNode )[0].childNodes[0];
- assert.equalDomElement(
selection.start.node, expectedNode, 'Node ' + msg );
- assert.strictEqual(
selection.start.offset, cases[i].expected[j].startOffset, 'Offset ' + msg );
+ expectedNode = $( '<div>' ).html(
cases[i].expected[j].anchorNode )[0].childNodes[0];
+ assert.equalDomElement(
selection.anchorNode, expectedNode, 'Anchor node ' + msg );
+ assert.strictEqual(
selection.anchorOffset, cases[i].expected[j].anchorOffset, 'Anchor offset ' +
msg );
+ expectedNode = $( '<div>' ).html(
cases[i].expected[j].focusNode )[0].childNodes[0];
+ assert.equalDomElement(
selection.focusNode, expectedNode, 'End node ' + msg );
+ assert.strictEqual(
selection.focusOffset, cases[i].expected[j].focusOffset, 'Focus offset ' + msg
);
}
}
}
--
To view, visit https://gerrit.wikimedia.org/r/222221
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I33c8073592341d5b775e2839be0221662705a6df
Gerrit-PatchSet: 1
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Divec <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits