html_editor_enhanced/lib/src/widgets/html_editor_widget_web.dart
2022-10-30 15:25:33 +07:00

800 lines
33 KiB
Dart

export 'dart:html';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:html_editor_enhanced/html_editor.dart';
import 'package:html_editor_enhanced/utils/utils.dart';
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;
import 'package:html_editor_enhanced/utils/shims/dart_ui.dart' as ui;
/// The HTML Editor widget itself, for web (uses IFrameElement)
class HtmlEditorWidget extends StatefulWidget {
HtmlEditorWidget({
Key? key,
required this.controller,
this.callbacks,
required this.plugins,
required this.htmlEditorOptions,
required this.htmlToolbarOptions,
required this.otherOptions,
required this.initBC,
}) : super(key: key);
final HtmlEditorController controller;
final Callbacks? callbacks;
final List<Plugins> plugins;
final HtmlEditorOptions htmlEditorOptions;
final HtmlToolbarOptions htmlToolbarOptions;
final OtherOptions otherOptions;
final BuildContext initBC;
@override
_HtmlEditorWidgetWebState createState() => _HtmlEditorWidgetWebState();
}
/// State for the web Html editor widget
///
/// A stateful widget is necessary here, otherwise the IFrameElement will be
/// rebuilt excessively, hurting performance
class _HtmlEditorWidgetWebState extends State<HtmlEditorWidget> {
/// The view ID for the IFrameElement. Must be unique.
late String createdViewId;
/// The actual height of the editor, used to automatically set the height
late double actualHeight;
/// A Future that is observed by the [FutureBuilder]. We don't use a function
/// as the Future on the [FutureBuilder] because when the widget is rebuilt,
/// the function may be excessively called, hurting performance.
Future<bool>? summernoteInit;
/// Helps get the height of the toolbar to accurately adjust the height of
/// the editor when the keyboard is visible.
GlobalKey toolbarKey = GlobalKey();
/// Tracks whether the editor was disabled onInit (to avoid re-disabling on reload)
bool alreadyDisabled = false;
@override
void initState() {
actualHeight = widget.otherOptions.height;
createdViewId = getRandString(10);
widget.controller.viewId = createdViewId;
initSummernote();
super.initState();
}
void initSummernote() async {
var headString = '';
var summernoteCallbacks = '''callbacks: {
onKeydown: function(e) {
var chars = \$(".note-editable").text();
var totalChars = chars.length;
${widget.htmlEditorOptions.characterLimit != null ? '''allowedKeys = (
e.which === 8 || /* BACKSPACE */
e.which === 35 || /* END */
e.which === 36 || /* HOME */
e.which === 37 || /* LEFT */
e.which === 38 || /* UP */
e.which === 39 || /* RIGHT*/
e.which === 40 || /* DOWN */
e.which === 46 || /* DEL*/
e.ctrlKey === true && e.which === 65 || /* CTRL + A */
e.ctrlKey === true && e.which === 88 || /* CTRL + X */
e.ctrlKey === true && e.which === 67 || /* CTRL + C */
e.ctrlKey === true && e.which === 86 || /* CTRL + V */
e.ctrlKey === true && e.which === 90 /* CTRL + Z */
);
if (!allowedKeys && \$(e.target).text().length >= ${widget.htmlEditorOptions.characterLimit}) {
e.preventDefault();
}''' : ''}
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: characterCount", "totalChars": totalChars}), "*");
},
''';
var maximumFileSize = 10485760;
for (var p in widget.plugins) {
headString = headString + p.getHeadString() + '\n';
if (p is SummernoteAtMention) {
summernoteCallbacks = summernoteCallbacks +
'''
\nsummernoteAtMention: {
getSuggestions: (value) => {
const mentions = ${p.getMentionsWeb()};
return mentions.filter((mention) => {
return mention.includes(value);
});
},
onSelect: (value) => {
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onSelectMention", "value": value}), "*");
},
},
''';
if (p.onSelect != null) {
html.window.onMessage.listen((event) {
var data = json.decode(event.data);
if (data['type'] != null &&
data['type'].contains('toDart:') &&
data['view'] == createdViewId &&
data['type'].contains('onSelectMention')) {
p.onSelect!.call(data['value']);
}
});
}
}
}
if (widget.callbacks != null) {
if (widget.callbacks!.onImageLinkInsert != null) {
summernoteCallbacks = summernoteCallbacks +
'''
onImageLinkInsert: function(url) {
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onImageLinkInsert", "url": url}), "*");
},
''';
}
if (widget.callbacks!.onImageUpload != null) {
summernoteCallbacks = summernoteCallbacks +
"""
onImageUpload: function(files) {
var reader = new FileReader();
var base64 = "<an error occurred>";
reader.onload = function (_) {
base64 = reader.result;
var newObject = {
'lastModified': files[0].lastModified,
'lastModifiedDate': files[0].lastModifiedDate,
'name': files[0].name,
'size': files[0].size,
'type': files[0].type,
'base64': base64
};
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onImageUpload", "lastModified": files[0].lastModified, "lastModifiedDate": files[0].lastModifiedDate, "name": files[0].name, "size": files[0].size, "mimeType": files[0].type, "base64": base64}), "*");
};
reader.onerror = function (_) {
var newObject = {
'lastModified': files[0].lastModified,
'lastModifiedDate': files[0].lastModifiedDate,
'name': files[0].name,
'size': files[0].size,
'type': files[0].type,
'base64': base64
};
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onImageUpload", "lastModified": files[0].lastModified, "lastModifiedDate": files[0].lastModifiedDate, "name": files[0].name, "size": files[0].size, "mimeType": files[0].type, "base64": base64}), "*");
};
reader.readAsDataURL(files[0]);
},
""";
}
if (widget.callbacks!.onImageUploadError != null) {
summernoteCallbacks = summernoteCallbacks +
"""
onImageUploadError: function(file, error) {
if (typeof file === 'string') {
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onImageUploadError", "base64": file, "error": error}), "*");
} else {
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onImageUploadError", "lastModified": file.lastModified, "lastModifiedDate": file.lastModifiedDate, "name": file.name, "size": file.size, "mimeType": file.type, "error": error}), "*");
}
},
""";
}
}
summernoteCallbacks = summernoteCallbacks + '}';
var darkCSS = '';
if ((Theme.of(widget.initBC).brightness == Brightness.dark ||
widget.htmlEditorOptions.darkMode == true) &&
widget.htmlEditorOptions.darkMode != false) {
darkCSS =
'<link href=\"assets/packages/html_editor_enhanced/assets/summernote-lite-dark.css\" rel=\"stylesheet\">';
}
var jsCallbacks = '';
if (widget.callbacks != null) {
jsCallbacks = getJsCallbacks(widget.callbacks!);
}
var userScripts = '';
if (widget.htmlEditorOptions.webInitialScripts != null) {
widget.htmlEditorOptions.webInitialScripts!.forEach((element) {
userScripts = userScripts +
'''
if (data["type"].includes("${element.name}")) {
${element.script}
}
''' +
'\n';
});
}
var summernoteScripts = """
<script type="text/javascript">
\$(document).ready(function () {
\$('#summernote-2').summernote({
placeholder: "${widget.htmlEditorOptions.hint}",
tabsize: 2,
height: ${widget.otherOptions.height},
disableGrammar: false,
spellCheck: ${widget.htmlEditorOptions.spellCheck},
maximumFileSize: $maximumFileSize,
${widget.htmlEditorOptions.customOptions}
$summernoteCallbacks
});
\$('#summernote-2').on('summernote.change', function(_, contents, \$editable) {
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onChangeContent", "contents": contents}), "*");
});
});
window.parent.addEventListener('message', handleMessage, false);
document.onselectionchange = onSelectionChange;
console.log('done');
function handleMessage(e) {
if (e && e.data && e.data.includes("toIframe:")) {
var data = JSON.parse(e.data);
if (data["view"].includes("$createdViewId")) {
if (data["type"].includes("getText")) {
var str = \$('#summernote-2').summernote('code');
window.parent.postMessage(JSON.stringify({"type": "toDart: getText", "text": str}), "*");
}
if (data["type"].includes("getHeight")) {
var height = document.body.scrollHeight;
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: htmlHeight", "height": height}), "*");
}
if (data["type"].includes("setInputType")) {
document.getElementsByClassName('note-editable')[0].setAttribute('inputmode', '${describeEnum(widget.htmlEditorOptions.inputType)}');
}
if (data["type"].includes("setText")) {
\$('#summernote-2').summernote('code', data["text"]);
}
if (data["type"].includes("setFullScreen")) {
\$("#summernote-2").summernote("fullscreen.toggle");
}
if (data["type"].includes("setFocus")) {
\$('#summernote-2').summernote('focus');
}
if (data["type"].includes("clear")) {
\$('#summernote-2').summernote('reset');
}
if (data["type"].includes("setHint")) {
\$(".note-placeholder").html(data["text"]);
}
if (data["type"].includes("toggleCodeview")) {
\$('#summernote-2').summernote('codeview.toggle');
}
if (data["type"].includes("disable")) {
\$('#summernote-2').summernote('disable');
}
if (data["type"].includes("enable")) {
\$('#summernote-2').summernote('enable');
}
if (data["type"].includes("undo")) {
\$('#summernote-2').summernote('undo');
}
if (data["type"].includes("redo")) {
\$('#summernote-2').summernote('redo');
}
if (data["type"].includes("insertText")) {
\$('#summernote-2').summernote('insertText', data["text"]);
}
if (data["type"].includes("insertHtml")) {
\$('#summernote-2').summernote('pasteHTML', data["html"]);
}
if (data["type"].includes("insertNetworkImage")) {
\$('#summernote-2').summernote('insertImage', data["url"], data["filename"]);
}
if (data["type"].includes("insertLink")) {
\$('#summernote-2').summernote('createLink', {
text: data["text"],
url: data["url"],
isNewWindow: data["isNewWindow"]
});
}
if (data["type"].includes("reload")) {
window.location.reload();
}
if (data["type"].includes("addNotification")) {
if (data["alertType"] === null) {
\$('.note-status-output').html(
data["html"]
);
} else {
\$('.note-status-output').html(
'<div class="' + data["alertType"] + '">' +
data["html"] +
'</div>'
);
}
}
if (data["type"].includes("removeNotification")) {
\$('.note-status-output').empty();
}
if (data["type"].includes("execCommand")) {
if (data["argument"] === null) {
document.execCommand(data["command"], false);
} else {
document.execCommand(data["command"], false, data["argument"]);
}
}
if (data["type"].includes("changeListStyle")) {
var \$focusNode = \$(window.getSelection().focusNode);
var \$parentList = \$focusNode.closest("div.note-editable ol, div.note-editable ul");
\$parentList.css("list-style-type", data["changed"]);
}
if (data["type"].includes("changeLineHeight")) {
\$('#summernote-2').summernote('lineHeight', data["changed"]);
}
if (data["type"].includes("changeTextDirection")) {
var s=document.getSelection();
if(s==''){
document.execCommand("insertHTML", false, "<p dir='"+data['direction']+"'></p>");
}else{
document.execCommand("insertHTML", false, "<div dir='"+data['direction']+"'>"+ document.getSelection()+"</div>");
}
}
if (data["type"].includes("changeCase")) {
var selected = \$('#summernote-2').summernote('createRange');
if(selected.toString()){
var texto;
var count = 0;
var value = data["case"];
console.log(value);
var nodes = selected.nodes();
for (var i=0; i< nodes.length; ++i) {
if (nodes[i].nodeName == "#text") {
count++;
texto = nodes[i].nodeValue.toLowerCase();
nodes[i].nodeValue = texto;
if (value == 'upper') {
nodes[i].nodeValue = texto.toUpperCase();
}
else if (value == 'sentence' && count==1) {
nodes[i].nodeValue = texto.charAt(0).toUpperCase() + texto.slice(1).toLowerCase();
} else if (value == 'title') {
var sentence = texto.split(" ");
for(var j = 0; j< sentence.length; j++){
sentence[j] = sentence[j][0].toUpperCase() + sentence[j].slice(1);
}
nodes[i].nodeValue = sentence.join(" ");
}
}
}
}
}
if (data["type"].includes("insertTable")) {
\$('#summernote-2').summernote('insertTable', data["dimensions"]);
}
if (data["type"].includes("getSelectedTextHtml")) {
var range = window.getSelection().getRangeAt(0);
var content = range.cloneContents();
var span = document.createElement('span');
span.appendChild(content);
var htmlContent = span.innerHTML;
window.parent.postMessage(JSON.stringify({"type": "toDart: getSelectedText", "text": htmlContent}), "*");
} else if (data["type"].includes("getSelectedText")) {
window.parent.postMessage(JSON.stringify({"type": "toDart: getSelectedText", "text": window.getSelection().toString()}), "*");
}
$userScripts
}
}
}
function onSelectionChange() {
let {anchorNode, anchorOffset, focusNode, focusOffset} = document.getSelection();
var isBold = false;
var isItalic = false;
var isUnderline = false;
var isStrikethrough = false;
var isSuperscript = false;
var isSubscript = false;
var isUL = false;
var isOL = false;
var isLeft = false;
var isRight = false;
var isCenter = false;
var isFull = false;
var parent;
var fontName;
var fontSize = 16;
var foreColor = "000000";
var backColor = "FFFF00";
var focusNode2 = \$(window.getSelection().focusNode);
var parentList = focusNode2.closest("div.note-editable ol, div.note-editable ul");
var parentListType = parentList.css('list-style-type');
var lineHeight = \$(focusNode.parentNode).css('line-height');
var direction = \$(focusNode.parentNode).css('direction');
if (document.queryCommandState) {
isBold = document.queryCommandState('bold');
isItalic = document.queryCommandState('italic');
isUnderline = document.queryCommandState('underline');
isStrikethrough = document.queryCommandState('strikeThrough');
isSuperscript = document.queryCommandState('superscript');
isSubscript = document.queryCommandState('subscript');
isUL = document.queryCommandState('insertUnorderedList');
isOL = document.queryCommandState('insertOrderedList');
isLeft = document.queryCommandState('justifyLeft');
isRight = document.queryCommandState('justifyRight');
isCenter = document.queryCommandState('justifyCenter');
isFull = document.queryCommandState('justifyFull');
}
if (document.queryCommandValue) {
parent = document.queryCommandValue('formatBlock');
fontSize = document.queryCommandValue('fontSize');
foreColor = document.queryCommandValue('foreColor');
backColor = document.queryCommandValue('hiliteColor');
fontName = document.queryCommandValue('fontName');
}
var message = {
'view': "$createdViewId",
'type': "toDart: updateToolbar",
'style': parent,
'fontName': fontName,
'fontSize': fontSize,
'font': [isBold, isItalic, isUnderline],
'miscFont': [isStrikethrough, isSuperscript, isSubscript],
'color': [foreColor, backColor],
'paragraph': [isUL, isOL],
'listStyle': parentListType,
'align': [isLeft, isCenter, isRight, isFull],
'lineHeight': lineHeight,
'direction': direction,
};
window.parent.postMessage(JSON.stringify(message), "*");
}
$jsCallbacks
</script>
""";
var filePath =
'packages/html_editor_enhanced/assets/summernote-no-plugins.html';
if (widget.htmlEditorOptions.filePath != null) {
filePath = widget.htmlEditorOptions.filePath!;
}
var htmlString = await rootBundle.loadString(filePath);
htmlString = htmlString
.replaceFirst('<!--darkCSS-->', darkCSS)
.replaceFirst('<!--headString-->', headString)
.replaceFirst('<!--summernoteScripts-->', summernoteScripts)
.replaceFirst('"jquery.min.js"',
'"assets/packages/html_editor_enhanced/assets/jquery.min.js"')
.replaceFirst('"summernote-lite.min.css"',
'"assets/packages/html_editor_enhanced/assets/summernote-lite.min.css"')
.replaceFirst('"summernote-lite.min.js"',
'"assets/packages/html_editor_enhanced/assets/summernote-lite.min.js"');
if (widget.callbacks != null) addJSListener(widget.callbacks!);
final iframe = html.IFrameElement()
..width = MediaQuery.of(widget.initBC).size.width.toString() //'800'
..height = widget.htmlEditorOptions.autoAdjustHeight
? actualHeight.toString()
: widget.otherOptions.height.toString()
// ignore: unsafe_html, necessary to load HTML string
..srcdoc = htmlString
..style.border = 'none'
..style.overflow = 'hidden'
..onLoad.listen((event) async {
if (widget.htmlEditorOptions.disabled && !alreadyDisabled) {
widget.controller.disable();
alreadyDisabled = true;
}
if (widget.callbacks != null && widget.callbacks!.onInit != null) {
widget.callbacks!.onInit!.call();
}
if (widget.htmlEditorOptions.initialText != null) {
widget.controller.setText(widget.htmlEditorOptions.initialText!);
}
var data = <String, Object>{'type': 'toIframe: getHeight'};
data['view'] = createdViewId;
var data2 = <String, Object>{'type': 'toIframe: setInputType'};
data2['view'] = createdViewId;
final jsonEncoder = JsonEncoder();
var jsonStr = jsonEncoder.convert(data);
var jsonStr2 = jsonEncoder.convert(data2);
html.window.onMessage.listen((event) {
var data = json.decode(event.data);
if (data['type'] != null &&
data['type'].contains('toDart: htmlHeight') &&
data['view'] == createdViewId &&
widget.htmlEditorOptions.autoAdjustHeight) {
final docHeight = data['height'] ?? actualHeight;
if ((docHeight != null && docHeight != actualHeight) &&
mounted &&
docHeight > 0) {
setState(mounted, this.setState, () {
actualHeight =
docHeight + (toolbarKey.currentContext?.size?.height ?? 0);
});
}
}
if (data['type'] != null &&
data['type'].contains('toDart: onChangeContent') &&
data['view'] == createdViewId) {
if (widget.callbacks != null &&
widget.callbacks!.onChangeContent != null) {
widget.callbacks!.onChangeContent!.call(data['contents']);
}
if (widget.htmlEditorOptions.shouldEnsureVisible &&
Scrollable.of(context) != null) {
Scrollable.of(context)!.position.ensureVisible(
context.findRenderObject()!,
duration: const Duration(milliseconds: 100),
curve: Curves.easeIn);
}
}
if (data['type'] != null &&
data['type'].contains('toDart: updateToolbar') &&
data['view'] == createdViewId) {
if (widget.controller.toolbar != null) {
widget.controller.toolbar!.updateToolbar(data);
}
}
});
html.window.postMessage(jsonStr, '*');
html.window.postMessage(jsonStr2, '*');
});
ui.platformViewRegistry
.registerViewFactory(createdViewId, (int viewId) => iframe);
setState(mounted, this.setState, () {
summernoteInit = Future.value(true);
});
}
@override
Widget build(BuildContext context) {
return Container(
height: widget.htmlEditorOptions.autoAdjustHeight
? actualHeight
: widget.otherOptions.height,
child: Column(
children: <Widget>[
widget.htmlToolbarOptions.toolbarPosition ==
ToolbarPosition.aboveEditor
? ToolbarWidget(
key: toolbarKey,
controller: widget.controller,
htmlToolbarOptions: widget.htmlToolbarOptions,
callbacks: widget.callbacks)
: Container(height: 0, width: 0),
Expanded(
child: Directionality(
textDirection: TextDirection.ltr,
child: FutureBuilder<bool>(
future: summernoteInit,
builder: (context, snapshot) {
if (snapshot.hasData) {
return HtmlElementView(
viewType: createdViewId,
);
} else {
return Container(
height: widget.htmlEditorOptions.autoAdjustHeight
? actualHeight
: widget.otherOptions.height);
}
}))),
widget.htmlToolbarOptions.toolbarPosition ==
ToolbarPosition.belowEditor
? ToolbarWidget(
key: toolbarKey,
controller: widget.controller,
htmlToolbarOptions: widget.htmlToolbarOptions,
callbacks: widget.callbacks)
: Container(height: 0, width: 0),
],
),
);
}
/// Adds the callbacks the user set into JavaScript
String getJsCallbacks(Callbacks c) {
var callbacks = '';
if (c.onBeforeCommand != null) {
callbacks = callbacks +
"""
\$('#summernote-2').on('summernote.before.command', function(_, contents, \$editable) {
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onBeforeCommand", "contents": contents}), "*");
});\n
""";
}
if (c.onChangeCodeview != null) {
callbacks = callbacks +
"""
\$('#summernote-2').on('summernote.change.codeview', function(_, contents, \$editable) {
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onChangeCodeview", "contents": contents}), "*");
});\n
""";
}
if (c.onDialogShown != null) {
callbacks = callbacks +
"""
\$('#summernote-2').on('summernote.dialog.shown', function() {
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onDialogShown"}), "*");
});\n
""";
}
if (c.onEnter != null) {
callbacks = callbacks +
"""
\$('#summernote-2').on('summernote.enter', function() {
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onEnter"}), "*");
});\n
""";
}
if (c.onFocus != null) {
callbacks = callbacks +
"""
\$('#summernote-2').on('summernote.focus', function() {
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onFocus"}), "*");
});\n
""";
}
if (c.onBlur != null) {
callbacks = callbacks +
"""
\$('#summernote-2').on('summernote.blur', function() {
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onBlur"}), "*");
});\n
""";
}
if (c.onBlurCodeview != null) {
callbacks = callbacks +
"""
\$('#summernote-2').on('summernote.blur.codeview', function() {
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onBlurCodeview"}), "*");
});\n
""";
}
if (c.onKeyDown != null) {
callbacks = callbacks +
"""
\$('#summernote-2').on('summernote.keydown', function(_, e) {
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onKeyDown", "keyCode": e.keyCode}), "*");
});\n
""";
}
if (c.onKeyUp != null) {
callbacks = callbacks +
"""
\$('#summernote-2').on('summernote.keyup', function(_, e) {
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onKeyUp", "keyCode": e.keyCode}), "*");
});\n
""";
}
if (c.onMouseDown != null) {
callbacks = callbacks +
"""
\$('#summernote-2').on('summernote.mousedown', function(_) {
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onMouseDown"}), "*");
});\n
""";
}
if (c.onMouseUp != null) {
callbacks = callbacks +
"""
\$('#summernote-2').on('summernote.mouseup', function(_) {
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onMouseUp"}), "*");
});\n
""";
}
if (c.onPaste != null) {
callbacks = callbacks +
"""
\$('#summernote-2').on('summernote.paste', function(_) {
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onPaste"}), "*");
});\n
""";
}
if (c.onScroll != null) {
callbacks = callbacks +
"""
\$('#summernote-2').on('summernote.scroll', function(_) {
window.parent.postMessage(JSON.stringify({"view": "$createdViewId", "type": "toDart: onScroll"}), "*");
});\n
""";
}
return callbacks;
}
/// Adds an event listener to check when a callback is fired
void addJSListener(Callbacks c) {
html.window.onMessage.listen((event) {
var data = json.decode(event.data);
if (data['type'] != null &&
data['type'].contains('toDart:') &&
data['view'] == createdViewId) {
if (data['type'].contains('onBeforeCommand')) {
c.onBeforeCommand!.call(data['contents']);
}
if (data['type'].contains('onChangeContent')) {
c.onChangeContent!.call(data['contents']);
}
if (data['type'].contains('onChangeCodeview')) {
c.onChangeCodeview!.call(data['contents']);
}
if (data['type'].contains('onDialogShown')) {
c.onDialogShown!.call();
}
if (data['type'].contains('onEnter')) {
c.onEnter!.call();
}
if (data['type'].contains('onFocus')) {
c.onFocus!.call();
}
if (data['type'].contains('onBlur')) {
c.onBlur!.call();
}
if (data['type'].contains('onBlurCodeview')) {
c.onBlurCodeview!.call();
}
if (data['type'].contains('onImageLinkInsert')) {
c.onImageLinkInsert!.call(data['url']);
}
if (data['type'].contains('onImageUpload')) {
var map = <String, dynamic>{
'lastModified': data['lastModified'],
'lastModifiedDate': data['lastModifiedDate'],
'name': data['name'],
'size': data['size'],
'type': data['mimeType'],
'base64': data['base64']
};
var jsonStr = json.encode(map);
var file = fileUploadFromJson(jsonStr);
c.onImageUpload!.call(file);
}
if (data['type'].contains('onImageUploadError')) {
if (data['base64'] != null) {
c.onImageUploadError!.call(
null,
data['base64'],
data['error'].contains('base64')
? UploadError.jsException
: data['error'].contains('unsupported')
? UploadError.unsupportedFile
: UploadError.exceededMaxSize);
} else {
var map = <String, dynamic>{
'lastModified': data['lastModified'],
'lastModifiedDate': data['lastModifiedDate'],
'name': data['name'],
'size': data['size'],
'type': data['mimeType']
};
var jsonStr = json.encode(map);
var file = fileUploadFromJson(jsonStr);
c.onImageUploadError!.call(
file,
null,
data['error'].contains('base64')
? UploadError.jsException
: data['error'].contains('unsupported')
? UploadError.unsupportedFile
: UploadError.exceededMaxSize);
}
}
if (data['type'].contains('onKeyDown')) {
c.onKeyDown!.call(data['keyCode']);
}
if (data['type'].contains('onKeyUp')) {
c.onKeyUp!.call(data['keyCode']);
}
if (data['type'].contains('onMouseDown')) {
c.onMouseDown!.call();
}
if (data['type'].contains('onMouseUp')) {
c.onMouseUp!.call();
}
if (data['type'].contains('onPaste')) {
c.onPaste!.call();
}
if (data['type'].contains('onScroll')) {
c.onScroll!.call();
}
if (data['type'].contains('characterCount')) {
widget.controller.characterCount = data['totalChars'];
}
}
});
}
}