Skip to content

Commit e346911

Browse files
authored
Merge pull request wix-incubator#8 from wix/update-offset-and-cursor-calculation-fix
Fix update offset and cursor position calculation
2 parents 7788ddb + 5d75ad3 commit e346911

File tree

4 files changed

+87
-33
lines changed

4 files changed

+87
-33
lines changed

src/RichTextEditor.js

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ import React, {Component, PropTypes} from 'react';
22
import WebViewBridge from 'react-native-webview-bridge-updated';
33
import {InjectedMessageHandler} from './WebviewMessageHandler';
44
import {actions, messages} from './const';
5-
import {Modal, View, Text, StyleSheet, TextInput, TouchableOpacity, Platform, PixelRatio, Keyboard} from 'react-native';
5+
import {Modal, View, Text, StyleSheet, TextInput, TouchableOpacity, Platform, PixelRatio, Keyboard, Dimensions} from 'react-native';
66

77
const injectScript = `
88
(function () {
99
${InjectedMessageHandler}
1010
}());
1111
`;
1212

13-
const PlatfomIOS = Platform.OS === 'ios';
13+
const PlatformIOS = Platform.OS === 'ios';
1414

1515
export default class RichTextEditor extends Component {
1616
static propTypes = {
@@ -21,7 +21,8 @@ export default class RichTextEditor extends Component {
2121
editorInitializedCallback: PropTypes.func,
2222
customCSS: PropTypes.string,
2323
hiddenTitle: PropTypes.bool,
24-
enableOnChange: PropTypes.bool
24+
enableOnChange: PropTypes.bool,
25+
footerHeight: PropTypes.number
2526
};
2627

2728
constructor(props) {
@@ -44,7 +45,7 @@ export default class RichTextEditor extends Component {
4445
}
4546

4647
componentWillMount() {
47-
if(PlatfomIOS) {
48+
if(PlatformIOS) {
4849
this.keyboardEventListeners = [
4950
Keyboard.addListener('keyboardWillShow', this._onKeyboardWillShow),
5051
Keyboard.addListener('keyboardWillHide', this._onKeyboardWillHide)
@@ -67,12 +68,24 @@ export default class RichTextEditor extends Component {
6768
if (this.state.keyboardHeight === newKeyboardHeight) {
6869
return;
6970
}
71+
if (newKeyboardHeight) {
72+
this.setEditorAvailableHeightBasedOnKeyboardHeight(newKeyboardHeight);
73+
}
7074
this.setState({keyboardHeight: newKeyboardHeight});
7175
}
7276

7377
_onKeyboardWillHide(event) {
7478
this.setState({keyboardHeight: 0});
7579
}
80+
81+
setEditorAvailableHeightBasedOnKeyboardHeight(keyboardHeight) {
82+
const {top = 0, bottom = 0} = this.props.contentInset;
83+
const {marginTop = 0, marginBottom = 0} = this.props.style;
84+
const spacing = marginTop + marginBottom + top + bottom;
85+
86+
const editorAvailableHeight = Dimensions.get('window').height - keyboardHeight - spacing;
87+
this.setEditorHeight(editorAvailableHeight);
88+
}
7689

7790
onBridgeMessage(str){
7891
try {
@@ -189,7 +202,7 @@ export default class RichTextEditor extends Component {
189202
onRequestClose={() => this.setState({showLinkDialog: false})}
190203
>
191204
<View style={styles.modal}>
192-
<View style={[styles.innerModal, {marginBottom: PlatfomIOS ? this.state.keyboardHeight : 0}]}>
205+
<View style={[styles.innerModal, {marginBottom: PlatformIOS ? this.state.keyboardHeight : 0}]}>
193206
<Text style={styles.inputTitle}>Title</Text>
194207
<View style={styles.inputWrapper}>
195208
<TextInput
@@ -209,7 +222,7 @@ export default class RichTextEditor extends Component {
209222
autoCorrect={false}
210223
/>
211224
</View>
212-
{PlatfomIOS && <View style={styles.lineSeparator}/>}
225+
{PlatformIOS && <View style={styles.lineSeparator}/>}
213226
{this._renderModalButtons()}
214227
</View>
215228
</View>
@@ -228,11 +241,11 @@ export default class RichTextEditor extends Component {
228241

229242
_renderModalButtons() {
230243
const insertUpdateDisabled = this.state.linkTitle.trim().length <= 0 || this.state.linkUrl.trim().length <= 0;
231-
const containerPlatformStyle = PlatfomIOS ? {justifyContent: 'space-between'} : {paddingTop: 15};
232-
const buttonPlatformStyle = PlatfomIOS ? {flex: 1, height: 45, justifyContent: 'center'} : {};
244+
const containerPlatformStyle = PlatformIOS ? {justifyContent: 'space-between'} : {paddingTop: 15};
245+
const buttonPlatformStyle = PlatformIOS ? {flex: 1, height: 45, justifyContent: 'center'} : {};
233246
return (
234247
<View style={[{alignSelf: 'stretch', flexDirection: 'row'}, containerPlatformStyle]}>
235-
{!PlatfomIOS && <View style={{flex: 1}}/>}
248+
{!PlatformIOS && <View style={{flex: 1}}/>}
236249
<TouchableOpacity
237250
onPress={() => this._hideModal()}
238251
style={buttonPlatformStyle}
@@ -266,16 +279,15 @@ export default class RichTextEditor extends Component {
266279
}
267280

268281
_upperCaseButtonTextIfNeeded(buttonText) {
269-
return PlatfomIOS ? buttonText : buttonText.toUpperCase();
282+
return PlatformIOS ? buttonText : buttonText.toUpperCase();
270283
}
271284

272285
render() {
273286
//in release build, external html files in Android can't be required, so they must be placed in the assets folder and accessed via uri
274-
const pageSource = PlatfomIOS ? require('./editor.html') : { uri: 'file:///android_asset/editor.html' };
287+
const pageSource = PlatformIOS ? require('./editor.html') : { uri: 'file:///android_asset/editor.html' };
275288
return (
276289
<View style={{flex: 1}}>
277290
<WebViewBridge
278-
style={{flex: 1}}
279291
{...this.props}
280292
hideKeyboardAccessoryView={true}
281293
keyboardDisplayRequiresUserAction={false}
@@ -504,6 +516,22 @@ export default class RichTextEditor extends Component {
504516

505517
init() {
506518
this._sendAction(actions.init);
519+
this.setPlatform();
520+
if (this.props.footerHeight) {
521+
this.setFooterHeight();
522+
}
523+
}
524+
525+
setEditorHeight(height) {
526+
this._sendAction(actions.setEditorHeight, height);
527+
}
528+
529+
setFooterHeight() {
530+
this._sendAction(actions.setFooterHeight, this.props.footerHeight);
531+
}
532+
533+
setPlatform() {
534+
this._sendAction(actions.setPlatform, Platform.OS);
507535
}
508536

509537
async getTitleHtml() {
@@ -587,12 +615,12 @@ const styles = StyleSheet.create({
587615
innerModal: {
588616
backgroundColor: 'rgba(255, 255, 255, 0.9)',
589617
paddingTop: 20,
590-
paddingBottom: PlatfomIOS ? 0 : 20,
618+
paddingBottom: PlatformIOS ? 0 : 20,
591619
paddingLeft: 20,
592620
paddingRight: 20,
593621
alignSelf: 'stretch',
594622
margin: 40,
595-
borderRadius: PlatfomIOS ? 8 : 2
623+
borderRadius: PlatformIOS ? 8 : 2
596624
},
597625
button: {
598626
fontSize: 16,
@@ -603,13 +631,13 @@ const styles = StyleSheet.create({
603631
marginTop: 5,
604632
marginBottom: 10,
605633
borderBottomColor: '#4a4a4a',
606-
borderBottomWidth: PlatfomIOS ? 1 / PixelRatio.get() : 0
634+
borderBottomWidth: PlatformIOS ? 1 / PixelRatio.get() : 0
607635
},
608636
inputTitle: {
609637
color: '#4a4a4a'
610638
},
611639
input: {
612-
height: PlatfomIOS ? 20 : 40,
640+
height: PlatformIOS ? 20 : 40,
613641
paddingTop: 0
614642
},
615643
lineSeparator: {

src/WebviewMessageHandler.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,15 @@ export const InjectedMessageHandler = `
161161
case '${actions.init}':
162162
zss_editor.init();
163163
break;
164+
case '${actions.setEditorHeight}':
165+
zss_editor.setEditorHeight(action.data);
166+
break;
167+
case '${actions.setFooterHeight}':
168+
zss_editor.setFooterHeight(action.data);
169+
break;
170+
case '${actions.setPlatform}':
171+
zss_editor.setPlatform(action.data);
172+
break;
164173
}
165174
};
166175
}

src/const.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ export const actions = {
4949
setCustomCSS: 'SET_CUSTOM_CSS',
5050
setTextColor: 'SET_TEXT_COLOR',
5151
setBackgroundColor: 'SET_BACKGROUND_COLOR',
52-
init: 'ZSSS_INIT'
52+
init: 'ZSSS_INIT',
53+
setEditorHeight: 'SET_EDITOR_HEIGHT',
54+
setFooterHeight: 'SET_FOOTER_HEIGHT',
55+
setPlatform: 'SET_PLATFORM'
5356
};
5457

5558

src/editor.html

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@
808808
zss_editor.enabledItems = {};
809809

810810
// Height of content window, will be set by viewController
811-
zss_editor.contentHeight = 244;
811+
zss_editor.editorHeight = 244;
812812

813813
// Sets to true when extra footer gap shows and requires to hide
814814
zss_editor.updateScrollOffset = false;
@@ -902,6 +902,11 @@
902902
$(window).on('touchstart', function(e) {
903903
zss_editor.isDragging = false;
904904
});
905+
$(window).on('scroll', function(e) {
906+
if (zss_editor.platform === 'ios') {
907+
zss_editor.updateOffset();
908+
}
909+
});
905910

906911
setupTouchEndFocus('zss_editor_title');
907912
setupTouchEndFocus('zss_editor_content');
@@ -965,9 +970,9 @@
965970

966971
var offsetY = window.document.body.scrollTop;
967972

968-
var footer = $('#zss_editor_footer');
973+
var footer = document.getElementById('zss_editor_footer');
969974

970-
var maxOffsetY = footer.offset().top - zss_editor.contentHeight;
975+
var maxOffsetY = footer.offsetTop + footer.offsetHeight - zss_editor.editorHeight;
971976

972977
if (maxOffsetY < 0)
973978
maxOffsetY = 0;
@@ -1033,22 +1038,23 @@
10331038
}
10341039

10351040
zss_editor.calculateEditorHeightWithCaretPosition = function() {
1036-
1037-
var padding = 50;
1038-
var c = zss_editor.getCaretYPosition();
1039-
1041+
var caretYPosition = zss_editor.getCaretYPosition();
1042+
var lineHeight = 20;
1043+
var halfLineHeight = lineHeight/2;
10401044
var offsetY = window.document.body.scrollTop;
1041-
var height = zss_editor.contentHeight;
1042-
1043-
var newPos = window.pageYOffset;
1044-
1045-
if (c < offsetY) {
1046-
newPos = c;
1047-
} else if (c > (offsetY + height - padding)) {
1048-
newPos = c - height + padding - 18;
1045+
var editorHeight = zss_editor.editorHeight;
1046+
var newPos;
1047+
1048+
var futureEditorHeight = caretYPosition + lineHeight;
1049+
if (caretYPosition < offsetY) {
1050+
newPos = caretYPosition;
1051+
} else if (futureEditorHeight > editorHeight + offsetY) {
1052+
newPos = futureEditorHeight - editorHeight + halfLineHeight;
10491053
}
10501054

1051-
window.scrollTo(0, newPos);
1055+
if (newPos) {
1056+
window.scrollTo(0, newPos);
1057+
}
10521058
}
10531059

10541060
zss_editor.backuprange = function(){
@@ -1629,6 +1635,14 @@
16291635
});
16301636
}
16311637

1638+
zss_editor.setEditorHeight = function(editorHeight) {
1639+
zss_editor.editorHeight = editorHeight;
1640+
}
1641+
1642+
zss_editor.setPlatform = function(platform) {
1643+
zss_editor.platform = platform;
1644+
}
1645+
16321646
//end
16331647
</script>
16341648

0 commit comments

Comments
 (0)