diff --git a/lib/models/selection.js b/lib/models/selection.js index 848b2e360..c2e822aa5 100644 --- a/lib/models/selection.js +++ b/lib/models/selection.js @@ -1,5 +1,6 @@ import includes from 'lodash/includes' +import memoize from '../utils/memoize' import { Record } from 'immutable' /** @@ -143,8 +144,9 @@ class Selection extends new Record(DEFAULTS) { */ hasAnchorAtStartOf(node) { + if (this.anchorOffset != 0) return false const first = node.kind == 'text' ? node : node.getTexts().first() - return this.anchorKey == first.key && this.anchorOffset == 0 + return this.anchorKey == first.key } /** @@ -171,9 +173,9 @@ class Selection extends new Record(DEFAULTS) { hasAnchorBetween(node, start, end) { return ( - this.hasAnchorIn(node) && + this.anchorOffset <= end && start <= this.anchorOffset && - this.anchorOffset <= end + this.hasAnchorIn(node) ) } @@ -209,8 +211,9 @@ class Selection extends new Record(DEFAULTS) { */ hasFocusAtStartOf(node) { + if (this.focusOffset != 0) return false const first = node.kind == 'text' ? node : node.getTexts().first() - return this.focusKey == first.key && this.focusOffset == 0 + return this.focusKey == first.key } /** @@ -225,9 +228,9 @@ class Selection extends new Record(DEFAULTS) { hasFocusBetween(node, start, end) { return ( - this.hasFocusIn(node) && start <= this.focusOffset && - this.focusOffset <= end + this.focusOffset <= end && + this.hasFocusIn(node) ) } @@ -251,9 +254,11 @@ class Selection extends new Record(DEFAULTS) { */ isAtStartOf(node) { - const { startKey, startOffset } = this + const { isExpanded, startKey, startOffset } = this + if (isExpanded) return false + if (startOffset != 0) return false const first = node.kind == 'text' ? node : node.getTexts().first() - return this.isCollapsed && startKey == first.key && startOffset == 0 + return startKey == first.key } /** @@ -264,9 +269,10 @@ class Selection extends new Record(DEFAULTS) { */ isAtEndOf(node) { - const { endKey, endOffset } = this + const { endKey, endOffset, isExpanded } = this + if (isExpanded) return false const last = node.kind == 'text' ? node : node.getTexts().last() - return this.isCollapsed && endKey == last.key && endOffset == last.length + return endKey == last.key && endOffset == last.length } /** @@ -578,9 +584,22 @@ START_END_METHODS.concat(EDGE_METHODS).forEach((pattern) => { }) /** - * Add edge methods. + * Memoize read methods. */ +memoize(Selection.prototype, [ + 'hasAnchorAtStartOf', + 'hasAnchorAtEndOf', + 'hasAnchorBetween', + 'hasAnchorIn', + 'hasFocusAtEndOf', + 'hasFocusAtStartOf', + 'hasFocusBetween', + 'hasFocusIn', + 'isAtStartOf', + 'isAtEndOf' +]) + /** * Export. */