Open smithjustinb opened 8 years ago
actually, eek - i mislabeled this. getCurrentInlineStyle, by definition, when you have selected multiple characters, doesn't compute the intersection of all of those characters' styles. it just uses that of the first character, which is why highlighting "bar bat" takes the inline style of the "b" in "bar", which happens to be bold.
i'd say this is a bug with the demo that needs to be fixed, but not a bug with the API.
this is also the reason why the draftjs-utils project by @jpuri implements a getSelectionInlineStyle method: https://github.com/jpuri/draftjs-utils/blob/master/js/inline.js#L24-L59
@hellendag - could you give some context as to why getCurrentInlineStyle doesn't take the intersection?
i was going to patch the rich text example with an adaptation of getSelectionInlineStyle (link above)
I know this is an old issue but I will post my solution here for others to see. I took code from draftjs-utils and modified it to be more generic. I found the draftjs-util implementation was geared towards the built in styles e.g. BOLD ITALIC etc. It didnt account for custom inline styles.
const getSelectionInlineStyle = (editorState: EditorState) => {
const currentSelection = editorState.getSelection()
if (currentSelection.isCollapsed()) {
return editorState.getCurrentInlineStyle()
}
const start = currentSelection.getStartOffset()
const end = currentSelection.getEndOffset()
const selectedBlocks = getSelectedBlocksMap(editorState).toList()
let set = Immutable.OrderedSet<string>()
if (selectedBlocks.size > 0) {
for (let i = 0; i < selectedBlocks.size; i += 1) {
let blockStart = i === 0 ? start : 0;
let blockEnd =
i === selectedBlocks.size - 1
? end
: selectedBlocks.get(i).getText().length
if (blockStart === blockEnd && blockStart === 0) {
blockStart = 1
blockEnd = 2
} else if (blockStart === blockEnd) {
blockStart -= 1
}
for (let j = blockStart; j < blockEnd; j += 1) {
set = set.merge(selectedBlocks.get(i).getInlineStyleAt(j))
}
}
}
return set
}
const getSelectedBlocksMap = (editorState: EditorState) => {
const selectionState = editorState.getSelection()
const contentState = editorState.getCurrentContent()
const startKey = selectionState.getStartKey()
const endKey = selectionState.getEndKey()
const blockMap = contentState.getBlockMap()
return blockMap
.toSeq()
.skipUntil((_, k) => k === startKey)
.takeUntil((_, k) => k === endKey)
.concat([[endKey, blockMap.get(endKey)]])
}
Calling getSelectionInlineStyle(myState) will now return a set of intersecting styles, taking into account multiple blocks.
I believe there is a bug in getCurrentInlineStyle (or, if it's current behavior is intentional, it is inconsistent with typical rich text editor behavior).
When selecting a block of text in which different characters have different styles, getCurrentInlineStyle usually doesn't show styles that aren't applied to the entire selection. This seems to be standard practice. However, it will show styles that are applied to the very start of the selection, even if they aren't applied throughout, which seems inconsistent.
This can be observed in the sample editor at https://facebook.github.io/draft-js/ Enter : foo bar bat. Highlight the whole line and the bold button will not be lit. Highlight "foo bar" and, again, bold is unlit. Highlight "bar bat" and bold will light, despite the fact that all the characters in the selection are not bold.
I'm seeing this in version 0.9.1