mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-29 18:09:49 +02:00
fix style, refactor noop
This commit is contained in:
@@ -11,6 +11,7 @@ import TYPES from '../constants/types'
|
|||||||
import getWindow from 'get-window'
|
import getWindow from 'get-window'
|
||||||
import includes from 'lodash/includes'
|
import includes from 'lodash/includes'
|
||||||
import keycode from 'keycode'
|
import keycode from 'keycode'
|
||||||
|
import noop from '../utils/noop'
|
||||||
import { IS_FIREFOX, IS_MAC } from '../constants/environment'
|
import { IS_FIREFOX, IS_MAC } from '../constants/environment'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,45 +22,6 @@ import { IS_FIREFOX, IS_MAC } from '../constants/environment'
|
|||||||
|
|
||||||
const debug = Debug('slate:content')
|
const debug = Debug('slate:content')
|
||||||
|
|
||||||
/**
|
|
||||||
* Noop.
|
|
||||||
*
|
|
||||||
* @type {Function}
|
|
||||||
*/
|
|
||||||
|
|
||||||
function noop() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the deepest descendant of a DOM `element`.
|
|
||||||
*
|
|
||||||
* @param {Element} node
|
|
||||||
* @return {Element}
|
|
||||||
*/
|
|
||||||
|
|
||||||
function findDeepestNode(element) {
|
|
||||||
return element.firstChild
|
|
||||||
? findDeepestNode(element.firstChild)
|
|
||||||
: element
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests if the child is a descendant of parent.
|
|
||||||
*
|
|
||||||
* @param parent
|
|
||||||
* @param child
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
|
|
||||||
function isDescendant(parent, child) {
|
|
||||||
if (!child || !parent) return false
|
|
||||||
let node = child.parentNode
|
|
||||||
while (node != null) {
|
|
||||||
if (node == parent) return true
|
|
||||||
node = node.parentNode
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Content.
|
* Content.
|
||||||
*
|
*
|
||||||
@@ -154,8 +116,8 @@ class Content extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When finished rendering, move the `isRendering` flag on next tick and clean up the DOM's activeElement
|
* When finished rendering, move the `isRendering` flag on next tick and
|
||||||
* if neccessary.
|
* clean up the DOM's activeElement if neccessary.
|
||||||
*
|
*
|
||||||
* @param {Object} prevProps
|
* @param {Object} prevProps
|
||||||
* @param {Object} prevState
|
* @param {Object} prevState
|
||||||
@@ -166,21 +128,16 @@ class Content extends React.Component {
|
|||||||
this.tmp.isRendering = false
|
this.tmp.isRendering = false
|
||||||
}, 1)
|
}, 1)
|
||||||
|
|
||||||
// If this component was focused last render, but is not now we might need to clean up the activeElement.
|
// If the state is blurred now, but was focused before, and the DOM still
|
||||||
|
// has a node inside the editor selected, we need to blur it.
|
||||||
if (this.props.state.isBlurred && prevProps.state.isFocused) {
|
if (this.props.state.isBlurred && prevProps.state.isFocused) {
|
||||||
// Get the current selection
|
const el = ReactDOM.findDOMNode(this)
|
||||||
const ref = ReactDOM.findDOMNode(this)
|
|
||||||
const el = findDeepestNode(ref)
|
|
||||||
const window = getWindow(el)
|
const window = getWindow(el)
|
||||||
const native = window.getSelection()
|
const native = window.getSelection()
|
||||||
|
if (!el.contains(native.anchorNode)) return
|
||||||
|
|
||||||
// We need to make sure that the selection from our state is up-to-date with the native selection.
|
native.removeAllRanges()
|
||||||
// We can do this by checking if native.anchorNode is a descendant of our this node.
|
el.blur()
|
||||||
if (isDescendant(ref, native.anchorNode)) {
|
|
||||||
// The selection was blurred, but the DOM selection state has not changed so we need to do this manually:
|
|
||||||
native.removeAllRanges()
|
|
||||||
if (ref) ref.blur()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,6 +6,7 @@ import React from 'react'
|
|||||||
import Schema from '../models/schema'
|
import Schema from '../models/schema'
|
||||||
import State from '../models/state'
|
import State from '../models/state'
|
||||||
import isReactComponent from '../utils/is-react-component'
|
import isReactComponent from '../utils/is-react-component'
|
||||||
|
import noop from '../utils/noop'
|
||||||
import typeOf from 'type-of'
|
import typeOf from 'type-of'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14,14 +15,6 @@ import typeOf from 'type-of'
|
|||||||
|
|
||||||
const debug = Debug('slate:editor')
|
const debug = Debug('slate:editor')
|
||||||
|
|
||||||
/**
|
|
||||||
* Noop.
|
|
||||||
*
|
|
||||||
* @type {Function}
|
|
||||||
*/
|
|
||||||
|
|
||||||
function noop() {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event handlers to mix in to the editor.
|
* Event handlers to mix in to the editor.
|
||||||
*
|
*
|
||||||
|
@@ -162,9 +162,10 @@ class Leaf extends React.Component {
|
|||||||
const native = window.getSelection()
|
const native = window.getSelection()
|
||||||
const parent = ref.closest('[contenteditable]')
|
const parent = ref.closest('[contenteditable]')
|
||||||
|
|
||||||
// In firefox it is not enough to create a range, you also need to focus the contenteditable element.
|
// COMPAT: In Firefox, it's not enough to create a range, you also need to
|
||||||
|
// focus the contenteditable element. (2016/11/16)
|
||||||
function focus() {
|
function focus() {
|
||||||
if (parent) setTimeout(() => parent.focus(), 0)
|
if (parent) setTimeout(() => parent.focus())
|
||||||
}
|
}
|
||||||
|
|
||||||
// If both the start and end are here, set the selection all at once.
|
// If both the start and end are here, set the selection all at once.
|
||||||
@@ -175,45 +176,45 @@ class Leaf extends React.Component {
|
|||||||
native.addRange(range)
|
native.addRange(range)
|
||||||
native.extend(el, focusOffset - start)
|
native.extend(el, focusOffset - start)
|
||||||
focus()
|
focus()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the selection is forward, we can set things in sequence. In
|
// Otherwise we need to set the selection across two different leaves.
|
||||||
// the first leaf to render, reset the selection and set the new start. And
|
|
||||||
// then in the second leaf to render, extend to the new end.
|
|
||||||
if (selection.isForward) {
|
|
||||||
if (hasAnchor) {
|
|
||||||
native.removeAllRanges()
|
|
||||||
const range = window.document.createRange()
|
|
||||||
range.setStart(el, anchorOffset - start)
|
|
||||||
native.addRange(range)
|
|
||||||
focus()
|
|
||||||
} else if (hasFocus) {
|
|
||||||
native.extend(el, focusOffset - start)
|
|
||||||
focus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, if the selection is backward, we need to hack the order a bit.
|
|
||||||
// In the first leaf to render, set a phony start anchor to store the true
|
|
||||||
// end position. And then in the second leaf to render, set the start and
|
|
||||||
// extend the end to the stored value.
|
|
||||||
else {
|
else {
|
||||||
if (hasFocus) {
|
// If the selection is forward, we can set things in sequence. In the
|
||||||
native.removeAllRanges()
|
// first leaf to render, reset the selection and set the new start. And
|
||||||
const range = window.document.createRange()
|
// then in the second leaf to render, extend to the new end.
|
||||||
range.setStart(el, focusOffset - start)
|
if (selection.isForward) {
|
||||||
native.addRange(range)
|
if (hasAnchor) {
|
||||||
focus()
|
native.removeAllRanges()
|
||||||
} else if (hasAnchor) {
|
const range = window.document.createRange()
|
||||||
const endNode = native.focusNode
|
range.setStart(el, anchorOffset - start)
|
||||||
const endOffset = native.focusOffset
|
native.addRange(range)
|
||||||
native.removeAllRanges()
|
} else if (hasFocus) {
|
||||||
const range = window.document.createRange()
|
native.extend(el, focusOffset - start)
|
||||||
range.setStart(el, anchorOffset - start)
|
focus()
|
||||||
native.addRange(range)
|
}
|
||||||
native.extend(endNode, endOffset)
|
}
|
||||||
focus()
|
|
||||||
|
// Otherwise, if the selection is backward, we need to hack the order a bit.
|
||||||
|
// In the first leaf to render, set a phony start anchor to store the true
|
||||||
|
// end position. And then in the second leaf to render, set the start and
|
||||||
|
// extend the end to the stored value.
|
||||||
|
else {
|
||||||
|
if (hasFocus) {
|
||||||
|
native.removeAllRanges()
|
||||||
|
const range = window.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()
|
||||||
|
range.setStart(el, anchorOffset - start)
|
||||||
|
native.addRange(range)
|
||||||
|
native.extend(endNode, endOffset)
|
||||||
|
focus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,16 +5,9 @@ import OffsetKey from '../utils/offset-key'
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import keycode from 'keycode'
|
import keycode from 'keycode'
|
||||||
|
import noop from '../utils/noop'
|
||||||
import { IS_FIREFOX } from '../constants/environment'
|
import { IS_FIREFOX } from '../constants/environment'
|
||||||
|
|
||||||
/**
|
|
||||||
* Noop.
|
|
||||||
*
|
|
||||||
* @type {Function}
|
|
||||||
*/
|
|
||||||
|
|
||||||
function noop() {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Void.
|
* Void.
|
||||||
*
|
*
|
||||||
|
14
src/utils/noop.js
Normal file
14
src/utils/noop.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* Noop.
|
||||||
|
*
|
||||||
|
* @return {Undefined}
|
||||||
|
*/
|
||||||
|
|
||||||
|
function noop() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default noop
|
Reference in New Issue
Block a user