feat: added more editor settings
This commit is contained in:
parent
666bd5f58a
commit
509808d220
@ -105,7 +105,8 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
placeholder: 'Start typing',
|
placeholder: 'Start typing',
|
||||||
// backgroundColor: Colors.blueGrey,
|
// backgroundColor: Colors.blueGrey,
|
||||||
// baseTextColor: Colors.white,
|
// baseTextColor: Colors.white,
|
||||||
padding: EdgeInsets.symmetric(horizontal: 50.0),
|
padding: EdgeInsets.symmetric(horizontal: 5.0),
|
||||||
|
baseFontFamily: 'sans-serif',
|
||||||
// You can return a Link (maybe you need to upload the image to your
|
// You can return a Link (maybe you need to upload the image to your
|
||||||
// storage before displaying in the editor or you can also use base64
|
// storage before displaying in the editor or you can also use base64
|
||||||
getImageUrl: (image) {
|
getImageUrl: (image) {
|
||||||
|
@ -281,7 +281,7 @@ packages:
|
|||||||
path: ".."
|
path: ".."
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "0.0.1"
|
version: "0.0.2"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -15,19 +15,21 @@ class RichEditor extends StatefulWidget {
|
|||||||
final Color? baseTextColor;
|
final Color? baseTextColor;
|
||||||
final EdgeInsets? padding;
|
final EdgeInsets? padding;
|
||||||
final String? placeholder;
|
final String? placeholder;
|
||||||
|
final String? baseFontFamily;
|
||||||
final Function(File image)? getImageUrl;
|
final Function(File image)? getImageUrl;
|
||||||
final Function(File video)? getVideoUrl;
|
final Function(File video)? getVideoUrl;
|
||||||
|
|
||||||
RichEditor(
|
RichEditor({
|
||||||
{Key? key,
|
Key? key,
|
||||||
this.value,
|
this.value,
|
||||||
this.backgroundColor,
|
this.backgroundColor,
|
||||||
this.baseTextColor,
|
this.baseTextColor,
|
||||||
this.padding,
|
this.padding,
|
||||||
this.placeholder,
|
this.placeholder,
|
||||||
this.getImageUrl,
|
this.baseFontFamily,
|
||||||
this.getVideoUrl})
|
this.getImageUrl,
|
||||||
: super(key: key);
|
this.getVideoUrl,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
RichEditorState createState() => RichEditorState();
|
RichEditorState createState() => RichEditorState();
|
||||||
@ -35,30 +37,29 @@ class RichEditor extends StatefulWidget {
|
|||||||
|
|
||||||
class RichEditorState extends State<RichEditor> {
|
class RichEditorState extends State<RichEditor> {
|
||||||
WebViewController? _controller;
|
WebViewController? _controller;
|
||||||
String text = "";
|
|
||||||
final Key _mapKey = UniqueKey();
|
final Key _mapKey = UniqueKey();
|
||||||
String assetPath = 'packages/rich_editor/assets/editor/editor.html';
|
String assetPath = 'packages/rich_editor/assets/editor/editor.html';
|
||||||
|
|
||||||
int port = 5321;
|
int port = 5321;
|
||||||
String html = '';
|
String html = '';
|
||||||
LocalServer? localServer;
|
LocalServer? localServer;
|
||||||
JavascriptExecutorBase javascriptExecutorBase = JavascriptExecutorBase();
|
JavascriptExecutorBase javascriptExecutor = JavascriptExecutorBase();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
|
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
|
||||||
if (!Platform.isAndroid) {
|
if (!Platform.isAndroid) {
|
||||||
initServer();
|
_initServer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initServer() async {
|
_initServer() async {
|
||||||
localServer = LocalServer(port);
|
localServer = LocalServer(port);
|
||||||
await localServer!.start(handleRequest);
|
await localServer!.start(_handleRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleRequest(HttpRequest request) {
|
void _handleRequest(HttpRequest request) {
|
||||||
try {
|
try {
|
||||||
if (request.method == 'GET' &&
|
if (request.method == 'GET' &&
|
||||||
request.uri.queryParameters['query'] == "getRawTeXHTML") {
|
request.uri.queryParameters['query'] == "getRawTeXHTML") {
|
||||||
@ -91,7 +92,7 @@ class RichEditorState extends State<RichEditor> {
|
|||||||
EditorToolBar(
|
EditorToolBar(
|
||||||
controller: _controller,
|
controller: _controller,
|
||||||
getImageUrl: widget.getImageUrl,
|
getImageUrl: widget.getImageUrl,
|
||||||
javascriptExecutorBase: javascriptExecutorBase,
|
javascriptExecutor: javascriptExecutor,
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: WebView(
|
child: WebView(
|
||||||
@ -105,7 +106,7 @@ class RichEditorState extends State<RichEditor> {
|
|||||||
await _controller!
|
await _controller!
|
||||||
.loadUrl('file:///android_asset/flutter_assets/$assetPath');
|
.loadUrl('file:///android_asset/flutter_assets/$assetPath');
|
||||||
}
|
}
|
||||||
javascriptExecutorBase.init(_controller!);
|
javascriptExecutor.init(_controller!);
|
||||||
},
|
},
|
||||||
onPageFinished: (link) async {
|
onPageFinished: (link) async {
|
||||||
await _setInitialValues();
|
await _setInitialValues();
|
||||||
@ -125,44 +126,70 @@ class RichEditorState extends State<RichEditor> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_setInitialValues() async {
|
_setInitialValues() async {
|
||||||
if (widget.value != null)
|
if (widget.value != null) await javascriptExecutor.setHtml(widget.value!);
|
||||||
await javascriptExecutorBase.setHtml(widget.value!);
|
|
||||||
if (widget.padding != null)
|
if (widget.padding != null)
|
||||||
await javascriptExecutorBase.setPadding(widget.padding!);
|
await javascriptExecutor.setPadding(widget.padding!);
|
||||||
if (widget.backgroundColor != null)
|
if (widget.backgroundColor != null)
|
||||||
await javascriptExecutorBase.setBackgroundColor(widget.backgroundColor!);
|
await javascriptExecutor.setBackgroundColor(widget.backgroundColor!);
|
||||||
if (widget.baseTextColor != null)
|
if (widget.baseTextColor != null)
|
||||||
await javascriptExecutorBase.setBaseTextColor(widget.baseTextColor!);
|
await javascriptExecutor.setBaseTextColor(widget.baseTextColor!);
|
||||||
if (widget.placeholder != null)
|
if (widget.placeholder != null)
|
||||||
await javascriptExecutorBase.setPlaceholder(widget.placeholder!);
|
await javascriptExecutor.setPlaceholder(widget.placeholder!);
|
||||||
|
if (widget.baseFontFamily != null)
|
||||||
|
await javascriptExecutor.setBaseFontFamily(widget.baseFontFamily!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get current HTML from editor
|
||||||
Future<String?> getHtml() async {
|
Future<String?> getHtml() async {
|
||||||
try {
|
try {
|
||||||
html = await javascriptExecutorBase.getCurrentHtml();
|
html = await javascriptExecutor.getCurrentHtml();
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set your HTML to the editor
|
||||||
setHtml(String html) async {
|
setHtml(String html) async {
|
||||||
return await javascriptExecutorBase.setHtml(html);
|
return await javascriptExecutor.setHtml(html);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide the keyboard using JavaScript since it's being opened in a WebView
|
/// Hide the keyboard using JavaScript since it's being opened in a WebView
|
||||||
// https://stackoverflow.com/a/8263376/10835183
|
/// https://stackoverflow.com/a/8263376/10835183
|
||||||
unFocus() {
|
unFocus() {
|
||||||
javascriptExecutorBase.unFocus();
|
javascriptExecutor.unFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear editor content using Javascript
|
/// Clear editor content using Javascript
|
||||||
clear() {
|
clear() {
|
||||||
_controller!.evaluateJavascript(
|
_controller!.evaluateJavascript(
|
||||||
'document.getElementById(\'editor\').innerHTML = "";');
|
'document.getElementById(\'editor\').innerHTML = "";');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Focus and Show the keyboard using JavaScript
|
/// Focus and Show the keyboard using JavaScript
|
||||||
// https://stackoverflow.com/a/6809236/10835183
|
/// https://stackoverflow.com/a/6809236/10835183
|
||||||
focus() {
|
focus() {
|
||||||
javascriptExecutorBase.focus();
|
javascriptExecutor.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add custom CSS code to Editor
|
||||||
|
loadCSS(String cssFile) {
|
||||||
|
var jsCSSImport = "(function() {" +
|
||||||
|
" var head = document.getElementsByTagName(\"head\")[0];" +
|
||||||
|
" var link = document.createElement(\"link\");" +
|
||||||
|
" link.rel = \"stylesheet\";" +
|
||||||
|
" link.type = \"text/css\";" +
|
||||||
|
" link.href = \"" +
|
||||||
|
cssFile +
|
||||||
|
"\";" +
|
||||||
|
" link.media = \"all\";" +
|
||||||
|
" head.appendChild(link);" +
|
||||||
|
"}) ();";
|
||||||
|
_controller!.evaluateJavascript(jsCSSImport);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// if html is equal to html RichTextEditor sets by default at start
|
||||||
|
/// (<p></p>) so that RichTextEditor can be considered as 'empty'.
|
||||||
|
Future<bool> isEmpty() async {
|
||||||
|
html = await javascriptExecutor.getCurrentHtml();
|
||||||
|
return html == '<p></p>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import 'package:rich_editor/src/models/font.dart';
|
|||||||
import 'package:rich_editor/src/models/system_font.dart';
|
import 'package:rich_editor/src/models/system_font.dart';
|
||||||
import 'package:xml2json/xml2json.dart';
|
import 'package:xml2json/xml2json.dart';
|
||||||
|
|
||||||
/// A simple port of FontListParser from Java to Kotlin
|
/// A simple port of FontListParser from Java to Dart
|
||||||
/// See https://stackoverflow.com/a/29533686/10835183
|
/// See https://stackoverflow.com/a/29533686/10835183
|
||||||
class FontListParser {
|
class FontListParser {
|
||||||
File androidFontsFile = File("/system/etc/fonts.xml");
|
File androidFontsFile = File("/system/etc/fonts.xml");
|
||||||
@ -39,7 +39,7 @@ class FontListParser {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( font.t != null) {
|
if (font.t != null) {
|
||||||
SystemFont systemFont = new SystemFont(family.name!, font.t!);
|
SystemFont systemFont = new SystemFont(family.name!, font.t!);
|
||||||
if (fonts.contains(systemFont)) {
|
if (fonts.contains(systemFont)) {
|
||||||
continue;
|
continue;
|
||||||
@ -76,7 +76,7 @@ class FontListParser {
|
|||||||
return fonts;
|
return fonts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets font from the list defined incase the above function doesn't work
|
/// Gets font from the list defined in case the above function doesn't work
|
||||||
List<SystemFont> safelyGetSystemFonts() {
|
List<SystemFont> safelyGetSystemFonts() {
|
||||||
try {
|
try {
|
||||||
return getSystemFonts();
|
return getSystemFonts();
|
||||||
@ -85,16 +85,16 @@ class FontListParser {
|
|||||||
["cursive", "DancingScript-Regular.ttf"],
|
["cursive", "DancingScript-Regular.ttf"],
|
||||||
["monospace", "DroidSansMono.ttf"],
|
["monospace", "DroidSansMono.ttf"],
|
||||||
["sans-serif", "Roboto-Regular.ttf"],
|
["sans-serif", "Roboto-Regular.ttf"],
|
||||||
["sans-serif-light" "Roboto-Light.ttf"],
|
["sans-serif-light" "Roboto-Light.ttf"],
|
||||||
["sans-serif-medium", "Roboto-Medium.ttf"],
|
["sans-serif-medium", "Roboto-Medium.ttf"],
|
||||||
["sans-serif-black", "Roboto-Black.ttf"],
|
["sans-serif-black", "Roboto-Black.ttf"],
|
||||||
["sans-serif-condensed", "RobotoCondensed-Regular.ttf"],
|
["sans-serif-condensed", "RobotoCondensed-Regular.ttf"],
|
||||||
["sans-serif-thin", "Roboto-Thin.ttf"],
|
["sans-serif-thin", "Roboto-Thin.ttf"],
|
||||||
["serif", "NotoSerif-Regular.ttf"]
|
["serif", "NotoSerif-Regular.ttf"]
|
||||||
];
|
];
|
||||||
List<SystemFont> fonts = <SystemFont>[];
|
List<SystemFont> fonts = <SystemFont>[];
|
||||||
for (List names in defaultSystemFonts) {
|
for (List names in defaultSystemFonts) {
|
||||||
File file = new File("/system/fonts/"+ names[1]);
|
File file = new File("/system/fonts/" + names[1]);
|
||||||
if (file.existsSync()) {
|
if (file.existsSync()) {
|
||||||
fonts.add(new SystemFont(names[0], file.path));
|
fonts.add(new SystemFont(names[0], file.path));
|
||||||
}
|
}
|
||||||
|
@ -173,48 +173,52 @@ class JavascriptExecutorBase {
|
|||||||
if (height == null) height = 300;
|
if (height == null) height = 300;
|
||||||
if (alt == null) alt = '';
|
if (alt == null) alt = '';
|
||||||
await executeJavascript(
|
await executeJavascript(
|
||||||
"insertImage('$url', '$alt', '$width', '$height', $rotation)",
|
"insertImage('$url', '$alt', '$width', '$height', $rotation);",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
insertCheckbox(String text) async {
|
insertCheckbox(String text) async {
|
||||||
await executeJavascript("insertCheckbox('$text')");
|
await executeJavascript("insertCheckbox('$text');");
|
||||||
}
|
}
|
||||||
|
|
||||||
insertHtml(String html) async {
|
insertHtml(String html) async {
|
||||||
String? encodedHtml = encodeHtml(html);
|
String? encodedHtml = encodeHtml(html);
|
||||||
await executeJavascript("insertHtml('$encodedHtml')");
|
await executeJavascript("insertHtml('$encodedHtml');");
|
||||||
}
|
}
|
||||||
|
|
||||||
makeImagesResizeable() async {
|
makeImagesResizeable() async {
|
||||||
await executeJavascript("makeImagesResizeable()");
|
await executeJavascript("makeImagesResizeable();");
|
||||||
}
|
}
|
||||||
|
|
||||||
disableImageResizing() async {
|
disableImageResizing() async {
|
||||||
await executeJavascript("disableImageResizing()");
|
await executeJavascript("disableImageResizing();");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Editor settings commands
|
// Editor settings commands
|
||||||
focus() async {
|
focus() async {
|
||||||
await executeJavascript("focus()");
|
await executeJavascript("focus();");
|
||||||
}
|
}
|
||||||
|
|
||||||
unFocus() async {
|
unFocus() async {
|
||||||
await executeJavascript("blurFocus()");
|
await executeJavascript("blurFocus();");
|
||||||
}
|
}
|
||||||
|
|
||||||
setBackgroundColor(Color? color) async {
|
setBackgroundColor(Color? color) async {
|
||||||
String? hex = color!.toHexColorString();
|
String? hex = color!.toHexColorString();
|
||||||
await executeJavascript("setBackgroundColor('$hex')");
|
await executeJavascript("setBackgroundColor('$hex');");
|
||||||
}
|
}
|
||||||
|
|
||||||
setBackgroundImage(String image) async {
|
setBackgroundImage(String image) async {
|
||||||
await executeJavascript("setBackgroundImage('$image')");
|
await executeJavascript("setBackgroundImage('$image');");
|
||||||
}
|
}
|
||||||
|
|
||||||
setBaseTextColor(Color? color) async {
|
setBaseTextColor(Color? color) async {
|
||||||
String? hex = color!.toHexColorString();
|
String? hex = color!.toHexColorString();
|
||||||
await executeJavascript("setBaseTextColor('$hex')");
|
await executeJavascript("setBaseTextColor('$hex');");
|
||||||
|
}
|
||||||
|
|
||||||
|
setBaseFontFamily(String fontFamily) async {
|
||||||
|
await executeJavascript("setBaseFontFamily('$fontFamily');");
|
||||||
}
|
}
|
||||||
|
|
||||||
setPadding(EdgeInsets? padding) async {
|
setPadding(EdgeInsets? padding) async {
|
||||||
@ -222,11 +226,21 @@ class JavascriptExecutorBase {
|
|||||||
String top = padding.top.toString();
|
String top = padding.top.toString();
|
||||||
String right = padding.right.toString();
|
String right = padding.right.toString();
|
||||||
String bottom = padding.bottom.toString();
|
String bottom = padding.bottom.toString();
|
||||||
await executeJavascript("setPadding('$left', '$top', '$right', '$bottom')");
|
await executeJavascript(
|
||||||
|
"setPadding('${left}px', '${top}px', '${right}px', '${bottom}px');");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Doesnt actually work for' now
|
||||||
setPlaceholder(String placeholder) async {
|
setPlaceholder(String placeholder) async {
|
||||||
await executeJavascript("setPlaceholder('$placeholder')");
|
await executeJavascript("setPlaceholder('$placeholder');");
|
||||||
|
}
|
||||||
|
|
||||||
|
setEditorWidth(int px) async {
|
||||||
|
await executeJavascript("setWidth('" + px.toString() + "px');");
|
||||||
|
}
|
||||||
|
|
||||||
|
setEditorHeight(int px) async {
|
||||||
|
await executeJavascript("setHeight('" + px.toString() + "px');");
|
||||||
}
|
}
|
||||||
|
|
||||||
static decodeHtml(String html) {
|
static decodeHtml(String html) {
|
||||||
|
@ -17,23 +17,18 @@ class EditorToolBar extends StatelessWidget {
|
|||||||
final WebViewController? controller;
|
final WebViewController? controller;
|
||||||
final Function(File image)? getImageUrl;
|
final Function(File image)? getImageUrl;
|
||||||
final Function(File video)? getVideoUrl;
|
final Function(File video)? getVideoUrl;
|
||||||
final JavascriptExecutorBase javascriptExecutorBase;
|
final JavascriptExecutorBase javascriptExecutor;
|
||||||
|
|
||||||
EditorToolBar({
|
EditorToolBar({
|
||||||
this.controller,
|
this.controller,
|
||||||
this.getImageUrl,
|
this.getImageUrl,
|
||||||
this.getVideoUrl,
|
this.getVideoUrl,
|
||||||
required this.javascriptExecutorBase,
|
required this.javascriptExecutor,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// if (controller != null) {
|
|
||||||
// javascriptExecutorBase.init(controller!);
|
|
||||||
// }
|
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
// color: Color(0xff424242),
|
|
||||||
height: 54.0,
|
height: 54.0,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
@ -46,21 +41,20 @@ class EditorToolBar extends StatelessWidget {
|
|||||||
tooltip: 'Bold',
|
tooltip: 'Bold',
|
||||||
icon: Icons.format_bold,
|
icon: Icons.format_bold,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.setBold();
|
await javascriptExecutor.setBold();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Italic',
|
tooltip: 'Italic',
|
||||||
icon: Icons.format_italic,
|
icon: Icons.format_italic,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.setItalic();
|
await javascriptExecutor.setItalic();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Insert Link',
|
tooltip: 'Insert Link',
|
||||||
icon: Icons.link,
|
icon: Icons.link,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
_closeKeyboard();
|
|
||||||
var link = await showDialog(
|
var link = await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
@ -69,14 +63,13 @@ class EditorToolBar extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (link != null)
|
if (link != null)
|
||||||
await javascriptExecutorBase.insertLink(link[0], link[1]);
|
await javascriptExecutor.insertLink(link[0], link[1]);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Insert Image',
|
tooltip: 'Insert Image',
|
||||||
icon: Icons.image,
|
icon: Icons.image,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
_closeKeyboard();
|
|
||||||
var link = await showDialog(
|
var link = await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
@ -88,7 +81,7 @@ class EditorToolBar extends StatelessWidget {
|
|||||||
if (getImageUrl != null && link[2]) {
|
if (getImageUrl != null && link[2]) {
|
||||||
link[0] = await getImageUrl!(File(link[0]));
|
link[0] = await getImageUrl!(File(link[0]));
|
||||||
}
|
}
|
||||||
await javascriptExecutorBase.insertImage(
|
await javascriptExecutor.insertImage(
|
||||||
link[0],
|
link[0],
|
||||||
alt: link[1],
|
alt: link[1],
|
||||||
);
|
);
|
||||||
@ -99,63 +92,62 @@ class EditorToolBar extends StatelessWidget {
|
|||||||
tooltip: 'Underline',
|
tooltip: 'Underline',
|
||||||
icon: Icons.format_underline,
|
icon: Icons.format_underline,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.setUnderline();
|
await javascriptExecutor.setUnderline();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Strike through',
|
tooltip: 'Strike through',
|
||||||
icon: Icons.format_strikethrough,
|
icon: Icons.format_strikethrough,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.setStrikeThrough();
|
await javascriptExecutor.setStrikeThrough();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Superscript',
|
tooltip: 'Superscript',
|
||||||
icon: Icons.superscript,
|
icon: Icons.superscript,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.setSuperscript();
|
await javascriptExecutor.setSuperscript();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Subscript',
|
tooltip: 'Subscript',
|
||||||
icon: Icons.subscript,
|
icon: Icons.subscript,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.setSubscript();
|
await javascriptExecutor.setSubscript();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Clear format',
|
tooltip: 'Clear format',
|
||||||
icon: Icons.format_clear,
|
icon: Icons.format_clear,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.removeFormat();
|
await javascriptExecutor.removeFormat();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Undo',
|
tooltip: 'Undo',
|
||||||
icon: Icons.undo,
|
icon: Icons.undo,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.undo();
|
await javascriptExecutor.undo();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Redo',
|
tooltip: 'Redo',
|
||||||
icon: Icons.redo,
|
icon: Icons.redo,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.redo();
|
await javascriptExecutor.redo();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Blockquote',
|
tooltip: 'Blockquote',
|
||||||
icon: Icons.format_quote,
|
icon: Icons.format_quote,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.setBlockQuote();
|
await javascriptExecutor.setBlockQuote();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Font format',
|
tooltip: 'Font format',
|
||||||
icon: Icons.text_format,
|
icon: Icons.text_format,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
_closeKeyboard();
|
|
||||||
var command = await showDialog(
|
var command = await showDialog(
|
||||||
// isScrollControlled: true,
|
// isScrollControlled: true,
|
||||||
context: context,
|
context: context,
|
||||||
@ -165,13 +157,13 @@ class EditorToolBar extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
if (command != null) {
|
if (command != null) {
|
||||||
if (command == 'p') {
|
if (command == 'p') {
|
||||||
await javascriptExecutorBase.setFormattingToParagraph();
|
await javascriptExecutor.setFormattingToParagraph();
|
||||||
} else if (command == 'pre') {
|
} else if (command == 'pre') {
|
||||||
await javascriptExecutorBase.setPreformat();
|
await javascriptExecutor.setPreformat();
|
||||||
} else if (command == 'blockquote') {
|
} else if (command == 'blockquote') {
|
||||||
await javascriptExecutorBase.setBlockQuote();
|
await javascriptExecutor.setBlockQuote();
|
||||||
} else {
|
} else {
|
||||||
await javascriptExecutorBase
|
await javascriptExecutor
|
||||||
.setHeading(int.tryParse(command)!);
|
.setHeading(int.tryParse(command)!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -184,9 +176,6 @@ class EditorToolBar extends StatelessWidget {
|
|||||||
tooltip: 'Font face',
|
tooltip: 'Font face',
|
||||||
icon: Icons.font_download,
|
icon: Icons.font_download,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
Directory fontsDir = Directory("/system/fonts/");
|
|
||||||
File file = File('/system/etc/fonts.xml');
|
|
||||||
// debugPrint(await file.readAsString());
|
|
||||||
var command = await showDialog(
|
var command = await showDialog(
|
||||||
// isScrollControlled: true,
|
// isScrollControlled: true,
|
||||||
context: context,
|
context: context,
|
||||||
@ -194,8 +183,9 @@ class EditorToolBar extends StatelessWidget {
|
|||||||
return FontsDialog();
|
return FontsDialog();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
print(command);
|
||||||
if (command != null)
|
if (command != null)
|
||||||
await javascriptExecutorBase.setFontName(command);
|
await javascriptExecutor.setFontName(command);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -203,7 +193,6 @@ class EditorToolBar extends StatelessWidget {
|
|||||||
icon: Icons.format_size,
|
icon: Icons.format_size,
|
||||||
tooltip: 'Font Size',
|
tooltip: 'Font Size',
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
_closeKeyboard();
|
|
||||||
String? command = await showDialog(
|
String? command = await showDialog(
|
||||||
// isScrollControlled: true,
|
// isScrollControlled: true,
|
||||||
context: context,
|
context: context,
|
||||||
@ -212,7 +201,7 @@ class EditorToolBar extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (command != null)
|
if (command != null)
|
||||||
await javascriptExecutorBase
|
await javascriptExecutor
|
||||||
.setFontSize(int.tryParse(command)!);
|
.setFontSize(int.tryParse(command)!);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -220,7 +209,6 @@ class EditorToolBar extends StatelessWidget {
|
|||||||
tooltip: 'Text Color',
|
tooltip: 'Text Color',
|
||||||
icon: Icons.format_color_text,
|
icon: Icons.format_color_text,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
_closeKeyboard();
|
|
||||||
var color = await showDialog(
|
var color = await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
@ -228,14 +216,13 @@ class EditorToolBar extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (color != null)
|
if (color != null)
|
||||||
await javascriptExecutorBase.setTextColor(color);
|
await javascriptExecutor.setTextColor(color);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Background Color',
|
tooltip: 'Background Color',
|
||||||
icon: Icons.format_color_fill,
|
icon: Icons.format_color_fill,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
_closeKeyboard();
|
|
||||||
var color = await showDialog(
|
var color = await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
@ -243,71 +230,69 @@ class EditorToolBar extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (color != null)
|
if (color != null)
|
||||||
await javascriptExecutorBase
|
await javascriptExecutor.setTextBackgroundColor(color);
|
||||||
.setTextBackgroundColor(color);
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Increase Indent',
|
tooltip: 'Increase Indent',
|
||||||
icon: Icons.format_indent_increase,
|
icon: Icons.format_indent_increase,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.setIndent();
|
await javascriptExecutor.setIndent();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Decrease Indent',
|
tooltip: 'Decrease Indent',
|
||||||
icon: Icons.format_indent_decrease,
|
icon: Icons.format_indent_decrease,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.setOutdent();
|
await javascriptExecutor.setOutdent();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Align Left',
|
tooltip: 'Align Left',
|
||||||
icon: Icons.format_align_left_outlined,
|
icon: Icons.format_align_left_outlined,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.setJustifyLeft();
|
await javascriptExecutor.setJustifyLeft();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Align Center',
|
tooltip: 'Align Center',
|
||||||
icon: Icons.format_align_center,
|
icon: Icons.format_align_center,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.setJustifyCenter();
|
await javascriptExecutor.setJustifyCenter();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Align Right',
|
tooltip: 'Align Right',
|
||||||
icon: Icons.format_align_right,
|
icon: Icons.format_align_right,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.setJustifyRight();
|
await javascriptExecutor.setJustifyRight();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Justify',
|
tooltip: 'Justify',
|
||||||
icon: Icons.format_align_justify,
|
icon: Icons.format_align_justify,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.setJustifyFull();
|
await javascriptExecutor.setJustifyFull();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Bullet List',
|
tooltip: 'Bullet List',
|
||||||
icon: Icons.format_list_bulleted,
|
icon: Icons.format_list_bulleted,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.insertBulletList();
|
await javascriptExecutor.insertBulletList();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Numbered List',
|
tooltip: 'Numbered List',
|
||||||
icon: Icons.format_list_numbered,
|
icon: Icons.format_list_numbered,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await javascriptExecutorBase.insertNumberedList();
|
await javascriptExecutor.insertNumberedList();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TabButton(
|
TabButton(
|
||||||
tooltip: 'Checkbox',
|
tooltip: 'Checkbox',
|
||||||
icon: Icons.check_box_outlined,
|
icon: Icons.check_box_outlined,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
_closeKeyboard();
|
|
||||||
var text = await showDialog(
|
var text = await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
@ -316,7 +301,7 @@ class EditorToolBar extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
print(text);
|
print(text);
|
||||||
if (text != null)
|
if (text != null)
|
||||||
await javascriptExecutorBase.insertCheckbox(text);
|
await javascriptExecutor.insertCheckbox(text);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -325,7 +310,7 @@ class EditorToolBar extends StatelessWidget {
|
|||||||
// tooltip: 'Search',
|
// tooltip: 'Search',
|
||||||
// icon: Icons.search,
|
// icon: Icons.search,
|
||||||
// onTap: () async {
|
// onTap: () async {
|
||||||
// // await javascriptExecutorBase.insertNumberedList();
|
// // await javascriptExecutor.insertNumberedList();
|
||||||
// },
|
// },
|
||||||
// ),
|
// ),
|
||||||
],
|
],
|
||||||
@ -335,10 +320,4 @@ class EditorToolBar extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide the keyboard using JavaScript since it's being opened in a WebView
|
|
||||||
// https://stackoverflow.com/a/8263376/10835183
|
|
||||||
_closeKeyboard() async {
|
|
||||||
// controller!.evaluateJavascript('document.activeElement.blur();');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,19 +23,13 @@ class FontsDialog extends StatelessWidget {
|
|||||||
InkWell(
|
InkWell(
|
||||||
child: Html(data: '<p style="font-family:${font.name}">'
|
child: Html(data: '<p style="font-family:${font.name}">'
|
||||||
'${basename(font.path!)}</p>'),
|
'${basename(font.path!)}</p>'),
|
||||||
onTap: () => Navigator.pop(context, font.path),
|
onTap: () {
|
||||||
|
Navigator.pop(context, font.name);
|
||||||
|
},
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fontSlug(FileSystemEntity font) {
|
|
||||||
String name = basename(font.path);
|
|
||||||
String slug = name.toLowerCase();
|
|
||||||
slug = slug.replaceAll(extension(font.path), '');
|
|
||||||
// print(slug);
|
|
||||||
return slug;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user