Skip to content

Commit 0e194df

Browse files
ajwildmarcbachmann
authored andcommitted
fix(events): Check event.target.closest() exists before calling
1 parent 3317356 commit 0e194df

File tree

6 files changed

+24
-12
lines changed

6 files changed

+24
-12
lines changed

examples/events.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, {Component} from 'react'
22
import {PropTypes} from 'prop-types'
33
import ReactDOM from 'react-dom'
44
import {CSSTransition, TransitionGroup} from 'react-transition-group'
5+
import {closest} from '../src/util/dom'
56

67
class Events extends Component {
78
render () {
@@ -97,7 +98,7 @@ function draw () {
9798
}
9899

99100
function isFromFirstExample (elem) {
100-
return !!elem.closest('.paragraph-example')
101+
return !!closest(elem, '.paragraph-example')
101102
}
102103

103104
export default function (editable) {

src/cursor.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import error from './util/error'
99
import * as rangeSaveRestore from './range-save-restore'
1010
// import printRange from './util/print_range'
1111
import NodeIterator from './node-iterator'
12+
import {closest} from './util/dom'
1213

1314
/**
1415
* The Cursor module provides a cross-browser abstraction layer for cursor.
@@ -20,8 +21,7 @@ import NodeIterator from './node-iterator'
2021
export default class Cursor {
2122

2223
static findHost (elem, selector) {
23-
if (!elem.closest) elem = elem.parentNode
24-
return elem.closest(selector)
24+
return closest(elem, selector)
2525
}
2626

2727
/**

src/dispatcher.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import eventable from './eventable'
44
import SelectionWatcher from './selection-watcher'
55
import config from './config'
66
import Keyboard from './keyboard'
7+
import {closest} from './util/dom'
78

89
// This will be set to true once we detect the input event is working.
910
// Input event description on MDN:
@@ -30,6 +31,7 @@ export default class Dispatcher {
3031
this.keyboard = new Keyboard(this.selectionWatcher)
3132
this.activeListeners = []
3233
this.setup()
34+
this.getEditableBlockByEvent = (evt) => closest(evt.target, editable.editableSelector)
3335
}
3436

3537
setupDocumentListener (event, func, capture = false) {
@@ -81,10 +83,6 @@ export default class Dispatcher {
8183
}
8284
}
8385

84-
getEditableBlockByEvent (evt) {
85-
return evt.target.closest(this.editableSelector)
86-
}
87-
8886
/**
8987
* Sets up events that are triggered on modifying an element.
9088
*

src/highlight-support.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ import rangy from 'rangy'
22
import * as content from './content'
33
import highlightText from './highlight-text'
44
import TextHighlighting from './plugins/highlighting/text-highlighting'
5-
import {createElement} from './util/dom'
5+
import {closest, createElement} from './util/dom'
66

77
function isInHost (elem, host) {
8-
if (!elem.closest) elem = elem.parentNode
9-
return elem.closest('[data-editable]:not([data-word-id])') === host
8+
return closest(elem, '[data-editable]:not([data-word-id])') === host
109
}
1110

1211
const highlightSupport = {

src/parser.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as string from './util/string'
22
import * as nodeType from './node-type'
33
import config from './config'
4+
import {closest} from './util/dom'
45

56
/**
67
* The parser module provides helper methods to parse html-chunks
@@ -20,8 +21,7 @@ import config from './config'
2021
*/
2122
export function getHost (node) {
2223
node = (node.jquery ? node[0] : node)
23-
if (!node.closest) node = node.parentNode
24-
return node.closest(`.${config.editableClass}`)
24+
return closest(node, `.${config.editableClass}`)
2525
}
2626

2727
/**

src/util/dom.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,17 @@ export const createElement = (html, win = window) => {
2828
el.innerHTML = html
2929
return el.firstElementChild
3030
}
31+
32+
/**
33+
* Get the closest dom element matching a selector
34+
* @description
35+
* - If a textNode is passed, it will still find the correct element
36+
* - If a document is passed, it will return undefined
37+
* @param {Node} elem
38+
* @param {String} selector
39+
* @returns {HTMLElement|undefined}
40+
*/
41+
export const closest = (elem, selector) => {
42+
if (!elem.closest) elem = elem.parentNode
43+
if (elem && elem.closest) return elem.closest(selector)
44+
}

0 commit comments

Comments
 (0)