Browse Source

Links, prepareInsert()

Yedidya Kennard 8 years ago
parent
commit
3ecc5c89a6

+ 129
- 11
src/RichTextEditor.js View File

2
 import WebViewBridge from 'react-native-webview-bridge-updated';
2
 import WebViewBridge from 'react-native-webview-bridge-updated';
3
 import {InjectedMessageHandler} from './WebviewMessageHandler';
3
 import {InjectedMessageHandler} from './WebviewMessageHandler';
4
 import {actions, messages} from './const';
4
 import {actions, messages} from './const';
5
+import {Modal, View, Text, StyleSheet, TextInput, TouchableOpacity} from 'react-native';
5
 
6
 
6
 const injectScript = `
7
 const injectScript = `
7
   (function () {
8
   (function () {
22
     this.registerToolbar = this.registerToolbar.bind(this);
23
     this.registerToolbar = this.registerToolbar.bind(this);
23
     this.onBridgeMessage = this.onBridgeMessage.bind(this);
24
     this.onBridgeMessage = this.onBridgeMessage.bind(this);
24
     this.state = {
25
     this.state = {
25
-      listeners: []
26
+      listeners: [],
27
+      showLinkDialog: false,
28
+      linkTitle: '',
29
+      linkUrl: ''
26
     };
30
     };
27
   }
31
   }
28
 
32
 
80
     }
84
     }
81
   }
85
   }
82
 
86
 
87
+  _renderLinkModal() {
88
+    return (
89
+        <Modal
90
+            animationType={"fade"}
91
+            transparent
92
+            visible={this.state.showLinkDialog}
93
+            onRequestClose={() => this.setState({showLinkDialog: false})}
94
+        >
95
+          <View style={styles.modal}>
96
+
97
+
98
+            <View style={styles.innerModal}>
99
+
100
+              <Text>Title</Text>
101
+              <View style={styles.inputWrapper}>
102
+                <TextInput
103
+                    style={{height: 20}}
104
+                    onChangeText={(text) => this.setState({linkTitle: text})}
105
+                    value={this.state.linkTitle}
106
+                />
107
+              </View>
108
+
109
+              <Text style={{marginTop: 10}}>URL</Text>
110
+              <View style={styles.inputWrapper}>
111
+                <TextInput
112
+                    style={{height: 20}}
113
+                    onChangeText={(text) => this.setState({linkUrl: text})}
114
+                    value={this.state.linkUrl}
115
+                />
116
+              </View>
117
+
118
+              {this._renderModalButtons()}
119
+            </View>
120
+          </View>
121
+        </Modal>
122
+    );
123
+  }
124
+
125
+  _hideModal() {
126
+    this.setState({
127
+      showLinkDialog: false,
128
+      linkTitle: '',
129
+      linkUrl: ''
130
+    })
131
+  }
132
+
133
+  _renderModalButtons() {
134
+    return (
135
+      <View style={{paddingTop: 10, alignSelf: 'stretch', flexDirection: 'row'}}>
136
+        <View style={{flex: 1}}/>
137
+        <TouchableOpacity
138
+            onPress={() => this._hideModal()}
139
+        >
140
+          <Text style={[styles.button, {paddingRight: 10}]}>
141
+            Cancel
142
+          </Text>
143
+        </TouchableOpacity>
144
+        <TouchableOpacity
145
+            onPress={() => {
146
+              this.insertLink(this.state.linkUrl, this.state.linkTitle);
147
+              this._hideModal();
148
+            }}
149
+        >
150
+          <Text style={styles.button}>
151
+            OK
152
+          </Text>
153
+        </TouchableOpacity>
154
+      </View>
155
+    );
156
+  }
157
+
83
   render() {
158
   render() {
84
     return (
159
     return (
85
-      <WebViewBridge
86
-        {...this.props}
87
-        hideKeyboardAccessoryView={true}
88
-        ref={(r) => {this.webviewBridge = r}}
89
-        onBridgeMessage={(message) => this.onBridgeMessage(message)}
90
-        injectedJavaScript={injectScript}
91
-        source={require('./editor.html')}
92
-      />
160
+      <View style={{flex: 1}}>
161
+        <WebViewBridge
162
+          style={{flex: 1}}
163
+          {...this.props}
164
+          hideKeyboardAccessoryView={true}
165
+          ref={(r) => {this.webviewBridge = r}}
166
+          onBridgeMessage={(message) => this.onBridgeMessage(message)}
167
+          injectedJavaScript={injectScript}
168
+          source={require('./editor.html')}
169
+        />
170
+        {this._renderLinkModal()}
171
+      </View>
93
     );
172
     );
94
   }
173
   }
95
 
174
 
