mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-22 15:02:51 +02:00
feat: Add findClosestNode utility (#728)
* feat: Add findClosestNode utlity * A light shim utility that wraps the functionality of the native `closest` method * IE11 and Edge don't support the `closest` method on nodes * For those browsers that don't support it, we shim it with a shim taken from MDN * Linting fixes * Remove extra semi-colons as per lint guidelines
This commit is contained in:
committed by
Ian Storm Taylor
parent
f39c4327fe
commit
c36537c6e8
@@ -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)
|
||||
)
|
||||
}
|
||||
|
||||
|
32
src/utils/find-closest-node.js
Normal file
32
src/utils/find-closest-node.js
Normal file
@@ -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
|
@@ -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
|
||||
|
Reference in New Issue
Block a user