diff --git a/src/components/content.js b/src/components/content.js index f3c8b7540..091580be6 100644 --- a/src/components/content.js +++ b/src/components/content.js @@ -3,6 +3,7 @@ import Base64 from '../serializers/base-64' import Debug from 'debug' import Node from './node' import getPoint from '../utils/get-point' +import findClosestNode from '../utils/find-closest-node' import React from 'react' import Selection from '../models/selection' import getTransferData from '../utils/get-transfer-data' @@ -243,7 +244,7 @@ class Content extends React.Component { const { target } = event return ( (target.isContentEditable) && - (target == element || target.closest('[data-slate-editor]') == element) + (target == element || findClosestNode(target, '[data-slate-editor]') == element) ) } diff --git a/src/utils/find-closest-node.js b/src/utils/find-closest-node.js new file mode 100644 index 000000000..f55177acf --- /dev/null +++ b/src/utils/find-closest-node.js @@ -0,0 +1,32 @@ + +/** + * Find the closest ancestor of a DOM `element` that matches a given selector. + * + * @param {Element} node + * @param {String} selector + * @return {Element} + */ + +function findClosestNode(node, selector) { + if (typeof node.closest === 'function') return node.closest(selector) + + // See https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill + const matches = (node.document || node.ownerDocument).querySelectorAll(selector) + let i + let parentNode = node + do { + i = matches.length + while (--i >= 0 && matches.item(i) !== parentNode); + } + while ((i < 0) && (parentNode = parentNode.parentElement)) + + return parentNode +} + +/** + * Export. + * + * @type {Function} + */ + +export default findClosestNode diff --git a/src/utils/offset-key.js b/src/utils/offset-key.js index c5ca6e34e..4fbc5ec0d 100644 --- a/src/utils/offset-key.js +++ b/src/utils/offset-key.js @@ -1,5 +1,6 @@ import normalizeNodeAndOffset from './normalize-node-and-offset' +import findClosestNode from './find-closest-node' /** * Offset key parser regex. @@ -68,12 +69,12 @@ function findKey(rawNode, rawOffset) { const { parentNode } = node // Find the closest parent with an offset key attribute. - let closest = parentNode.closest(SELECTOR) + let closest = findClosestNode(parentNode, SELECTOR) // For void nodes, the element with the offset key will be a cousin, not an // ancestor, so find it by going down from the nearest void parent. if (!closest) { - const closestVoid = parentNode.closest(VOID_SELECTOR) + const closestVoid = findClosestNode(parentNode, VOID_SELECTOR) if (!closestVoid) return null closest = closestVoid.querySelector(SELECTOR) offset = closest.textContent.length