zhangchao 4 년 전
부모
커밋
9d8ee04b6a

BIN
img/icon_format_bold@1.5x.png 파일 보기


BIN
img/icon_format_bold@1x.png 파일 보기


BIN
img/icon_format_bold@2x.png 파일 보기


BIN
img/icon_format_bold@3x.png 파일 보기


BIN
img/icon_format_bold@4x.png 파일 보기


BIN
img/icon_format_italic@1.5x.png 파일 보기


BIN
img/icon_format_italic@1x.png 파일 보기


BIN
img/icon_format_italic@2x.png 파일 보기


BIN
img/icon_format_italic@3x.png 파일 보기


BIN
img/icon_format_italic@4x.png 파일 보기


BIN
img/icon_format_link@1.5x.png 파일 보기


BIN
img/icon_format_link@1x.png 파일 보기


BIN
img/icon_format_link@2x.png 파일 보기


BIN
img/icon_format_link@3x.png 파일 보기


BIN
img/icon_format_link@4x.png 파일 보기


BIN
img/icon_format_media@1.5x.png 파일 보기


BIN
img/icon_format_media@1x.png 파일 보기


BIN
img/icon_format_media@2x.png 파일 보기


BIN
img/icon_format_media@3x.png 파일 보기


BIN
img/icon_format_media@4x.png 파일 보기


BIN
img/icon_format_ol@1.5x.png 파일 보기


BIN
img/icon_format_ol@1x.png 파일 보기


BIN
img/icon_format_ol@2x.png 파일 보기


BIN
img/icon_format_ol@3x.png 파일 보기


BIN
img/icon_format_ol@4x.png 파일 보기


BIN
img/icon_format_ul@1.5x.png 파일 보기


BIN
img/icon_format_ul@1x.png 파일 보기


BIN
img/icon_format_ul@2x.png 파일 보기


BIN
img/icon_format_ul@3x.png 파일 보기


BIN
img/icon_format_ul@4x.png 파일 보기


BIN
readme/editor.png 파일 보기


BIN
readme/toolbar.png 파일 보기


BIN
readme/toolbar_selected.png 파일 보기


+ 4
- 3
src/RichTextEditor.js 파일 보기

