xrb21 / flutter-html-editor

MIT License
82 stars 64 forks source link

ERRO when getText() (IOS Only) #19

Open milzamhibatullah opened 4 years ago

milzamhibatullah commented 4 years ago

Hi @xrb21 . have problem when getText() in ios platform

Screen Shot 2020-10-06 at 19 21 45
blue492 commented 4 years ago

Same issue here, _keyEditor.currentState.getText() dont work in ios, only in Android works.

Shirley0207 commented 4 years ago

I have the same question. I tested it on ios 12,13 and 14. After the plugin finishes rederring, it will throw exception in all ios system(12,13 and 14), but it can work.

[VERBOSE-2:ui_dart_state.cc(177)] Unhandled Exception: PlatformException(evaluateJavaScript_failed, Failed evaluating JavaScript, JavaScript string was: '$(".note-placeholder").html("请填写回复内容");'
Error Domain=WKErrorDomain Code=5 "JavaScript execution returned a result of an unsupported type" UserInfo={NSLocalizedDescription=JavaScript execution returned a result of an unsupported type}, null)
#0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:582:7)
#1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:159:18)
<asynchronous suspension>
#2      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:332:12)
#3      MethodChannelWebViewPlatform.evaluateJavascript (package:webview_flutter/src/webview_method_channel.dart:115:21)
#4      WebViewController.evaluateJavascript (package:webview_flutter/webview_flutter.dart:672:39)
#5      HtmlEditorState.setHint (package:html_editor/html_editor.dar<…>

When I call getText() after input some content, ios 14 will throw exception, but ios 12 and 13 will work without exception.

[VERBOSE-2:ui_dart_state.cc(177)] Unhandled Exception: PlatformException(evaluateJavaScript_failed, Failed evaluating JavaScript, JavaScript string was: 'GetTextSummernote.postMessage(document.getElementsByClassName('note-editable')[0].innerHTML);'
Error Domain=WKErrorDomain Code=5 "JavaScript execution returned a result of an unsupported type" UserInfo={NSLocalizedDescription=JavaScript execution returned a result of an unsupported type}, null)
#0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:582:7)
#1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:159:18)
<asynchronous suspension>
#2      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:332:12)
#3      MethodChannelWebViewPlatform.evaluateJavascript (package:webview_flutter/src/webview_method_channel.dart:115:21)
#4      WebViewController.evaluateJavascript (package:webview_flutter/webview_flutter.dart:672:39)
#5      HtmlEditorState.getT<…>
Shirley0207 commented 4 years ago

I found a solution. Download the source and modify the html_editor.dart add setTimeout() to getText() and setHint():

Future<String> getText() async {
    String content = await _controller.evaluateJavascript(
        "setTimeout(function(){GetTextSummernote.postMessage(document.getElementsByClassName('note-editable')[0].innerHTML)}, 0);");    
    return text;
  }

setHint(String text) {
    String hint = '\$(".note-placeholder").html("$text");';
    _controller.evaluateJavascript("setTimeout(function(){$hint}, 0);");
  }

And then there is a problem, the getText() will return null in the first time. We can get text from getTextJavascriptChannel() after called getText(). Add a function for HtmlEditor:

final Function(String) returnContent;
HtmlEditor(
      {Key key,
      this.value,
      this.height = 380,
      this.decoration,
      this.useBottomSheet = true,
      this.widthImage = "100%",
      this.showBottomToolbar = true,
      this.hint, this.returnContent})
      : super(key: key);

And then call this function in getTextJavascriptChannel():

avascriptChannel getTextJavascriptChannel(BuildContext context) {
    return JavascriptChannel(
        name: 'GetTextSummernote',
        onMessageReceived: (JavascriptMessage message) {
          String isi = message.message;
          if (isi.isEmpty ||
              isi == "<p></p>" ||
              isi == "<p><br></p>" ||
              isi == "<p><br/></p>") {
            isi = "";
          }
          setState(() {
            text = isi;
          });
          // call returnContent
          if(widget.returnContent != null) {
            widget.returnContent(text);
          }
        });
  }

Finally, add function for HtmlEditor when you use it,and call keyEditor.currentState.getText() when you want the content.

HtmlEditor(
    hint: Strings.content, 
    key: keyEditor,
    returnContent: _submitContent )

_submitContent(String content) {
   // do something
  }
coxfrederic commented 4 years ago

Any fix possible without setTimeout?

AdnanAli285 commented 3 years ago

Did anyone find a fix for this issue?