Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

I/6154: Allow selection on object element (ie. on table cells) #1820

Merged
merged 27 commits into from
Feb 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2e19a66
Add events to mouseobserver.
jodator Sep 6, 2018
aae51a1
Changed: Selection post-fixer should not merge multi-range selection.
jodator Sep 7, 2018
57579d4
It should be possible to select table cells.
jodator Sep 10, 2018
78652c4
POC: Pause selection rendering while mouse is down.
jodator Sep 11, 2018
a844848
Merge branch 'master' into t/ckeditor5-table/63
jodator Nov 26, 2018
c5bf50f
Update code to the latest engine API.
jodator Nov 26, 2018
9d8275c
Merge branch 'master' into t/ckeditor5-table/63
jodator Jun 7, 2019
80e02bb
Merge branch 'master' into t/ckeditor5-table/63
jodator Oct 14, 2019
e5549a0
Merge branch 'master' into i/3202
jodator Nov 4, 2019
1be35db
Merge branch 'master' into i/3202
jodator Jan 21, 2020
bec7f9f
Update license header.
jodator Jan 27, 2020
8212995
Use fake selection to render table selection.
jodator Jan 27, 2020
6664f83
Fix tests for MouseObserver.
jodator Jan 27, 2020
24d1672
Revert MouseObserver to master version.
jodator Jan 28, 2020
fa4ef3d
Merge branch 'master' into i/3202
jodator Jan 28, 2020
4f3694a
Fix some selection post fixer tests.
jodator Jan 28, 2020
d219d5b
Unify the selection post fixing when selection is between limit eleme…
jodator Jan 28, 2020
3ca0d10
Restore beforeEach callback from master.
jodator Jan 28, 2020
dcb7e6f
Move test code around.
jodator Jan 28, 2020
fdb88eb
Remove dead code.
jodator Jan 28, 2020
ad2f060
Update src/model/utils/selection-post-fixer.js
jodator Jan 29, 2020
eac8284
User parenthesis in test names to keep consistency.
jodator Jan 29, 2020
735ce6d
Fix tests description.
jodator Jan 29, 2020
3da493a
Fix tests description.
jodator Jan 29, 2020
3604784
Add more test cases.
jodator Jan 29, 2020
70c4175
Fix range de-intersecting when one of the ranges is bigger then others.
jodator Jan 29, 2020
007da5b
Add more table selection scenarios.
jodator Jan 31, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 34 additions & 20 deletions src/model/utils/selection-post-fixer.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,20 +92,7 @@ function selectionPostFixer( writer, model ) {

// If any of ranges were corrected update the selection.
if ( wasFixed ) {
// The above algorithm might create ranges that intersects each other when selection contains more then one range.
// This is case happens mostly on Firefox which creates multiple ranges for selected table.
let fixedRanges = ranges;

// Fixing selection with many ranges usually breaks the selection in Firefox. As only Firefox supports multiple selection ranges
// we simply create one continuous range from fixed selection ranges (even if they are not adjacent).
if ( ranges.length > 1 ) {
const selectionStart = ranges[ 0 ].start;
const selectionEnd = ranges[ ranges.length - 1 ].end;

fixedRanges = [ new Range( selectionStart, selectionEnd ) ];
}

writer.setSelection( fixedRanges, { backward: selection.isBackward } );
writer.setSelection( mergeIntersectingRanges( ranges ), { backward: selection.isBackward } );
}
}

Expand Down Expand Up @@ -140,18 +127,17 @@ function tryFixingCollapsedRange( range, schema ) {
return null;
}

if ( !nearestSelectionRange.isCollapsed ) {
return nearestSelectionRange;
}

const fixedPosition = nearestSelectionRange.start;

// Fixed position is the same as original - no need to return corrected range.
if ( originalPosition.isEqual( fixedPosition ) ) {
return null;
}

// Check single node selection (happens in tables).
if ( fixedPosition.nodeAfter && schema.isLimit( fixedPosition.nodeAfter ) ) {
return new Range( fixedPosition, Position._createAfter( fixedPosition.nodeAfter ) );
}

return new Range( fixedPosition );
}

Expand Down Expand Up @@ -263,6 +249,35 @@ function checkSelectionOnNonLimitElements( start, end, schema ) {
return startIsOnBlock || endIsOnBlock;
}

// Returns a minimal non-intersecting array of ranges.
//
// @param {Array.<module:engine/model/range~Range>} ranges
// @returns {Array.<module:engine/model/range~Range>}
function mergeIntersectingRanges( ranges ) {
const nonIntersectingRanges = [];

// First range will always be fine.
nonIntersectingRanges.push( ranges.shift() );

for ( const range of ranges ) {
const previousRange = nonIntersectingRanges.pop();

if ( range.isIntersecting( previousRange ) ) {
// Get the sum of two ranges.
const start = previousRange.start.isAfter( range.start ) ? range.start : previousRange.start;
const end = previousRange.end.isAfter( range.end ) ? previousRange.end : range.end;

const merged = new Range( start, end );
nonIntersectingRanges.push( merged );
} else {
nonIntersectingRanges.push( previousRange );
nonIntersectingRanges.push( range );
}
}

return nonIntersectingRanges;
}

// Checks if node exists and if it's an object.
//
// @param {module:engine/model/node~Node} node
Expand All @@ -271,4 +286,3 @@ function checkSelectionOnNonLimitElements( start, end, schema ) {
function isInObject( node, schema ) {
return node && schema.isObject( node );
}

Loading