zhangchao 4 years ago
parent
commit
b4f4a9253d
4 changed files with 63 additions and 28 deletions
  1. 27
    6
      src/RichTextEditor.js
  2. 6
    2
      src/WebviewMessageHandler.js
  3. 2
    0
      src/const.js
  4. 28
    20
      src/editor.html

+ 27
- 6
src/RichTextEditor.js View File

147
           this.setContentHTML(this.props.initialContentHTML || '');
147
           this.setContentHTML(this.props.initialContentHTML || '');
148
           !this.props.hiddenTitle && this.showTitle();
148
           !this.props.hiddenTitle && this.showTitle();
149
           this.props.enableOnChange && this.enableOnChange();
149
           this.props.enableOnChange && this.enableOnChange();
150
-
150
+          
151
           this.props.editorInitializedCallback && this.props.editorInitializedCallback();
151
           this.props.editorInitializedCallback && this.props.editorInitializedCallback();
152
 
152
 
153
           break;
153
           break;
170
         case messages.CONTENT_BLUR:
170
         case messages.CONTENT_BLUR:
171
           this.contentBlurHandler && this.contentBlurHandler();
171
           this.contentBlurHandler && this.contentBlurHandler();
172
           break;
172
           break;
173
+        case messages.ONCHANGE_EMPTY_OR_NOT:
174
+          this.onChangeEmptyOrNot && this.onChangeEmptyOrNot();
175
+          break;
173
         case messages.SELECTION_CHANGE: {
176
         case messages.SELECTION_CHANGE: {
174
           const items = message.data.items;
177
           const items = message.data.items;
175
           this.state.selectionChangeListeners.map((listener) => {
178
           this.state.selectionChangeListeners.map((listener) => {
310
   //-------------------------------------------------------------------------------
313
   //-------------------------------------------------------------------------------
311
   //--------------- Public API
314
   //--------------- Public API
312
 
315
 
313
-  showLinkDialog(optionalTitle = '', optionalUrl = '') {
316
+  showLinkDialog(optionalTitle = '', optionalUrl = '', notCheckedUrlCallback) {
317
+    this.notCheckedUrlCallback = notCheckedUrlCallback || this.notCheckedUrlCallback;
314
     this.prepareInsert();
318
     this.prepareInsert();
315
     this.setState({
319
     this.setState({
316
       linkInitialUrl: optionalUrl,
320
       linkInitialUrl: optionalUrl,
437
   }
441
   }
438
 
442
 
439
   insertLink(url, title) {
443
   insertLink(url, title) {
440
-    this._sendAction(actions.insertLink, {url, title});
444
+    if (/^(http:\/\/|https:\/\/)/.test(url)) {
445
+      this._sendAction(actions.insertLink, {url, title});
446
+    } else {
447
+      this.notCheckedUrlCallback && this.notCheckedUrlCallback()
448
+    }
441
   }
449
   }
442
 
450
 
443
   updateLink(url, title) {
451
   updateLink(url, title) {
444
-    this._sendAction(actions.updateLink, {url, title});
452
+    if (/^(http:\/\/|https:\/\/)/.test(url)) {
453
+      this._sendAction(actions.updateLink, {url, title});
454
+    } else {
455
+      this.notCheckedUrlCallback && this.notCheckedUrlCallback()
456
+    }
445
   }
457
   }
446
 
458
 
447
   insertImage(url) {
459
   insertImage(url) {
452
     this._sendAction(actions.insertEmoji, url);
464
     this._sendAction(actions.insertEmoji, url);
453
   }
465
   }
454
 
466
 
467
+  deleteEmoji(url) {
468
+    this._sendAction(actions.deleteEmoji, url);
469
+  }
470
+  
455
   setSubscript() {
471
   setSubscript() {
456
     this._sendAction(actions.setSubscript);
472
     this._sendAction(actions.setSubscript);
457
   }
473
   }
496
     this._sendAction(actions.setCustomCSS, css);
512
     this._sendAction(actions.setCustomCSS, css);
497
   }
513
   }
498
 
514
 
499
-  prepareInsert() {
500
-    this._sendAction(actions.prepareInsert);
515
+  prepareInsert(showCaretPlaceholder) {
516
+    this._sendAction(actions.prepareInsert, showCaretPlaceholder);
501
   }
517
   }
502
 
518
 
503
   restoreSelection() {
519
   restoreSelection() {
595
     this._sendAction(actions.setContentBlurHandler);
611
     this._sendAction(actions.setContentBlurHandler);
596
   }
612
   }
597
 
613
 
614
+  setOnChangeEmptyOrNot(callbackHandler) {
615
+    this.onChangeEmptyOrNot = callbackHandler;
616
+    this._sendAction(actions.setOnChangeEmptyOrNot);
617
+  }
618
+
598
   addSelectedTextChangeListener(listener) {
619
   addSelectedTextChangeListener(listener) {
599
     this._selectedTextChangeListeners.push(listener);
620
     this._selectedTextChangeListeners.push(listener);
600
   }
621
   }

+ 6
- 2
src/WebviewMessageHandler.js View File

59
     case `${actions.insertLink}`:
59
     case `${actions.insertLink}`:
60
       return `zss_editor.insertLink('${action.data.url}', '${action.data.title}');`;
60
       return `zss_editor.insertLink('${action.data.url}', '${action.data.title}');`;
61
     case `${actions.updateLink}`:
61
     case `${actions.updateLink}`:
62
-      return `zss_editor.updateLink('${action.data.url}, ${action.data.title}');`;
62
+      return `zss_editor.updateLink('${action.data.url}', '${action.data.title}');`;
63
     case `${actions.insertImage}`:
63
     case `${actions.insertImage}`:
64
       return `zss_editor.insertImage('${action.data}');`;
64
       return `zss_editor.insertImage('${action.data}');`;
65
     case `${actions.insertEmoji}`:
65
     case `${actions.insertEmoji}`:
66
         return `zss_editor.insertEmoji('${action.data}');`;
66
         return `zss_editor.insertEmoji('${action.data}');`;
67
+    case `${actions.deleteEmoji}`:
68
+        return `zss_editor.deleteEmoji();`;
67
     case `${actions.setSubscript}`:
69
     case `${actions.setSubscript}`:
68
       return `zss_editor.setSubscript();`;
70
       return `zss_editor.setSubscript();`;
69
     case `${actions.setSuperscript}`:
71
     case `${actions.setSuperscript}`:
85
     case `${actions.focusTitle}`:
87
     case `${actions.focusTitle}`:
86
       return `zss_editor.focusTitle();`;
88
       return `zss_editor.focusTitle();`;
87
     case `${actions.prepareInsert}`:
89
     case `${actions.prepareInsert}`:
88
-      return `zss_editor.prepareInsert();`;
90
+      return `zss_editor.prepareInsert(${action.data});`;
89
     case `${actions.restoreSelection}`:
91
     case `${actions.restoreSelection}`:
90
       return `zss_editor.restorerange();`;
92
       return `zss_editor.restorerange();`;
91
     case `${actions.setCustomCSS}`:
93
     case `${actions.setCustomCSS}`:
106
       return `zss_editor.setContentFocusHandler();`;
108
       return `zss_editor.setContentFocusHandler();`;
107
     case `${actions.setContentBlurHandler}`:
109
     case `${actions.setContentBlurHandler}`:
108
         return `zss_editor.setContentBlurHandler();`;
110
         return `zss_editor.setContentBlurHandler();`;
111
+    case `${actions.setOnChangeEmptyOrNot}`:
112
+        return `zss_editor.setOnChangeEmptyOrNot();`;
109
     case `${actions.getTitleHtml}`:
113
     case `${actions.getTitleHtml}`:
110
       return `var html = zss_editor.getTitleHTML();
114
       return `var html = zss_editor.getTitleHTML();
111
       ReactNativeWebView.postMessage(JSON.stringify({type: '${messages.TITLE_HTML_RESPONSE}', data: html}));`
115
       ReactNativeWebView.postMessage(JSON.stringify({type: '${messages.TITLE_HTML_RESPONSE}', data: html}));`

+ 2
- 0
src/const.js View File

35
   updateLink: 'UPDATE_LINK',
35
   updateLink: 'UPDATE_LINK',
36
   insertImage: 'INST_IMAGE',
36
   insertImage: 'INST_IMAGE',
37
   insertEmoji: 'INST_EMOJI',
37
   insertEmoji: 'INST_EMOJI',
38
+  deleteEmoji: 'DELETE_EMOJI',
38
   setSubscript: 'subscript',
39
   setSubscript: 'subscript',
39
   setSuperscript: 'superscript',
40
   setSuperscript: 'superscript',
40
   setStrikethrough: 'strikeThrough',
41
   setStrikethrough: 'strikeThrough',
46
   setTitleFocusHandler: 'SET_TITLE_FOCUS_HANDLER',
47
   setTitleFocusHandler: 'SET_TITLE_FOCUS_HANDLER',
47
   setContentFocusHandler: 'SET_CONTENT_FOCUS_HANDLER',
48
   setContentFocusHandler: 'SET_CONTENT_FOCUS_HANDLER',
48
   setContentBlurHandler: 'SET_CONTENT_BLUR_HANDLER',
49
   setContentBlurHandler: 'SET_CONTENT_BLUR_HANDLER',
50
+  setOnChangeEmptyOrNot: 'SET_ONCHANGE_EMPTY_OR_NOT',
49
   prepareInsert: 'PREPARE_INSERT',
51
   prepareInsert: 'PREPARE_INSERT',
50
   restoreSelection: 'RESTORE_SELECTION',
52
   restoreSelection: 'RESTORE_SELECTION',
51
   setCustomCSS: 'SET_CUSTOM_CSS',
53
   setCustomCSS: 'SET_CUSTOM_CSS',

+ 28
- 20
src/editor.html View File

1057
 				}
1057
 				}
1058
 			}
1058
 			}
1059
 
1059
 
1060
-			zss_editor.backuprange = function(){
1060
+			zss_editor.backuprange = function(showCaretPlaceholder){
1061
 				var selection = window.getSelection();
1061
 				var selection = window.getSelection();
1062
 				try {
1062
 				try {
1063
 					var range = selection.getRangeAt(0);
1063
 					var range = selection.getRangeAt(0);
1064
 					zss_editor.currentSelection = {"startContainer": range.startContainer, "startOffset":range.startOffset,"endContainer":range.endContainer, "endOffset":range.endOffset};
1064
 					zss_editor.currentSelection = {"startContainer": range.startContainer, "startOffset":range.startOffset,"endContainer":range.endContainer, "endOffset":range.endOffset};
1065
-					if (range.endOffset === range.startOffset) {
1065
+					if (range.endOffset === range.startOffset && showCaretPlaceholder === true) {
1066
 						zss_editor.insertHTML('<div class="caret_placeholder">&nbsp;&nbsp;</div>');
1066
 						zss_editor.insertHTML('<div class="caret_placeholder">&nbsp;&nbsp;</div>');
1067
 					}
1067
 					}
1068
 				} catch (err) {}
1068
 				} catch (err) {}
1260
 			zss_editor.insertLink = function(url, title) {
1260
 			zss_editor.insertLink = function(url, title) {
1261
 				zss_editor.restorerange();
1261
 				zss_editor.restorerange();
1262
 				var sel = window.getSelection();
1262
 				var sel = window.getSelection();
1263
-				sel.deleteFromDocument();
1263
+				// sel.deleteFromDocument();
1264
 				zss_editor.insertHTML('<a href="'+ url +'">'+ title +'</a>');
1264
 				zss_editor.insertHTML('<a href="'+ url +'">'+ title +'</a>');
1265
+				zss_editor.focusContent();
1265
 				zss_editor.enabledEditingItems();
1266
 				zss_editor.enabledEditingItems();
1266
 			}
1267
 			}
1267
 
1268
 
1344
 
1345
 
1345
 			}
1346
 			}
1346
 
1347
 
1347
-			zss_editor.prepareInsert = function() {
1348
-				zss_editor.backuprange();
1348
+			zss_editor.prepareInsert = function(showCaretPlaceholder) {
1349
+				zss_editor.backuprange(showCaretPlaceholder);
1349
 			}
1350
 			}
1350
 
1351
 
1351
 			zss_editor.insertImage = function(url) {
1352
 			zss_editor.insertImage = function(url) {
1359
 			zss_editor.insertEmoji = function(url) {
1360
 			zss_editor.insertEmoji = function(url) {
1360
 				zss_editor.restorerange();
1361
 				zss_editor.restorerange();
1361
 				document.execCommand('insertHTML', false, '<img class="emoji" src="' + encodeHtmlEntities(url) + '"/>');
1362
 				document.execCommand('insertHTML', false, '<img class="emoji" src="' + encodeHtmlEntities(url) + '"/>');
1362
-				zss_editor.backuprange();
1363
+				zss_editor.backuprange(true);
1364
+				zss_editor.blurContentEditor();
1365
+				zss_editor.enabledEditingItems();
1366
+
1367
+			}
1368
+
1369
+			zss_editor.deleteEmoji = function(url) {
1370
+				zss_editor.restorerange();
1371
+				document.execCommand('Delete', false, null);
1372
+				zss_editor.backuprange(true);
1363
 				zss_editor.blurContentEditor();
1373
 				zss_editor.blurContentEditor();
1364
-				
1365
 				zss_editor.enabledEditingItems();
1374
 				zss_editor.enabledEditingItems();
1366
 			}
1375
 			}
1367
 
1376
 
1406
 			}
1415
 			}
1407
 
1416
 
1408
 			zss_editor.setContentHTML = function(html) {
1417
 			zss_editor.setContentHTML = function(html) {
1418
+				contentIsEmpty = html.length === 0; 
1409
 				setHTML('zss_editor_content', html);
1419
 				setHTML('zss_editor_content', html);
1410
 			}
1420
 			}
1411
 
1421
 
1590
 			}
1600
 			}
1591
 
1601
 
1592
 			zss_editor.focusEditor = function(editorId) {
1602
 			zss_editor.focusEditor = function(editorId) {
1593
-
1594
 				// the following was taken from http://stackoverflow.com/questions/1125292/how-to-move-cursor-to-end-of-contenteditable-entity/3866442#3866442
1603
 				// the following was taken from http://stackoverflow.com/questions/1125292/how-to-move-cursor-to-end-of-contenteditable-entity/3866442#3866442
1595
 				// and ensures we move the cursor to the end of the editor
1604
 				// and ensures we move the cursor to the end of the editor
1596
 				var editor = $('#' + editorId);
1605
 				var editor = $('#' + editorId);
1613
 			}
1622
 			}
1614
 
1623
 
1615
 			zss_editor.setCustomCSS = function(customCSS) {
1624
 			zss_editor.setCustomCSS = function(customCSS) {
1616
-
1617
 				document.getElementsByTagName('style')[1].innerHTML=customCSS;
1625
 				document.getElementsByTagName('style')[1].innerHTML=customCSS;
1618
-
1619
-				//set focus
1620
-				/*editor.focusout(function(){
1621
-				 var element = $(this);
1622
-				 if (!element.text().trim().length) {
1623
-				 element.empty();
1624
-				 }
1625
-				 });*/
1626
-
1627
-
1628
-
1629
 			}
1626
 			}
1630
 
1627
 
1631
 			function addFocusEvent(editorId, callbackHandler) {
1628
 			function addFocusEvent(editorId, callbackHandler) {
1657
 				});
1654
 				});
1658
 			}
1655
 			}
1659
 
1656
 
1657
+			var contentIsEmpty = true;
1658
+			zss_editor.setOnChangeEmptyOrNot = function() {
1659
+				$('#zss_editor_content').on('input', function() {
1660
+					if (!this.textContent && this.querySelectorAll('img, li').length === 0 && !contentIsEmpty) {
1661
+						ReactNativeWebView.postMessage(JSON.stringify({type: 'ONCHANGE_EMPTY_OR_NOT', isEmpty: true}))
1662
+					} else if (contentIsEmpty && (this.textContent || this.querySelectorAll('img, li').length > 0)) {
1663
+						ReactNativeWebView.postMessage(JSON.stringify({type: 'ONCHANGE_EMPTY_OR_NOT', isEmpty: false}))
1664
+					}
1665
+				});
1666
+			}
1667
+
1660
 			zss_editor.setEditorHeight = function(editorHeight) {
1668
 			zss_editor.setEditorHeight = function(editorHeight) {
1661
 				zss_editor.editorHeight = editorHeight;
1669
 				zss_editor.editorHeight = editorHeight;
1662
 			}
1670
 			}