114
   //-------------------------------------------------------------------------------
193
   //-------------------------------------------------------------------------------
115
   //--------------- Public API
194
   //--------------- Public API
116
 
195
 
196
+  showLinkDialog() {
197
+    this.setState({
198
+      showLinkDialog: true
199
+    });
200
+  }
201
+
117
   focusTitle() {
202
   focusTitle() {
118
     this._sendAction(actions.focusTitle);
203
     this._sendAction(actions.focusTitle);
119
-  }wewe
204
+  }
120
 
205
 
121
   focusContent() {
206
   focusContent() {
122
     this._sendAction(actions.focusContent);
207
     this._sendAction(actions.focusContent);
213
   }
298
   }
214
 
299
 
215
   insertLink(url, title) {
300
   insertLink(url, title) {
301
+
216
     this._sendAction(actions.insertLink, {url, title});
302
     this._sendAction(actions.insertLink, {url, title});
217
   }
303
   }
218
 
304
 
252
     this._sendAction(actions.setContentPlaceholder);
338
     this._sendAction(actions.setContentPlaceholder);
253
   }
339
   }
254
 
340
 
341
+  prepareInsert() {
342
+    this._sendAction(actions.prepareInsert);
343
+  }
344
+
345
+  restoreSelection() {
346
+    this._sendAction(actions.restoreSelection);
347
+  }
348
+
255
   async getTitleHtml() {
349
   async getTitleHtml() {
256
     return new Promise((resolve, reject) => {
350
     return new Promise((resolve, reject) => {
257
       this.titleResolve = resolve;
351
       this.titleResolve = resolve;
289
     this.contentFocusHandler = callbackHandler;
383
     this.contentFocusHandler = callbackHandler;
290
     this._sendAction(actions.setContentFocusHandler);
384
     this._sendAction(actions.setContentFocusHandler);
291
   }
385
   }
292
-}
386
+}
387
+
388
+const styles = StyleSheet.create({
389
+  modal: {
390
+    flex: 1,
391
+    justifyContent: 'center',
392
+    alignItems: 'center',
393
+    backgroundColor: 'rgba(0, 0, 0, 0.5)'
394
+  },
395
+  innerModal: {
396
+    backgroundColor: '#ffffff',
397
+    padding: 20,
398
+    alignSelf: 'stretch',
399
+    margin: 40
400
+  },
401
+  button: {
402
+    fontSize: 16
403
+  },
404
+  inputWrapper: {
405
+    marginTop: 10,
406
+    marginBottom: 10,
407
+    borderBottomColor: '#000000',
408
+    borderBottomWidth: 1
409
+  }
410
+});

+ 4
- 0
src/RichTextToolbar.js View File

144
         this.state.editor._sendAction(action);
144
         this.state.editor._sendAction(action);
145
         break;
145
         break;
146
       case actions.insertLink:
146
       case actions.insertLink:
147
+        this.state.editor.prepareInsert();
147
         if(this.props.onPressAddLink) {
148
         if(this.props.onPressAddLink) {
148
           this.props.onPressAddLink();
149
           this.props.onPressAddLink();
150
+        } else {
151
+          this.state.editor.showLinkDialog();
149
         }
152
         }
150
         break;
153
         break;
151
       case actions.insertImage:
154
       case actions.insertImage:
155
+        this.state.editor.prepareInsert();
152
         if(this.props.onPressAddImage) {
156
         if(this.props.onPressAddImage) {
153
           this.props.onPressAddImage();
157
           this.props.onPressAddImage();
154
         }
158
         }

+ 7
- 3
src/WebviewMessageHandler.js View File

69
           zss_editor.setOrderedList();
69
           zss_editor.setOrderedList();
70
           break;
70
           break;
71
         case '${actions.insertLink}':
71
         case '${actions.insertLink}':
72
-          zss_editor.prepareInsert();
73
           zss_editor.insertLink(action.data.url, action.data.title);
72
           zss_editor.insertLink(action.data.url, action.data.title);
74
           break;
73
           break;
75
         case '${actions.insertImage}':
74
         case '${actions.insertImage}':
76
-          zss_editor.prepareInsert();
77
           zss_editor.insertImage(action.data.url, action.data.alt);
75
           zss_editor.insertImage(action.data.url, action.data.alt);
78
           break;
76
           break;
79
         case '${actions.setSubscript}':
77
         case '${actions.setSubscript}':
120
         case '${actions.focusTitle}':
118
         case '${actions.focusTitle}':
121
           zss_editor.focusTitle();
119
           zss_editor.focusTitle();
122
           break;
120
           break;
121
+        case '${actions.prepareInsert}':
122
+          zss_editor.prepareInsert();
123
+          break;
124
+        case '${actions.restoreSelection}':
125
+          zss_editor.restorerange();
126
+          break;
123
       }
127
       }
