From f37c3a4776bbb49c3b5c123b3ea392431ea9c21f Mon Sep 17 00:00:00 2001 From: Ben Southgate Date: Thu, 10 May 2018 22:07:11 -0400 Subject: [PATCH] fix: prevent IE11 from throwing if selection contains tables (#1825) * fix: prevent IE11 from throwing if selection contains tables * fix: run prettier * fix: lint --- .../slate-react/src/components/content.js | 5 ++-- .../slate-react/src/utils/clone-fragment.js | 5 ++-- .../src/utils/remove-all-ranges.js | 27 +++++++++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 packages/slate-react/src/utils/remove-all-ranges.js diff --git a/packages/slate-react/src/components/content.js b/packages/slate-react/src/components/content.js index 3d657d34b..e282c90ce 100644 --- a/packages/slate-react/src/components/content.js +++ b/packages/slate-react/src/components/content.js @@ -16,6 +16,7 @@ import Node from './node' import findDOMRange from '../utils/find-dom-range' import findRange from '../utils/find-range' import scrollToSelection from '../utils/scroll-to-selection' +import removeAllRanges from '../utils/remove-all-ranges' /** * Debug. @@ -151,7 +152,7 @@ class Content extends React.Component { // DOM, blur it manually. if (selection.isBlurred) { if (!this.isInEditor(anchorNode)) return - native.removeAllRanges() + removeAllRanges(native) this.element.blur() debug('updateSelection', { selection, native }) return @@ -195,7 +196,7 @@ class Content extends React.Component { // Otherwise, set the `isUpdatingSelection` flag and update the selection. this.tmp.isUpdatingSelection = true - native.removeAllRanges() + removeAllRanges(native) // COMPAT: IE 11 does not support Selection.setBaseAndExtent if (native.setBaseAndExtent) { diff --git a/packages/slate-react/src/utils/clone-fragment.js b/packages/slate-react/src/utils/clone-fragment.js index 9c8bbaec0..2a4d7b65a 100644 --- a/packages/slate-react/src/utils/clone-fragment.js +++ b/packages/slate-react/src/utils/clone-fragment.js @@ -4,6 +4,7 @@ import { IS_CHROME, IS_SAFARI, IS_OPERA } from 'slate-dev-environment' import getWindow from 'get-window' import findDOMNode from './find-dom-node' import { ZERO_WIDTH_SELECTOR, ZERO_WIDTH_ATTRIBUTE } from './find-point' +import removeAllRanges from './remove-all-ranges' /** * Prepares a Slate document fragment to be copied to the clipboard. @@ -130,13 +131,13 @@ function cloneFragment(event, value, fragment = value.fragment) { // throws an error, so we use the older `range` equivalent. (2016/06/21) const r = window.document.createRange() r.selectNodeContents(div) - native.removeAllRanges() + removeAllRanges(native) native.addRange(r) // Revert to the previous selection right after copying. window.requestAnimationFrame(() => { editor.removeChild(div) - native.removeAllRanges() + removeAllRanges(native) native.addRange(range) }) } diff --git a/packages/slate-react/src/utils/remove-all-ranges.js b/packages/slate-react/src/utils/remove-all-ranges.js new file mode 100644 index 000000000..7807b520f --- /dev/null +++ b/packages/slate-react/src/utils/remove-all-ranges.js @@ -0,0 +1,27 @@ +/** + * COMPAT: if we are in <= IE11 and the selection contains + * tables, `removeAllRanges()` will throw + * "unable to complete the operation due to error 800a025e" + * + * @param {Selection} selection document selection + */ + +function removeAllRanges(selection) { + const doc = window.document + if (doc && doc.body.createTextRange) { + // All IE but Edge + const range = doc.body.createTextRange() + range.collapse() + range.select() + } else { + selection.removeAllRanges() + } +} + +/** + * Export. + * + * @type {Function} + */ + +export default removeAllRanges