devexpress-richedit
Version:
DevExpress Rich Text Editor is an advanced word-processing tool designed for working with rich text documents.
165 lines (164 loc) • 6.93 kB
JavaScript
import { TableNavDirection } from './table-nav-direction';
import { LinkedInterval } from '../model/position/linked-interval';
import { SelectionIntervalsInfo } from './selection-intervals-info';
import { FixedInterval } from '@devexpress/utils/lib/intervals/fixed';
import { ListUtils } from '@devexpress/utils/lib/utils/list';
export class TableCellSelectionState {
constructor(anchorCellPosition, activeCellPosition, singleCellEntryDirection = TableNavDirection.None, singleCellShrinkDirection = TableNavDirection.None, textSelectionAnchorPosition = -1, textSelectionActivePosition = -1, textSelectionEndOfLine = false) {
this.anchorCellPosition = anchorCellPosition;
this.activeCellPosition = activeCellPosition;
this.singleCellEntryDirection = singleCellEntryDirection;
this.singleCellShrinkDirection = singleCellShrinkDirection;
this.textSelectionAnchorPosition = textSelectionAnchorPosition;
this.textSelectionActivePosition = textSelectionActivePosition;
this.textSelectionEndOfLine = textSelectionEndOfLine;
}
clone() {
return new TableCellSelectionState(this.anchorCellPosition, this.activeCellPosition, this.singleCellEntryDirection, this.singleCellShrinkDirection, this.textSelectionAnchorPosition, this.textSelectionActivePosition, this.textSelectionEndOfLine);
}
equals(other) {
if (this === other)
return true;
if (!other)
return false;
return this.anchorCellPosition === other.anchorCellPosition &&
this.activeCellPosition === other.activeCellPosition &&
this.singleCellEntryDirection === other.singleCellEntryDirection &&
this.singleCellShrinkDirection === other.singleCellShrinkDirection &&
this.textSelectionAnchorPosition === other.textSelectionAnchorPosition &&
this.textSelectionActivePosition === other.textSelectionActivePosition &&
this.textSelectionEndOfLine === other.textSelectionEndOfLine;
}
}
export class SelectionState {
get interval() { return this.intervalsInfo.interval; }
;
get anchorPosition() { return this.forwardDirection ? this.interval.start : this.interval.end; }
get activePosition() { return this.forwardDirection ? this.interval.end : this.interval.start; }
get reversedAnchorPosition() { return this.forwardDirection ? this.interval.end : this.interval.start; }
constructor(intervalsInfo, forwardDirection, endOfLine, pageIndex) {
this.forwardDirection = true;
this.endOfLine = false;
this.keepX = -1;
this.pageIndex = -1;
this.tableSelection = null;
this.intervalsInfo = intervalsInfo.clone();
this.forwardDirection = forwardDirection;
this.endOfLine = endOfLine;
this.pageIndex = pageIndex;
}
setEndOfLine(endOfLine) {
this.endOfLine = endOfLine;
return this;
}
resetKeepX() {
this.keepX = -1;
return this;
}
setKeepX(keepX) {
this.keepX = keepX;
return this;
}
setForwardDirection(fd) {
this.forwardDirection = fd;
return this;
}
setInterval(interval) {
this.intervalsInfo.intervals = [this.getNormalizedLastInterval(interval)];
this.resetTableSelectionInfo();
return this;
}
setIntervals(intervals) {
this.intervalsInfo.intervals = intervals;
this.resetTableSelectionInfo();
return this;
}
setPosition(pos) {
this.intervalsInfo.position = pos;
this.resetTableSelectionInfo();
return this;
}
addInterval(interval) {
if (this.intervalsInfo.isCollapsed)
this.intervalsInfo.interval = interval;
else
this.intervalsInfo.lastIntervalIndex = this.intervalsInfo.intervals.push(this.getNormalizedLastInterval(interval)) - 1;
this.resetTableSelectionInfo();
return this;
}
extendLastInterval(end) {
const oldAnchor = this.anchorPosition;
this.interval.start = Math.min(oldAnchor, end);
this.interval.length = Math.abs(oldAnchor - end);
this.forwardDirection = end >= oldAnchor;
this.resetTableSelectionInfo();
return this;
}
setPageIndex(pageIndex) {
this.pageIndex = pageIndex;
return this;
}
setSubDocument(subDocument) {
this.intervalsInfo.subDocument = subDocument;
return this;
}
setTableSelectionInfo(tableSelection) {
this.tableSelection = tableSelection.clone();
return this;
}
resetTableSelectionInfo() {
this.tableSelection = null;
return this;
}
getNormalizedLastInterval(interval) {
this.forwardDirection = interval.length >= 0;
return this.forwardDirection ? interval : new FixedInterval(interval.end, interval.start);
}
static getDefault(activeSubDocument) {
return new SelectionState(SelectionIntervalsInfo.fromPosition(activeSubDocument, 0), true, false, -1);
}
clone() {
const copy = new SelectionState(this.intervalsInfo.clone(), this.forwardDirection, this.endOfLine, this.pageIndex);
copy.keepX = this.keepX;
copy.tableSelection = this.tableSelection
? this.tableSelection.clone()
: null;
return copy;
}
equals(obj) {
return this.partiallyEquals(obj) &&
ListUtils.equals(this.intervalsInfo.intervals, obj.intervalsInfo.intervals);
}
partiallyEquals(obj) {
return obj &&
this.keepX == obj.keepX &&
this.forwardDirection == obj.forwardDirection &&
this.endOfLine == obj.endOfLine &&
this.tableSelectionEquals(this.tableSelection, obj.tableSelection) &&
this.intervalsInfo.lastIntervalIndex == obj.intervalsInfo.lastIntervalIndex &&
this.pageIndex == obj.pageIndex;
}
tableSelectionEquals(a, b) {
if (a === b)
return true;
if (!a || !b)
return false;
return a.equals(b);
}
}
export class SelectionFloatingState {
constructor(state) {
this.state = state;
this.linkedIntervals = ListUtils.map(state.intervalsInfo.intervals, (curr) => new LinkedInterval(state.intervalsInfo.subDocument.positionManager, curr));
}
finalize() {
const intervals = [];
for (let interval of this.linkedIntervals) {
intervals.push(interval.getFixedInterval());
interval.destructor(this.state.intervalsInfo.subDocument.positionManager);
}
this.linkedIntervals = [];
this.state.intervalsInfo.intervals = intervals;
return this.state;
}
}