mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-31 02:49:56 +02:00
bug fixing
This commit is contained in:
@@ -66,8 +66,11 @@ class App extends React.Component {
|
|||||||
renderMark={mark => this.renderMark(mark)}
|
renderMark={mark => this.renderMark(mark)}
|
||||||
state={this.state.state}
|
state={this.state.state}
|
||||||
onChange={(state) => {
|
onChange={(state) => {
|
||||||
console.log('State:', state.toJS())
|
console.groupCollapsed('Change!')
|
||||||
|
console.log('Document:', state.document.toJS())
|
||||||
|
console.log('Selection:', state.selection.toJS())
|
||||||
console.log('Content:', Raw.serialize(state))
|
console.log('Content:', Raw.serialize(state))
|
||||||
|
console.groupEnd()
|
||||||
this.setState({ state })
|
this.setState({ state })
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@@ -25,8 +25,11 @@ class App extends React.Component {
|
|||||||
<Editor
|
<Editor
|
||||||
state={this.state.state}
|
state={this.state.state}
|
||||||
onChange={(state) => {
|
onChange={(state) => {
|
||||||
|
console.groupCollapsed('Change!')
|
||||||
console.log('Document:', state.document.toJS())
|
console.log('Document:', state.document.toJS())
|
||||||
|
console.log('Selection:', state.selection.toJS())
|
||||||
console.log('Content:', Plaintext.serialize(state))
|
console.log('Content:', Plaintext.serialize(state))
|
||||||
|
console.groupEnd()
|
||||||
this.setState({ state })
|
this.setState({ state })
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@@ -128,8 +128,11 @@ class App extends React.Component {
|
|||||||
renderNode={node => this.renderNode(node)}
|
renderNode={node => this.renderNode(node)}
|
||||||
renderMark={mark => this.renderMark(mark)}
|
renderMark={mark => this.renderMark(mark)}
|
||||||
onChange={(state) => {
|
onChange={(state) => {
|
||||||
|
console.groupCollapsed('Change!')
|
||||||
console.log('Document:', state.document.toJS())
|
console.log('Document:', state.document.toJS())
|
||||||
|
console.log('Selection:', state.selection.toJS())
|
||||||
console.log('Content:', Raw.serialize(state))
|
console.log('Content:', Raw.serialize(state))
|
||||||
|
console.groupEnd()
|
||||||
this.setState({ state })
|
this.setState({ state })
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@@ -34,15 +34,13 @@ class Text extends React.Component {
|
|||||||
const { node } = this.props
|
const { node } = this.props
|
||||||
const { characters } = node
|
const { characters } = node
|
||||||
const ranges = groupByMarks(characters)
|
const ranges = groupByMarks(characters)
|
||||||
return ranges.size == 0
|
return ranges.map((range, i, ranges) => {
|
||||||
? this.renderSpacerLeaf()
|
const previous = ranges.slice(0, i)
|
||||||
: ranges.map((range, i, ranges) => {
|
const offset = previous.size
|
||||||
const previous = ranges.slice(0, i)
|
? previous.map(range => range.text).join('').length
|
||||||
const offset = previous.size
|
: 0
|
||||||
? previous.map(range => range.text).join('').length
|
return this.renderLeaf(range, offset)
|
||||||
: 0
|
})
|
||||||
return this.renderLeaf(range, offset)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLeaf(range, offset) {
|
renderLeaf(range, offset) {
|
||||||
@@ -71,14 +69,6 @@ class Text extends React.Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSpacerLeaf() {
|
|
||||||
return this.renderLeaf({
|
|
||||||
marks: new List(),
|
|
||||||
offset: 0,
|
|
||||||
text: ''
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -242,6 +242,27 @@ const Node = {
|
|||||||
return list
|
return list
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the first text child node.
|
||||||
|
*
|
||||||
|
* @return {Text or Null} text
|
||||||
|
*/
|
||||||
|
|
||||||
|
getFirstTextNode() {
|
||||||
|
return this.findNode(node => node.type == 'text') || null
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the last text child node.
|
||||||
|
*
|
||||||
|
* @return {Text or Null} text
|
||||||
|
*/
|
||||||
|
|
||||||
|
getLastTextNode() {
|
||||||
|
const texts = this.findNode(node => node.type == 'text')
|
||||||
|
return texts.size ? texts.get(texts.size - 1) : null
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a set of the marks in a `range`.
|
* Get a set of the marks in a `range`.
|
||||||
*
|
*
|
||||||
|
@@ -109,7 +109,7 @@ class Selection extends SelectionRecord {
|
|||||||
|
|
||||||
isAtStartOf(node) {
|
isAtStartOf(node) {
|
||||||
const { startKey, startOffset } = this
|
const { startKey, startOffset } = this
|
||||||
const first = node.type == 'text' ? node : node.nodes.first()
|
const first = node.type == 'text' ? node : node.getFirstTextNode()
|
||||||
return startKey == first.key && startOffset == 0
|
return startKey == first.key && startOffset == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@ class Selection extends SelectionRecord {
|
|||||||
|
|
||||||
isAtEndOf(node) {
|
isAtEndOf(node) {
|
||||||
const { endKey, endOffset } = this
|
const { endKey, endOffset } = this
|
||||||
const last = node.type == 'text' ? node : node.nodes.last()
|
const last = node.type == 'text' ? node : node.getLastTextNode()
|
||||||
return endKey == last.key && endOffset == last.length
|
return endKey == last.key && endOffset == last.length
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -133,7 +133,11 @@ class State extends Record(DEFAULTS) {
|
|||||||
const { startKey } = selection
|
const { startKey } = selection
|
||||||
const startNode = document.getNode(startKey)
|
const startNode = document.getNode(startKey)
|
||||||
|
|
||||||
if (selection.isExpanded) {
|
if (selection.isAtStartOf(document)) {
|
||||||
|
after = selection
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (selection.isExpanded) {
|
||||||
after = selection.moveToStart()
|
after = selection.moveToStart()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
import Character from '../models/character'
|
import Character from '../models/character'
|
||||||
import Node from '../models/node'
|
import Element from '../models/element'
|
||||||
import Text from '../models/text'
|
import Text from '../models/text'
|
||||||
import Document from '../models/document'
|
import Document from '../models/document'
|
||||||
import State from '../models/state'
|
import State from '../models/state'
|
||||||
@@ -33,13 +33,13 @@ function deserialize(string) {
|
|||||||
}, Character.createList())
|
}, Character.createList())
|
||||||
|
|
||||||
const text = Text.create({ characters })
|
const text = Text.create({ characters })
|
||||||
const texts = Node.createMap([text])
|
const texts = Element.createMap([text])
|
||||||
const node = Node.create({
|
const node = Element.create({
|
||||||
type: 'paragraph',
|
type: 'paragraph',
|
||||||
nodes: texts,
|
nodes: texts,
|
||||||
})
|
})
|
||||||
|
|
||||||
const nodes = Node.createMap([node])
|
const nodes = Element.createMap([node])
|
||||||
const document = Document.create({ nodes })
|
const document = Document.create({ nodes })
|
||||||
const state = State.create({ document })
|
const state = State.create({ document })
|
||||||
return state
|
return state
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
import { List, Map, Record } from 'immutable'
|
import { List, Map, Record, Set } from 'immutable'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Range.
|
* Range.
|
||||||
@@ -7,7 +7,7 @@ import { List, Map, Record } from 'immutable'
|
|||||||
|
|
||||||
const Range = new Record({
|
const Range = new Record({
|
||||||
text: '',
|
text: '',
|
||||||
marks: new List()
|
marks: new Set()
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -18,6 +18,12 @@ const Range = new Record({
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function groupByMarks(characters) {
|
function groupByMarks(characters) {
|
||||||
|
if (characters.size == 0) {
|
||||||
|
let ranges = new List()
|
||||||
|
ranges = ranges.push(new Range())
|
||||||
|
return ranges
|
||||||
|
}
|
||||||
|
|
||||||
return characters
|
return characters
|
||||||
.toList()
|
.toList()
|
||||||
.reduce((ranges, char, i) => {
|
.reduce((ranges, char, i) => {
|
||||||
|
@@ -10,6 +10,7 @@ const PARSER = /^(\w+)(?::(\d+)-(\d+))?$/
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const ATTRIBUTE = 'data-offset-key'
|
const ATTRIBUTE = 'data-offset-key'
|
||||||
|
const SELECTOR = `[${ATTRIBUTE}]`
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* From a `node`, find the closest parent's offset key.
|
* From a `node`, find the closest parent's offset key.
|
||||||
@@ -20,9 +21,17 @@ const ATTRIBUTE = 'data-offset-key'
|
|||||||
|
|
||||||
function findKey(node) {
|
function findKey(node) {
|
||||||
if (node.nodeType == 3) node = node.parentNode
|
if (node.nodeType == 3) node = node.parentNode
|
||||||
const parent = node.closest(`[${ATTRIBUTE}]`)
|
|
||||||
if (!parent) return null
|
// If a parent with an offset key exists, use it.
|
||||||
return parent.getAttribute(ATTRIBUTE)
|
const parent = node.closest(SELECTOR)
|
||||||
|
if (parent) return parent.getAttribute(ATTRIBUTE)
|
||||||
|
|
||||||
|
// Otherwise, if a child with an offset key exists, use it.
|
||||||
|
const child = node.querySelector(SELECTOR)
|
||||||
|
if (child) return child.getAttribute(ATTRIBUTE)
|
||||||
|
|
||||||
|
// Shouldn't get here... else we have an edge case to handle.
|
||||||
|
console.error('No offset key found for node:', node)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user