1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-02-21 23:53:50 +01:00

Core component will deduce the context from the dispatched event.target element

This commit is contained in:
Vladimir 2016-08-03 03:27:33 +03:00
parent 5fa616a01d
commit 186f1a7c6d
4 changed files with 42 additions and 18 deletions

View File

@ -9,6 +9,7 @@ import TYPES from '../utils/types'
import includes from 'lodash/includes'
import keycode from 'keycode'
import { IS_FIREFOX, IS_MAC } from '../utils/environment'
import findElementWindow from '../utils/find-element-window'
/**
* Debug.
@ -380,11 +381,13 @@ class Content extends React.Component {
// Resolve the point where the drop occured.
let range
const contextWindow = findElementWindow(e.nativeEvent.target)
// COMPAT: In Firefox, `caretRangeFromPoint` doesn't exist. (2016/07/25)
if (window.document.caretRangeFromPoint) {
range = window.document.caretRangeFromPoint(x, y)
if (contextWindow.document.caretRangeFromPoint) {
range = contextWindow.document.caretRangeFromPoint(x, y)
} else {
range = window.document.createRange()
range = contextWindow.document.createRange()
range.setStart(e.nativeEvent.rangeParent, e.nativeEvent.rangeOffset)
}
@ -459,9 +462,11 @@ class Content extends React.Component {
if (isNonEditable(e)) return
debug('onInput')
const contextWindow = findElementWindow(e.nativeEvent.target)
let { state, renderDecorations } = this.props
const { selection } = state
const native = window.getSelection()
const native = contextWindow.getSelection()
const { anchorNode, anchorOffset, focusOffset } = native
const point = this.getPoint(anchorNode, anchorOffset)
const { key, index, start, end } = point
@ -624,9 +629,11 @@ class Content extends React.Component {
if (this.tmp.isComposing) return
if (isNonEditable(e)) return
const contextWindow = findElementWindow(e.nativeEvent.target)
const { state, renderDecorations } = this.props
let { document, selection } = state
const native = window.getSelection()
const native = contextWindow.getSelection()
const data = {}
// If there are no ranges, the editor was blurred natively.

View File

@ -3,7 +3,7 @@ import Debug from 'debug'
import OffsetKey from '../utils/offset-key'
import React from 'react'
import ReactDOM from 'react-dom'
import findElementWindow from '../utils/find-element-window'
/**
* Debugger.
*
@ -135,14 +135,16 @@ class Leaf extends React.Component {
focusOffset = 0
}
const contextWindow = findElementWindow(ReactDOM.findDOMNode(this));
// We have a selection to render, so prepare a few things...
const native = window.getSelection()
const native = contextWindow.getSelection()
const el = findDeepestNode(ReactDOM.findDOMNode(this))
// If both the start and end are here, set the selection all at once.
if (hasAnchor && hasFocus) {
native.removeAllRanges()
const range = window.document.createRange()
const range = contextWindow.document.createRange()
range.setStart(el, anchorOffset - start)
native.addRange(range)
native.extend(el, focusOffset - start)
@ -155,7 +157,7 @@ class Leaf extends React.Component {
if (selection.isForward) {
if (hasAnchor) {
native.removeAllRanges()
const range = window.document.createRange()
const range = contextWindow.document.createRange()
range.setStart(el, anchorOffset - start)
native.addRange(range)
} else if (hasFocus) {
@ -170,14 +172,14 @@ class Leaf extends React.Component {
else {
if (hasFocus) {
native.removeAllRanges()
const range = window.document.createRange()
const range = contextWindow.document.createRange()
range.setStart(el, focusOffset - start)
native.addRange(range)
} else if (hasAnchor) {
const endNode = native.focusNode
const endOffset = native.focusOffset
native.removeAllRanges()
const range = window.document.createRange()
const range = contextWindow.document.createRange()
range.setStart(el, anchorOffset - start)
native.addRange(range)
native.extend(endNode, endOffset)

View File

@ -5,6 +5,7 @@ import Debug from 'debug'
import Placeholder from '../components/placeholder'
import React from 'react'
import String from '../utils/string'
import findElementWindow from '../utils/find-element-window'
/**
* Debug.
@ -28,7 +29,7 @@ function Plugin(options = {}) {
const {
placeholder,
placeholderClassName,
placeholderStyle
placeholderStyle,
} = options
/**
@ -204,7 +205,9 @@ function Plugin(options = {}) {
*/
function onCutOrCopy(e, data, state) {
const native = window.getSelection()
const contextWindow = findElementWindow(e.nativeEvent.target)
const native = contextWindow.getSelection()
if (!native.rangeCount) return
const { fragment } = data
@ -214,10 +217,10 @@ function Plugin(options = {}) {
// fragment attached as an attribute, so it will show up in the copied HTML.
const range = native.getRangeAt(0)
const contents = range.cloneContents()
const wrapper = window.document.createElement('span')
const wrapper = contextWindow.document.createElement('span')
const text = contents.childNodes[0]
const char = text.textContent.slice(0, 1)
const first = window.document.createTextNode(char)
const first = contextWindow.document.createTextNode(char)
const rest = text.textContent.slice(1)
text.textContent = rest
wrapper.appendChild(first)
@ -225,8 +228,8 @@ function Plugin(options = {}) {
contents.insertBefore(wrapper, text)
// Add the phony content to the DOM, and select it, so it will be copied.
const body = window.document.querySelector('body')
const div = window.document.createElement('div')
const body = contextWindow.document.querySelector('body')
const div = contextWindow.document.createElement('div')
div.setAttribute('contenteditable', true)
div.style.position = 'absolute'
div.style.left = '-9999px'
@ -235,7 +238,7 @@ function Plugin(options = {}) {
// COMPAT: In Firefox, trying to use the terser `native.selectAllChildren`
// throws an error, so we use the older `range` equivalent. (2016/06/21)
const r = window.document.createRange()
const r = contextWindow.document.createRange()
r.selectNodeContents(div)
native.removeAllRanges()
native.addRange(r)

View File

@ -0,0 +1,12 @@
/**
* Find the DOM context for the `node`, fallback to top level global window object.
*
* @param {Node} node
* @return {Element} el
*/
function findElementWindow (domNode) {
const doc = domNode.ownerDocument || domNode
return doc.defaultView || doc.parentWindow
}
export default findElementWindow