Skip to content

Commit e899799

Browse files
committed
#WOA-2970|#WOA-2603|Fix update offset and cursor position calculation
1 parent cf47487 commit e899799

File tree

4 files changed

+78
-32
lines changed

4 files changed

+78
-32
lines changed

src/RichTextEditor.js

Lines changed: 35 additions & 15 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 = {
@@ -43,7 +43,7 @@ export default class RichTextEditor extends Component {
4343
}
4444

4545
componentWillMount() {
46-
if(PlatfomIOS) {
46+
if(PlatformIOS) {
4747
this.keyboardEventListeners = [
4848
Keyboard.addListener('keyboardWillShow', this._onKeyboardWillShow),
4949
Keyboard.addListener('keyboardWillHide', this._onKeyboardWillHide)
@@ -66,12 +66,24 @@ export default class RichTextEditor extends Component {
6666
if (this.state.keyboardHeight === newKeyboardHeight) {
6767
return;
6868
}
69+
if (newKeyboardHeight) {
70+
this.setEditorAvailableHeightBasedOnKeyboardHeight(newKeyboardHeight);
71+
}
6972
this.setState({keyboardHeight: newKeyboardHeight});
7073
}
7174

7275
_onKeyboardWillHide(event) {
7376
this.setState({keyboardHeight: 0});
7477
}
78+
79+
setEditorAvailableHeightBasedOnKeyboardHeight(keyboardHeight) {
80+
const {top = 0, bottom = 0} = this.props.contentInset;
81+
const {marginTop = 0, marginBottom = 0} = this.props.style;
82+
const spacing = marginTop + marginBottom + top + bottom;
83+
84+
const editorAvailableHeight = Dimensions.get('window').height - keyboardHeight - spacing;
85+
this.setEditorHeight(editorAvailableHeight);
86+
}
7587

7688
onBridgeMessage(str){
7789
try {
@@ -177,7 +189,7 @@ export default class RichTextEditor extends Component {
177189
onRequestClose={() => this.setState({showLinkDialog: false})}
178190
>
179191
<View style={styles.modal}>
180-
<View style={[styles.innerModal, {marginBottom: PlatfomIOS ? this.state.keyboardHeight : 0}]}>
192+
<View style={[styles.innerModal, {marginBottom: PlatformIOS ? this.state.keyboardHeight : 0}]}>
181193
<Text style={styles.inputTitle}>Title</Text>
182194
<View style={styles.inputWrapper}>
183195
<TextInput
@@ -197,7 +209,7 @@ export default class RichTextEditor extends Component {
197209
autoCorrect={false}
198210
/>
199211
</View>
200-
{PlatfomIOS && <View style={styles.lineSeparator}/>}
212+
{PlatformIOS && <View style={styles.lineSeparator}/>}
201213
{this._renderModalButtons()}
202214
</View>
203215
</View>
@@ -216,11 +228,11 @@ export default class RichTextEditor extends Component {
216228

217229
_renderModalButtons() {
218230
const insertUpdateDisabled = this.state.linkTitle.trim().length <= 0 || this.state.linkUrl.trim().length <= 0;
219-
const containerPlatformStyle = PlatfomIOS ? {justifyContent: 'space-between'} : {paddingTop: 15};
220-
const buttonPlatformStyle = PlatfomIOS ? {flex: 1, height: 45, justifyContent: 'center'} : {};
231+
const containerPlatformStyle = PlatformIOS ? {justifyContent: 'space-between'} : {paddingTop: 15};
232+
const buttonPlatformStyle = PlatformIOS ? {flex: 1, height: 45, justifyContent: 'center'} : {};
221233
return (
222234
<View style={[{alignSelf: 'stretch', flexDirection: 'row'}, containerPlatformStyle]}>
223-
{!PlatfomIOS && <View style={{flex: 1}}/>}
235+
{!PlatformIOS && <View style={{flex: 1}}/>}
224236
<TouchableOpacity
225237
onPress={() => this._hideModal()}
226238
style={buttonPlatformStyle}
@@ -254,16 +266,15 @@ export default class RichTextEditor extends Component {
254266
}
255267

256268
_upperCaseButtonTextIfNeeded(buttonText) {
257-
return PlatfomIOS ? buttonText : buttonText.toUpperCase();
269+
return PlatformIOS ? buttonText : buttonText.toUpperCase();
258270
}
259271

260272
render() {
261273
//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
262-
const pageSource = PlatfomIOS ? require('./editor.html') : { uri: 'file:///android_asset/editor.html' };
274+
const pageSource = PlatformIOS ? require('./editor.html') : { uri: 'file:///android_asset/editor.html' };
263275
return (
264276
<View style={{flex: 1}}>
265277
<WebViewBridge
266-
style={{flex: 1}}
267278
{...this.props}
268279
hideKeyboardAccessoryView={true}
269280
keyboardDisplayRequiresUserAction={false}
@@ -492,6 +503,15 @@ export default class RichTextEditor extends Component {
492503

493504
init() {
494505
this._sendAction(actions.init);
506+
this.setPlatform();
507+
}
508+
509+
setEditorHeight(height) {
510+
this._sendAction(actions.setEditorHeight, height);
511+
}
512+
513+
setPlatform() {
514+
this._sendAction(actions.setPlatform, Platform.OS);
495515
}
496516

497517
async getTitleHtml() {
@@ -571,12 +591,12 @@ const styles = StyleSheet.create({
571591
innerModal: {
572592
backgroundColor: 'rgba(255, 255, 255, 0.9)',
573593
paddingTop: 20,
574-
paddingBottom: PlatfomIOS ? 0 : 20,
594+
paddingBottom: PlatformIOS ? 0 : 20,
575595
paddingLeft: 20,
576596
paddingRight: 20,
577597
alignSelf: 'stretch',
578598
margin: 40,
579-
borderRadius: PlatfomIOS ? 8 : 2
599+
borderRadius: PlatformIOS ? 8 : 2
580600
},
581601
button: {
582602
fontSize: 16,
@@ -587,13 +607,13 @@ const styles = StyleSheet.create({
587607
marginTop: 5,
588608
marginBottom: 10,
589609
borderBottomColor: '#4a4a4a',
590-
borderBottomWidth: PlatfomIOS ? 1 / PixelRatio.get() : 0
610+
borderBottomWidth: PlatformIOS ? 1 / PixelRatio.get() : 0
591611
},
592612
inputTitle: {
593613
color: '#4a4a4a'
594614
},
595615
input: {
596-
height: PlatfomIOS ? 20 : 40,
616+
height: PlatformIOS ? 20 : 40,
597617
paddingTop: 0
598618
},
599619
lineSeparator: {

src/WebviewMessageHandler.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,12 @@ 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.setPlatform}':
168+
zss_editor.setPlatform(action.data);
169+
break;
164170
}
165171
};
166172
}

src/const.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ 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+
setPlatform: 'SET_PLATFORM'
5355
};
5456

5557

src/editor.html

Lines changed: 34 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;
@@ -901,6 +901,11 @@
901901
$(window).on('touchstart', function(e) {
902902
zss_editor.isDragging = false;
903903
});
904+
$(window).on('scroll', function(e) {
905+
if (zss_editor.platform === 'ios') {
906+
zss_editor.updateOffset();
907+
}
908+
});
904909

905910
setupTouchEndFocus('zss_editor_title');
906911
setupTouchEndFocus('zss_editor_content');
@@ -952,9 +957,9 @@
952957

953958
var offsetY = window.document.body.scrollTop;
954959

955-
var footer = $('#zss_editor_footer');
960+
var footer = document.getElementById('zss_editor_footer');
956961

957-
var maxOffsetY = footer.offset().top - zss_editor.contentHeight;
962+
var maxOffsetY = footer.offsetTop + footer.offsetHeight - zss_editor.editorHeight;
958963

959964
if (maxOffsetY < 0)
960965
maxOffsetY = 0;
@@ -1020,22 +1025,23 @@
10201025
}
10211026

10221027
zss_editor.calculateEditorHeightWithCaretPosition = function() {
1023-
1024-
var padding = 50;
1025-
var c = zss_editor.getCaretYPosition();
1026-
1028+
var caretYPosition = zss_editor.getCaretYPosition();
1029+
var lineHeight = 20;
1030+
var halfLineHeight = lineHeight/2;
10271031
var offsetY = window.document.body.scrollTop;
1028-
var height = zss_editor.contentHeight;
1029-
1030-
var newPos = window.pageYOffset;
1031-
1032-
if (c < offsetY) {
1033-
newPos = c;
1034-
} else if (c > (offsetY + height - padding)) {
1035-
newPos = c - height + padding - 18;
1032+
var editorHeight = zss_editor.editorHeight;
1033+
var newPos;
1034+
1035+
var futureEditorHeight = caretYPosition + lineHeight;
1036+
if (caretYPosition < offsetY) {
1037+
newPos = caretYPosition;
1038+
} else if (futureEditorHeight > editorHeight + offsetY) {
1039+
newPos = futureEditorHeight - editorHeight + halfLineHeight;
10361040
}
10371041

1038-
window.scrollTo(0, newPos);
1042+
if (newPos) {
1043+
window.scrollTo(0, newPos);
1044+
}
10391045
}
10401046

10411047
zss_editor.backuprange = function(){
@@ -1604,6 +1610,14 @@
16041610
});
16051611
}
16061612

1613+
zss_editor.setEditorHeight = function(editorHeight) {
1614+
zss_editor.editorHeight = editorHeight;
1615+
}
1616+
1617+
zss_editor.setPlatform = function(platform) {
1618+
zss_editor.platform = platform;
1619+
}
1620+
16071621
//end
16081622
</script>
16091623

@@ -1696,6 +1710,10 @@
16961710
padding-left: 10px;
16971711
padding-right: 10px;
16981712
}
1713+
1714+
#zss_editor_footer {
1715+
height: 10px;
1716+
}
16991717
</style>
17001718

17011719
<style type="text/css">

0 commit comments

Comments
 (0)