@@ -325,6 +325,8 @@ export default class RichTextEditor extends Component {
325 325
 
326 326
   _sendAction(action, data) {
327 327
     let jsToBeExecutedOnPage = MessageConverter({ type: action, data });
328
+
329
+    console.log(jsToBeExecutedOnPage)
328 330
     this.webview.injectJavaScript(jsToBeExecutedOnPage + ';true;');
329 331
   }
330 332
 
@@ -464,9 +466,8 @@ export default class RichTextEditor extends Component {
464 466
     this._sendAction(actions.updateLink, {url, title});
465 467
   }
466 468
 
467
-  insertImage(attributes) {
468
-    this._sendAction(actions.insertImage, attributes);
469
-    this.prepareInsert(); //This must be called BEFORE insertImage. But WebViewBridge uses a stack :/
469
+  insertImage(url) {
470
+    this._sendAction(actions.insertImage, url);
470 471
   }
471 472
 
472 473
   setSubscript() {

+ 0
- 192
src/RichTextToolbar.js 파일 보기

@@ -1,192 +0,0 @@
1
-import React, { Component } from 'react';
2
-import PropTypes from 'prop-types';
3
-import {ListView, View, TouchableOpacity, Image, StyleSheet} from 'react-native';
4
-import {actions} from './const';
5
-
6
-const defaultActions = [
7
-  actions.insertImage,
8
-  actions.setBold,
9
-  actions.setItalic,
10
-  actions.insertBulletsList,
11
-  actions.insertOrderedList,
12
-  actions.insertLink
13
-];
14
-
15
-function getDefaultIcon() {
16
-  const texts = {};
17
-  texts[actions.insertImage] = require('../img/icon_format_media.png');
18
-  texts[actions.setBold] = require('../img/icon_format_bold.png');
19
-  texts[actions.setItalic] = require('../img/icon_format_italic.png');
20
-  texts[actions.insertBulletsList] = require('../img/icon_format_ul.png');
21
-  texts[actions.insertOrderedList] = require('../img/icon_format_ol.png');
22
-  texts[actions.insertLink] = require('../img/icon_format_link.png');
23
-  return texts;
24
-}
25
-
26
-
27
-export default class RichTextToolbar extends Component {
28
-
29
-  static propTypes = {
30
-    getEditor: PropTypes.func.isRequired,
31
-    actions: PropTypes.array,
32
-    onPressAddLink: PropTypes.func,
33
-    onPressAddImage: PropTypes.func,
34
-    selectedButtonStyle: PropTypes.object,
35
-    iconTint: PropTypes.any,
36
-    selectedIconTint: PropTypes.any,
37
-    unselectedButtonStyle: PropTypes.object,
38
-    renderAction: PropTypes.func,
39
-    iconMap: PropTypes.object,
40
-  };
41
-
42
-  constructor(props) {
43
-    super(props);
44
-    const actions = this.props.actions ? this.props.actions : defaultActions;
45
-    this.state = {
46
-      editor: undefined,
47
-      selectedItems: [],
48
-      actions,
49
-      ds: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}).cloneWithRows(this.getRows(actions, []))
50
-    };
51
-  }
52
-
53
-  componentDidReceiveProps(newProps) {
54
-    const actions = newProps.actions ? newProps.actions : defaultActions;
55
-    this.setState({
56
-      actions,
57
-      ds: this.state.ds.cloneWithRows(this.getRows(actions, this.state.selectedItems))
58
-    });
59
-  }
60
-
61
-  getRows(actions, selectedItems) {
62
-    return actions.map((action) => {return {action, selected: selectedItems.includes(action)};});
63
-  }
64
-
65
-  componentDidMount() {
66
-    const editor = this.props.getEditor();
67
-    if (!editor) {
68
-      throw new Error('Toolbar has no editor!');
69
-    } else {
70
-      editor.registerToolbar((selectedItems) => this.setSelectedItems(selectedItems));
71
-      this.setState({editor});
72
-    }
73
-  }
74
-
75
-  setSelectedItems(selectedItems) {
76
-    if (selectedItems !== this.state.selectedItems) {
77
-      this.setState({
78
-        selectedItems,
79
-        ds: this.state.ds.cloneWithRows(this.getRows(this.state.actions, selectedItems))
80
-      });
81
-    }
82
-  }
83
-
84
-  _getButtonSelectedStyle() {
85
-    return this.props.selectedButtonStyle ? this.props.selectedButtonStyle : styles.defaultSelectedButton;
86
-  }
87
-
88
-  _getButtonUnselectedStyle() {
89
-    return this.props.unselectedButtonStyle ? this.props.unselectedButtonStyle : styles.defaultUnselectedButton;
90
-  }
91
-
92
-  _getButtonIcon(action) {
93
-    if (this.props.iconMap && this.props.iconMap[action]) {
94
-      return this.props.iconMap[action];
95
-    } else if (getDefaultIcon()[action]){
96
-      return getDefaultIcon()[action];
97
-    } else {
98
-      return undefined;
99
-    }
100
-  }
101
-
102
-  _defaultRenderAction(action, selected) {
103
-    const icon = this._getButtonIcon(action);
104
-    return (
105
-      <TouchableOpacity
106
-          key={action}
107
-          style={[
108
-            {height: 50, width: 50, justifyContent: 'center'},
109
-            selected ? this._getButtonSelectedStyle() : this._getButtonUnselectedStyle()
110
-          ]}
111
-          onPress={() => this._onPress(action)}
112
-      >
113
-        {icon ? <Image source={icon} style={{tintColor: selected ? this.props.selectedIconTint : this.props.iconTint}}/> : null}
114
-      </TouchableOpacity>
115
-    );
116
-  }
117
-
118
-  _renderAction(action, selected) {
119
-    return this.props.renderAction ?
120
-        this.props.renderAction(action, selected) :
121
-        this._defaultRenderAction(action, selected);
122
-  }
123
-
124
-  render() {
125
-    return (
126
-      <View
127
-          style={[{height: 50, backgroundColor: '#D3D3D3', alignItems: 'center'}, this.props.style]}
128
-      >
129
-        <ListView
130
-            horizontal
131
-            contentContainerStyle={{flexDirection: 'row'}}
132
-            dataSource={this.state.ds}
133
-            renderRow= {(row) => this._renderAction(row.action, row.selected)}
134
-        />
135
-      </View>
136
-    );
137
-  }
138
-
139
-  _onPress(action) {
140
-    switch(action) {
141
-      case actions.setBold:
142
-      case actions.setItalic:
143
-      case actions.insertBulletsList:
144
-      case actions.insertOrderedList:
145
-      case actions.setUnderline:
146
-      case actions.heading1:
147
-      case actions.heading2:
148
-      case actions.heading3:
149
-      case actions.heading4:
150
-      case actions.heading5:
151
-      case actions.heading6:
152
-      case actions.setParagraph:
153
-      case actions.removeFormat:
154
-      case actions.alignLeft:
155
-      case actions.alignCenter:
156
-      case actions.alignRight:
157
-      case actions.alignFull:
158
-      case actions.setSubscript:
159
-      case actions.setSuperscript:
160
-      case actions.setStrikethrough:
161
-      case actions.setHR:
162
-      case actions.setIndent:
163
-      case actions.setOutdent:
164
-        this.state.editor._sendAction(action);
165
-        break;
166
-      case actions.insertLink:
167
-        this.state.editor.prepareInsert();
168
-        if(this.props.onPressAddLink) {
169
-          this.props.onPressAddLink();
170
-        } else {
171
-          this.state.editor.getSelectedText().then(selectedText => {
172
-            this.state.editor.showLinkDialog(selectedText);
173
-          });
174
-        }
175
-        break;
176
-      case actions.insertImage:
177
-        this.state.editor.prepareInsert();
178
-        if(this.props.onPressAddImage) {
179
-          this.props.onPressAddImage();
180
-        }
181
-        break;
182
-        break;
183
-    }
184
-  }
185
-}
186
-
187
-const styles = StyleSheet.create({
188
-  defaultSelectedButton: {
189
-    backgroundColor: 'red'
190
-  },
191
-  defaultUnselectedButton: {}
192
-});

+ 15
- 12
src/editor.html 파일 보기

@@ -917,7 +917,7 @@
917 917
 				whenPastingInsertAsPlainText('zss_editor_title');
918 918
 				whenPastingInsertAsPlainText('zss_editor_content');
919 919
 
920
-				// zss_editor.focusTitle();
920
+				zss_editor.focusContent();
921 921
 
922 922
 				setTimeout(function() {
923 923
 					ReactNativeWebView.postMessage(JSON.stringify({type: 'ZSS_INITIALIZED'}))
@@ -1059,17 +1059,21 @@
1059 1059
 
1060 1060
 			zss_editor.backuprange = function(){
1061 1061
 				var selection = window.getSelection();
1062
-				var range = selection.getRangeAt(0);
1063
-				zss_editor.currentSelection = {"startContainer": range.startContainer, "startOffset":range.startOffset,"endContainer":range.endContainer, "endOffset":range.endOffset};
1062
+				try {
1063
+					var range = selection.getRangeAt(0);
1064
+					zss_editor.currentSelection = {"startContainer": range.startContainer, "startOffset":range.startOffset,"endContainer":range.endContainer, "endOffset":range.endOffset};
1065
+				} catch (err) {}
1064 1066
 			}
1065 1067
 
1066 1068
 			zss_editor.restorerange = function(){
1067
-				// var selection = window.getSelection();
1068
-				// selection.removeAllRanges();
1069
-				// var range = document.createRange();
1070
-				// range.setStart(zss_editor.currentSelection.startContainer, zss_editor.currentSelection.startOffset);
1071
-				// range.setEnd(zss_editor.currentSelection.endContainer, zss_editor.currentSelection.endOffset);
1072
-				// selection.addRange(range);
1069
+				try {
1070
+					var selection = window.getSelection();
1071
+					selection.removeAllRanges();
1072
+					var range = document.createRange();
1073
+					range.setStart(zss_editor.currentSelection.startContainer, zss_editor.currentSelection.startOffset);
1074
+					range.setEnd(zss_editor.currentSelection.endContainer, zss_editor.currentSelection.endOffset);
1075
+					selection.addRange(range);
1076
+				} catch (err) {}
1073 1077
 			}
1074 1078
 
1075 1079
 			zss_editor.getSelectedNode = function() {
@@ -1216,7 +1220,6 @@
1216 1220
 			}
1217 1221
 
1218 1222
 			zss_editor.setFontFamily = function(fontFamily) {
1219
-
1220 1223
 				zss_editor.restorerange();
1221 1224
 				document.execCommand("styleWithCSS", null, true);
1222 1225
 				document.execCommand("fontName", false, fontFamily);
@@ -1344,7 +1347,7 @@
1344 1347
 			}
1345 1348
 
1346 1349
 			zss_editor.prepareInsert = function() {
1347
-				// zss_editor.backuprange();
1350
+				zss_editor.backuprange();
1348 1351
 			}
1349 1352
 
1350 1353
 			zss_editor.insertImage = function(url) {
@@ -1535,7 +1538,7 @@
1535 1538
 					//Fonts
1536 1539
 					var font = t.css('font-family');
1537 1540
 					if (font.length != 0 && font != 'Arial, Helvetica, sans-serif') {
1538
-						items.push('fonts');
1541
+						items.push('fonts'); 
1539 1542
 					}
1540 1543
 
1541 1544
 					// Blockquote