''');
@@ -318,7 +317,7 @@ class _HtmlEditorExampleState extends State {
TextButton(
style: TextButton.styleFrom(
backgroundColor:
- Theme.of(context).colorScheme.secondary),
+ Theme.of(context).colorScheme.secondary),
onPressed: () async {
controller.insertLink(
'Google linked', 'https://google.com', true);
@@ -334,7 +333,7 @@ class _HtmlEditorExampleState extends State {
TextButton(
style: TextButton.styleFrom(
backgroundColor:
- Theme.of(context).colorScheme.secondary),
+ Theme.of(context).colorScheme.secondary),
onPressed: () {
controller.insertNetworkImage(
'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png',
@@ -362,7 +361,7 @@ class _HtmlEditorExampleState extends State {
'Info notification', NotificationType.info);
},
child:
- Text('Info', style: TextStyle(color: Colors.white)),
+ Text('Info', style: TextStyle(color: Colors.white)),
),
SizedBox(
width: 16,
@@ -383,7 +382,7 @@ class _HtmlEditorExampleState extends State {
TextButton(
style: TextButton.styleFrom(
backgroundColor:
- Theme.of(context).colorScheme.secondary),
+ Theme.of(context).colorScheme.secondary),
onPressed: () async {
controller.addNotification(
'Success notification', NotificationType.success);
@@ -399,7 +398,7 @@ class _HtmlEditorExampleState extends State {
TextButton(
style: TextButton.styleFrom(
backgroundColor:
- Theme.of(context).colorScheme.secondary),
+ Theme.of(context).colorScheme.secondary),
onPressed: () {
controller.addNotification(
'Danger notification', NotificationType.danger);
@@ -434,7 +433,7 @@ class _HtmlEditorExampleState extends State {
TextButton(
style: TextButton.styleFrom(
backgroundColor:
- Theme.of(context).colorScheme.secondary),
+ Theme.of(context).colorScheme.secondary),
onPressed: () async {
controller.removeNotification();
},
diff --git a/example/pubspec.yaml b/example/pubspec.yaml
index 5e1c4814..3d6cad01 100644
--- a/example/pubspec.yaml
+++ b/example/pubspec.yaml
@@ -6,7 +6,7 @@ description: Demonstrates how to use the html_editor_enhanced plugin.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
environment:
- sdk: '>=2.12.0 <3.0.0'
+ sdk: '>=2.15.0 <3.0.0'
dependencies:
flutter:
diff --git a/lib/src/html_editor_controller_mobile.dart b/lib/src/html_editor_controller_mobile.dart
index 7210d11c..36547428 100644
--- a/lib/src/html_editor_controller_mobile.dart
+++ b/lib/src/html_editor_controller_mobile.dart
@@ -224,7 +224,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
void addNotification(String html, NotificationType notificationType) async {
await _evaluateJavascript(source: """
\$('.note-status-output').html(
- '
$html
'
+ '
$html
'
);
""");
recalculateHeight();
diff --git a/lib/src/html_editor_controller_unsupported.dart b/lib/src/html_editor_controller_unsupported.dart
index e79e8f84..419e92d3 100644
--- a/lib/src/html_editor_controller_unsupported.dart
+++ b/lib/src/html_editor_controller_unsupported.dart
@@ -37,7 +37,7 @@ class HtmlEditorController {
tags.add(element);
}
});
- String tag = '';
+ var tag = '';
tags.forEach((element) {
tag = '$tag$element';
});
diff --git a/lib/src/html_editor_controller_web.dart b/lib/src/html_editor_controller_web.dart
index 01ff3dec..9a6324e6 100644
--- a/lib/src/html_editor_controller_web.dart
+++ b/lib/src/html_editor_controller_web.dart
@@ -288,7 +288,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
_evaluateJavascriptWeb(data: {
'type': 'toIframe: addNotification',
'html': html,
- 'alertType': 'alert alert-${describeEnum(notificationType)}'
+ 'alertType': 'alert alert-${(notificationType.name)}'
});
}
recalculateHeight();
diff --git a/lib/src/widgets/html_editor_widget_mobile.dart b/lib/src/widgets/html_editor_widget_mobile.dart
index a2458ca8..94f46fcd 100644
--- a/lib/src/widgets/html_editor_widget_mobile.dart
+++ b/lib/src/widgets/html_editor_widget_mobile.dart
@@ -180,9 +180,8 @@ class _HtmlEditorWidgetMobileState extends State {
print(message.message);
},
onWindowFocus: (controller) async {
- if (widget.htmlEditorOptions.shouldEnsureVisible &&
- Scrollable.of(context) != null) {
- await Scrollable.of(context)!.position.ensureVisible(
+ if (widget.htmlEditorOptions.shouldEnsureVisible) {
+ await Scrollable.of(context).position.ensureVisible(
context.findRenderObject()!,
);
}
@@ -451,7 +450,7 @@ class _HtmlEditorWidgetMobileState extends State {
"document.onselectionchange = onSelectionChange; console.log('done');");
await controller.evaluateJavascript(
source:
- "document.getElementsByClassName('note-editable')[0].setAttribute('inputmode', '${describeEnum(widget.htmlEditorOptions.inputType)}');");
+ "document.getElementsByClassName('note-editable')[0].setAttribute('inputmode', '${(widget.htmlEditorOptions.inputType.name)}');");
if ((Theme.of(context).brightness == Brightness.dark ||
widget.htmlEditorOptions.darkMode == true) &&
widget.htmlEditorOptions.darkMode != false) {
@@ -526,9 +525,8 @@ class _HtmlEditorWidgetMobileState extends State {
controller.addJavaScriptHandler(
handlerName: 'onChangeContent',
callback: (contents) {
- if (widget.htmlEditorOptions.shouldEnsureVisible &&
- Scrollable.of(context) != null) {
- Scrollable.of(context)!.position.ensureVisible(
+ if (widget.htmlEditorOptions.shouldEnsureVisible) {
+ Scrollable.of(context).position.ensureVisible(
context.findRenderObject()!,
);
}
diff --git a/lib/src/widgets/html_editor_widget_web.dart b/lib/src/widgets/html_editor_widget_web.dart
index c348920f..103d35c2 100644
--- a/lib/src/widgets/html_editor_widget_web.dart
+++ b/lib/src/widgets/html_editor_widget_web.dart
@@ -1,15 +1,14 @@
-export 'dart:html';
-
import 'dart:convert';
+// ignore: avoid_web_libraries_in_flutter
+import 'dart:html' as html;
-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;
+import 'package:html_editor_enhanced/utils/utils.dart';
+
+export 'dart:html';
/// The HTML Editor widget itself, for web (uses IFrameElement)
class HtmlEditorWidget extends StatefulWidget {
@@ -241,7 +240,7 @@ class _HtmlEditorWidgetWebState extends State {
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)}');
+ document.getElementsByClassName('note-editable')[0].setAttribute('inputmode', '${(widget.htmlEditorOptions.inputType).name}');
}
if (data["type"].includes("setText")) {
\$('#summernote-2').summernote('code', data["text"]);
@@ -513,9 +512,8 @@ class _HtmlEditorWidgetWebState extends State {
widget.callbacks!.onChangeContent != null) {
widget.callbacks!.onChangeContent!.call(data['contents']);
}
- if (widget.htmlEditorOptions.shouldEnsureVisible &&
- Scrollable.of(context) != null) {
- Scrollable.of(context)!.position.ensureVisible(
+ if (widget.htmlEditorOptions.shouldEnsureVisible) {
+ Scrollable.of(context).position.ensureVisible(
context.findRenderObject()!,
duration: const Duration(milliseconds: 100),
curve: Curves.easeIn);
diff --git a/lib/src/widgets/toolbar_widget.dart b/lib/src/widgets/toolbar_widget.dart
index 2e33f27f..bdce4767 100644
--- a/lib/src/widgets/toolbar_widget.dart
+++ b/lib/src/widgets/toolbar_widget.dart
@@ -1,3 +1,5 @@
+import 'dart:async';
+import 'dart:collection';
import 'dart:convert';
import 'package:file_picker/file_picker.dart';
@@ -7,8 +9,10 @@ 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';
+import 'package:math_keyboard/math_keyboard.dart';
import 'package:numberpicker/numberpicker.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
+import 'package:webview_flutter/webview_flutter.dart';
/// Toolbar widget class
class ToolbarWidget extends StatefulWidget {
@@ -90,6 +94,7 @@ class ToolbarWidgetState extends State {
/// Tracks the expanded status of the toolbar
bool _isExpanded = false;
+ final HashMap _latexMap = HashMap();
@override
void initState() {
@@ -498,7 +503,7 @@ class ToolbarWidgetState extends State {
dropdownColor: widget.htmlToolbarOptions.dropdownBackgroundColor,
menuDirection: widget.htmlToolbarOptions.dropdownMenuDirection ??
(widget.htmlToolbarOptions.toolbarPosition ==
- ToolbarPosition.belowEditor
+ ToolbarPosition.belowEditor
? DropdownMenuDirection.up
: DropdownMenuDirection.down),
menuMaxHeight: widget.htmlToolbarOptions.dropdownMenuMaxHeight ??
@@ -1120,7 +1125,7 @@ class ToolbarWidgetState extends State {
newColor = color;
},
title: Text('Choose a Color',
- style: Theme.of(context).textTheme.headline6),
+ style: Theme.of(context).textTheme.titleLarge),
width: 40,
height: 40,
spacing: 0,
@@ -1134,7 +1139,7 @@ class ToolbarWidgetState extends State {
ColorPickerType.wheel: true,
},
copyPasteBehavior:
- const ColorPickerCopyPasteBehavior(
+ const ColorPickerCopyPasteBehavior(
parseShortHexCode: true,
),
actionButtons: const ColorPickerActionButtons(
@@ -1758,6 +1763,7 @@ class ToolbarWidgetState extends State {
t.picture ||
t.link ||
t.hr ||
+ t.fn ||
t.table)) {
toolbarChildren.add(ToggleButtons(
constraints: BoxConstraints.tightFor(
@@ -1872,7 +1878,7 @@ class ToolbarWidgetState extends State {
style: TextStyle(
color: Theme.of(context)
.textTheme
- .bodyText1
+ .bodyLarge
?.color)),
),
],
@@ -1986,7 +1992,7 @@ class ToolbarWidgetState extends State {
style: TextStyle(
color: Theme.of(context)
.textTheme
- .bodyText1
+ .bodyLarge
?.color)),
),
suffixIcon: result != null
@@ -2146,7 +2152,7 @@ class ToolbarWidgetState extends State {
style: TextStyle(
color: Theme.of(context)
.textTheme
- .bodyText1
+ .bodyLarge
?.color)),
),
suffixIcon: result != null
@@ -2298,7 +2304,7 @@ class ToolbarWidgetState extends State {
style: TextStyle(
color: Theme.of(context)
.textTheme
- .bodyText1
+ .bodyLarge
?.color)),
),
suffixIcon: result != null
@@ -2450,7 +2456,7 @@ class ToolbarWidgetState extends State {
style: TextStyle(
color: Theme.of(context)
.textTheme
- .bodyText1
+ .bodyLarge
?.color)),
),
suffixIcon: result != null
@@ -2600,6 +2606,29 @@ class ToolbarWidgetState extends State {
widget.controller.insertHtml('');
}
}
+ if (t.getIcons()[index].icon == Icons.functions) {
+ var proceed = await widget.htmlToolbarOptions.onButtonPressed
+ ?.call(ButtonType.fn, null, null) ??
+ true;
+ if (proceed) {
+ final c = MathFieldEditingController();
+ await showDialog(
+ context: context,
+ builder: (context) => MathKeyboardDialog(controller: c));
+ var math = c.texString;
+ if (math != '') {
+ var texAsFun = c.texStringAsFun;
+ var result =
+ await _latexToHtml(math.replaceAll('\\', '\\\\'));
+ result = '';
+ _latexMap.addAll({
+ result: texAsFun,
+ });
+ widget.controller.addToHashMap(result, texAsFun);
+ widget.controller.insertHtml(result);
+ }
+ }
+ }
},
isSelected: List.filled(t.getIcons().length, false),
children: t.getIcons(),
@@ -2688,7 +2717,7 @@ class ToolbarWidgetState extends State {
child: SingleChildScrollView(
child: DataTable(
columnSpacing: 5,
- dataRowHeight: 75,
+ dataRowMinHeight: 75,
columns: const [
DataColumn(
label: Text(
@@ -2998,4 +3027,28 @@ class ToolbarWidgetState extends State {
}
return toolbarChildren;
}
+
+ Future _latexToHtml(String latex) async {
+ var completer = Completer();
+ var controller = WebViewController();
+ await controller.setJavaScriptMode(JavaScriptMode.unrestricted);
+ await controller.addJavaScriptChannel('MathMLChannel',
+ onMessageReceived: (JavaScriptMessage message) {
+ print('Received message: ${message.message}');
+ completer.complete(message.message);
+ });
+ WebViewWidget(controller: controller);
+ await controller.runJavaScript('''
+ (async () => {
+ try {
+ const mathlive = await import("https://unpkg.com/mathlive?module");
+ const mathML = mathlive.convertLatexToMathMl('\$\$$latex\$\$');
+ MathMLChannel.postMessage(mathML);
+ } catch (error) {
+ console.error('Error:', error);
+ }
+ })();
+ ''');
+ return completer.future;
+ }
}
diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart
index 8d9c6c8d..cbe2c46f 100644
--- a/lib/utils/utils.dart
+++ b/lib/utils/utils.dart
@@ -949,7 +949,7 @@ class _DropdownButtonState extends State>
}
TextStyle? get _textStyle =>
- widget.style ?? Theme.of(context).textTheme.subtitle1;
+ widget.style ?? Theme.of(context).textTheme.titleMedium;
void _handleTap() {
final textDirection = Directionality.maybeOf(context);
@@ -1009,7 +1009,7 @@ class _DropdownButtonState extends State>
double get _denseButtonHeight {
final fontSize = _textStyle!.fontSize ??
- Theme.of(context).textTheme.subtitle1!.fontSize!;
+ Theme.of(context).textTheme.titleMedium!.fontSize!;
return max(fontSize, max(widget.iconSize, _kDenseButtonHeight));
}
@@ -1090,8 +1090,7 @@ class _DropdownButtonState extends State>
hintIndex = items.length;
items.add(DefaultTextStyle(
style: _textStyle!.copyWith(color: Theme.of(context).hintColor),
- child: IgnorePointer(
- ignoringSemantics: false,
+ child: ExcludeSemantics(
child: displayedHint,
),
));
From 16d2a26cf76d0732bc9a22b0ed47a63f8604468d Mon Sep 17 00:00:00 2001
From: Ahmad Khateeb
Date: Wed, 20 Dec 2023 10:01:59 +0200
Subject: [PATCH 05/29] added latex
---
lib/utils/toolbar.dart | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/utils/toolbar.dart b/lib/utils/toolbar.dart
index 09a95921..6146ae8d 100644
--- a/lib/utils/toolbar.dart
+++ b/lib/utils/toolbar.dart
@@ -175,6 +175,7 @@ class InsertButtons extends Toolbar {
if (otherFile) icons.add(Icon(Icons.attach_file));
if (table) icons.add(Icon(Icons.table_chart_outlined));
if (hr) icons.add(Icon(Icons.horizontal_rule));
+ if (fn) icons.add(Icon(Icons.functions));
return icons;
}
}
From 7bfa428d50c756655178fd200920a95df3413417 Mon Sep 17 00:00:00 2001
From: Ahmad Khateeb
Date: Wed, 20 Dec 2023 10:12:10 +0200
Subject: [PATCH 06/29] bug fixes
---
lib/src/widgets/custom_html_editor.dart | 1 -
1 file changed, 1 deletion(-)
diff --git a/lib/src/widgets/custom_html_editor.dart b/lib/src/widgets/custom_html_editor.dart
index f12cfbfe..e7bb9e0b 100644
--- a/lib/src/widgets/custom_html_editor.dart
+++ b/lib/src/widgets/custom_html_editor.dart
@@ -150,7 +150,6 @@ class CustomHtmlEditorWidget extends StatelessWidget {
return _htmlWidget();
}
}
-
const tableTex = r'''
\begin{array} { | l | l | l | }
From a154ca1c5350701c665b5cb1bd8f6abfd0b710f0 Mon Sep 17 00:00:00 2001
From: Ahmad Khateeb
Date: Wed, 20 Dec 2023 10:42:29 +0200
Subject: [PATCH 07/29] Create dart.yml
---
.github/workflows/dart.yml | 42 ++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
create mode 100644 .github/workflows/dart.yml
diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml
new file mode 100644
index 00000000..f45e642e
--- /dev/null
+++ b/.github/workflows/dart.yml
@@ -0,0 +1,42 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+name: Dart
+
+on:
+ push:
+ branches: [ "master" ]
+ pull_request:
+ branches: [ "master" ]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v3
+
+ # Note: This workflow uses the latest stable version of the Dart SDK.
+ # You can specify other versions if desired, see documentation here:
+ # https://github.com/dart-lang/setup-dart/blob/main/README.md
+ # - uses: dart-lang/setup-dart@v1
+ - uses: dart-lang/setup-dart@9a04e6d73cca37bd455e0608d7e5092f881fd603
+
+ - name: Install dependencies
+ run: dart pub get
+
+ # Uncomment this step to verify the use of 'dart format' on each commit.
+ # - name: Verify formatting
+ # run: dart format --output=none --set-exit-if-changed .
+
+ # Consider passing '--fatal-infos' for slightly stricter analysis.
+ - name: Analyze project source
+ run: dart analyze
+
+ # Your project will need to have tests in test/ and a dependency on
+ # package:test for this step to succeed. Note that Flutter projects will
+ # want to change this to 'flutter test'.
+ - name: Run tests
+ run: dart test
From 2372872aa257c2229cbd9305128e72e2e9c5bedc Mon Sep 17 00:00:00 2001
From: Ahmad Khateeb
Date: Wed, 20 Dec 2023 10:46:57 +0200
Subject: [PATCH 08/29] Create flutter.yml
---
.github/workflows/flutter.yml | 42 +++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
create mode 100644 .github/workflows/flutter.yml
diff --git a/.github/workflows/flutter.yml b/.github/workflows/flutter.yml
new file mode 100644
index 00000000..97c5382e
--- /dev/null
+++ b/.github/workflows/flutter.yml
@@ -0,0 +1,42 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+name: Dart
+
+on:
+ push:
+ branches: [ "master" ]
+ pull_request:
+ branches: [ "master" ]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v3
+
+ # Note: This workflow uses the latest stable version of the Dart SDK.
+ # You can specify other versions if desired, see documentation here:
+ # https://github.com/dart-lang/setup-dart/blob/main/README.md
+ # - uses: dart-lang/setup-dart@v1
+ - uses: dart-lang/setup-dart@9a04e6d73cca37bd455e0608d7e5092f881fd603
+
+ - name: Install dependencies
+ run: flutter pub get
+
+ # Uncomment this step to verify the use of 'dart format' on each commit.
+ # - name: Verify formatting
+ # run: dart format --output=none --set-exit-if-changed .
+
+ # Consider passing '--fatal-infos' for slightly stricter analysis.
+ - name: Analyze project source
+ run: flutter analyze
+
+ # Your project will need to have tests in test/ and a dependency on
+ # package:test for this step to succeed. Note that Flutter projects will
+ # want to change this to 'flutter test'.
+ - name: Run tests
+ run: flutter test
From 26aa25259e1316988a80a01dbef180dc6240ec0a Mon Sep 17 00:00:00 2001
From: Ahmad Khateeb
Date: Wed, 20 Dec 2023 11:17:15 +0200
Subject: [PATCH 09/29] changed from 'html_editor_enhanced' to
'html_editor_enhanced_fork_latex'
---
example/android/build.gradle | 2 +-
.../gradle/wrapper/gradle-wrapper.properties | 2 +-
example/lib/main.dart | 2 +-
example/pubspec.lock | 4 +--
example/pubspec.yaml | 2 +-
lib/html_editor.dart | 32 +++++++++----------
lib/src/html_editor_controller_mobile.dart | 4 +--
.../html_editor_controller_unsupported.dart | 2 +-
lib/src/html_editor_controller_web.dart | 4 +--
lib/src/html_editor_mobile.dart | 8 ++---
lib/src/html_editor_unsupported.dart | 2 +-
lib/src/html_editor_web.dart | 4 +--
.../widgets/html_editor_widget_mobile.dart | 4 +--
lib/src/widgets/html_editor_widget_web.dart | 6 ++--
lib/src/widgets/toolbar_widget.dart | 4 +--
lib/utils/callbacks.dart | 2 +-
lib/utils/options.dart | 2 +-
lib/utils/utils.dart | 4 +--
pubspec.yaml | 4 +--
19 files changed, 47 insertions(+), 47 deletions(-)
diff --git a/example/android/build.gradle b/example/android/build.gradle
index 714549c2..05744a00 100644
--- a/example/android/build.gradle
+++ b/example/android/build.gradle
@@ -26,6 +26,6 @@ subprojects {
project.evaluationDependsOn(':app')
}
-task clean(type: Delete) {
+tasks.register("clean", Delete) {
delete rootProject.buildDir
}
diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties
index bc6a58af..cfe88f69 100644
--- a/example/android/gradle/wrapper/gradle-wrapper.properties
+++ b/example/android/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
diff --git a/example/lib/main.dart b/example/lib/main.dart
index 88ce86e8..56115b85 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -1,7 +1,7 @@
import 'package:file_picker/file_picker.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
-import 'package:html_editor_enhanced/html_editor.dart';
+import 'package:html_editor_enhanced_fork_latex/html_editor.dart';
void main() => runApp(HtmlEditorExampleApp());
diff --git a/example/pubspec.lock b/example/pubspec.lock
index 1a771515..3e04836c 100644
--- a/example/pubspec.lock
+++ b/example/pubspec.lock
@@ -205,13 +205,13 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.0"
- html_editor_enhanced:
+ html_editor_enhanced_fork_latex:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
- version: "2.5.1"
+ version: "2.5.2"
infinite_listview:
dependency: transitive
description:
diff --git a/example/pubspec.yaml b/example/pubspec.yaml
index 3d6cad01..9e5b1cf9 100644
--- a/example/pubspec.yaml
+++ b/example/pubspec.yaml
@@ -12,7 +12,7 @@ dependencies:
flutter:
sdk: flutter
- html_editor_enhanced:
+ html_editor_enhanced_fork_latex:
# When depending on this package from a real application you should use:
# html_editor_enhanced: ^x.y.z
# See https://dart.dev/tools/pub/dependencies#version-constraints
diff --git a/lib/html_editor.dart b/lib/html_editor.dart
index a1bf776c..c280cc13 100644
--- a/lib/html_editor.dart
+++ b/lib/html_editor.dart
@@ -1,22 +1,22 @@
library html_editor;
-export 'package:html_editor_enhanced/src/html_editor_controller_unsupported.dart'
- if (dart.library.html) 'package:html_editor_enhanced/src/html_editor_controller_web.dart'
- if (dart.library.io) 'package:html_editor_enhanced/src/html_editor_controller_mobile.dart';
-export 'package:html_editor_enhanced/src/html_editor_unsupported.dart'
- if (dart.library.html) 'package:html_editor_enhanced/src/html_editor_web.dart'
- if (dart.library.io) 'package:html_editor_enhanced/src/html_editor_mobile.dart';
-export 'package:html_editor_enhanced/src/widgets/custom_html_editor.dart';
-export 'package:html_editor_enhanced/src/widgets/math_keyboard_dialog.dart';
-export 'package:html_editor_enhanced/src/widgets/toolbar_widget.dart';
-export 'package:html_editor_enhanced/utils/callbacks.dart';
-export 'package:html_editor_enhanced/utils/file_upload_model.dart';
-export 'package:html_editor_enhanced/utils/options.dart';
-export 'package:html_editor_enhanced/utils/plugins.dart';
-export 'package:html_editor_enhanced/utils/shims/flutter_inappwebview_fake.dart'
+export 'package:html_editor_enhanced_fork_latex/src/html_editor_controller_unsupported.dart'
+ if (dart.library.html) 'package:html_editor_enhanced_fork_latex/src/html_editor_controller_web.dart'
+ if (dart.library.io) 'package:html_editor_enhanced_fork_latex/src/html_editor_controller_mobile.dart';
+export 'package:html_editor_enhanced_fork_latex/src/html_editor_unsupported.dart'
+ if (dart.library.html) 'package:html_editor_enhanced_fork_latex/src/html_editor_web.dart'
+ if (dart.library.io) 'package:html_editor_enhanced_fork_latex/src/html_editor_mobile.dart';
+export 'package:html_editor_enhanced_fork_latex/src/widgets/custom_html_editor.dart';
+export 'package:html_editor_enhanced_fork_latex/src/widgets/math_keyboard_dialog.dart';
+export 'package:html_editor_enhanced_fork_latex/src/widgets/toolbar_widget.dart';
+export 'package:html_editor_enhanced_fork_latex/utils/callbacks.dart';
+export 'package:html_editor_enhanced_fork_latex/utils/file_upload_model.dart';
+export 'package:html_editor_enhanced_fork_latex/utils/options.dart';
+export 'package:html_editor_enhanced_fork_latex/utils/plugins.dart';
+export 'package:html_editor_enhanced_fork_latex/utils/shims/flutter_inappwebview_fake.dart'
if (dart.library.io) 'package:flutter_inappwebview/flutter_inappwebview.dart';
-export 'package:html_editor_enhanced/utils/toolbar.dart';
-export 'package:html_editor_enhanced/utils/utils.dart'
+export 'package:html_editor_enhanced_fork_latex/utils/toolbar.dart';
+export 'package:html_editor_enhanced_fork_latex/utils/utils.dart'
hide setState, intersperse, getRandString;
/// Defines the 3 different cases for file insertion failing
diff --git a/lib/src/html_editor_controller_mobile.dart b/lib/src/html_editor_controller_mobile.dart
index 36547428..5cac876b 100644
--- a/lib/src/html_editor_controller_mobile.dart
+++ b/lib/src/html_editor_controller_mobile.dart
@@ -1,8 +1,8 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
-import 'package:html_editor_enhanced/html_editor.dart';
-import 'package:html_editor_enhanced/src/html_editor_controller_unsupported.dart'
+import 'package:html_editor_enhanced_fork_latex/html_editor.dart';
+import 'package:html_editor_enhanced_fork_latex/src/html_editor_controller_unsupported.dart'
as unsupported;
/// Controller for mobile
diff --git a/lib/src/html_editor_controller_unsupported.dart b/lib/src/html_editor_controller_unsupported.dart
index 419e92d3..87b687f7 100644
--- a/lib/src/html_editor_controller_unsupported.dart
+++ b/lib/src/html_editor_controller_unsupported.dart
@@ -1,6 +1,6 @@
import 'dart:collection';
-import 'package:html_editor_enhanced/html_editor.dart';
+import 'package:html_editor_enhanced_fork_latex/html_editor.dart';
import 'package:meta/meta.dart';
/// Fallback controller (should never be used)
diff --git a/lib/src/html_editor_controller_web.dart b/lib/src/html_editor_controller_web.dart
index 9a6324e6..b1b0e717 100644
--- a/lib/src/html_editor_controller_web.dart
+++ b/lib/src/html_editor_controller_web.dart
@@ -3,8 +3,8 @@ import 'dart:convert';
import 'dart:html' as html;
import 'package:flutter/foundation.dart';
-import 'package:html_editor_enhanced/html_editor.dart';
-import 'package:html_editor_enhanced/src/html_editor_controller_unsupported.dart'
+import 'package:html_editor_enhanced_fork_latex/html_editor.dart';
+import 'package:html_editor_enhanced_fork_latex/src/html_editor_controller_unsupported.dart'
as unsupported;
import 'package:meta/meta.dart';
diff --git a/lib/src/html_editor_mobile.dart b/lib/src/html_editor_mobile.dart
index 50faf109..e52dc809 100644
--- a/lib/src/html_editor_mobile.dart
+++ b/lib/src/html_editor_mobile.dart
@@ -1,9 +1,9 @@
-import 'package:html_editor_enhanced/html_editor.dart'
- hide HtmlEditorController;
-import 'package:html_editor_enhanced/src/html_editor_controller_mobile.dart';
-import 'package:html_editor_enhanced/src/widgets/html_editor_widget_mobile.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
+import 'package:html_editor_enhanced_fork_latex/html_editor.dart'
+ hide HtmlEditorController;
+import 'package:html_editor_enhanced_fork_latex/src/html_editor_controller_mobile.dart';
+import 'package:html_editor_enhanced_fork_latex/src/widgets/html_editor_widget_mobile.dart';
/// HtmlEditor class for mobile
class HtmlEditor extends StatelessWidget {
diff --git a/lib/src/html_editor_unsupported.dart b/lib/src/html_editor_unsupported.dart
index e4443167..47664389 100644
--- a/lib/src/html_editor_unsupported.dart
+++ b/lib/src/html_editor_unsupported.dart
@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
-import 'package:html_editor_enhanced/html_editor.dart';
+import 'package:html_editor_enhanced_fork_latex/html_editor.dart';
/// Fallback HtmlEditor class (should never be called)
class HtmlEditor extends StatelessWidget {
diff --git a/lib/src/html_editor_web.dart b/lib/src/html_editor_web.dart
index 3de5c787..f7ed1b41 100644
--- a/lib/src/html_editor_web.dart
+++ b/lib/src/html_editor_web.dart
@@ -1,7 +1,7 @@
-import 'package:html_editor_enhanced/html_editor.dart';
-import 'package:html_editor_enhanced/src/widgets/html_editor_widget_web.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
+import 'package:html_editor_enhanced_fork_latex/html_editor.dart';
+import 'package:html_editor_enhanced_fork_latex/src/widgets/html_editor_widget_web.dart';
/// HtmlEditor class for web
class HtmlEditor extends StatelessWidget {
diff --git a/lib/src/widgets/html_editor_widget_mobile.dart b/lib/src/widgets/html_editor_widget_mobile.dart
index 94f46fcd..aba91df2 100644
--- a/lib/src/widgets/html_editor_widget_mobile.dart
+++ b/lib/src/widgets/html_editor_widget_mobile.dart
@@ -8,9 +8,9 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
-import 'package:html_editor_enhanced/html_editor.dart'
+import 'package:html_editor_enhanced_fork_latex/html_editor.dart'
hide NavigationActionPolicy, UserScript, ContextMenu;
-import 'package:html_editor_enhanced/utils/utils.dart';
+import 'package:html_editor_enhanced_fork_latex/utils/utils.dart';
import 'package:visibility_detector/visibility_detector.dart';
/// The HTML Editor widget itself, for mobile (uses InAppWebView)
diff --git a/lib/src/widgets/html_editor_widget_web.dart b/lib/src/widgets/html_editor_widget_web.dart
index 103d35c2..1f0224f2 100644
--- a/lib/src/widgets/html_editor_widget_web.dart
+++ b/lib/src/widgets/html_editor_widget_web.dart
@@ -4,9 +4,9 @@ import 'dart:html' as html;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
-import 'package:html_editor_enhanced/html_editor.dart';
-import 'package:html_editor_enhanced/utils/shims/dart_ui.dart' as ui;
-import 'package:html_editor_enhanced/utils/utils.dart';
+import 'package:html_editor_enhanced_fork_latex/html_editor.dart';
+import 'package:html_editor_enhanced_fork_latex/utils/shims/dart_ui.dart' as ui;
+import 'package:html_editor_enhanced_fork_latex/utils/utils.dart';
export 'dart:html';
diff --git a/lib/src/widgets/toolbar_widget.dart b/lib/src/widgets/toolbar_widget.dart
index bdce4767..fefbeadb 100644
--- a/lib/src/widgets/toolbar_widget.dart
+++ b/lib/src/widgets/toolbar_widget.dart
@@ -7,8 +7,8 @@ import 'package:flex_color_picker/flex_color_picker.dart';
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';
+import 'package:html_editor_enhanced_fork_latex/html_editor.dart';
+import 'package:html_editor_enhanced_fork_latex/utils/utils.dart';
import 'package:math_keyboard/math_keyboard.dart';
import 'package:numberpicker/numberpicker.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
diff --git a/lib/utils/callbacks.dart b/lib/utils/callbacks.dart
index 366a6a94..daefdbd9 100644
--- a/lib/utils/callbacks.dart
+++ b/lib/utils/callbacks.dart
@@ -1,6 +1,6 @@
import 'dart:async';
-import 'package:html_editor_enhanced/html_editor.dart';
+import 'package:html_editor_enhanced_fork_latex/html_editor.dart';
/// Manages all the callback functions the library provides
class Callbacks {
diff --git a/lib/utils/options.dart b/lib/utils/options.dart
index 8212be6c..6ad3a959 100644
--- a/lib/utils/options.dart
+++ b/lib/utils/options.dart
@@ -3,7 +3,7 @@ import 'dart:collection';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
-import 'package:html_editor_enhanced/html_editor.dart';
+import 'package:html_editor_enhanced_fork_latex/html_editor.dart';
/// Options that modify the editor and its behavior
class HtmlEditorOptions {
diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart
index cbe2c46f..37c7449d 100644
--- a/lib/utils/utils.dart
+++ b/lib/utils/utils.dart
@@ -5,8 +5,8 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
-import 'package:html_editor_enhanced/html_editor.dart';
-import 'package:html_editor_enhanced/utils/shims/dart_ui.dart';
+import 'package:html_editor_enhanced_fork_latex/html_editor.dart';
+import 'package:html_editor_enhanced_fork_latex/utils/shims/dart_ui.dart';
/// small function to always check if mounted before running setState()
void setState(
diff --git a/pubspec.yaml b/pubspec.yaml
index cac25a53..d0d6abee 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,7 +1,7 @@
-name: html_editor_enhanced
+name: html_editor_enhanced_fork_latex
description: HTML rich text editor for Android, iOS, and Web, using the Summernote library.
Enhanced with highly customizable widget-based controls, bug fixes, callbacks, dark mode, and more.
-version: 2.5.1
+version: 2.5.2
homepage: https://github.com/tneotia/html-editor-enhanced
environment:
From 409cff88e79f3beb959a7467e1cdc0aaa0e2a8e1 Mon Sep 17 00:00:00 2001
From: Ahmad Khateeb
Date: Wed, 20 Dec 2023 12:11:49 +0200
Subject: [PATCH 10/29] changed from 'html_editor_enhanced' to
'html_editor_enhanced_fork_latex'
---
analysis_options.yaml | 1 -
example/pubspec.lock | 92 +++++++++++++--------
lib/src/widgets/math_keyboard_dialog.dart | 70 ++++++++--------
lib/src/widgets/toolbar_widget.dart | 4 +-
lib/utils/custom_math_field_controller.dart | 17 ++++
pubspec.lock | 86 ++++++++++++-------
pubspec.yaml | 19 +++--
7 files changed, 177 insertions(+), 112 deletions(-)
create mode 100644 lib/utils/custom_math_field_controller.dart
diff --git a/analysis_options.yaml b/analysis_options.yaml
index d4fcc1ad..e69de29b 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -1 +0,0 @@
-include: package:pedantic/analysis_options.yaml
\ No newline at end of file
diff --git a/example/pubspec.lock b/example/pubspec.lock
index 3e04836c..8d05b2e9 100644
--- a/example/pubspec.lock
+++ b/example/pubspec.lock
@@ -53,10 +53,10 @@ packages:
dependency: "direct main"
description:
name: cupertino_icons
- sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
+ sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
url: "https://pub.dev"
source: hosted
- version: "1.0.5"
+ version: "1.0.6"
fake_async:
dependency: transitive
description:
@@ -69,26 +69,26 @@ packages:
dependency: transitive
description:
name: ffi
- sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978
+ sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
url: "https://pub.dev"
source: hosted
- version: "2.0.1"
+ version: "2.1.0"
file_picker:
dependency: transitive
description:
name: file_picker
- sha256: d090ae03df98b0247b82e5928f44d1b959867049d18d73635e2e0bc3f49542b9
+ sha256: "4e42aacde3b993c5947467ab640882c56947d9d27342a5b6f2895b23956954a6"
url: "https://pub.dev"
source: hosted
- version: "5.2.5"
+ version: "6.1.1"
flex_color_picker:
dependency: transitive
description:
name: flex_color_picker
- sha256: "40c1cbf8426a05c2b418ecf6c0fce386429fd7f9d238abbb2182985e8e6c5596"
+ sha256: f37476ab3e80dcaca94e428e159944d465dd16312fda9ff41e07e86f04bfa51c
url: "https://pub.dev"
source: hosted
- version: "3.0.2"
+ version: "3.3.0"
flex_seed_scheme:
dependency: transitive
description:
@@ -106,18 +106,18 @@ packages:
dependency: transitive
description:
name: flutter_inappwebview
- sha256: f73505c792cf083d5566e1a94002311be497d984b5607f25be36d685cf6361cf
+ sha256: d198297060d116b94048301ee6749cd2e7d03c1f2689783f52d210a6b7aba350
url: "https://pub.dev"
source: hosted
- version: "5.7.2+3"
+ version: "5.8.0"
flutter_keyboard_visibility:
dependency: transitive
description:
name: flutter_keyboard_visibility
- sha256: "86b71bbaffa38e885f5c21b1182408b9be6951fd125432cf6652c636254cef2d"
+ sha256: "4983655c26ab5b959252ee204c2fffa4afeb4413cd030455194ec0caa3b8e7cb"
url: "https://pub.dev"
source: hosted
- version: "5.4.0"
+ version: "5.4.1"
flutter_keyboard_visibility_linux:
dependency: transitive
description:
@@ -175,10 +175,10 @@ packages:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
- sha256: "60fc7b78455b94e6de2333d2f95196d32cf5c22f4b0b0520a628804cb463503b"
+ sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da
url: "https://pub.dev"
source: hosted
- version: "2.0.7"
+ version: "2.0.17"
flutter_svg:
dependency: transitive
description:
@@ -211,7 +211,7 @@ packages:
path: ".."
relative: true
source: path
- version: "2.5.2"
+ version: "2.6.0"
infinite_listview:
dependency: transitive
description:
@@ -228,6 +228,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.18.1"
+ lints:
+ dependency: transitive
+ description:
+ name: lints
+ sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.0"
matcher:
dependency: transitive
description:
@@ -280,10 +288,10 @@ packages:
dependency: transitive
description:
name: numberpicker
- sha256: "73723bd13c940ebcd9e5f0ed56b4874588c1748a9a6a38254f97ad627715142e"
+ sha256: "4c129154944b0f6b133e693f8749c3f8bfb67c4d07ef9dcab48b595c22d1f156"
url: "https://pub.dev"
source: hosted
- version: "2.1.1"
+ version: "2.1.2"
path:
dependency: transitive
description:
@@ -300,14 +308,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.1"
- pedantic:
- dependency: transitive
- description:
- name: pedantic
- sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602"
- url: "https://pub.dev"
- source: hosted
- version: "1.11.1"
petitparser:
dependency: transitive
description:
@@ -320,18 +320,42 @@ packages:
dependency: transitive
description:
name: plugin_platform_interface
- sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a
+ sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8
url: "https://pub.dev"
source: hosted
- version: "2.1.3"
+ version: "2.1.7"
pointer_interceptor:
dependency: transitive
description:
name: pointer_interceptor
- sha256: fee6ba42b910637465bc0d367ba27066c6eccfbc3bc0ceb14831915acc600db0
+ sha256: fda979f3eb65558a389517521c8315060289dda5a1a6087f3892bdea9550eade
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.10.0"
+ pointer_interceptor_ios:
+ dependency: transitive
+ description:
+ name: pointer_interceptor_ios
+ sha256: "4282ebfe21b54e21e26ab982c6086f0a67dc63423026bfba8db39a2e22045f26"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.10.0"
+ pointer_interceptor_platform_interface:
+ dependency: transitive
+ description:
+ name: pointer_interceptor_platform_interface
+ sha256: "59a446ead3be360bde72c3725f5ecacbba203c8a760e3061024c20f7da53f825"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.10.0"
+ pointer_interceptor_web:
+ dependency: transitive
+ description:
+ name: pointer_interceptor_web
+ sha256: "2a8a069206f7b234a895d30ccab8b18ea267eeb79a832e5e3d1b6464d659eb6a"
url: "https://pub.dev"
source: hosted
- version: "0.9.3+3"
+ version: "0.10.0"
provider:
dependency: transitive
description:
@@ -437,10 +461,10 @@ packages:
dependency: transitive
description:
name: visibility_detector
- sha256: "15c54a459ec2c17b4705450483f3d5a2858e733aee893dcee9d75fd04814940d"
+ sha256: dd5cc11e13494f432d15939c3aa8ae76844c42b723398643ce9addb88a5ed420
url: "https://pub.dev"
source: hosted
- version: "0.3.3"
+ version: "0.4.0+2"
web:
dependency: transitive
description:
@@ -485,10 +509,10 @@ packages:
dependency: transitive
description:
name: win32
- sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46
+ sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574
url: "https://pub.dev"
source: hosted
- version: "3.1.3"
+ version: "5.1.1"
xml:
dependency: transitive
description:
@@ -499,4 +523,4 @@ packages:
version: "6.3.0"
sdks:
dart: ">=3.2.0-194.0.dev <4.0.0"
- flutter: ">=3.10.0"
+ flutter: ">=3.13.0"
diff --git a/lib/src/widgets/math_keyboard_dialog.dart b/lib/src/widgets/math_keyboard_dialog.dart
index a236e601..1ccb67ea 100644
--- a/lib/src/widgets/math_keyboard_dialog.dart
+++ b/lib/src/widgets/math_keyboard_dialog.dart
@@ -1,6 +1,7 @@
import 'dart:developer';
import 'package:flutter/material.dart';
+import 'package:html_editor_enhanced_fork_latex/utils/custom_math_field_controller.dart';
import 'package:math_keyboard/math_keyboard.dart';
class MathKeyboardDialog extends StatelessWidget {
@@ -13,11 +14,12 @@ class MathKeyboardDialog extends StatelessWidget {
}
}
- final MathFieldEditingController controller;
+ final CustomMathFieldEditingController controller;
final MathField? mathField;
@override
Widget build(BuildContext context) {
+ var tex = '';
return Dialog(
child: Padding(
padding: const EdgeInsets.all(8.0),
@@ -25,20 +27,47 @@ class MathKeyboardDialog extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
- _mathField(context),
+ SizedBox(
+ width: MediaQuery.of(context).size.width,
+ child: MathField(
+ focusNode: mathField?.focusNode,
+ autofocus: mathField?.autofocus ?? true,
+ controller: controller,
+ variables:
+ mathField?.variables ?? ['x', 'y', 'z', 'A', 'B', 'C'],
+ decoration: mathField?.decoration ??
+ InputDecoration(
+ suffix: MouseRegion(
+ cursor: MaterialStateMouseCursor.clickable,
+ child: GestureDetector(
+ onTap: controller.clear,
+ child: const Icon(
+ Icons.highlight_remove_rounded,
+ color: Colors.grey,
+ ),
+ ),
+ ),
+ ),
+ onChanged: mathField?.onChanged ??
+ (str) {
+ tex = str;
+ },
+ onSubmitted: mathField?.onSubmitted,
+ opensKeyboard: mathField?.opensKeyboard ?? true,
+ ),
+ ),
const SizedBox(height: 15),
TextButton(
onPressed: () {
- controller.setTexString('');
Navigator.pop(context, '');
- print(controller.texStringAsFun);
+ print(texStringAsFun(tex));
},
child: const Text('Close'),
),
TextButton(
onPressed: () {
Navigator.pop(context, controller.texStringAsFun);
- print(controller.texStringAsFun);
+ print(texStringAsFun(tex));
},
child: const Text('save'),
),
@@ -48,34 +77,5 @@ class MathKeyboardDialog extends StatelessWidget {
);
}
- Widget _mathField(context) {
- return SizedBox(
- width: MediaQuery.of(context).size.width,
- child: MathField(
- focusNode: mathField?.focusNode,
- autofocus: mathField?.autofocus ?? true,
- controller: controller,
- variables: mathField?.variables ?? ['x', 'y', 'z', 'A', 'B', 'C'],
- decoration: mathField?.decoration ??
- InputDecoration(
- suffix: MouseRegion(
- cursor: MaterialStateMouseCursor.clickable,
- child: GestureDetector(
- onTap: controller.clear,
- child: const Icon(
- Icons.highlight_remove_rounded,
- color: Colors.grey,
- ),
- ),
- ),
- ),
- onChanged: mathField?.onChanged ??
- (str) {
- controller.setTexString(str);
- },
- onSubmitted: mathField?.onSubmitted,
- opensKeyboard: mathField?.opensKeyboard ?? true,
- ),
- );
- }
+ String texStringAsFun(String str) => '\\($str\\)';
}
diff --git a/lib/src/widgets/toolbar_widget.dart b/lib/src/widgets/toolbar_widget.dart
index fefbeadb..70b94032 100644
--- a/lib/src/widgets/toolbar_widget.dart
+++ b/lib/src/widgets/toolbar_widget.dart
@@ -8,8 +8,8 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:html_editor_enhanced_fork_latex/html_editor.dart';
+import 'package:html_editor_enhanced_fork_latex/utils/custom_math_field_controller.dart';
import 'package:html_editor_enhanced_fork_latex/utils/utils.dart';
-import 'package:math_keyboard/math_keyboard.dart';
import 'package:numberpicker/numberpicker.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:webview_flutter/webview_flutter.dart';
@@ -2611,7 +2611,7 @@ class ToolbarWidgetState extends State {
?.call(ButtonType.fn, null, null) ??
true;
if (proceed) {
- final c = MathFieldEditingController();
+ final c = CustomMathFieldEditingController();
await showDialog(
context: context,
builder: (context) => MathKeyboardDialog(controller: c));
diff --git a/lib/utils/custom_math_field_controller.dart b/lib/utils/custom_math_field_controller.dart
new file mode 100644
index 00000000..34b28132
--- /dev/null
+++ b/lib/utils/custom_math_field_controller.dart
@@ -0,0 +1,17 @@
+import 'package:math_keyboard/math_keyboard.dart';
+
+class CustomMathFieldEditingController extends MathFieldEditingController {
+ /// Constructs a [MathKeyboardViewModel].
+ CustomMathFieldEditingController() {
+ currentNode = root;
+ currentNode.setCursor();
+ }
+
+ String texString = '';
+
+ void setTexString(String str) {
+ texString = str;
+ }
+
+ String get texStringAsFun => '\\($texString\\)';
+}
diff --git a/pubspec.lock b/pubspec.lock
index 2e36c442..52ecca82 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -61,26 +61,26 @@ packages:
dependency: transitive
description:
name: ffi
- sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978
+ sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
url: "https://pub.dev"
source: hosted
- version: "2.0.1"
+ version: "2.1.0"
file_picker:
dependency: "direct main"
description:
name: file_picker
- sha256: d090ae03df98b0247b82e5928f44d1b959867049d18d73635e2e0bc3f49542b9
+ sha256: "4e42aacde3b993c5947467ab640882c56947d9d27342a5b6f2895b23956954a6"
url: "https://pub.dev"
source: hosted
- version: "5.2.5"
+ version: "6.1.1"
flex_color_picker:
dependency: "direct main"
description:
name: flex_color_picker
- sha256: "40c1cbf8426a05c2b418ecf6c0fce386429fd7f9d238abbb2182985e8e6c5596"
+ sha256: f37476ab3e80dcaca94e428e159944d465dd16312fda9ff41e07e86f04bfa51c
url: "https://pub.dev"
source: hosted
- version: "3.0.2"
+ version: "3.3.0"
flex_seed_scheme:
dependency: transitive
description:
@@ -98,18 +98,18 @@ packages:
dependency: "direct main"
description:
name: flutter_inappwebview
- sha256: f73505c792cf083d5566e1a94002311be497d984b5607f25be36d685cf6361cf
+ sha256: d198297060d116b94048301ee6749cd2e7d03c1f2689783f52d210a6b7aba350
url: "https://pub.dev"
source: hosted
- version: "5.7.2+3"
+ version: "5.8.0"
flutter_keyboard_visibility:
dependency: "direct main"
description:
name: flutter_keyboard_visibility
- sha256: "86b71bbaffa38e885f5c21b1182408b9be6951fd125432cf6652c636254cef2d"
+ sha256: "4983655c26ab5b959252ee204c2fffa4afeb4413cd030455194ec0caa3b8e7cb"
url: "https://pub.dev"
source: hosted
- version: "5.4.0"
+ version: "5.4.1"
flutter_keyboard_visibility_linux:
dependency: transitive
description:
@@ -167,10 +167,10 @@ packages:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
- sha256: "60fc7b78455b94e6de2333d2f95196d32cf5c22f4b0b0520a628804cb463503b"
+ sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da
url: "https://pub.dev"
source: hosted
- version: "2.0.7"
+ version: "2.0.17"
flutter_svg:
dependency: transitive
description:
@@ -213,6 +213,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.18.1"
+ lints:
+ dependency: "direct main"
+ description:
+ name: lints
+ sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.0"
matcher:
dependency: transitive
description:
@@ -265,10 +273,10 @@ packages:
dependency: "direct main"
description:
name: numberpicker
- sha256: "73723bd13c940ebcd9e5f0ed56b4874588c1748a9a6a38254f97ad627715142e"
+ sha256: "4c129154944b0f6b133e693f8749c3f8bfb67c4d07ef9dcab48b595c22d1f156"
url: "https://pub.dev"
source: hosted
- version: "2.1.1"
+ version: "2.1.2"
path:
dependency: transitive
description:
@@ -285,14 +293,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.1"
- pedantic:
- dependency: "direct main"
- description:
- name: pedantic
- sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602"
- url: "https://pub.dev"
- source: hosted
- version: "1.11.1"
petitparser:
dependency: transitive
description:
@@ -305,18 +305,42 @@ packages:
dependency: transitive
description:
name: plugin_platform_interface
- sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a
+ sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8
url: "https://pub.dev"
source: hosted
- version: "2.1.3"
+ version: "2.1.7"
pointer_interceptor:
dependency: "direct main"
description:
name: pointer_interceptor
- sha256: fee6ba42b910637465bc0d367ba27066c6eccfbc3bc0ceb14831915acc600db0
+ sha256: fda979f3eb65558a389517521c8315060289dda5a1a6087f3892bdea9550eade
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.10.0"
+ pointer_interceptor_ios:
+ dependency: transitive
+ description:
+ name: pointer_interceptor_ios
+ sha256: "4282ebfe21b54e21e26ab982c6086f0a67dc63423026bfba8db39a2e22045f26"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.10.0"
+ pointer_interceptor_platform_interface:
+ dependency: transitive
+ description:
+ name: pointer_interceptor_platform_interface
+ sha256: "59a446ead3be360bde72c3725f5ecacbba203c8a760e3061024c20f7da53f825"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.10.0"
+ pointer_interceptor_web:
+ dependency: transitive
+ description:
+ name: pointer_interceptor_web
+ sha256: "2a8a069206f7b234a895d30ccab8b18ea267eeb79a832e5e3d1b6464d659eb6a"
url: "https://pub.dev"
source: hosted
- version: "0.9.3+3"
+ version: "0.10.0"
provider:
dependency: transitive
description:
@@ -422,10 +446,10 @@ packages:
dependency: "direct main"
description:
name: visibility_detector
- sha256: "15c54a459ec2c17b4705450483f3d5a2858e733aee893dcee9d75fd04814940d"
+ sha256: dd5cc11e13494f432d15939c3aa8ae76844c42b723398643ce9addb88a5ed420
url: "https://pub.dev"
source: hosted
- version: "0.3.3"
+ version: "0.4.0+2"
web:
dependency: transitive
description:
@@ -470,10 +494,10 @@ packages:
dependency: transitive
description:
name: win32
- sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46
+ sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574
url: "https://pub.dev"
source: hosted
- version: "3.1.3"
+ version: "5.1.1"
xml:
dependency: transitive
description:
@@ -484,4 +508,4 @@ packages:
version: "6.3.0"
sdks:
dart: ">=3.2.0-194.0.dev <4.0.0"
- flutter: ">=3.10.0"
+ flutter: ">=3.13.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index d0d6abee..dfdcfd59 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,8 +1,9 @@
name: html_editor_enhanced_fork_latex
description: HTML rich text editor for Android, iOS, and Web, using the Summernote library.
Enhanced with highly customizable widget-based controls, bug fixes, callbacks, dark mode, and more.
-version: 2.5.2
+version: 2.6.1
homepage: https://github.com/tneotia/html-editor-enhanced
+repository: https://github.com/AhmadKhateebq/html-editor-enhanced-with-latex.git
environment:
sdk: '>=2.15.0 <3.0.0'
@@ -12,26 +13,26 @@ dependencies:
flutter:
sdk: flutter
# webview plugin
- flutter_inappwebview: ^5.7.2+3
+ flutter_inappwebview: ^5.8.0
# plugin to get webview's visible fraction for keyboard height adjustment
- visibility_detector: ^0.3.3
+ visibility_detector: ^0.4.0+2
# plugin to get when the keyboard is hidden via back (Android)
# or "done" (iOS) to reset the editor's height
flutter_keyboard_visibility: ^5.4.0
# plugin to show a color picker for foreground/highlight color
- flex_color_picker: ^3.0.2
+ flex_color_picker: ^3.3.0
# plugin to get files from filesystem
- file_picker: ^5.2.0+1
+ file_picker: ^6.1.1
# plugin to show a scrollable number picker for inserting tables
- numberpicker: ^2.1.1
+ numberpicker: ^2.1.2
# plugin to allow dropdowns and dialogs to be interactable when displaying over the editor
# related to https://github.com/flutter/flutter/issues/54027
# pinned to 0.9.1 because of issues with CanvasKit in the latest versions
- pointer_interceptor: ^0.9.3+3
+ pointer_interceptor: ^0.10.0
# plugin to help maintain effective Dart standards
- pedantic: ^1.11.1
+ lints: ^3.0.0
# plugin for @internal annotation
- meta: '>=1.0.0 <2.0.0'
+ meta: ^1.10.0
math_keyboard: ^0.2.1
webview_flutter: ^4.4.2
From 1fa09ae06c768fe3ef32092840a39083fa400d69 Mon Sep 17 00:00:00 2001
From: Ahmad Khateeb
Date: Wed, 20 Dec 2023 14:59:15 +0200
Subject: [PATCH 11/29] fixed bugs in math keyboard and did dart format
---
CHANGELOG.md | 41 ++-
README.md | 16 +-
example/android/build.gradle | 2 +-
example/lib/main.dart | 4 +-
example/pubspec.lock | 2 +-
lib/html_editor.dart | 2 +-
lib/src/html_editor_controller_mobile.dart | 4 +-
.../html_editor_controller_unsupported.dart | 4 +-
lib/src/html_editor_controller_web.dart | 6 +-
lib/src/html_editor_mobile.dart | 2 +-
lib/src/html_editor_unsupported.dart | 2 +-
lib/src/html_editor_web.dart | 2 +-
lib/src/widgets/custom_html_editor.dart | 1 +
.../widgets/html_editor_widget_mobile.dart | 7 +-
lib/src/widgets/html_editor_widget_web.dart | 10 +-
lib/src/widgets/math_keyboard_dialog.dart | 11 +-
lib/src/widgets/toolbar_widget.dart | 2 +-
lib/utils/custom_classes.dart | 270 ++++++++++++++++++
lib/utils/custom_math_field_controller.dart | 18 ++
lib/utils/plugins.dart | 2 +-
lib/utils/toolbar.dart | 2 +-
lib/utils/utils.dart | 2 +
pubspec.yaml | 22 +-
23 files changed, 378 insertions(+), 56 deletions(-)
create mode 100644 lib/utils/custom_classes.dart
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a145802f..2fed830e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,14 +1,47 @@
-## [2.5.1] = 2023-01-25
+## [2.6.4] = 2023-12-20
+
+* Fixed Cursor bug in math keyboard
+
+## [2.6.3] = 2023-12-20
+
+* Fixed the assets for name change
+
+## [2.6.2] = 2023-12-20
+
+* Dart formatter
+*
+
+## [2.6.1] = 2023-12-20
+
+* Update pubspec
+* Added repo url
+
+## [2.6.0] = 2023-12-20
+
+* Bug fixes
+* Added a Custom Math Keyboard
+
+## [2.5.2] = 2023-12-20
+
+* Added latex
+* Added dependencies
+
+## [2.5.1] = 2023-12-20
+
* Fix build issues on Flutter 3.4.0+ due to assets directory
* Update dependencies
## [2.5.0] - 2022-06-04
+
* Support Flutter 3.0 (remove warnings) (@Cteq3132)
-* [BREAKING] Support modifying `foreColorSelected` and `backColorSelected` when using a custom dialog for font coloring
- * If you are using a custom `updateStatus` function for the font coloring, that function is now defined as `updateStatus(Color)`
+* [BREAKING] Support modifying `foreColorSelected` and `backColorSelected` when using a custom
+ dialog for font coloring
+ * If you are using a custom `updateStatus` function for the font coloring, that function is now
+ defined as `updateStatus(Color)`
* Added `disabled` parameter to automatically disable editor on initial load
* Fixed white background color appearing sometimes when pressing backspace on text
-* Added `useHybridComposition` parameter in case devs want to disable this behavior (improves animations of app)
+* Added `useHybridComposition` parameter in case devs want to disable this behavior (improves
+ animations of app)
* [WEB] Fixed editor height being 0 when `initialText` is `null` (@dab246)
* Migrated example to Android embedding V2
* Removed woff fonts to allow iOS App Store submissions
diff --git a/README.md b/README.md
index 7dce292a..f2202616 100644
--- a/README.md
+++ b/README.md
@@ -481,9 +481,11 @@ Notes:
You can use these files from the package to avoid adding more asset files:
```html
-
-
-
+
+
+
+
```
See the example HTML file [below](#example-html-for-filepath) for an actual example.
@@ -848,7 +850,7 @@ import 'package:flutter/cupertino.dart';
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_fork_latex/html_editor.dart';
class _ExampleState extends State {
final HtmlEditorController controller = HtmlEditorController();
@@ -950,9 +952,9 @@ class _ExampleState extends State {
Summernote Text Editor HTML
-
-
-
+
+
+
diff --git a/example/android/build.gradle b/example/android/build.gradle
index 05744a00..7849bedc 100644
--- a/example/android/build.gradle
+++ b/example/android/build.gradle
@@ -6,7 +6,7 @@ buildscript {
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.1.0'
+ classpath 'com.android.tools.build:gradle:7.4.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
diff --git a/example/lib/main.dart b/example/lib/main.dart
index 56115b85..cfac4eae 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -208,10 +208,10 @@ class _HtmlEditorExampleState extends State {
backgroundColor:
Theme.of(context).colorScheme.secondary),
onPressed: () async {
- var txt = await controller.getText();
+ var txt = await controller.getHtmlStringWithLatex();
if (txt.contains('src=\"data:')) {
txt =
- '';
+ '';
}
setState(() {
result = txt;
diff --git a/example/pubspec.lock b/example/pubspec.lock
index 8d05b2e9..f9666903 100644
--- a/example/pubspec.lock
+++ b/example/pubspec.lock
@@ -211,7 +211,7 @@ packages:
path: ".."
relative: true
source: path
- version: "2.6.0"
+ version: "2.6.3"
infinite_listview:
dependency: transitive
description:
diff --git a/lib/html_editor.dart b/lib/html_editor.dart
index c280cc13..c5c2c9f1 100644
--- a/lib/html_editor.dart
+++ b/lib/html_editor.dart
@@ -99,4 +99,4 @@ enum DropdownMenuDirection { down, up }
enum InsertFileType { image, audio, video }
/// Sets how the virtual keyboard appears on mobile devices
-enum HtmlInputType { decimal, email, numeric, tel, url, text }
\ No newline at end of file
+enum HtmlInputType { decimal, email, numeric, tel, url, text }
diff --git a/lib/src/html_editor_controller_mobile.dart b/lib/src/html_editor_controller_mobile.dart
index 5cac876b..6033e7fe 100644
--- a/lib/src/html_editor_controller_mobile.dart
+++ b/lib/src/html_editor_controller_mobile.dart
@@ -195,7 +195,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
@override
void reloadWeb() {
throw Exception(
- 'Non-Flutter Web environment detected, please make sure you are importing package:html_editor_enhanced/html_editor.dart and check kIsWeb before calling this function');
+ 'Non-Flutter Web environment detected, please make sure you are importing package:html_editor_enhanced_fork_latex/html_editor.dart and check kIsWeb before calling this function');
}
/// Resets the height of the editor back to the original if it was changed to
@@ -265,7 +265,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
return result;
} else {
throw Exception(
- 'Flutter Web environment detected, please make sure you are importing package:html_editor_enhanced/html_editor.dart');
+ 'Flutter Web environment detected, please make sure you are importing package:html_editor_enhanced_fork_latex/html_editor.dart');
}
}
diff --git a/lib/src/html_editor_controller_unsupported.dart b/lib/src/html_editor_controller_unsupported.dart
index 87b687f7..e69be568 100644
--- a/lib/src/html_editor_controller_unsupported.dart
+++ b/lib/src/html_editor_controller_unsupported.dart
@@ -119,7 +119,7 @@ class HtmlEditorController {
/// A function to execute JS passed as a [WebScript] to the editor. This should
/// only be used on Flutter Web.
Future evaluateJavascriptWeb(String name,
- {bool hasReturnValue = false}) =>
+ {bool hasReturnValue = false}) =>
Future.value();
/// Gets the text from the editor and returns it as a [String].
@@ -206,4 +206,4 @@ class HtmlEditorController {
/// Internal function to insert table on Web
@internal
void insertTable(String dimensions) {}
-}
\ No newline at end of file
+}
diff --git a/lib/src/html_editor_controller_web.dart b/lib/src/html_editor_controller_web.dart
index b1b0e717..2f7e826d 100644
--- a/lib/src/html_editor_controller_web.dart
+++ b/lib/src/html_editor_controller_web.dart
@@ -187,7 +187,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
@override
void clearFocus() {
throw Exception(
- 'Flutter Web environment detected, please make sure you are importing package:html_editor_enhanced/html_editor.dart and check kIsWeb before calling this method.');
+ 'Flutter Web environment detected, please make sure you are importing package:html_editor_enhanced_fork_latex/html_editor.dart and check kIsWeb before calling this method.');
}
/// Resets the height of the editor back to the original if it was changed to
@@ -196,7 +196,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
@override
void resetHeight() {
throw Exception(
- 'Flutter Web environment detected, please make sure you are importing package:html_editor_enhanced/html_editor.dart and check kIsWeb before calling this method.');
+ 'Flutter Web environment detected, please make sure you are importing package:html_editor_enhanced_fork_latex/html_editor.dart and check kIsWeb before calling this method.');
}
/// Refresh the page
@@ -323,7 +323,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
html.window.postMessage(json, '*');
} else {
throw Exception(
- 'Non-Flutter Web environment detected, please make sure you are importing package:html_editor_enhanced/html_editor.dart');
+ 'Non-Flutter Web environment detected, please make sure you are importing package:html_editor_enhanced_fork_latex/html_editor.dart');
}
}
}
diff --git a/lib/src/html_editor_mobile.dart b/lib/src/html_editor_mobile.dart
index e52dc809..0afe5ce4 100644
--- a/lib/src/html_editor_mobile.dart
+++ b/lib/src/html_editor_mobile.dart
@@ -51,7 +51,7 @@ class HtmlEditor extends StatelessWidget {
);
} else {
return Text(
- 'Flutter Web environment detected, please make sure you are importing package:html_editor_enhanced/html_editor.dart');
+ 'Flutter Web environment detected, please make sure you are importing package:html_editor_enhanced_fork_latex/html_editor.dart');
}
}
}
diff --git a/lib/src/html_editor_unsupported.dart b/lib/src/html_editor_unsupported.dart
index 47664389..a8eabf55 100644
--- a/lib/src/html_editor_unsupported.dart
+++ b/lib/src/html_editor_unsupported.dart
@@ -37,4 +37,4 @@ class HtmlEditor extends StatelessWidget {
Widget build(BuildContext context) {
return Text('Unsupported in this environment');
}
-}
\ No newline at end of file
+}
diff --git a/lib/src/html_editor_web.dart b/lib/src/html_editor_web.dart
index f7ed1b41..81f072bf 100644
--- a/lib/src/html_editor_web.dart
+++ b/lib/src/html_editor_web.dart
@@ -50,7 +50,7 @@ class HtmlEditor extends StatelessWidget {
);
} else {
return Text(
- 'Non-Flutter Web environment detected, please make sure you are importing package:html_editor_enhanced/html_editor.dart');
+ 'Non-Flutter Web environment detected, please make sure you are importing package:html_editor_enhanced_fork_latex/html_editor.dart');
}
}
}
diff --git a/lib/src/widgets/custom_html_editor.dart b/lib/src/widgets/custom_html_editor.dart
index e7bb9e0b..f12cfbfe 100644
--- a/lib/src/widgets/custom_html_editor.dart
+++ b/lib/src/widgets/custom_html_editor.dart
@@ -150,6 +150,7 @@ class CustomHtmlEditorWidget extends StatelessWidget {
return _htmlWidget();
}
}
+
const tableTex = r'''
\begin{array} { | l | l | l | }
diff --git a/lib/src/widgets/html_editor_widget_mobile.dart b/lib/src/widgets/html_editor_widget_mobile.dart
index aba91df2..f2c064a6 100644
--- a/lib/src/widgets/html_editor_widget_mobile.dart
+++ b/lib/src/widgets/html_editor_widget_mobile.dart
@@ -72,9 +72,10 @@ class _HtmlEditorWidgetMobileState extends State {
filePath = widget.htmlEditorOptions.filePath!;
} else if (widget.plugins.isEmpty) {
filePath =
- 'packages/html_editor_enhanced/assets/summernote-no-plugins.html';
+ 'packages/html_editor_enhanced_fork_latex/assets/summernote-no-plugins.html';
} else {
- filePath = 'packages/html_editor_enhanced/assets/summernote.html';
+ filePath =
+ 'packages/html_editor_enhanced_fork_latex/assets/summernote.html';
}
super.initState();
}
@@ -456,7 +457,7 @@ class _HtmlEditorWidgetMobileState extends State {
widget.htmlEditorOptions.darkMode != false) {
//todo fix for iOS (https://github.com/pichillilorenzo/flutter_inappwebview/issues/695)
var darkCSS =
- '';
+ '';
await controller.evaluateJavascript(
source: "\$('head').append('$darkCSS');");
}
diff --git a/lib/src/widgets/html_editor_widget_web.dart b/lib/src/widgets/html_editor_widget_web.dart
index 1f0224f2..2bae694d 100644
--- a/lib/src/widgets/html_editor_widget_web.dart
+++ b/lib/src/widgets/html_editor_widget_web.dart
@@ -186,7 +186,7 @@ class _HtmlEditorWidgetWebState extends State {
widget.htmlEditorOptions.darkMode == true) &&
widget.htmlEditorOptions.darkMode != false) {
darkCSS =
- '';
+ '';
}
var jsCallbacks = '';
if (widget.callbacks != null) {
@@ -446,7 +446,7 @@ class _HtmlEditorWidgetWebState extends State {
""";
var filePath =
- 'packages/html_editor_enhanced/assets/summernote-no-plugins.html';
+ 'packages/html_editor_enhanced_fork_latex/assets/summernote-no-plugins.html';
if (widget.htmlEditorOptions.filePath != null) {
filePath = widget.htmlEditorOptions.filePath!;
}
@@ -456,11 +456,11 @@ class _HtmlEditorWidgetWebState extends State {
.replaceFirst('', headString)
.replaceFirst('', summernoteScripts)
.replaceFirst('"jquery.min.js"',
- '"assets/packages/html_editor_enhanced/assets/jquery.min.js"')
+ '"assets/packages/html_editor_enhanced_fork_latex/assets/jquery.min.js"')
.replaceFirst('"summernote-lite.min.css"',
- '"assets/packages/html_editor_enhanced/assets/summernote-lite.min.css"')
+ '"assets/packages/html_editor_enhanced_fork_latex/assets/summernote-lite.min.css"')
.replaceFirst('"summernote-lite.min.js"',
- '"assets/packages/html_editor_enhanced/assets/summernote-lite.min.js"');
+ '"assets/packages/html_editor_enhanced_fork_latex/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'
diff --git a/lib/src/widgets/math_keyboard_dialog.dart b/lib/src/widgets/math_keyboard_dialog.dart
index 1ccb67ea..0a205c99 100644
--- a/lib/src/widgets/math_keyboard_dialog.dart
+++ b/lib/src/widgets/math_keyboard_dialog.dart
@@ -19,7 +19,6 @@ class MathKeyboardDialog extends StatelessWidget {
@override
Widget build(BuildContext context) {
- var tex = '';
return Dialog(
child: Padding(
padding: const EdgeInsets.all(8.0),
@@ -48,10 +47,7 @@ class MathKeyboardDialog extends StatelessWidget {
),
),
),
- onChanged: mathField?.onChanged ??
- (str) {
- tex = str;
- },
+ onChanged: mathField?.onChanged ?? controller.setTexString,
onSubmitted: mathField?.onSubmitted,
opensKeyboard: mathField?.opensKeyboard ?? true,
),
@@ -60,14 +56,14 @@ class MathKeyboardDialog extends StatelessWidget {
TextButton(
onPressed: () {
Navigator.pop(context, '');
- print(texStringAsFun(tex));
+ print(controller.texStringAsFun);
},
child: const Text('Close'),
),
TextButton(
onPressed: () {
Navigator.pop(context, controller.texStringAsFun);
- print(texStringAsFun(tex));
+ print(controller.texStringAsFun);
},
child: const Text('save'),
),
@@ -77,5 +73,4 @@ class MathKeyboardDialog extends StatelessWidget {
);
}
- String texStringAsFun(String str) => '\\($str\\)';
}
diff --git a/lib/src/widgets/toolbar_widget.dart b/lib/src/widgets/toolbar_widget.dart
index 70b94032..a4298b30 100644
--- a/lib/src/widgets/toolbar_widget.dart
+++ b/lib/src/widgets/toolbar_widget.dart
@@ -503,7 +503,7 @@ class ToolbarWidgetState extends State {
dropdownColor: widget.htmlToolbarOptions.dropdownBackgroundColor,
menuDirection: widget.htmlToolbarOptions.dropdownMenuDirection ??
(widget.htmlToolbarOptions.toolbarPosition ==
- ToolbarPosition.belowEditor
+ ToolbarPosition.belowEditor
? DropdownMenuDirection.up
: DropdownMenuDirection.down),
menuMaxHeight: widget.htmlToolbarOptions.dropdownMenuMaxHeight ??
diff --git a/lib/utils/custom_classes.dart b/lib/utils/custom_classes.dart
new file mode 100644
index 00000000..331ddc36
--- /dev/null
+++ b/lib/utils/custom_classes.dart
@@ -0,0 +1,270 @@
+// import 'dart:ui';
+//
+// import 'package:flutter/foundation.dart';
+// import 'package:math_keyboard/src/foundation/node.dart' as mk;
+//
+// /// Block representing a node of TeX.
+// class TeXNode {
+// /// Constructs a [TeXNode].
+// TeXNode(this.parent);
+//
+// /// The parent of the node.
+// TeXFunction? parent;
+//
+// /// The courser position in this node.
+// int courserPosition = 0;
+//
+// /// A block can have one or more child blocks.
+// final List children = [];
+//
+// /// Sets the courser to the actual position.
+// void setCursor() {
+// children.insert(courserPosition, const Cursor());
+// }
+//
+// /// Removes the courser.
+// void removeCursor() {
+// children.removeAt(courserPosition);
+// }
+//
+// /// Returns whether the last child node is the cursor.
+// ///
+// /// This does *not* traverse the children recursively as that might not be
+// /// a guarantee for visually being all the way on the right with the cursor.
+// /// Imagine a `\frac` node with a horizontally long string in the nominator:
+// /// now, when the cursor is at the end, it is not visually on the right of the
+// /// node as the denominator might not even be visible when scrolling to the
+// /// right.
+// bool cursorAtTheEnd() {
+// if (children.isEmpty) return false;
+// if (children.last is Cursor) return true;
+//
+// return false;
+// }
+//
+// /// Shift courser to the left.
+// NavigationState shiftCursorLeft() {
+// if (courserPosition == 0) {
+// return NavigationState.end;
+// }
+// removeCursor();
+// courserPosition--;
+// if (children[courserPosition] is TeXFunction) {
+// return NavigationState.func;
+// }
+// setCursor();
+// return NavigationState.success;
+// }
+//
+// /// Shift courser to the right.
+// NavigationState shiftCursorRight() {
+// if (courserPosition == children.length - 1) {
+// return NavigationState.end;
+// }
+// removeCursor();
+// courserPosition++;
+// if (children[courserPosition - 1] is TeXFunction) {
+// return NavigationState.func;
+// }
+// setCursor();
+// return NavigationState.success;
+// }
+//
+// /// Adds a new node.
+// void addTeX(TeX teX) {
+// children.insert(courserPosition, teX);
+// courserPosition++;
+// }
+//
+// /// Removes the last node.
+// NavigationState remove() {
+// if (courserPosition == 0) {
+// return NavigationState.end;
+// }
+// removeCursor();
+// courserPosition--;
+// if (children[courserPosition] is TeXFunction) {
+// return NavigationState.func;
+// }
+// children.removeAt(courserPosition);
+// setCursor();
+// return NavigationState.success;
+// }
+//
+// /// Builds the TeX representation of this node.
+// ///
+// /// This includes the representation of the children of the node.
+// ///
+// /// Returns the TeX expression as a [String].
+// static String buildTeXStringFromMathKeyboard({
+// Color? cursorColor,
+// bool placeholderWhenEmpty = true,
+// required mk.TeXNode root,
+// }) {
+// if (root.children.isEmpty) {
+// return placeholderWhenEmpty ? '\\Box' : '';
+// }
+// final buffer = StringBuffer();
+// for (final tex in root.children) {
+// buffer.write(tex.buildString(cursorColor: cursorColor));
+// }
+// return buffer.toString();
+// }
+//
+// String buildTeXString({
+// Color? cursorColor,
+// bool placeholderWhenEmpty = true,
+// }) {
+// if (children.isEmpty) {
+// return placeholderWhenEmpty ? '\\Box' : '';
+// }
+// final buffer = StringBuffer();
+// for (final tex in children) {
+// buffer.write(tex.buildString(cursorColor: cursorColor));
+// }
+// return buffer.toString();
+// }
+// }
+//
+// /// Class holding a TeX function.
+// class TeXFunction extends TeX {
+// /// Constructs a [TeXFunction].
+// ///
+// /// [argNodes] can be passed directly if the nodes are already known. In that
+// /// case, the [TeXNode.parent] is set in the constructor body. If [argNodes]
+// /// is passed empty (default), empty [TeXNode]s will be inserted for each
+// /// arg.
+// TeXFunction(String expression, this.parent, this.args,
+// [List? argNodes])
+// : assert(args.isNotEmpty, 'A function needs at least one argument.'),
+// assert(argNodes == null || argNodes.length == args.length),
+// argNodes = argNodes ?? List.empty(growable: true),
+// super(expression) {
+// if (this.argNodes.isEmpty) {
+// for (var i = 0; i < args.length; i++) {
+// this.argNodes.add(TeXNode(this));
+// }
+// } else {
+// for (final node in this.argNodes) {
+// node.parent = this;
+// }
+// }
+// }
+//
+// /// The functions parent node.
+// TeXNode parent;
+//
+// /// The delimiters of the arguments.
+// final List args;
+//
+// /// The arguments to this function.
+// final List argNodes;
+//
+// /// Returns the opening character for a function argument.
+// String openingChar(TeXArg type) {
+// switch (type) {
+// case TeXArg.braces:
+// return '{';
+// case TeXArg.brackets:
+// return '[';
+// default:
+// return '(';
+// }
+// }
+//
+// /// Returns the closing character for a function argument.
+// String closingChar(TeXArg type) {
+// switch (type) {
+// case TeXArg.braces:
+// return '}';
+// case TeXArg.brackets:
+// return ']';
+// default:
+// return ')';
+// }
+// }
+//
+// @override
+// String buildString({Color? cursorColor}) {
+// final buffer = StringBuffer(expression);
+// for (var i = 0; i < args.length; i++) {
+// buffer.write(openingChar(args[i]));
+// buffer.write(argNodes[i].buildTeXString(
+// cursorColor: cursorColor,
+// ));
+// buffer.write(closingChar(args[i]));
+// }
+// return buffer.toString();
+// }
+// }
+//
+// /// Class holding a single TeX expression.
+// class TeXLeaf extends TeX {
+// /// Constructs a [TeXLeaf].
+// const TeXLeaf(String expression) : super(expression);
+//
+// @override
+// String buildString({Color? cursorColor}) {
+// return expression;
+// }
+// }
+//
+// /// Class holding TeX.
+// abstract class TeX {
+// /// Constructs a [TeX].
+// const TeX(this.expression);
+//
+// /// The expression of this TeX
+// final String expression;
+//
+// /// Builds the string representation of this TeX expression.
+// String buildString({required Color? cursorColor});
+// }
+//
+// /// Class describing the cursor as a TeX expression.
+// class Cursor extends TeX {
+// /// Creates a TeX [Cursor].
+// const Cursor() : super('');
+//
+// @override
+// String buildString({required Color? cursorColor}) {
+// if (cursorColor == null) {
+// return '';
+// }
+// final colorString =
+// '#${(cursorColor.value & 0xFFFFFF).toRadixString(16).padLeft(6, '0')}';
+// return '\\textcolor{$colorString}{\\cursor}';
+// }
+// }
+//
+// /// The state of a node when trying to navigate back- or forward.
+// enum NavigationState {
+// /// The upcoming tex expression in navigation direction is a function.
+// func,
+//
+// /// The current courser position is already at the end.
+// end,
+//
+// /// Navigating was successful.
+// success,
+// }
+//
+// /// How the argument is marked.
+// enum TeXArg {
+// /// { }
+// ///
+// /// In most of the cases, braces will be used. (E.g arguments of fractions).
+// braces,
+//
+// /// [ ]
+// ///
+// /// Brackets are only used for the nth root at the moment.
+// brackets,
+//
+// /// ()
+// ///
+// /// Parentheses are used for base n logarithm right now, but could be used
+// /// for functions like sin, cos, tan, etc. as well, so the user doesn't have
+// /// to close the parentheses manually.
+// parentheses,
+// }
diff --git a/lib/utils/custom_math_field_controller.dart b/lib/utils/custom_math_field_controller.dart
index 34b28132..223d6cc0 100644
--- a/lib/utils/custom_math_field_controller.dart
+++ b/lib/utils/custom_math_field_controller.dart
@@ -1,3 +1,4 @@
+import 'package:flutter/material.dart';
import 'package:math_keyboard/math_keyboard.dart';
class CustomMathFieldEditingController extends MathFieldEditingController {
@@ -14,4 +15,21 @@ class CustomMathFieldEditingController extends MathFieldEditingController {
}
String get texStringAsFun => '\\($texString\\)';
+
+ @override
+ String currentEditingValue({bool placeholderWhenEmpty = true}) {
+ currentNode.removeCursor();
+ // Store the expression as a TeX string.
+ final expression = root.buildTeXString(
+ // By passing null as the cursor color here, we are asserting
+ // that the cursor is not part of the tree in a way.
+ cursorColor: Colors.transparent,
+ placeholderWhenEmpty: placeholderWhenEmpty,
+ );
+ currentNode.setCursor();
+ final colorString =
+ '#${(Colors.transparent.value & 0xFFFFFF).toRadixString(16).padLeft(6, '0')}';
+ var text = '\\textcolor{$colorString}{\\cursor}';
+ return expression.replaceAll(text, '');
+ }
}
diff --git a/lib/utils/plugins.dart b/lib/utils/plugins.dart
index 7fe4b8a7..14c58869 100644
--- a/lib/utils/plugins.dart
+++ b/lib/utils/plugins.dart
@@ -34,7 +34,7 @@ class SummernoteAtMention extends Plugins {
@override
String getHeadString() {
- return '';
+ return '';
}
@override
diff --git a/lib/utils/toolbar.dart b/lib/utils/toolbar.dart
index 6146ae8d..f3788ce4 100644
--- a/lib/utils/toolbar.dart
+++ b/lib/utils/toolbar.dart
@@ -216,4 +216,4 @@ class OtherButtons extends Toolbar {
if (paste) icons.add(Icon(Icons.paste));
return icons;
}
-}
\ No newline at end of file
+}
diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart
index 37c7449d..43100f9f 100644
--- a/lib/utils/utils.dart
+++ b/lib/utils/utils.dart
@@ -491,6 +491,7 @@ class _DropdownRouteResult {
class _MenuLimits {
const _MenuLimits(this.top, this.bottom, this.height, this.scrollOffset);
+
final double top;
final double bottom;
final double height;
@@ -845,6 +846,7 @@ class _DropdownButtonState extends State>
_DropdownRoute? _dropdownRoute;
Orientation? _lastOrientation;
FocusNode? _internalNode;
+
FocusNode? get focusNode => widget.focusNode ?? _internalNode;
bool _hasPrimaryFocus = false;
late Map> _actionMap;
diff --git a/pubspec.yaml b/pubspec.yaml
index dfdcfd59..dca106c2 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,12 +1,12 @@
name: html_editor_enhanced_fork_latex
description: HTML rich text editor for Android, iOS, and Web, using the Summernote library.
Enhanced with highly customizable widget-based controls, bug fixes, callbacks, dark mode, and more.
-version: 2.6.1
+version: 2.6.3
homepage: https://github.com/tneotia/html-editor-enhanced
repository: https://github.com/AhmadKhateebq/html-editor-enhanced-with-latex.git
environment:
- sdk: '>=2.15.0 <3.0.0'
+ sdk: '>=2.15.0 <4.0.0'
flutter: ">=3.0.0"
dependencies:
@@ -47,15 +47,15 @@ dev_dependencies:
flutter:
assets:
- - packages/html_editor_enhanced/assets/summernote.html
- - packages/html_editor_enhanced/assets/summernote-no-plugins.html
- - packages/html_editor_enhanced/assets/summernote-lite.min.css
- - packages/html_editor_enhanced/assets/summernote-lite-dark.css
- - packages/html_editor_enhanced/assets/summernote-lite.min.js
- - packages/html_editor_enhanced/assets/jquery.min.js
- - packages/html_editor_enhanced/assets/font/summernote.eot
- - packages/html_editor_enhanced/assets/font/summernote.ttf
- - packages/html_editor_enhanced/assets/plugins/summernote-at-mention/summernote-at-mention.js
+ - packages/html_editor_enhanced_fork_latex/assets/summernote.html
+ - packages/html_editor_enhanced_fork_latex/assets/summernote-no-plugins.html
+ - packages/html_editor_enhanced_fork_latex/assets/summernote-lite.min.css
+ - packages/html_editor_enhanced_fork_latex/assets/summernote-lite-dark.css
+ - packages/html_editor_enhanced_fork_latex/assets/summernote-lite.min.js
+ - packages/html_editor_enhanced_fork_latex/assets/jquery.min.js
+ - packages/html_editor_enhanced_fork_latex/assets/font/summernote.eot
+ - packages/html_editor_enhanced_fork_latex/assets/font/summernote.ttf
+ - packages/html_editor_enhanced_fork_latex/assets/plugins/summernote-at-mention/summernote-at-mention.js
# This section identifies this Flutter project as a plugin project.
# The 'pluginClass' and Android 'package' identifiers should not ordinarily
# be modified. They are used by the tooling to maintain consistency when
From 6811f48de6427173f11dc1b5ac5b63cd5c011e2b Mon Sep 17 00:00:00 2001
From: Ahmad Khateeb
Date: Wed, 20 Dec 2023 15:02:03 +0200
Subject: [PATCH 12/29] changed version number
---
pubspec.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pubspec.yaml b/pubspec.yaml
index dca106c2..2f4718ee 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,7 +1,7 @@
name: html_editor_enhanced_fork_latex
description: HTML rich text editor for Android, iOS, and Web, using the Summernote library.
Enhanced with highly customizable widget-based controls, bug fixes, callbacks, dark mode, and more.
-version: 2.6.3
+version: 2.6.4
homepage: https://github.com/tneotia/html-editor-enhanced
repository: https://github.com/AhmadKhateebq/html-editor-enhanced-with-latex.git
From 0e38855614c8a0a5c4d5b3d3d3a1ddc46fabfb62 Mon Sep 17 00:00:00 2001
From: Ahmad Khateeb
Date: Wed, 20 Dec 2023 15:37:16 +0200
Subject: [PATCH 13/29] changed version number
---
CHANGELOG.md | 227 ++++++++++++++--------
lib/src/widgets/math_keyboard_dialog.dart | 1 -
lib/src/widgets/toolbar_widget.dart | 2 +-
pubspec.yaml | 2 +-
4 files changed, 151 insertions(+), 81 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2fed830e..bf107741 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## [2.6.5] = 2023-12-20
+
+* Version Name
+
## [2.6.4] = 2023-12-20
* Fixed Cursor bug in math keyboard
@@ -47,9 +51,10 @@
* Removed woff fonts to allow iOS App Store submissions
## [2.4.0] - 2021-10-30
+
* Improved color picker
- * Added scrollable support to picker
- * Fixed issue where keyboard would disappear and prevent users from selecting a new color
+ * Added scrollable support to picker
+ * Fixed issue where keyboard would disappear and prevent users from selecting a new color
* Added support for getting selected text in Flutter Web (`controller.getSelectedTextWeb()`)
* Added support for spellcheck
* Added support for custom options in summernote initialization
@@ -59,6 +64,7 @@
* Updated dependencies and fixed flutter_colorpicker dependency error (@eliudio)
## [2.3.0] - 2021-09-09
+
* Potentially fixed bad state error for `stream.first`
* Fixed Summernote-@-Mention not inserting text after selecting the dropdown item
* Fixed whitespace after @ sign when inserting a mention
@@ -74,208 +80,273 @@ NOTE: If you are on Flutter Beta+, you must use `dependency_overrides` in `pubsp
```yaml
dependency_overrides:
- flutter_colorpicker: ^0.5.0
+ flutter_colorpicker: ^0.5.0
```
## [2.2.0+1] - 2021-06-15 (BETA)
+
* Updated `flutter_colorpicker` to the latest version to fix deprecations on Flutter beta+
* [NOTE] Do not use this version on Flutter stable!
## [2.2.0] - 2021-06-14
+
* Fixed null safety warnings due to latest `file_picker` version
* Potentially fixed editor controller creating a new instance on widget rebuild
* Fixed issue where custom HTML files would have custom JS replaced with built-in JS
* Fixed darkMode not applying when `filePath` is used on Android
* Fixed "null" text showing as the hint when no hint is given
* Added new `onChangeSelection` callback that passes the editor settings whenever the user changes
-their current selection (e.g. tap on a different word, create a new node, select text, etc)
+ their current selection (e.g. tap on a different word, create a new node, select text, etc)
* Added support for custom JS injection on Flutter Web
* Fixed minor bug with automatic height adjustment on mobile
-* Added new `ToolbarType.nativeExpandable` which allows the user to switch between the
-scrollview or gridview toolbar on the fly
-* Support setting the `inputmode` for the editor, which changes the virtual keyboard display on mobile devices (e.g. number pad, email keyboard, etc)
+* Added new `ToolbarType.nativeExpandable` which allows the user to switch between the
+ scrollview or gridview toolbar on the fly
+* Support setting the `inputmode` for the editor, which changes the virtual keyboard display on
+ mobile devices (e.g. number pad, email keyboard, etc)
* [BREAKING] renamed `onChange` callback to `onChangeContent`
* [BREAKING] disabled a lot of the buttons by default, now only around half of the editor buttons
-are enabled to improve the UX. You can still re-enable the rest if you want.
+ are enabled to improve the UX. You can still re-enable the rest if you want.
* [BREAKING] min Flutter version requirement bumped to 2.2.0
## [2.1.1] - 2021-05-22
+
* Fixed bottom overflow error on `AlertDialog`s if the screen size is small
* Fixed `StyleButtons(style: false)` would not remove the style dropdown
* Fixed JS/Dart communication hiccup on Web (make sure `postMessage` data is not null)
* Code cleanup
## [2.1.0+1] - 2021-05-11
+
* Hotfix for `copyWith` not defined for `ScrollBehavior` in v2.1.0
## [2.1.0] - 2021-05-10
+
* Fixed `setState` and `Stream.first` error on page dispose
* Fixed height adjustment not working
* Fixed `getText` on Web
-* Improved dropdown UX when `ToolbarPosition.belowEditor` by opening upwards and making it scrollable after a certain height
+* Improved dropdown UX when `ToolbarPosition.belowEditor` by opening upwards and making it
+ scrollable after a certain height
## [2.0.1] - 2021-04-28
+
* Added support for setting custom `UserScript`s on the webview (mobile only)
-* Added support for customizing the context menu (menu when user selects text) for the webview (mobile only)
-* Added `LongPressGestureRecognizer` to the webview to allow users to select text via a long press (mobile only)
- * You can set the duration before the long press is recognized via `HtmlEditorOptions > mobileLongPressDuration`
-* Added support for placing the toolbar wherever using `HtmlToolbarOptions > toolbarPosition: ToolbarPosition.custom`
-* See the README if you'd like to use any of these new features. `UserScript` and the context menu customization have external documentation via flutter_inappwebview - the docs are linked in the README.
+* Added support for customizing the context menu (menu when user selects text) for the webview (
+ mobile only)
+* Added `LongPressGestureRecognizer` to the webview to allow users to select text via a long press (
+ mobile only)
+ * You can set the duration before the long press is recognized
+ via `HtmlEditorOptions > mobileLongPressDuration`
+* Added support for placing the toolbar wherever
+ using `HtmlToolbarOptions > toolbarPosition: ToolbarPosition.custom`
+* See the README if you'd like to use any of these new features. `UserScript` and the context menu
+ customization have external documentation via flutter_inappwebview - the docs are linked in the
+ README.
## [2.0.0+1] - 2021-04-22
-* Transitioned to fully native controls! These are extremely customizable and have much better UX than the previous controls.
+
+* Transitioned to fully native controls! These are extremely customizable and have much better UX
+ than the previous controls.
* [BREAKING] refactored a lot of options into separate constructors
* [BREAKING] refactored toolbar classes, so toolbar customizations will need updating
* Added a bunch of interceptors and callbacks for button presses
* Added the ability to make custom buttons and set their positions
* Added native support for numerous Summernote plugins
- * [BREAKING] removed all Summernote plugins except Summernote @ Mention. The package now supports the majority of plugins out of the box.
- * Reduced package size by removing the Summernote plugin files
- * Reduced size further by using a stripped-down version of Summernote @ Mention libs
+ * [BREAKING] removed all Summernote plugins except Summernote @ Mention. The package now
+ supports the majority of plugins out of the box.
+ * Reduced package size by removing the Summernote plugin files
+ * Reduced size further by using a stripped-down version of Summernote @ Mention libs
* Added `execCommand` to controller to help you create custom toolbar buttons
* Improved automatic height adjustment
* Bumped dependencies
* [BREAKING] Require Flutter 2.0.0+
* As always, see the README for full documentation on these changes
-* See the [Migration Guide](https://github.com/tneotia/html-editor-enhanced/wiki/v2.0.0-Migration-Guide) for help migrating your v1.x.x widget code
+* See
+ the [Migration Guide](https://github.com/tneotia/html-editor-enhanced/wiki/v2.0.0-Migration-Guide)
+ for help migrating your v1.x.x widget code
## [1.8.0] - 2021-04-07
-* Add support for `getSuggestionsMobile` (Summernote @ Mentions Plugin) - allows you to programatically return the list of mentions.
- * Only supported on mobile.
- * [BREAKING] renamed `mentions` to `mentionsWeb` as a result of this change
+
+* Add support for `getSuggestionsMobile` (Summernote @ Mentions Plugin) - allows you to
+ programatically return the list of mentions.
+ * Only supported on mobile.
+ * [BREAKING] renamed `mentions` to `mentionsWeb` as a result of this change
* Added support for the remainder of Summernote callbacks:
- * `onBeforeCommand`
- * `onChangeCodeview`
- * `onDialogShown`
- * `onImageUploadError`
- * `onMouseDown`
- * `onMouseUp`
- * `onScroll`
- * See the README for how these work.
+ * `onBeforeCommand`
+ * `onChangeCodeview`
+ * `onDialogShown`
+ * `onImageUploadError`
+ * `onMouseDown`
+ * `onMouseUp`
+ * `onScroll`
+ * See the README for how these work.
* Added a few new functions:
- * recalculateHeight(): recalculates the editor height and applies it
- * addNotification(): adds a notification bar to the bottom of the editor in a specified style with specified text
- * removeNotification(): removes the current notification from the bottom of the editor
+ * recalculateHeight(): recalculates the editor height and applies it
+ * addNotification(): adds a notification bar to the bottom of the editor in a specified style
+ with specified text
+ * removeNotification(): removes the current notification from the bottom of the editor
* Fixed blank space at the bottom of the editor when `showBottomToolbar: false`
* Fixed 'Android resource linking failed' (bumped flutter_inappwebview to 5.3.1+1)
## [1.7.1] - 2021-03-26
-* Fixed bug where initial text would not be inserted and default toolbar would be shown regardless of editor options
+
+* Fixed bug where initial text would not be inserted and default toolbar would be shown regardless
+ of editor options
* Significantly improved keyboard height detection (detect when keyboard comes up and goes down)
-* Adjusted HTML processing algorithm to fix issues where `"` and `'` would not be properly escaped on HTML insertion
- * Added `processNewLineAsBr` - this will replace any `\n` in the input string to ` ` rather than the default `""`
- * Applied processing to `setHint()` and `insertHtml()` functions
+* Adjusted HTML processing algorithm to fix issues where `"` and `'` would not be properly escaped
+ on HTML insertion
+ * Added `processNewLineAsBr` - this will replace any `\n` in the input string to ` ` rather
+ than the default `""`
+ * Applied processing to `setHint()` and `insertHtml()` functions
* Added support for returning the file's base64 data in `onImageUpload` and `onFileUpload`
- * Now you can use `MultipartFile.fromBytes()` to upload to server - [example](https://github.com/tneotia/html-editor-enhanced#example-for-onimageupload-and-onimagelinkinsert)
+ * Now you can use `MultipartFile.fromBytes()` to upload to
+ server - [example](https://github.com/tneotia/html-editor-enhanced#example-for-onimageupload-and-onimagelinkinsert)
* Added support for `onFileUploadError` and `onFileLinkInsert` (Summernote File plugin)
* Added support for `maximumFileSize` (Summernote File plugin)
* See the README for more details on these changes
## [1.7.0+1] - 2021-03-22
+
* Fixed `type 'double' is not a subtype of type 'int?' in type cast` on iOS
- * By extension this fixes the `adjustHeightForKeyboard` not working on iOS
-* Fixed `Bad state: Cannot add new events after calling close` exception when disposing the page containing the editor
-* Fixed web page not found when inserting a video URL (see [here](https://github.com/summernote/summernote/issues/3252))
+ * By extension this fixes the `adjustHeightForKeyboard` not working on iOS
+* Fixed `Bad state: Cannot add new events after calling close` exception when disposing the page
+ containing the editor
+* Fixed web page not found when inserting a video URL (
+ see [here](https://github.com/summernote/summernote/issues/3252))
## [1.7.0] - 2021-03-17
+
* [BREAKING]:
- * Refactored `height`, `autoAdjustHeight`, `decoration`, `showBottomToolbar`, and `darkMode` into new `HtmlEditorOptions` class - see README for how to migrate
- * Removed 'Summernote Classes' plugin
- * Sorry for all the breaking changes lately - I think I've finally figured out how I want to do the API design so there should be far less in future releases
+ * Refactored `height`, `autoAdjustHeight`, `decoration`, `showBottomToolbar`, and `darkMode`
+ into new `HtmlEditorOptions` class - see README for how to migrate
+ * Removed 'Summernote Classes' plugin
+ * Sorry for all the breaking changes lately - I think I've finally figured out how I want to do
+ the API design so there should be far less in future releases
* Added `onImageUpload` callback that fires when an image is inserted via ``
* Added `onImageLinkInsert` callback that fires when an image is inserted via URL
-* Added `shouldEnsureVisible` that scrolls the editor into view when it is focused or text is typed, kind of like `TextField`s
-* Added `adjustHeightForKeyboard` (default true) that adjusts the editor's height when the keyboard is active to ensure no content is cut off by the keyboard
+* Added `shouldEnsureVisible` that scrolls the editor into view when it is focused or text is typed,
+ kind of like `TextField`s
+* Added `adjustHeightForKeyboard` (default true) that adjusts the editor's height when the keyboard
+ is active to ensure no content is cut off by the keyboard
* Added `filePath` which allows you to provide a completely custom HTML file to load
-* If you plan on using any of the above, it is highly recommend looking at the README for more details and examples.
-* Removed disabled scroll feature since it prevented the editor from scrolling even when the editor content was larger than the height
+* If you plan on using any of the above, it is highly recommend looking at the README for more
+ details and examples.
+* Removed disabled scroll feature since it prevented the editor from scrolling even when the editor
+ content was larger than the height
* Code cleanup
## [1.6.0] - 2021-03-13
+
* [BREAKING] removed `dispose()` method on controller
- * The editor no longer uses a `Stream` to get text and therefore nothing needs to be disposed
+ * The editor no longer uses a `Stream` to get text and therefore nothing needs to be disposed
* Added `onInit` callback that fires once the editor is ready to function and accept JS
* Added a few new parameters:
- * `autoAdjustHeight` - for `HtmlEditor`: default true, automatically adjusts the height of the editor to make sure scrolling is not necessary
- * `processInputHtml` - for `HtmlEditorController`: processes input HTML (e.g. new lines become ` `)
- * `processOutputHtml` - for `HtmlEditorController`: processes output HTML (e.g. `
` becomes `""`)
+ * `autoAdjustHeight` - for `HtmlEditor`: default true, automatically adjusts the height of the
+ editor to make sure scrolling is not necessary
+ * `processInputHtml` - for `HtmlEditorController`: processes input HTML (e.g. new lines
+ become ` `)
+ * `processOutputHtml` - for `HtmlEditorController`: processes output HTML (e.g. `
`
+ becomes `""`)
* Added more plugins:
- * Summernote Case Converter
- * Summernote List Styles
- * Summernote RTL
- * Summernote @ Mention
- * Summernote Codewrapper
- * Summernote File
- * See the README for more details.
+ * Summernote Case Converter
+ * Summernote List Styles
+ * Summernote RTL
+ * Summernote @ Mention
+ * Summernote Codewrapper
+ * Summernote File
+ * See the README for more details.
* Added shim for dart:ui to remove the `ui.PlatformViewRegistry not found` error
-* Added the summernote-no-plugins.html file to load a de-bloated HTML file when no plugins are active
+* Added the summernote-no-plugins.html file to load a de-bloated HTML file when no plugins are
+ active
* Fixed bug where two editors would be initialized in the same webview in some cases
* Reduced the size of assets to ~650kb - ~300kb summernote libs, ~350kb plugin libs
* Code cleanup
## [1.5.0+1] - 2021-03-10
+
* Fixed getText() returning null on mobile for any device
## [1.5.0] - 2021-03-01
+
* Nullsafety preview
-* Added Flutter's Hybrid Composition to the HTML Editor. This significantly improves the keyboard experience on Android.
+* Added Flutter's Hybrid Composition to the HTML Editor. This significantly improves the keyboard
+ experience on Android.
## [1.4.0] - 2021-03-01
-* [BREAKING] removed `HtmlParser` for calling methods, instead you now must pass an `HtmlEditorController` to the plugin (like a `TextField`). All methods are accessible from that controller. See the usage section in the README for an example.
- * This allows you to have multiple independent editors on a page, whereas earlier the package would not know which editor the method should be called on.
-* Add support for certain Summernote plugins from [Summernote Awesome](https://github.com/summernote/awesome-summernote). See the README for details on the API and the currently supported plugins.
+
+* [BREAKING] removed `HtmlParser` for calling methods, instead you now must pass
+ an `HtmlEditorController` to the plugin (like a `TextField`). All methods are accessible from that
+ controller. See the usage section in the README for an example.
+ * This allows you to have multiple independent editors on a page, whereas earlier the package
+ would not know which editor the method should be called on.
+* Add support for certain Summernote plugins
+ from [Summernote Awesome](https://github.com/summernote/awesome-summernote). See the README for
+ details on the API and the currently supported plugins.
* Nullsafety pre-release coming soon.
## [1.3.0] - 2021-02-23
+
* Add official support for Flutter Web
* Add support for modifying the toolbar options. See the README for details on the API.
* Add support for a native dark mode
-* Removed image_picker plugin and image button in toolbar because users can insert images via the image button in Summernote
- * [BREAKING] Removed the `imageWidth` and `useBottomSheet` params due to the above change
+* Removed image_picker plugin and image button in toolbar because users can insert images via the
+ image button in Summernote
+ * [BREAKING] Removed the `imageWidth` and `useBottomSheet` params due to the above change
## [1.2.0+1] - 2021-02-20
+
* Add support for accessing `InAppWebViewController` via a getter
* Add support for inserting files via the editor dialog itself
* Add methods:
- * toggle code view
- * enable/disable editor
- * undo/redo
- * inserting plaintext/HTML/images/links
+ * toggle code view
+ * enable/disable editor
+ * undo/redo
+ * inserting plaintext/HTML/images/links
* Add callbacks:
- * onChange
- * onEnter
- * onFocus/onBlur/onBlurCodeview
- * onKeyUp/onKeyDown
- * onPaste
+ * onChange
+ * onEnter
+ * onFocus/onBlur/onBlurCodeview
+ * onKeyUp/onKeyDown
+ * onPaste
* Downgraded dependencies to non-nullsafety to prevent errors
-* Updated docs and example app to showcase new features, refer to those for info on the above changes
+* Updated docs and example app to showcase new features, refer to those for info on the above
+ changes
## [1.1.1] - 2021-02-19
+
* Minor update to add documentation to code and completely refactor/reorganize code
## [1.1.0] - 2021-02-19
+
* Switch webview dependency to `flutter_inappwebview`
-* Remove localserver, instead get Summernote HTML directly from assets (improves performance and loading speeds)
+* Remove localserver, instead get Summernote HTML directly from assets (improves performance and
+ loading speeds)
* [BREAKING] Switch to `StatelessWidget`
- * You no longer need a `GlobalKey` for the `HtmlEditorState`. All of the methods are static and can be called like so:
+ * You no longer need a `GlobalKey` for the `HtmlEditorState`. All of the methods are static and
+ can be called like so:
```dart
HtmlEditor.setEmpty();
```
* Fix deprecations and update dependencies
## Flutter HTML Editor changes by xrb21
+
## [1.0.1] - 2020-05-07
+
* Update Readme usage for iOS
## [1.0.0] - 2020-05-07
+
* fixing iOS blank screen
* fixing text hint
## [0.0.2+1] - 2020-05-02
+
* fixing path packages
## [0.0.2] - 2020-05-02
+
* Change link repo
## [0.0.1] - 2020-05-02
+
* Initial Release
\ No newline at end of file
diff --git a/lib/src/widgets/math_keyboard_dialog.dart b/lib/src/widgets/math_keyboard_dialog.dart
index 0a205c99..c6e6dafd 100644
--- a/lib/src/widgets/math_keyboard_dialog.dart
+++ b/lib/src/widgets/math_keyboard_dialog.dart
@@ -72,5 +72,4 @@ class MathKeyboardDialog extends StatelessWidget {
),
);
}
-
}
diff --git a/lib/src/widgets/toolbar_widget.dart b/lib/src/widgets/toolbar_widget.dart
index a4298b30..0514c02f 100644
--- a/lib/src/widgets/toolbar_widget.dart
+++ b/lib/src/widgets/toolbar_widget.dart
@@ -1139,7 +1139,7 @@ class ToolbarWidgetState extends State {
ColorPickerType.wheel: true,
},
copyPasteBehavior:
- const ColorPickerCopyPasteBehavior(
+ const ColorPickerCopyPasteBehavior(
parseShortHexCode: true,
),
actionButtons: const ColorPickerActionButtons(
diff --git a/pubspec.yaml b/pubspec.yaml
index 2f4718ee..be0b1528 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,7 +1,7 @@
name: html_editor_enhanced_fork_latex
description: HTML rich text editor for Android, iOS, and Web, using the Summernote library.
Enhanced with highly customizable widget-based controls, bug fixes, callbacks, dark mode, and more.
-version: 2.6.4
+version: 2.6.5
homepage: https://github.com/tneotia/html-editor-enhanced
repository: https://github.com/AhmadKhateebq/html-editor-enhanced-with-latex.git
From 23ae82487a9e809100143fef854318420be571b9 Mon Sep 17 00:00:00 2001
From: Ahmad Khateeb
Date: Wed, 20 Dec 2023 15:39:23 +0200
Subject: [PATCH 14/29] changed version number
---
lib/utils/custom_classes.dart | 270 ----------------------------------
1 file changed, 270 deletions(-)
delete mode 100644 lib/utils/custom_classes.dart
diff --git a/lib/utils/custom_classes.dart b/lib/utils/custom_classes.dart
deleted file mode 100644
index 331ddc36..00000000
--- a/lib/utils/custom_classes.dart
+++ /dev/null
@@ -1,270 +0,0 @@
-// import 'dart:ui';
-//
-// import 'package:flutter/foundation.dart';
-// import 'package:math_keyboard/src/foundation/node.dart' as mk;
-//
-// /// Block representing a node of TeX.
-// class TeXNode {
-// /// Constructs a [TeXNode].
-// TeXNode(this.parent);
-//
-// /// The parent of the node.
-// TeXFunction? parent;
-//
-// /// The courser position in this node.
-// int courserPosition = 0;
-//
-// /// A block can have one or more child blocks.
-// final List children = [];
-//
-// /// Sets the courser to the actual position.
-// void setCursor() {
-// children.insert(courserPosition, const Cursor());
-// }
-//
-// /// Removes the courser.
-// void removeCursor() {
-// children.removeAt(courserPosition);
-// }
-//
-// /// Returns whether the last child node is the cursor.
-// ///
-// /// This does *not* traverse the children recursively as that might not be
-// /// a guarantee for visually being all the way on the right with the cursor.
-// /// Imagine a `\frac` node with a horizontally long string in the nominator:
-// /// now, when the cursor is at the end, it is not visually on the right of the
-// /// node as the denominator might not even be visible when scrolling to the
-// /// right.
-// bool cursorAtTheEnd() {
-// if (children.isEmpty) return false;
-// if (children.last is Cursor) return true;
-//
-// return false;
-// }
-//
-// /// Shift courser to the left.
-// NavigationState shiftCursorLeft() {
-// if (courserPosition == 0) {
-// return NavigationState.end;
-// }
-// removeCursor();
-// courserPosition--;
-// if (children[courserPosition] is TeXFunction) {
-// return NavigationState.func;
-// }
-// setCursor();
-// return NavigationState.success;
-// }
-//
-// /// Shift courser to the right.
-// NavigationState shiftCursorRight() {
-// if (courserPosition == children.length - 1) {
-// return NavigationState.end;
-// }
-// removeCursor();
-// courserPosition++;
-// if (children[courserPosition - 1] is TeXFunction) {
-// return NavigationState.func;
-// }
-// setCursor();
-// return NavigationState.success;
-// }
-//
-// /// Adds a new node.
-// void addTeX(TeX teX) {
-// children.insert(courserPosition, teX);
-// courserPosition++;
-// }
-//
-// /// Removes the last node.
-// NavigationState remove() {
-// if (courserPosition == 0) {
-// return NavigationState.end;
-// }
-// removeCursor();
-// courserPosition--;
-// if (children[courserPosition] is TeXFunction) {
-// return NavigationState.func;
-// }
-// children.removeAt(courserPosition);
-// setCursor();
-// return NavigationState.success;
-// }
-//
-// /// Builds the TeX representation of this node.
-// ///
-// /// This includes the representation of the children of the node.
-// ///
-// /// Returns the TeX expression as a [String].
-// static String buildTeXStringFromMathKeyboard({
-// Color? cursorColor,
-// bool placeholderWhenEmpty = true,
-// required mk.TeXNode root,
-// }) {
-// if (root.children.isEmpty) {
-// return placeholderWhenEmpty ? '\\Box' : '';
-// }
-// final buffer = StringBuffer();
-// for (final tex in root.children) {
-// buffer.write(tex.buildString(cursorColor: cursorColor));
-// }
-// return buffer.toString();
-// }
-//
-// String buildTeXString({
-// Color? cursorColor,
-// bool placeholderWhenEmpty = true,
-// }) {
-// if (children.isEmpty) {
-// return placeholderWhenEmpty ? '\\Box' : '';
-// }
-// final buffer = StringBuffer();
-// for (final tex in children) {
-// buffer.write(tex.buildString(cursorColor: cursorColor));
-// }
-// return buffer.toString();
-// }
-// }
-//
-// /// Class holding a TeX function.
-// class TeXFunction extends TeX {
-// /// Constructs a [TeXFunction].
-// ///
-// /// [argNodes] can be passed directly if the nodes are already known. In that
-// /// case, the [TeXNode.parent] is set in the constructor body. If [argNodes]
-// /// is passed empty (default), empty [TeXNode]s will be inserted for each
-// /// arg.
-// TeXFunction(String expression, this.parent, this.args,
-// [List? argNodes])
-// : assert(args.isNotEmpty, 'A function needs at least one argument.'),
-// assert(argNodes == null || argNodes.length == args.length),
-// argNodes = argNodes ?? List.empty(growable: true),
-// super(expression) {
-// if (this.argNodes.isEmpty) {
-// for (var i = 0; i < args.length; i++) {
-// this.argNodes.add(TeXNode(this));
-// }
-// } else {
-// for (final node in this.argNodes) {
-// node.parent = this;
-// }
-// }
-// }
-//
-// /// The functions parent node.
-// TeXNode parent;
-//
-// /// The delimiters of the arguments.
-// final List args;
-//
-// /// The arguments to this function.
-// final List argNodes;
-//
-// /// Returns the opening character for a function argument.
-// String openingChar(TeXArg type) {
-// switch (type) {
-// case TeXArg.braces:
-// return '{';
-// case TeXArg.brackets:
-// return '[';
-// default:
-// return '(';
-// }
-// }
-//
-// /// Returns the closing character for a function argument.
-// String closingChar(TeXArg type) {
-// switch (type) {
-// case TeXArg.braces:
-// return '}';
-// case TeXArg.brackets:
-// return ']';
-// default:
-// return ')';
-// }
-// }
-//
-// @override
-// String buildString({Color? cursorColor}) {
-// final buffer = StringBuffer(expression);
-// for (var i = 0; i < args.length; i++) {
-// buffer.write(openingChar(args[i]));
-// buffer.write(argNodes[i].buildTeXString(
-// cursorColor: cursorColor,
-// ));
-// buffer.write(closingChar(args[i]));
-// }
-// return buffer.toString();
-// }
-// }
-//
-// /// Class holding a single TeX expression.
-// class TeXLeaf extends TeX {
-// /// Constructs a [TeXLeaf].
-// const TeXLeaf(String expression) : super(expression);
-//
-// @override
-// String buildString({Color? cursorColor}) {
-// return expression;
-// }
-// }
-//
-// /// Class holding TeX.
-// abstract class TeX {
-// /// Constructs a [TeX].
-// const TeX(this.expression);
-//
-// /// The expression of this TeX
-// final String expression;
-//
-// /// Builds the string representation of this TeX expression.
-// String buildString({required Color? cursorColor});
-// }
-//
-// /// Class describing the cursor as a TeX expression.
-// class Cursor extends TeX {
-// /// Creates a TeX [Cursor].
-// const Cursor() : super('');
-//
-// @override
-// String buildString({required Color? cursorColor}) {
-// if (cursorColor == null) {
-// return '';
-// }
-// final colorString =
-// '#${(cursorColor.value & 0xFFFFFF).toRadixString(16).padLeft(6, '0')}';
-// return '\\textcolor{$colorString}{\\cursor}';
-// }
-// }
-//
-// /// The state of a node when trying to navigate back- or forward.
-// enum NavigationState {
-// /// The upcoming tex expression in navigation direction is a function.
-// func,
-//
-// /// The current courser position is already at the end.
-// end,
-//
-// /// Navigating was successful.
-// success,
-// }
-//
-// /// How the argument is marked.
-// enum TeXArg {
-// /// { }
-// ///
-// /// In most of the cases, braces will be used. (E.g arguments of fractions).
-// braces,
-//
-// /// [ ]
-// ///
-// /// Brackets are only used for the nth root at the moment.
-// brackets,
-//
-// /// ()
-// ///
-// /// Parentheses are used for base n logarithm right now, but could be used
-// /// for functions like sin, cos, tan, etc. as well, so the user doesn't have
-// /// to close the parentheses manually.
-// parentheses,
-// }
From 2d3f53ab7f5fd6311f0bfd7439b4aa9852445cc8 Mon Sep 17 00:00:00 2001
From: Ahmad Khateeb
Date: Wed, 20 Dec 2023 16:29:58 +0200
Subject: [PATCH 15/29] changed version number
---
CHANGELOG.md | 4 ++++
lib/src/widgets/custom_html_editor.dart | 5 -----
pubspec.yaml | 2 +-
3 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bf107741..7156968a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## [2.6.6] = 2023-12-20
+
+* Image Upload was turned off, now its on
+
## [2.6.5] = 2023-12-20
* Version Name
diff --git a/lib/src/widgets/custom_html_editor.dart b/lib/src/widgets/custom_html_editor.dart
index f12cfbfe..cb9f6a04 100644
--- a/lib/src/widgets/custom_html_editor.dart
+++ b/lib/src/widgets/custom_html_editor.dart
@@ -43,11 +43,6 @@ class CustomHtmlEditorWidget extends StatelessWidget {
//by default
onButtonPressed:
(ButtonType type, bool? status, Function? updateStatus) {
- if (type.name == ButtonType.picture.name) {
- print('no image');
- controller.insertHtml(tableTex);
- return false;
- }
print(
"button '${type.name}' pressed, the current selected status is $status");
return true;
diff --git a/pubspec.yaml b/pubspec.yaml
index be0b1528..bb6032de 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,7 +1,7 @@
name: html_editor_enhanced_fork_latex
description: HTML rich text editor for Android, iOS, and Web, using the Summernote library.
Enhanced with highly customizable widget-based controls, bug fixes, callbacks, dark mode, and more.
-version: 2.6.5
+version: 2.6.6
homepage: https://github.com/tneotia/html-editor-enhanced
repository: https://github.com/AhmadKhateebq/html-editor-enhanced-with-latex.git
From d31e8fccba27ee3ebe7ba2e49f42f1cdbcd8a414 Mon Sep 17 00:00:00 2001
From: Ahmad Khateeb
Date: Sun, 24 Dec 2023 09:20:26 +0200
Subject: [PATCH 16/29] updated performance
---
CHANGELOG.md | 4 +
example/lib/main.dart | 154 ++++++++++++++++++++++------
example/pubspec.lock | 10 +-
example/pubspec.yaml | 2 +-
lib/src/widgets/toolbar_widget.dart | 37 +++++--
pubspec.yaml | 2 +-
6 files changed, 162 insertions(+), 47 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7156968a..d55b05f8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## [2.6.7] = 2023-12-20
+
+* improved performance
+
## [2.6.6] = 2023-12-20
* Image Upload was turned off, now its on
diff --git a/example/lib/main.dart b/example/lib/main.dart
index cfac4eae..37479a61 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -1,6 +1,7 @@
import 'package:file_picker/file_picker.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
+import 'package:get/get.dart';
import 'package:html_editor_enhanced_fork_latex/html_editor.dart';
void main() => runApp(HtmlEditorExampleApp());
@@ -14,10 +15,95 @@ class HtmlEditorExampleApp extends StatelessWidget {
theme: ThemeData(),
darkTheme: ThemeData.dark(),
home: HtmlEditorExample(title: 'Flutter HTML Editor Example'),
+ // home: MyApp2(title: 'Flutter HTML Editor Example'),
);
}
}
+class MyApp2 extends StatelessWidget {
+ final String title;
+
+ MyApp2({Key? key, required this.title}) : super(key: key);
+ final HtmlEditorController controller = HtmlEditorController();
+ final HtmlEditorController controller2 = HtmlEditorController();
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ body: SingleChildScrollView(
+ child: Column(
+ children: [
+ tb(controller),
+ tb(controller2),
+ ],
+ ),
+ ),
+ appBar: AppBar(
+ title: Text(this.title),
+ ),
+ );
+ }
+
+ Widget tb(HtmlEditorController controller) {
+ var isVisible = false.obs;
+ return Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Obx(
+ () => isVisible.value
+ ? ToolbarWidget(
+ controller: controller,
+ htmlToolbarOptions: HtmlToolbarOptions(
+ toolbarType: kIsWeb
+ ? ToolbarType.nativeGrid
+ : ToolbarType.nativeScrollable,
+ toolbarPosition: ToolbarPosition
+ .custom, //required to place toolbar anywhere!
+ //other options
+ ),
+ callbacks: null)
+ : IconButton(
+ onPressed: () {
+ controller.insertHtml(
+ r'', breakPoint), context);
+ for (var value in a.split('break')) {
+ log(value.trim(), name: 'latex');
+ }
+ log(a, name: 'MathMl');
+ return a;
}
@override
Widget build(BuildContext context) {
return Scaffold(
+ floatingActionButton: FloatingActionButton(onPressed: () {
+ (_latexToHtml('{x}', controller));
+ }),
body: Stack(
children: [
SingleChildScrollView(
child: Column(
children: [
tb(controller1),
- tb(controller2),
],
),
),
@@ -155,6 +154,17 @@ class _HtmlEditorExampleState extends State {
String result = '';
final HtmlEditorController controller = HtmlEditorController();
+ Future _latexToHtml(String latex) async {
+ const breakPoint = 'break';
+ var a = await controller.mathMlToLatex(
+ latex.replaceAll('', breakPoint), context);
+ for (var value in a.split('break')) {
+ log(value.trim(), name: 'latex');
+ }
+ log(a, name: 'MathMl');
+ return a;
+ }
+
@override
Widget build(BuildContext context) {
return GestureDetector(
@@ -286,10 +296,11 @@ class _HtmlEditorExampleState extends State {
style: TextButton.styleFrom(
backgroundColor: Colors.blueGrey),
onPressed: () {
- controller.undo();
+ controller.insertHtmlStringWithLatex(
+ r'
Hello
\(\sqrt{x} e \pi \)
');
},
- child:
- Text('Undo', style: TextStyle(color: Colors.white)),
+ child: Text('insert mathMl',
+ style: TextStyle(color: Colors.white)),
),
SizedBox(
width: 16,
@@ -297,11 +308,13 @@ class _HtmlEditorExampleState extends State {
TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.blueGrey),
- onPressed: () {
- controller.clear();
+ onPressed: () async {
+ var text = await controller.getText();
+ var res = await _latexToHtml(text);
+ log(res, name: 'result');
},
- child:
- Text('Reset', style: TextStyle(color: Colors.white)),
+ child: Text('Get Latex',
+ style: TextStyle(color: Colors.white)),
),
SizedBox(
width: 16,
@@ -311,7 +324,11 @@ class _HtmlEditorExampleState extends State {
backgroundColor:
Theme.of(context).colorScheme.secondary),
onPressed: () async {
- var txt = await controller.getHtmlStringWithLatex();
+ // var txt = await controller.getHtmlStringWithLatex(context);
+ var txt =
+ await controller.getHtmlStringWithLatex(context);
+ print(txt);
+ // print(res);
if (txt.contains('src=\"data:')) {
txt =
'';
@@ -333,10 +350,10 @@ class _HtmlEditorExampleState extends State {
backgroundColor:
Theme.of(context).colorScheme.secondary),
onPressed: () {
- controller.redo();
+ controller.insertLatex(r'\(\sqrt{x}\)');
},
child: Text(
- 'Redo',
+ 'insert latex',
style: TextStyle(color: Colors.white),
),
),
diff --git a/example/pubspec.lock b/example/pubspec.lock
index eb1502f0..a0357de7 100644
--- a/example/pubspec.lock
+++ b/example/pubspec.lock
@@ -211,7 +211,7 @@ packages:
path: ".."
relative: true
source: path
- version: "3.0.0"
+ version: "3.1.0"
infinite_listview:
dependency: transitive
description:
diff --git a/lib/src/html_editor_controller_mobile.dart b/lib/src/html_editor_controller_mobile.dart
index d9a49254..92571cba 100644
--- a/lib/src/html_editor_controller_mobile.dart
+++ b/lib/src/html_editor_controller_mobile.dart
@@ -1,3 +1,4 @@
+import 'dart:async';
import 'dart:developer';
import 'package:flutter/foundation.dart';
@@ -6,9 +7,10 @@ import 'package:flutter/services.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:html_editor_enhanced_fork_latex/html_editor.dart';
import 'package:html_editor_enhanced_fork_latex/src/html_editor_controller_unsupported.dart'
- as unsupported;
+as unsupported;
import 'package:html_editor_enhanced_fork_latex/utils/custom_math_field_controller.dart';
import 'package:math_keyboard/math_keyboard.dart';
+import 'package:webview_flutter/webview_flutter.dart';
/// Controller for mobile
class HtmlEditorController extends unsupported.HtmlEditorController {
@@ -67,7 +69,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
void execCommand(String command, {String? argument}) {
_evaluateJavascript(
source:
- "document.execCommand('$command', false${argument == null ? "" : ", '$argument'"});");
+ "document.execCommand('$command', false${argument == null ? "" : ", '$argument'"});");
}
/// Gets the text from the editor and returns it as a [String].
@@ -175,7 +177,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
void insertNetworkImage(String url, {String filename = ''}) {
_evaluateJavascript(
source:
- "\$('#summernote-2').summernote('insertImage', '$url', '$filename');");
+ "\$('#summernote-2').summernote('insertImage', '$url', '$filename');");
}
/// Insert a link at the position of the cursor in the editor
@@ -212,7 +214,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
void resetHeight() {
_evaluateJavascript(
source:
- "window.flutter_inappwebview.callHandler('setHeight', 'reset');");
+ "window.flutter_inappwebview.callHandler('setHeight', 'reset');");
}
/// Recalculates the height of the editor to remove any vertical scrolling.
@@ -221,7 +223,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
void recalculateHeight() {
_evaluateJavascript(
source:
- "var height = document.body.scrollHeight; window.flutter_inappwebview.callHandler('setHeight', height);");
+ "var height = document.body.scrollHeight; window.flutter_inappwebview.callHandler('setHeight', height);");
}
/// Add a notification to the bottom of the editor. This is styled similar to
@@ -305,16 +307,16 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
await showDialog(
context: context,
builder: (context) => MathKeyboardDialog(
- controller: c,
- mathField: this.mathField,
- ));
+ controller: c,
+ mathField: this.mathField,
+ ));
if (!kIsWeb) {
this.setFocus();
}
var math = c.texString;
if (math != '') {
var texAsFun = c.texStringAsFun;
- var result = await latexToHtml(math.replaceAll('\\', '\\\\'));
+ var result = await latexToHtml(math);
result = '$result';
latexMap.addAll({
result: texAsFun,
@@ -327,6 +329,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
@override
Future latexToHtml(String latex) async {
+ latex = latex.replaceAll('\\', '\\\\');
var res = await editorController!.callAsyncJavaScript(
functionBody: r'''
async function func(){
@@ -344,4 +347,149 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
log(res?.toMap().toString() ?? '');
return res!.value.toString();
}
+
+ @override
+ Future mathMlToLatex(String mathMl, BuildContext context) async {
+ String result = '';
+ late BuildContext dialogContext;
+ Completer completer = Completer();
+ final webViewController = WebViewController()
+ ..setJavaScriptMode(JavaScriptMode.unrestricted)
+ ..setOnConsoleMessage((message) async {
+ log(
+ message.message,
+ name: 'ON_CONSOLE_MESSAGE',
+ );
+ result = message.message;
+ completer.complete(result);
+ await Future.delayed(Duration(milliseconds: 150));
+ Navigator.pop(dialogContext);
+ })
+ ..loadHtmlString(_getHtmlMathMlToLatex(mathMl));
+ showDialog(
+ context: context,
+ builder: (context) {
+ dialogContext = context;
+ return Stack(
+ children: [
+ Center(child: CircularProgressIndicator()),
+ Visibility(
+ visible: false,
+ child: WebViewWidget(
+ controller: webViewController,
+ )),
+ ],
+ );
+ });
+ return completer.future;
+ }
+
+ insertLatex(String latex) async {
+ var html = await latexToHtml(latex);
+ this.insertHtml('$html');
+ }
+
+ Future getHtmlStringWithLatex(context) async {
+ var txt = await getText();
+ final reg = RegExp('', multiLine: true);
+ var tags = [];
+ var res = txt.split(reg);
+ print('result = $res');
+ String latexString = '';
+ const bp = 'break';
+ int index = 0;
+ res.forEach((element) {
+ if (element.contains(r'')) {
+ var split = element.split(r'');
+ var after = split.last;
+ element = '${split.first}';
+ latexString = '$latexString$element';
+ // tags.add(latexMap[element
+ // .replaceAll('π', 'pi')
+ // .replaceAll('π', 'pi')
+ // .replaceAll(' ', '')
+ // .trim()] ??
+ // '');
+ tags.add('LATEX#');
+ if (after.isNotEmpty) tags.add(after);
+ } else {
+ tags.add(element);
+ }
+ });
+ latexString = latexString.replaceAll('', bp);
+ log(latexString, name: 'latex string');
+ var latexRes = await mathMlToLatex(latexString, context);
+ log(latexRes, name: 'mathMlToLatex');
+ var latexList = latexRes.split('break');
+ bool isTrue = true;
+
+ var tag = '';
+ tags.forEach((element) {
+ if (element.isNotEmpty) tag = '$tag$element';
+ });
+ while (isTrue) {
+ if (tag.contains('LATEX#')) {
+ tag = tag.replaceFirst('LATEX#', '\\(${latexList[index++]}\\)');
+ } else {
+ isTrue = false;
+ }
+ }
+ return tag.replaceAll('
', '');
+ }
+
+ Future insertHtmlStringWithLatex(String latex) async {
+ var txt = latex;
+ final reg = RegExp(r'\(', multiLine: true);
+ var tags = [];
+ var res = txt.split(reg);
+ print('result = $res');
+ String latexString = '';
+ const bp = 'break';
+ int index = 0;
+ res.forEach((element) {
+ if (element.contains(r'\)')) {
+ var split = element.split(r'\)');
+ var after = split.last;
+ element = '\\(${split.first}\\)';
+ latexString = '$latexString$element';
+ tags.add('LATEX#');
+ if (after.isNotEmpty) tags.add(after);
+ } else {
+ tags.add(element);
+ }
+ });
+ latexString = latexString.replaceAll('\\)\\(', bp);
+ log(latexString, name: 'latex string');
+ var latexRes = await latexToHtml(
+ latexString,
+ );
+ log(latexRes, name: 'LatexToMathMl');
+ var latexList = latexRes.split('break');
+ bool isTrue = true;
+ var tag = '';
+ tags.forEach((element) {
+ if (element.isNotEmpty) tag = '$tag$element';
+ });
+ while (isTrue) {
+ if (tag.contains('LATEX#')) {
+ tag = tag.replaceFirst('LATEX#',
+ '${latexList[index++]}');
+ } else {
+ isTrue = false;
+ }
+ }
+ this.insertHtml(tag.replaceAll('