buildWebView method

Widget buildWebView()

Implementation

Widget buildWebView() {
  return InAppWebView(
    initialOptions: widget.webViewOptions ??
        InAppWebViewGroupOptions(
          crossPlatform: InAppWebViewOptions(
            javaScriptEnabled: true,
            transparentBackground: true,
            disableHorizontalScroll: true,
            disableVerticalScroll: widget.flexibleHeight,
            horizontalScrollBarEnabled: false,
            verticalScrollBarEnabled: !widget.flexibleHeight,
            //supportZoom: false,
          ),
          android: AndroidInAppWebViewOptions(
            geolocationEnabled: false,
            builtInZoomControls: false,
            thirdPartyCookiesEnabled: false,
            textZoom: (100 * widget.scaleFactor).toInt(),
            useHybridComposition: widget.useAndroidHybridComposition,
          ),
        ),
    contextMenu: _contextMenu,
    onConsoleMessage: widget.printWebViewLog
        ? (_, message) {
            print("Webview: " + message.message);
          }
        : null,
    initialData: InAppWebViewInitialData(
      data: htmlData,
    ),
    onWebViewCreated: (controller) {
      _controller = controller;
    },
    onLoadError: (_, __, ___, ____) {
      _isInitializedCompleter.complete(false);
    },
    onLoadStop: (controller, _) {
      // set up editor and add callbacks
      controller.evaluateJavascript(source: """
          // initialize
          var editor = document.getElementById("editor");
          editor.innerHTML = "<p><br></p>";
          var placeholder = document.createElement("div");
          placeholder.innerHTML = "<p>${widget.placeholder}</p>";
          placeholder.id = "placeholder";
          var body = document.getElementById("body");
          showPlaceholder();
          // block delete input to keep default content
          editor.addEventListener("keydown", event => {
              var key = event.key || event.code || event.keyCode.toString;
              if ((key === "Backspace" || key === "8" || key === "46") && editor.innerHTML === '<p><br></p>') {
                  event.preventDefault();
              }
          });

          // clean intput on paste so layout is not messed up
          editor.addEventListener('paste', event => {
              event.preventDefault();
              var text = event.clipboardData.getData("text/plain");
              console.log(text);
              document.execCommand("insertHTML", false, text);
          }, false);

          // focus callback
          editor.addEventListener('focus', (event) => {
              console.log("Editor focused");
              window.flutter_inappwebview.callHandler("onFocus");
          });

          document.getElementById("body").addEventListener('scroll', (event) => {
              console.log("Scroll!");
              event.preventDefault();
          });

          // blur callback
          editor.addEventListener('blur', (event) => {
              console.log("Editor unfocused");
              window.flutter_inappwebview.callHandler("onBlur");
          });

          // onChange callback
          editor.addEventListener("input", (event) => {
              var content = editor.innerHTML;
              var height = editor.scrollHeight;
              if (content != '<p><br></p>') {
                hidePlaceholder();
              }
              else {
                showPlaceholder();
              }
              console.log("Text:" + editor.innerHTML);
              console.log("Flexible height:" + height);
              window.flutter_inappwebview.callHandler("onChange", content, height);
          }, false);

          function showPlaceholder() {
            document.getElementById("body").prepend(placeholder);
          }
          function hidePlaceholder() {
            placeholder.remove();
          }
          """);
      // add handlers
      controller.addJavaScriptHandler(
          handlerName: 'onFocus',
          callback: (_) {
            if (Platform.isIOS) {
              setState(() {
                _height += Random().nextBool() ? 0.5 : -0.5;
              });
            }
            widget.onFocus?.call();
          });
      controller.addJavaScriptHandler(
          handlerName: 'onBlur',
          callback: (_) {
            widget.onBlur?.call();
          });
      controller.addJavaScriptHandler(
          handlerName: 'onChange',
          callback: (args) {
            String content = args[0];
            int height = args[1];
            if (widget.flexibleHeight) {
              adjustEditorHeight(contentHeight: height.toDouble());
            }
            widget.onChange?.call(content, height.toDouble());
          });
      _controller = controller;
      widget.controller.setWebViewController(controller);
      _isInitializedCompleter.complete(true);
      if (widget.initialText != null) {
        widget.controller.setHtml('<p>${widget.initialText!}</p>');
      }
    },
  );
}