1
0
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:
Craig Michael Thompson
2017-04-19 17:05:57 +01:00
committed by Ian Storm Taylor
parent f39c4327fe
commit c36537c6e8
3 changed files with 37 additions and 3 deletions

View File

@@ -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)
)
}

View 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

View File

@@ -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