slate-react
Advanced tools
Comparing version 0.10.3 to 0.10.4
@@ -118,2 +118,3 @@ 'use strict'; | ||
var selection = value.selection; | ||
var isBackward = selection.isBackward; | ||
@@ -150,5 +151,16 @@ var window = (0, _getWindow2.default)(_this.element); | ||
// If the new range matches the current selection, do nothing. | ||
if (current && range.startContainer == current.startContainer && range.startOffset == current.startOffset && range.endContainer == current.endContainer && range.endOffset == current.endOffset) { | ||
return; | ||
var startContainer = range.startContainer, | ||
startOffset = range.startOffset, | ||
endContainer = range.endContainer, | ||
endOffset = range.endOffset; | ||
// If the new range matches the current selection, there is nothing to fix. | ||
// COMPAT: The native `Range` object always has it's "start" first and "end" | ||
// last in the DOM. It has no concept of "backwards/forwards", so we have | ||
// to check both orientations here. (2017/10/31) | ||
if (current) { | ||
if (startContainer == current.startContainer && startOffset == current.startOffset && endContainer == current.endContainer && endOffset == current.endOffset || startContainer == current.endContainer && startOffset == current.endOffset && endContainer == current.startContainer && endOffset == current.startOffset) { | ||
return; | ||
} | ||
} | ||
@@ -159,3 +171,12 @@ | ||
native.removeAllRanges(); | ||
native.addRange(range); | ||
// COMPAT: Again, since the DOM range has no concept of backwards/forwards | ||
// we need to check and do the right thing here. | ||
if (isBackward) { | ||
native.setBaseAndExtent(endContainer, endOffset, startContainer, startOffset); | ||
} else { | ||
native.setBaseAndExtent(startContainer, startOffset, endContainer, endOffset); | ||
} | ||
// Scroll to the selection, in case it's out of view. | ||
(0, _scrollToSelection2.default)(native); | ||
@@ -162,0 +183,0 @@ |
@@ -167,3 +167,2 @@ 'use strict'; | ||
node = _props3.node, | ||
parent = _props3.parent, | ||
text = _props3.text, | ||
@@ -173,16 +172,6 @@ index = _props3.index, | ||
// COMPAT: If the text is empty and it's the only child, we need to render a | ||
// line break to get the block to have the proper height. | ||
if (text == '' && parent.kind == 'block' && parent.text == '') { | ||
return _react2.default.createElement( | ||
'span', | ||
{ 'data-slate-empty-block': true }, | ||
'\n' | ||
); | ||
} | ||
// COMPAT: If the text is empty otherwise, it's because it's on the edge of | ||
// an inline void node, so we render a zero-width space so that the | ||
// selection can be inserted next to it still. | ||
if (text == '') return _react2.default.createElement( | ||
@@ -189,0 +178,0 @@ 'span', |
@@ -309,2 +309,11 @@ 'use strict'; | ||
div.style.left = '-9999px'; | ||
// COMPAT: In Firefox, the viewport jumps to find the phony div, so it | ||
// should be created at the current scroll offset with `style.top`. | ||
// The box model attributes which can interact with 'top' are also reset. | ||
div.style.border = '0px'; | ||
div.style.padding = '0px'; | ||
div.style.margin = '0px'; | ||
div.style.top = (window.pageYOffset || window.document.documentElement.scrollTop) + 'px'; | ||
div.appendChild(contents); | ||
@@ -841,2 +850,3 @@ body.appendChild(div); | ||
if (!editor.props.placeholder) return; | ||
if (editor.state.isComposing) return; | ||
@@ -843,0 +853,0 @@ if (node.kind != 'block') return; |
@@ -393,7 +393,7 @@ 'use strict'; | ||
// When composing, these characters commit the composition but also move the | ||
// selection before we're able to handle it, so prevent their default, | ||
// selection-moving behavior. | ||
if (isComposing && _hotkeys2.default.COMPOSING(event)) { | ||
event.preventDefault(); | ||
// When composing, we need to prevent all hotkeys from executing while | ||
// typing. However, certain characters also move the selection before | ||
// we're able to handle it, so prevent their default behavior. | ||
if (isComposing) { | ||
if (_hotkeys2.default.COMPOSING(event)) event.preventDefault(); | ||
return true; | ||
@@ -400,0 +400,0 @@ } |
@@ -51,8 +51,2 @@ 'use strict'; | ||
// COMPAT: For empty blocks with only a single empty text node, we will have | ||
// rendered a `<span>` with `\n` inside, instead of a text node. | ||
if (el.childNodes.length == 1 && el.childNodes[0].childNodes.length == 1 && el.childNodes[0].childNodes[0].hasAttributes('data-slate-empty-block')) { | ||
return { node: el.childNodes[0], offset: 0 }; | ||
} | ||
return null; | ||
@@ -59,0 +53,0 @@ } |
@@ -71,5 +71,7 @@ 'use strict'; | ||
// COMPAT: If the parent node is a Slate zero-width space, this is because the | ||
// text node has no characters, so the offset can only be zero. | ||
if (offset != 0 && parentNode.getAttribute('data-slate-zero-width')) { | ||
offset = 0; | ||
// text node should have no characters. However, during IME composition the | ||
// ASCII characters will be prepended to the zero-width space, so subtract 1 | ||
// from the offset to account for the zero-width space character. | ||
if (offset == node.textContent.length && parentNode.hasAttribute('data-slate-zero-width')) { | ||
offset--; | ||
} | ||
@@ -76,0 +78,0 @@ |
@@ -18,2 +18,38 @@ 'use strict'; | ||
/** | ||
* CSS overflow values that would cause scrolling. | ||
* | ||
* @type {Array} | ||
*/ | ||
var OVERFLOWS = ['auto', 'overlay', 'scroll']; | ||
/** | ||
* Find the nearest parent with scrolling, or window. | ||
* | ||
* @param {el} Element | ||
*/ | ||
function findScrollContainer(el) { | ||
var window = (0, _getWindow2.default)(el); | ||
var parent = el.parentNode; | ||
var scroller = window; | ||
while (!scroller) { | ||
if (!parent.parentNode) break; | ||
var style = window.getComputedStyle(parent); | ||
var overflowY = style.overflowY; | ||
if (OVERFLOWS.includes(overflowY)) { | ||
scroller = parent; | ||
break; | ||
} | ||
parent = parent.parentNode; | ||
} | ||
return scroller; | ||
} | ||
/** | ||
* Scroll the current selection's focus point into view if needed. | ||
@@ -28,18 +64,47 @@ * | ||
var window = (0, _getWindow2.default)(selection.anchorNode); | ||
var scroller = findScrollContainer(selection.anchorNode); | ||
var isWindow = scroller == window; | ||
var backward = (0, _selectionIsBackward2.default)(selection); | ||
var range = selection.getRangeAt(0); | ||
var rect = range.getBoundingClientRect(); | ||
var innerWidth = window.innerWidth, | ||
innerHeight = window.innerHeight, | ||
pageYOffset = window.pageYOffset, | ||
pageXOffset = window.pageXOffset; | ||
var width = void 0; | ||
var height = void 0; | ||
var yOffset = void 0; | ||
var xOffset = void 0; | ||
var top = (backward ? rect.top : rect.bottom) + pageYOffset; | ||
var left = (backward ? rect.left : rect.right) + pageXOffset; | ||
if (isWindow) { | ||
var _innerWidth = scroller.innerWidth, | ||
innerHeight = scroller.innerHeight, | ||
pageYOffset = scroller.pageYOffset, | ||
pageXOffset = scroller.pageXOffset; | ||
var x = left < pageXOffset || innerWidth + pageXOffset < left ? left - innerWidth / 2 : pageXOffset; | ||
width = _innerWidth; | ||
height = innerHeight; | ||
yOffset = pageYOffset; | ||
xOffset = pageXOffset; | ||
} else { | ||
var offsetWidth = scroller.offsetWidth, | ||
offsetHeight = scroller.offsetHeight, | ||
scrollTop = scroller.scrollTop, | ||
scrollLeft = scroller.scrollLeft; | ||
var y = top < pageYOffset || innerHeight + pageYOffset < top ? top - innerHeight / 2 : pageYOffset; | ||
width = offsetWidth; | ||
height = offsetHeight; | ||
yOffset = scrollTop; | ||
xOffset = scrollLeft; | ||
} | ||
window.scrollTo(x, y); | ||
var top = (backward ? rect.top : rect.bottom) + yOffset; | ||
var left = (backward ? rect.left : rect.right) + xOffset; | ||
var x = left < yOffset || innerWidth + xOffset < left ? left - width / 2 : xOffset; | ||
var y = top < yOffset || height + yOffset < top ? top - height / 2 : yOffset; | ||
if (isWindow) { | ||
window.scrollTo(x, y); | ||
} else { | ||
scroller.scrollTop = scroller.scrollTop + y; | ||
scroller.scrollLeft = scroller.scrollLeft + x; | ||
} | ||
} | ||
@@ -46,0 +111,0 @@ |
{ | ||
"name": "slate-react", | ||
"description": "A set of React components for building completely customizable rich-text editors.", | ||
"version": "0.10.3", | ||
"version": "0.10.4", | ||
"license": "MIT", | ||
@@ -6,0 +6,0 @@ "repository": "git://github.com/ianstormtaylor/slate.git", |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
744299
33
15129