124
     };
128
     };
125
   }
129
   }
126
-`;
130
+`;

+ 10
- 15
src/ZSSRichTextEditor/ZSSRichTextEditor.js View File

204
 
204
 
205
 zss_editor.backuprange = function(){
205
 zss_editor.backuprange = function(){
206
     var selection = window.getSelection();
206
     var selection = window.getSelection();
207
-    if(selection && selection.length > 0) {
208
-        var range = selection.getRangeAt(0);
209
-        zss_editor.currentSelection = {"startContainer": range.startContainer, "startOffset":range.startOffset,"endContainer":range.endContainer, "endOffset":range.endOffset};
210
-    }
207
+    var range = selection.getRangeAt(0);
208
+    zss_editor.currentSelection = {"startContainer": range.startContainer, "startOffset":range.startOffset,"endContainer":range.endContainer, "endOffset":range.endOffset};
211
 }
209
 }
212
 
210
 
213
 zss_editor.restorerange = function(){
211
 zss_editor.restorerange = function(){
214
     var selection = window.getSelection();
212
     var selection = window.getSelection();
215
-    if(selection && selection.length > 0) {
216
-        selection.removeAllRanges();
217
-        var range = document.createRange();
218
-        range.setStart(zss_editor.currentSelection.startContainer, zss_editor.currentSelection.startOffset);
219
-        range.setEnd(zss_editor.currentSelection.endContainer, zss_editor.currentSelection.endOffset);
220
-        selection.addRange(range);
221
-    }
213
+    selection.removeAllRanges();
214
+    var range = document.createRange();
215
+    range.setStart(zss_editor.currentSelection.startContainer, zss_editor.currentSelection.startOffset);
216
+    range.setEnd(zss_editor.currentSelection.endContainer, zss_editor.currentSelection.endOffset);
217
+    selection.addRange(range);
222
 }
218
 }
223
 
219
 
224
 zss_editor.getSelectedNode = function() {
220
 zss_editor.getSelectedNode = function() {
396
 // Needs addClass method
392
 // Needs addClass method
397
 
393
 
398
 zss_editor.insertLink = function(url, title) {
394
 zss_editor.insertLink = function(url, title) {
399
-    
395
+
400
     zss_editor.restorerange();
396
     zss_editor.restorerange();
401
     var sel = document.getSelection();
397
     var sel = document.getSelection();
402
     console.log(sel);
398
     console.log(sel);
508
 }
504
 }
509
 
505
 
510
 zss_editor.insertImage = function(url, alt) {
506
 zss_editor.insertImage = function(url, alt) {
511
-    zss_editor.focusContent();
512
     zss_editor.restorerange();
507
     zss_editor.restorerange();
513
     var html = '<img src="'+url+'" alt="'+alt+'" />';
508
     var html = '<img src="'+url+'" alt="'+alt+'" />';
514
     zss_editor.insertHTML(html);
509
     zss_editor.insertHTML(html);
708
 }
703
 }
709
 
704
 
710
 zss_editor.focusContent = function() {
705
 zss_editor.focusContent = function() {
711
-    zss_editor.focusEditor('zss_editor_content');
706
+    $('#zss_editor_content').focus();
712
 }
707
 }
713
 
708
 
714
 zss_editor.focusTitle = function() {
709
 zss_editor.focusTitle = function() {
715
-    zss_editor.focusEditor('zss_editor_title');
710
+    $('#zss_editor_title').focus();
716
 }
711
 }
717
 
712
 
718
 zss_editor.focusEditor = function(editorId) {
713
 zss_editor.focusEditor = function(editorId) {

+ 3
- 1
src/const.js View File

36
   setTitlePlaceholder: 'SET_TITLE_PLACEHOLDER',
36
   setTitlePlaceholder: 'SET_TITLE_PLACEHOLDER',
37
   setContentPlaceholder: 'SET_TITLE_PLACEHOLDER',
37
   setContentPlaceholder: 'SET_TITLE_PLACEHOLDER',
38
   setTitleFocusHandler: 'SET_TITLE_FOCUS_HANDLER',
38
   setTitleFocusHandler: 'SET_TITLE_FOCUS_HANDLER',
39
-  setContentFocusHandler: 'SET_CONTENT_FOCUS_HANDLER'
39
+  setContentFocusHandler: 'SET_CONTENT_FOCUS_HANDLER',
40
+  prepareInsert: 'PREPARE_INSERT',
41
+  restoreSelection: 'RESTORE_SELECTION'
40
 };
42
 };
41
 
43
 
42
 
44