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
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
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a145802f..cc22b2c5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,22 +1,96 @@
-## [2.5.1] = 2023-01-25
+## [3.2.0] = 2023-1-11
+
+* changed how the mathMl to Latex works, now faster
+
+## [3.1.0] = 2023-1-8
+
+* changed how the latex to mathMl works, now faster
+
+## [3.0.0] = 2023-1-4
+
+* compatibility
+
+## [2.6.9+1] = 2023-1-2
+
+* improved the math keyboard dialog
+
+## [2.6.9] = 2023-1-2
+
+* improved the math keyboard dialog
+
+## [2.6.8] = 2023-12-31
+
+* moved the math keyboard to the controller
+
+## [2.6.7] = 2023-12-20
+
+* customizable math keyboard
+
+## [2.6.7] = 2023-12-20
+
+* improved performance
+
+## [2.6.6] = 2023-12-20
+
+* Image Upload was turned off, now its on
+
+## [2.6.5] = 2023-12-20
+
+* Version Name
+
+## [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
## [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
@@ -26,6 +100,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
@@ -41,208 +116,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/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/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/android/build.gradle b/example/android/build.gradle
index 714549c2..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"
}
}
@@ -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 85057082..aa69f9b6 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -1,7 +1,10 @@
+import 'dart:developer';
+
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
-import 'package:html_editor_enhanced/html_editor.dart';
-import 'package:file_picker/file_picker.dart';
+import 'package:flutter_inappwebview/flutter_inappwebview.dart' as inApp;
+import 'package:get/get.dart';
+import 'package:html_editor_enhanced_fork_latex/html_editor.dart';
void main() => runApp(HtmlEditorExampleApp());
@@ -14,8 +17,128 @@ 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 StatefulWidget {
+ final String title;
+
+ MyApp2({Key? key, required this.title}) : super(key: key);
+
+ @override
+ State createState() => _MyApp2State();
+}
+
+class _MyApp2State extends State {
+ final HtmlEditorController controller1 = HtmlEditorController();
+ inApp.InAppWebViewController controller =
+ inApp.InAppWebViewController(0123, inApp.InAppWebView());
+
+ final controller2 = HtmlEditorController();
+
+ @override
+ void initState() {
+ super.initState();
+ }
+
+ Future _latexToHtml(String latex, editorController) async {
+ const breakPoint = 'break ';
+ var mathMl =
+ 'x x x x x x ';
+
+ var a = await controller2.mathMlToLatex(
+ mathMl.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 Scaffold(
+ floatingActionButton: FloatingActionButton(onPressed: () {
+ (_latexToHtml('{x}', controller));
+ }),
+ body: Stack(
+ children: [
+ SingleChildScrollView(
+ child: Column(
+ children: [
+ tb(controller1),
+ ],
+ ),
+ ),
+ ],
+ ),
+ appBar: AppBar(
+ title: Text(this.widget.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'y y >');
+ isVisible.value = true;
+ },
+ icon: Icon(Icons.functions_outlined)),
+ ),
+ //other widgets here
+ HtmlEditor(
+ controller: controller,
+ callbacks: Callbacks(
+ onBlur: () {
+ print('onBlur');
+ isVisible.value = false;
+ },
+ onNavigationRequestMobile: (s) async {
+ print('on NavReq to $s');
+ return NavigationActionPolicy.ALLOW;
+ },
+ onDialogShown: () => print('onDialogOpen'),
+ onFocus: () {
+ print('onFocus');
+ isVisible.value = true;
+ },
+ ),
+ htmlEditorOptions: HtmlEditorOptions(
+ hint: 'Your text here...',
+ shouldEnsureVisible: true,
+ //initialText: "text content initial, if any
",
+ ),
+ htmlToolbarOptions: HtmlToolbarOptions(
+ toolbarPosition:
+ ToolbarPosition.custom, // required to place toolbar anywhere!
+
+ //other options
+ ),
+ otherOptions: OtherOptions(height: 550),
+ ),
+ ]);
+ }
}
class HtmlEditorExample extends StatefulWidget {
@@ -31,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(
@@ -74,32 +208,10 @@ class _HtmlEditorExampleState extends State {
//initialText: "text content initial, if any
",
),
htmlToolbarOptions: HtmlToolbarOptions(
- toolbarPosition: ToolbarPosition.aboveEditor, //by default
- toolbarType: ToolbarType.nativeScrollable, //by default
- onButtonPressed:
- (ButtonType type, bool? status, Function? updateStatus) {
- print(
- "button '${describeEnum(type)}' pressed, the current selected status is $status");
- return true;
- },
- onDropdownChanged: (DropdownType type, dynamic changed,
- Function(dynamic)? updateSelectedItem) {
- print(
- "dropdown '${describeEnum(type)}' changed to $changed");
- return true;
- },
- mediaLinkInsertInterceptor:
- (String url, InsertFileType type) {
- print(url);
- return true;
- },
- mediaUploadInterceptor:
- (PlatformFile file, InsertFileType type) async {
- print(file.name); //filename
- print(file.size); //size in bytes
- print(file.extension); //file extension (eg jpeg or mp4)
- return true;
- },
+ toolbarPosition: ToolbarPosition.aboveEditor,
+ //by default
+ toolbarType: ToolbarType.nativeScrollable,
+ //by default
),
otherOptions: OtherOptions(height: 550),
callbacks: Callbacks(onBeforeCommand: (String? currentHtml) {
@@ -136,7 +248,7 @@ class _HtmlEditorExampleState extends State {
},*/
onImageUploadError: (FileUpload? file, String? base64Str,
UploadError error) {
- print(describeEnum(error));
+ print((error.name));
print(base64Str ?? '');
if (file != null) {
print(file.name);
@@ -184,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,
@@ -195,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,
@@ -209,7 +324,11 @@ class _HtmlEditorExampleState extends State {
backgroundColor:
Theme.of(context).colorScheme.secondary),
onPressed: () async {
- var txt = await controller.getText();
+ // var txt = await controller.getHtmlStringWithLatex(context);
+ var txt =
+ await controller.getHtmlStringWithLatex(context);
+ print(txt);
+ // print(res);
if (txt.contains('src=\"data:')) {
txt =
'';
@@ -231,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/lib/two_editors.dart b/example/lib/two_editors.dart
new file mode 100644
index 00000000..eee38188
--- /dev/null
+++ b/example/lib/two_editors.dart
@@ -0,0 +1,199 @@
+import 'package:flutter/material.dart';
+import 'package:html_editor_enhanced_fork_latex/html_editor.dart';
+
+class EditorWithFocusChange extends StatefulWidget {
+ const EditorWithFocusChange();
+
+ @override
+ createState() => _EditorWithFocusChangeState();
+}
+
+class _EditorWithFocusChangeState extends State {
+ final HtmlEditorController controller = HtmlEditorController();
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ children: [
+ VisibleToolbar(controller: controller),
+ HtmlEditor(
+ controller: controller,
+ htmlEditorOptions: HtmlEditorOptions(
+ hint: 'Your text here...',
+ shouldEnsureVisible: true,
+ //initialText: "text content initial, if any
",
+ ),
+ htmlToolbarOptions: HtmlToolbarOptions(
+ toolbarPosition: ToolbarPosition.custom,
+ // toolbarType: ToolbarType.nativeScrollable,
+ // onButtonPressed:
+ // (ButtonType type, bool? status, Function? updateStatus) {
+ // print(
+ // "button '${(type.name)}' pressed, the current selected status is $status");
+ // return true;
+ // },
+ // onDropdownChanged: (DropdownType type, dynamic changed,
+ // Function(dynamic)? updateSelectedItem) {
+ // print("dropdown '${(type.name)}' changed to $changed");
+ // return true;
+ // },
+ // mediaLinkInsertInterceptor: (String url, InsertFileType type) {
+ // print(url);
+ // return true;
+ // },
+ // mediaUploadInterceptor: (PlatformFile file, InsertFileType type) async {
+ // print(file.name); //filename
+ // print(file.size); //size in bytes
+ // print(file.extension); //file extension (eg jpeg or mp4)
+ // return true;
+ // },
+ ),
+ otherOptions: OtherOptions(height: 550),
+ plugins: [
+ SummernoteAtMention(
+ getSuggestionsMobile: (String value) {
+ var mentions = ['test1', 'test2', 'test3'];
+ return mentions
+ .where((element) => element.contains(value))
+ .toList();
+ },
+ mentionsWeb: ['test1', 'test2', 'test3'],
+ onSelect: (String value) {
+ print(value);
+ },
+ ),
+ ],
+ ),
+ ],
+ );
+ }
+}
+
+class VisibleToolbar extends StatefulWidget {
+ const VisibleToolbar({required this.controller});
+
+ final HtmlEditorController controller;
+
+ @override
+ State createState() => _VisibleToolbarState();
+}
+
+class _VisibleToolbarState extends State {
+ bool _isVisible = false;
+
+ @override
+ Widget build(BuildContext context) {
+ return Visibility(
+ visible: _isVisible,
+ child: ToolbarWidget(
+ controller: widget.controller,
+ htmlToolbarOptions: HtmlToolbarOptions(
+ toolbarPosition: ToolbarPosition.custom,
+ toolbarType: ToolbarType.nativeScrollable,
+ defaultToolbarButtons: const [
+ StyleButtons(),
+ FontSettingButtons(fontSizeUnit: false, fontName: false),
+ FontButtons(clearAll: false),
+ ColorButtons(highlightColor: false),
+ ListButtons(listStyles: false),
+ ParagraphButtons(
+ textDirection: false,
+ lineHeight: false,
+ caseConverter: false,
+ alignJustify: false),
+ InsertButtons(
+ video: false,
+ link: false,
+ audio: false,
+ table: true,
+ hr: true,
+ otherFile: false),
+ ],
+ ),
+ callbacks: Callbacks(
+ onBeforeCommand: (String? currentHtml) {
+ print('html before change is $currentHtml');
+ },
+ onChangeContent: (String? changed) {
+ print('content changed to $changed');
+ },
+ onChangeCodeview: (String? changed) {
+ print('code changed to $changed');
+ },
+ onChangeSelection: (EditorSettings settings) {
+ print('parent element is ${settings.parentElement}');
+ print('font name is ${settings.fontName}');
+ },
+ onDialogShown: () {
+ print('dialog shown');
+ },
+ onEnter: () {
+ print('enter/return pressed');
+ },
+ onFocus: () {
+ setState(() {
+ _isVisible = true;
+ });
+ print('editor focused');
+ },
+ onBlur: () {
+ setState(() {
+ _isVisible = false;
+ });
+ print('editor unfocused');
+ },
+ onBlurCodeview: () {
+ print('codeview either focused or unfocused');
+ },
+ onInit: () {
+ print('init');
+ },
+ //this is commented because it overrides the default Summernote handlers
+ /*onImageLinkInsert: (String? url) {
+ print(url ?? "unknown url");
+ },
+ onImageUpload: (FileUpload file) async {
+ print(file.name);
+ print(file.size);
+ print(file.type);
+ print(file.base64);
+ },*/
+ onImageUploadError:
+ (FileUpload? file, String? base64Str, UploadError error) {
+ print((error.name));
+ print(base64Str ?? '');
+ if (file != null) {
+ print(file.name);
+ print(file.size);
+ print(file.type);
+ }
+ },
+ onKeyDown: (int? keyCode) {
+ print('$keyCode key downed');
+ print(
+ 'current character count: ${widget.controller.characterCount}');
+ },
+ onKeyUp: (int? keyCode) {
+ print('$keyCode key released');
+ },
+ onMouseDown: () {
+ print('mouse downed');
+ },
+ onMouseUp: () {
+ print('mouse released');
+ },
+ onNavigationRequestMobile: (String url) {
+ print(url);
+ return NavigationActionPolicy.ALLOW;
+ },
+ onPaste: () {
+ print('pasted into editor');
+ },
+ onScroll: () {
+ print('editor scrolled');
+ },
+ ),
+ ),
+ );
+ }
+}
diff --git a/example/pubspec.lock b/example/pubspec.lock
index b98a159b..fb5f6e94 100644
--- a/example/pubspec.lock
+++ b/example/pubspec.lock
@@ -1,83 +1,110 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
+ args:
+ dependency: transitive
+ description:
+ name: args
+ sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.6.0"
async:
dependency: transitive
description:
name: async
- url: "https://pub.dartlang.org"
+ sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
+ url: "https://pub.dev"
source: hosted
- version: "2.9.0"
+ version: "2.11.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
- url: "https://pub.dartlang.org"
+ sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.0"
+ version: "2.1.1"
characters:
dependency: transitive
description:
name: characters
- url: "https://pub.dartlang.org"
+ sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
+ url: "https://pub.dev"
source: hosted
- version: "1.2.1"
+ version: "1.3.0"
clock:
dependency: transitive
description:
name: clock
- url: "https://pub.dartlang.org"
+ sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
+ url: "https://pub.dev"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
- url: "https://pub.dartlang.org"
+ sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.18.0"
+ cross_file:
+ dependency: transitive
+ description:
+ name: cross_file
+ sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670"
+ url: "https://pub.dev"
source: hosted
- version: "1.16.0"
+ version: "0.3.4+2"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
- url: "https://pub.dartlang.org"
+ sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
+ url: "https://pub.dev"
source: hosted
- version: "1.0.5"
+ version: "1.0.6"
fake_async:
dependency: transitive
description:
name: fake_async
- url: "https://pub.dartlang.org"
+ sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
+ url: "https://pub.dev"
source: hosted
version: "1.3.1"
ffi:
dependency: transitive
description:
name: ffi
- url: "https://pub.dartlang.org"
+ sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
+ url: "https://pub.dev"
source: hosted
- version: "2.0.1"
+ version: "2.1.3"
file_picker:
dependency: transitive
description:
name: file_picker
- url: "https://pub.dartlang.org"
+ sha256: "04a7b85852255759fd3010530cafac250eaa1f8202546670834d25057bb3251a"
+ url: "https://pub.dev"
source: hosted
- version: "5.2.5"
+ version: "8.0.0"
flex_color_picker:
dependency: transitive
description:
name: flex_color_picker
- url: "https://pub.dartlang.org"
+ sha256: "5c846437069fb7afdd7ade6bf37e628a71d2ab0787095ddcb1253bf9345d5f3a"
+ url: "https://pub.dev"
source: hosted
- version: "3.0.2"
+ version: "3.4.1"
flex_seed_scheme:
dependency: transitive
description:
name: flex_seed_scheme
- url: "https://pub.dartlang.org"
+ sha256: "4cee2f1d07259f77e8b36f4ec5f35499d19e74e17c7dce5b819554914082bc01"
+ url: "https://pub.dev"
source: hosted
- version: "1.1.0"
+ version: "1.5.0"
flutter:
dependency: "direct main"
description: flutter
@@ -87,58 +114,87 @@ packages:
dependency: transitive
description:
name: flutter_inappwebview
- url: "https://pub.dartlang.org"
+ 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
- url: "https://pub.dartlang.org"
+ sha256: "98664be7be0e3ffca00de50f7f6a287ab62c763fc8c762e0a21584584a3ff4f8"
+ url: "https://pub.dev"
source: hosted
- version: "5.4.0"
+ version: "6.0.0"
flutter_keyboard_visibility_linux:
dependency: transitive
description:
name: flutter_keyboard_visibility_linux
- url: "https://pub.dartlang.org"
+ sha256: "6fba7cd9bb033b6ddd8c2beb4c99ad02d728f1e6e6d9b9446667398b2ac39f08"
+ url: "https://pub.dev"
source: hosted
version: "1.0.0"
flutter_keyboard_visibility_macos:
dependency: transitive
description:
name: flutter_keyboard_visibility_macos
- url: "https://pub.dartlang.org"
+ sha256: c5c49b16fff453dfdafdc16f26bdd8fb8d55812a1d50b0ce25fc8d9f2e53d086
+ url: "https://pub.dev"
source: hosted
version: "1.0.0"
flutter_keyboard_visibility_platform_interface:
dependency: transitive
description:
name: flutter_keyboard_visibility_platform_interface
- url: "https://pub.dartlang.org"
+ sha256: e43a89845873f7be10cb3884345ceb9aebf00a659f479d1c8f4293fcb37022a4
+ url: "https://pub.dev"
source: hosted
version: "2.0.0"
flutter_keyboard_visibility_web:
dependency: transitive
description:
name: flutter_keyboard_visibility_web
- url: "https://pub.dartlang.org"
+ sha256: d3771a2e752880c79203f8d80658401d0c998e4183edca05a149f5098ce6e3d1
+ url: "https://pub.dev"
source: hosted
version: "2.0.0"
flutter_keyboard_visibility_windows:
dependency: transitive
description:
name: flutter_keyboard_visibility_windows
- url: "https://pub.dartlang.org"
+ sha256: fc4b0f0b6be9b93ae527f3d527fb56ee2d918cd88bbca438c478af7bcfd0ef73
+ url: "https://pub.dev"
source: hosted
version: "1.0.0"
+ flutter_localizations:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ flutter_math_fork:
+ dependency: transitive
+ description:
+ name: flutter_math_fork
+ sha256: "94bee4642892a94939af0748c6a7de0ff8318feee588379dcdfea7dc5cba06c8"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.7.2"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
- url: "https://pub.dartlang.org"
+ sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.17"
+ flutter_svg:
+ dependency: transitive
+ description:
+ name: flutter_svg
+ sha256: f991fdb1533c3caeee0cdc14b04f50f0c3916f0dbcbc05237ccbe4e3c6b93f3f
+ url: "https://pub.dev"
source: hosted
- version: "2.0.7"
+ version: "2.0.5"
flutter_test:
dependency: "direct dev"
description: flutter
@@ -149,83 +205,197 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
- html_editor_enhanced:
+ get:
+ dependency: "direct main"
+ description:
+ name: get
+ sha256: "2ba20a47c8f1f233bed775ba2dd0d3ac97b4cf32fc17731b3dfc672b06b0e92a"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.6.5"
+ holding_gesture:
+ dependency: transitive
+ description:
+ name: holding_gesture
+ sha256: "6d12a991c498357f9c8a532656facf97c47858be9a7249d5caaa84707aecc052"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.0"
+ html_editor_enhanced_fork_latex:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
- version: "2.5.1"
+ version: "4.0.0"
infinite_listview:
dependency: transitive
description:
name: infinite_listview
- url: "https://pub.dartlang.org"
+ sha256: f6062c1720eb59be553dfa6b89813d3e8dd2f054538445aaa5edaddfa5195ce6
+ url: "https://pub.dev"
source: hosted
version: "1.1.0"
- js:
+ intl:
dependency: transitive
description:
- name: js
- url: "https://pub.dartlang.org"
+ name: intl
+ sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
+ url: "https://pub.dev"
source: hosted
- version: "0.6.4"
+ version: "0.18.1"
+ leak_tracker:
+ dependency: transitive
+ description:
+ name: leak_tracker
+ sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
+ url: "https://pub.dev"
+ source: hosted
+ version: "10.0.0"
+ leak_tracker_flutter_testing:
+ dependency: transitive
+ description:
+ name: leak_tracker_flutter_testing
+ sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
+ leak_tracker_testing:
+ dependency: transitive
+ description:
+ name: leak_tracker_testing
+ sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
matcher:
dependency: transitive
description:
name: matcher
- url: "https://pub.dartlang.org"
+ sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
+ url: "https://pub.dev"
source: hosted
- version: "0.12.12"
+ version: "0.12.16+1"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
- url: "https://pub.dartlang.org"
+ sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.8.0"
+ math_expressions:
+ dependency: transitive
+ description:
+ name: math_expressions
+ sha256: "3576593617c3870d75728a751f6ec6e606706d44e363f088ac394b5a28a98064"
+ url: "https://pub.dev"
source: hosted
- version: "0.1.5"
+ version: "2.4.0"
+ math_keyboard:
+ dependency: "direct main"
+ description:
+ name: math_keyboard
+ sha256: "7a7a644ce4313f31b74bc31c9d522dbdc08e5462dfa7beb4d0973cd4232e9ba3"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.2.0"
meta:
dependency: transitive
description:
name: meta
- url: "https://pub.dartlang.org"
+ sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
+ url: "https://pub.dev"
source: hosted
- version: "1.8.0"
+ version: "1.11.0"
+ nested:
+ dependency: transitive
+ description:
+ name: nested
+ sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.0"
numberpicker:
dependency: transitive
description:
name: numberpicker
- url: "https://pub.dartlang.org"
+ sha256: "4c129154944b0f6b133e693f8749c3f8bfb67c4d07ef9dcab48b595c22d1f156"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.1"
+ version: "2.1.2"
path:
dependency: transitive
description:
name: path
- url: "https://pub.dartlang.org"
+ sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
+ url: "https://pub.dev"
source: hosted
- version: "1.8.2"
- pedantic:
+ version: "1.9.0"
+ path_parsing:
dependency: transitive
description:
- name: pedantic
- url: "https://pub.dartlang.org"
+ name: path_parsing
+ sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf
+ url: "https://pub.dev"
source: hosted
- version: "1.11.1"
+ version: "1.0.1"
+ petitparser:
+ dependency: transitive
+ description:
+ name: petitparser
+ sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.1.0"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
- url: "https://pub.dartlang.org"
+ sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.3"
+ version: "2.1.8"
pointer_interceptor:
dependency: transitive
description:
name: pointer_interceptor
- url: "https://pub.dartlang.org"
+ sha256: "57210410680379aea8b1b7ed6ae0c3ad349bfd56fe845b8ea934a53344b9d523"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.10.1+2"
+ pointer_interceptor_ios:
+ dependency: transitive
+ description:
+ name: pointer_interceptor_ios
+ sha256: a6906772b3205b42c44614fcea28f818b1e5fdad73a4ca742a7bd49818d9c917
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.10.1"
+ pointer_interceptor_platform_interface:
+ dependency: transitive
+ description:
+ name: pointer_interceptor_platform_interface
+ sha256: "0597b0560e14354baeb23f8375cd612e8bd4841bf8306ecb71fcd0bb78552506"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.10.0+1"
+ pointer_interceptor_web:
+ dependency: transitive
+ description:
+ name: pointer_interceptor_web
+ sha256: "7a7087782110f8c1827170660b09f8aa893e0e9a61431dbbe2ac3fc482e8c044"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.10.2+1"
+ provider:
+ dependency: transitive
+ description:
+ name: provider
+ sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096"
+ url: "https://pub.dev"
source: hosted
- version: "0.9.3+3"
+ version: "6.1.1"
sky_engine:
dependency: transitive
description: flutter
@@ -235,65 +405,162 @@ packages:
dependency: transitive
description:
name: source_span
- url: "https://pub.dartlang.org"
+ sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
+ url: "https://pub.dev"
source: hosted
- version: "1.9.0"
+ version: "1.10.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
- url: "https://pub.dartlang.org"
+ sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
+ url: "https://pub.dev"
source: hosted
- version: "1.10.0"
+ version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
- url: "https://pub.dartlang.org"
+ sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
+ url: "https://pub.dev"
source: hosted
- version: "2.1.0"
+ version: "2.1.2"
string_scanner:
dependency: transitive
description:
name: string_scanner
- url: "https://pub.dartlang.org"
+ sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
+ url: "https://pub.dev"
source: hosted
- version: "1.1.1"
+ version: "1.2.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
- url: "https://pub.dartlang.org"
+ sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
+ url: "https://pub.dev"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
- url: "https://pub.dartlang.org"
+ sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.6.1"
+ tuple:
+ dependency: transitive
+ description:
+ name: tuple
+ sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.2"
+ vector_graphics:
+ dependency: transitive
+ description:
+ name: vector_graphics
+ sha256: ea8d3fc7b2e0f35de38a7465063ecfcf03d8217f7962aa2a6717132cb5d43a79
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.5"
+ vector_graphics_codec:
+ dependency: transitive
+ description:
+ name: vector_graphics_codec
+ sha256: a5eaa5d19e123ad4f61c3718ca1ed921c4e6254238d9145f82aa214955d9aced
+ url: "https://pub.dev"
source: hosted
- version: "0.4.12"
+ version: "1.1.5"
+ vector_graphics_compiler:
+ dependency: transitive
+ description:
+ name: vector_graphics_compiler
+ sha256: "15edc42f7eaa478ce854eaf1fbb9062a899c0e4e56e775dd73b7f4709c97c4ca"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.5"
vector_math:
dependency: transitive
description:
name: vector_math
- url: "https://pub.dartlang.org"
+ sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.2"
+ version: "2.1.4"
visibility_detector:
dependency: transitive
description:
name: visibility_detector
- url: "https://pub.dartlang.org"
+ sha256: dd5cc11e13494f432d15939c3aa8ae76844c42b723398643ce9addb88a5ed420
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.4.0+2"
+ vm_service:
+ dependency: transitive
+ description:
+ name: vm_service
+ sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
+ url: "https://pub.dev"
source: hosted
- version: "0.3.3"
+ version: "13.0.0"
+ web:
+ dependency: transitive
+ description:
+ name: web
+ sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.5.1"
+ webview_flutter:
+ dependency: transitive
+ description:
+ name: webview_flutter
+ sha256: "42393b4492e629aa3a88618530a4a00de8bb46e50e7b3993fedbfdc5352f0dbf"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.4.2"
+ webview_flutter_android:
+ dependency: transitive
+ description:
+ name: webview_flutter_android
+ sha256: "8326ee235f87605a2bfc444a4abc897f4abc78d83f054ba7d3d1074ce82b4fbf"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.12.1"
+ webview_flutter_platform_interface:
+ dependency: transitive
+ description:
+ name: webview_flutter_platform_interface
+ sha256: "6d9213c65f1060116757a7c473247c60f3f7f332cac33dc417c9e362a9a13e4f"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.6.0"
+ webview_flutter_wkwebview:
+ dependency: transitive
+ description:
+ name: webview_flutter_wkwebview
+ sha256: accdaaa49a2aca2dc3c3230907988954cdd23fed0a19525d6c9789d380f4dc76
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.9.4"
win32:
dependency: transitive
description:
name: win32
- url: "https://pub.dartlang.org"
+ sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.5.0"
+ xml:
+ dependency: transitive
+ description:
+ name: xml
+ sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5"
+ url: "https://pub.dev"
source: hosted
- version: "3.1.3"
+ version: "6.2.2"
sdks:
- dart: ">=2.18.0 <3.0.0"
- flutter: ">=3.3.0"
+ dart: ">=3.3.0 <4.0.0"
+ flutter: ">=3.19.0"
diff --git a/example/pubspec.yaml b/example/pubspec.yaml
index 5e1c4814..72cf9a63 100644
--- a/example/pubspec.yaml
+++ b/example/pubspec.yaml
@@ -6,13 +6,14 @@ 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:
sdk: flutter
-
- html_editor_enhanced:
+ get: ^4.0.0
+ math_keyboard: 0.2.0
+ 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 c11e5afc..c5c2c9f1 100644
--- a/lib/html_editor.dart
+++ b/lib/html_editor.dart
@@ -1,24 +1,23 @@
library html_editor;
-export 'package:html_editor_enhanced/src/widgets/toolbar_widget.dart';
-export 'package:html_editor_enhanced/utils/callbacks.dart';
-export 'package:html_editor_enhanced/utils/toolbar.dart';
-export 'package:html_editor_enhanced/utils/plugins.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/utils.dart'
- hide setState, intersperse, getRandString;
-
-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/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/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_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
enum UploadError { unsupportedFile, exceededMaxSize, jsException }
@@ -72,6 +71,7 @@ enum ButtonType {
otherFile,
table,
hr,
+ fn,
fullscreen,
codeview,
undo,
diff --git a/lib/src/html_editor_controller_mobile.dart b/lib/src/html_editor_controller_mobile.dart
index 7210d11c..92571cba 100644
--- a/lib/src/html_editor_controller_mobile.dart
+++ b/lib/src/html_editor_controller_mobile.dart
@@ -1,9 +1,16 @@
+import 'dart:async';
+import 'dart:developer';
+
import 'package:flutter/foundation.dart';
+import 'package:flutter/material.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'
- as unsupported;
+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: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 {
@@ -11,6 +18,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
this.processInputHtml = true,
this.processNewLineAsBr = false,
this.processOutputHtml = true,
+ this.mathField,
});
/// Toolbar widget state to call various methods. For internal use only.
@@ -38,6 +46,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
/// The default value is true.
@override
final bool processOutputHtml;
+ final MathField? mathField;
/// Manages the [InAppWebViewController] for the [HtmlEditorController]
InAppWebViewController? _editorController;
@@ -195,7 +204,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
@@ -224,7 +233,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
void addNotification(String html, NotificationType notificationType) async {
await _evaluateJavascript(source: """
\$('.note-status-output').html(
- '$html
'
+ '$html
'
);
""");
recalculateHeight();
@@ -265,7 +274,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');
}
}
@@ -288,4 +297,199 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
/// Internal function to insert table on Web
@override
void insertTable(String dimensions) {}
+
+ @override
+ openMathDialog(BuildContext context) async {
+ final c = CustomMathFieldEditingController();
+ if (!kIsWeb) {
+ this.clearFocus();
+ }
+ await showDialog(
+ context: context,
+ builder: (context) => MathKeyboardDialog(
+ controller: c,
+ mathField: this.mathField,
+ ));
+ if (!kIsWeb) {
+ this.setFocus();
+ }
+ var math = c.texString;
+ if (math != '') {
+ var texAsFun = c.texStringAsFun;
+ var result = await latexToHtml(math);
+ result = '$result ';
+ latexMap.addAll({
+ result: texAsFun,
+ });
+ this.addToHashMap(result, texAsFun);
+ this.insertHtml(result);
+ this.insertText(' ');
+ }
+ }
+
+ @override
+ Future latexToHtml(String latex) async {
+ latex = latex.replaceAll('\\', '\\\\');
+ var res = await editorController!.callAsyncJavaScript(
+ functionBody: r'''
+ async function func(){
+ const mathlive = await import("https://unpkg.com/mathlive?module");
+ const mathML = mathlive.convertLatexToMathMl('\$\$'''
+ '$latex'
+ r'''\$\$');
+ return(mathML);
+ };
+ var p = await func();
+ return p;
+ ''',
+ arguments: {'latex': latex});
+ log(res.toString());
+ 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('
', ''));
+ return tag.replaceAll('
', '');
+ }
+
+ String _getHtmlMathMlToLatex(String mathMl) => '''
+
+ '
+ '
+ ''';
}
diff --git a/lib/src/html_editor_controller_unsupported.dart b/lib/src/html_editor_controller_unsupported.dart
index 618cbf1a..b1ed75f5 100644
--- a/lib/src/html_editor_controller_unsupported.dart
+++ b/lib/src/html_editor_controller_unsupported.dart
@@ -1,4 +1,9 @@
-import 'package:html_editor_enhanced/html_editor.dart';
+import 'dart:async';
+import 'dart:collection';
+
+import 'package:flutter/material.dart';
+import 'package:html_editor_enhanced_fork_latex/html_editor.dart';
+import 'package:math_keyboard/math_keyboard.dart';
import 'package:meta/meta.dart';
/// Fallback controller (should never be used)
@@ -7,8 +12,60 @@ class HtmlEditorController {
this.processInputHtml = true,
this.processNewLineAsBr = false,
this.processOutputHtml = true,
+ this.mathField,
});
+ final HashMap latexMap = HashMap();
+
+ openMathDialog(BuildContext context) async {}
+
+ latexToHtml(String latex) {}
+
+ Future mathMlToLatex(String mathMl, BuildContext context) {
+ throw Exception('UnImplemented');
+ }
+
+ void addToHashMap(String key, String value) {
+ latexMap.addAll({
+ key
+ .replaceAll('π', 'pi')
+ .replaceAll('π', 'pi')
+ .replaceAll(' ', '')
+ .trim(): value,
+ });
+ }
+
+ Future getHtmlStringWithLatex(context) async {
+ var txt = await getText();
+ final reg = RegExp('', multiLine: true);
+ var tags = [];
+ var res = txt.split(reg);
+ print('result = $res');
+
+ res.forEach((element) {
+ if (element.contains(r' ')) {
+ var split = element.split(r'
');
+ var after = split.last;
+ element = '${split.first} ';
+ tags.add(latexMap[element
+ .replaceAll('π', 'pi')
+ .replaceAll('π', 'pi')
+ .trim()] ??
+ '');
+ if (after.isNotEmpty) tags.add(after);
+ } else {
+ tags.add(element);
+ }
+ });
+ var tag = '';
+ tags.forEach((element) {
+ if (element.isNotEmpty) tag = '$tag$element';
+ });
+ return tag;
+ }
+
+ insertLatex(String latex) {}
+
/// Toolbar widget state to call various methods. For internal use only.
@internal
ToolbarWidgetState? toolbar;
@@ -31,6 +88,7 @@ class HtmlEditorController {
///
/// The default value is true.
final bool processOutputHtml;
+ final MathField? mathField;
/// Internally tracks the character count in the editor
int _characterCount = 0;
@@ -171,4 +229,6 @@ class HtmlEditorController {
/// Internal function to insert table on Web
@internal
void insertTable(String dimensions) {}
+
+ insertHtmlStringWithLatex(String latex) {}
}
diff --git a/lib/src/html_editor_controller_web.dart b/lib/src/html_editor_controller_web.dart
index 01ff3dec..0065cea1 100644
--- a/lib/src/html_editor_controller_web.dart
+++ b/lib/src/html_editor_controller_web.dart
@@ -3,8 +3,10 @@ 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:flutter/material.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;
import 'package:meta/meta.dart';
@@ -14,7 +16,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
this.processInputHtml = true,
this.processNewLineAsBr = false,
this.processOutputHtml = true,
- });
+ }) : super(mathField: null);
/// Toolbar widget state to call various methods. For internal use only.
@override
@@ -187,7 +189,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 +198,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
@@ -288,7 +290,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
_evaluateJavascriptWeb(data: {
'type': 'toIframe: addNotification',
'html': html,
- 'alertType': 'alert alert-${describeEnum(notificationType)}'
+ 'alertType': 'alert alert-${(notificationType.name)}'
});
}
recalculateHeight();
@@ -323,7 +325,19 @@ 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');
}
}
+
+ @override
+ openMathDialog(BuildContext context) async {
+ throw Exception(
+ '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.');
+ }
+
+ @override
+ Future latexToHtml(String latex) async {
+ throw Exception(
+ '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.');
+ }
}
diff --git a/lib/src/html_editor_mobile.dart b/lib/src/html_editor_mobile.dart
index 50faf109..0afe5ce4 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 {
@@ -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 abc6239a..a8eabf55 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..81f072bf 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 {
@@ -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
new file mode 100644
index 00000000..cb9f6a04
--- /dev/null
+++ b/lib/src/widgets/custom_html_editor.dart
@@ -0,0 +1,169 @@
+// ignore_for_file: avoid_print
+
+import 'package:file_picker/file_picker.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+
+import '../../html_editor.dart';
+
+class CustomHtmlEditorWidget extends StatelessWidget {
+ const CustomHtmlEditorWidget({required this.controller, double? height})
+ : _height = height ?? 500;
+ final HtmlEditorController controller;
+ final double _height;
+
+ Widget _htmlWidget() {
+ return HtmlEditor(
+ controller: controller,
+ htmlEditorOptions: const HtmlEditorOptions(
+ hint: 'Your text here...',
+ shouldEnsureVisible: true,
+ //initialText: "text content initial, if any
",
+ ),
+ htmlToolbarOptions: HtmlToolbarOptions(
+ toolbarPosition: ToolbarPosition.aboveEditor,
+ defaultToolbarButtons: [
+ const StyleButtons(),
+ const FontSettingButtons(fontSizeUnit: false),
+ const FontButtons(clearAll: false),
+ const ColorButtons(),
+ const ListButtons(listStyles: false),
+ const ParagraphButtons(
+ textDirection: false, lineHeight: false, caseConverter: false),
+ const InsertButtons(
+ video: false,
+ audio: false,
+ table: true,
+ hr: true,
+ fn: true,
+ otherFile: false),
+ ],
+ //by default
+ toolbarType: ToolbarType.nativeExpandable,
+ //by default
+ onButtonPressed:
+ (ButtonType type, bool? status, Function? updateStatus) {
+ print(
+ "button '${type.name}' pressed, the current selected status is $status");
+ return true;
+ },
+ onDropdownChanged: (DropdownType type, dynamic changed,
+ Function(dynamic)? updateSelectedItem) {
+ print("dropdown '${type.name}' changed to $changed");
+ return true;
+ },
+ mediaLinkInsertInterceptor: (String url, InsertFileType type) {
+ print(url);
+ return true;
+ },
+ mediaUploadInterceptor: (PlatformFile file, InsertFileType type) async {
+ if (kDebugMode) {
+ print(file.name);
+ } //filename
+ print(file.size); //size in bytes
+ print(file.extension); //file extension (eg jpeg or mp4)
+ return true;
+ },
+ ),
+ otherOptions: OtherOptions(height: _height),
+ callbacks: Callbacks(onBeforeCommand: (String? currentHtml) {
+ print('html before change is $currentHtml');
+ }, onChangeContent: (String? changed) {
+ print('content changed to $changed');
+ }, onChangeCodeview: (String? changed) {
+ print('code changed to $changed');
+ }, onChangeSelection: (EditorSettings settings) {
+ print('parent element is ${settings.parentElement}');
+ print('font name is ${settings.fontName}');
+ }, onDialogShown: () {
+ print('dialog shown');
+ }, onEnter: () {
+ print('enter/return pressed');
+ }, onFocus: () {
+ print('editor focused');
+ }, onBlur: () {
+ print('editor unfocused');
+ }, onBlurCodeview: () {
+ print('codeview either focused or unfocused');
+ }, onInit: () {
+ print('init');
+ },
+ //this is commented because it overrides the default Summernote handlers
+ /*onImageLinkInsert: (String? url) {
+ print(url ?? "unknown url");
+ },
+ onImageUpload: (FileUpload file) async {
+ print(file.name);
+ print(file.size);
+ print(file.type);
+ print(file.base64);
+ },*/
+ onImageUploadError:
+ (FileUpload? file, String? base64Str, UploadError error) {
+ print((error.name));
+ print(base64Str ?? '');
+ if (file != null) {
+ print(file.name);
+ print(file.size);
+ print(file.type);
+ }
+ }, onKeyDown: (int? keyCode) {
+ print('$keyCode key downed');
+ print('current character count: ${controller.characterCount}');
+ }, onKeyUp: (int? keyCode) {
+ print('$keyCode key released');
+ }, onMouseDown: () {
+ print('mouse downed');
+ }, onMouseUp: () {
+ print('mouse released');
+ }, onNavigationRequestMobile: (String url) {
+ print(url);
+ return NavigationActionPolicy.ALLOW;
+ }, onPaste: () {
+ print('pasted into editor');
+ }, onScroll: () {
+ print('editor scrolled');
+ }),
+ plugins: [
+ SummernoteAtMention(
+ getSuggestionsMobile: (String value) {
+ var mentions = ['test1', 'test2', 'test3'];
+ return mentions
+ .where((element) => element.contains(value))
+ .toList();
+ },
+ mentionsWeb: ['test1', 'test2', 'test3'],
+ onSelect: (String value) {
+ print(value);
+ }),
+ ],
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return _htmlWidget();
+ }
+}
+
+const tableTex = r'''
+
+ \begin{array} { | l | l | l | }
+\hline \text { Year } & \begin{array} { l }
+\text { Number of U.S. } \\
+\text { farms (in } \\
+\text { millions) }
+\end{array} & \begin{array} { l }
+\text { Average size of } \\
+\text { U.S. farms } \\
+\text { (acres) }
+\end{array} \\
+\hline 1950 & 5.6 & 234 \\
+\hline 1960 & 4.0 & 330 \\
+\hline 1970 & 2.9 & 399 \\
+\hline 1980 & 2.4 & 441 \\
+\hline 1990 & 2.1 & 478 \\
+\hline 2000 & 2.2 & 439 \\
+\hline
+\end{array}
+ ''';
diff --git a/lib/src/widgets/html_editor_widget_mobile.dart b/lib/src/widgets/html_editor_widget_mobile.dart
index a2458ca8..f2c064a6 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)
@@ -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();
}
@@ -180,9 +181,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,13 +451,13 @@ 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) {
//todo fix for iOS (https://github.com/pichillilorenzo/flutter_inappwebview/issues/695)
var darkCSS =
- ' ';
+ ' ';
await controller.evaluateJavascript(
source: "\$('head').append('$darkCSS');");
}
@@ -526,9 +526,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..2bae694d 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_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';
/// The HTML Editor widget itself, for web (uses IFrameElement)
class HtmlEditorWidget extends StatefulWidget {
@@ -187,7 +186,7 @@ class _HtmlEditorWidgetWebState extends State {
widget.htmlEditorOptions.darkMode == true) &&
widget.htmlEditorOptions.darkMode != false) {
darkCSS =
- ' ';
+ ' ';
}
var jsCallbacks = '';
if (widget.callbacks != null) {
@@ -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"]);
@@ -447,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!;
}
@@ -457,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'
@@ -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/math_keyboard_dialog.dart b/lib/src/widgets/math_keyboard_dialog.dart
new file mode 100644
index 00000000..287a6339
--- /dev/null
+++ b/lib/src/widgets/math_keyboard_dialog.dart
@@ -0,0 +1,84 @@
+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 {
+ MathKeyboardDialog({required this.controller, this.mathField}) {
+ if (mathField != null && mathField!.controller != null) {
+ log('',
+ name: 'Warning',
+ error:
+ 'do not set the math field controller as it will get ignored\n');
+ }
+ }
+
+ final CustomMathFieldEditingController controller;
+ final MathField? mathField;
+
+ @override
+ Widget build(BuildContext context) {
+ return Dialog(
+ insetPadding: EdgeInsets.all(10),
+ child: Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ SizedBox(
+ width: MediaQuery.of(context).size.width,
+ height: 100,
+ child: MathField(
+ focusNode: mathField?.focusNode,
+ autofocus: mathField?.autofocus ?? true,
+ controller: controller,
+ keyboardType:
+ mathField?.keyboardType ?? MathKeyboardType.expression,
+ 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.cleaning_services_rounded,
+ color: Colors.grey,
+ ),
+ ),
+ ),
+ ),
+ onChanged: mathField?.onChanged ?? controller.setTexString,
+ onSubmitted: mathField?.onSubmitted,
+ opensKeyboard: mathField?.opensKeyboard ?? true,
+ ),
+ ),
+ const SizedBox(height: 15),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ TextButton(
+ onPressed: () {
+ Navigator.pop(context, '');
+ print(controller.texStringAsFun);
+ },
+ child: const Text('Close'),
+ ),
+ TextButton(
+ onPressed: () {
+ Navigator.pop(context, controller.texStringAsFun);
+ print(controller.texStringAsFun);
+ },
+ child: const Text('Save'),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/src/widgets/toolbar_widget.dart b/lib/src/widgets/toolbar_widget.dart
index 2e33f27f..3a188e15 100644
--- a/lib/src/widgets/toolbar_widget.dart
+++ b/lib/src/widgets/toolbar_widget.dart
@@ -1,3 +1,4 @@
+import 'dart:async';
import 'dart:convert';
import 'package:file_picker/file_picker.dart';
@@ -5,8 +6,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:numberpicker/numberpicker.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
@@ -1120,7 +1121,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,
@@ -1758,6 +1759,7 @@ class ToolbarWidgetState extends State {
t.picture ||
t.link ||
t.hr ||
+ t.fn ||
t.table)) {
toolbarChildren.add(ToggleButtons(
constraints: BoxConstraints.tightFor(
@@ -1872,7 +1874,7 @@ class ToolbarWidgetState extends State {
style: TextStyle(
color: Theme.of(context)
.textTheme
- .bodyText1
+ .bodyLarge
?.color)),
),
],
@@ -1986,7 +1988,7 @@ class ToolbarWidgetState extends State {
style: TextStyle(
color: Theme.of(context)
.textTheme
- .bodyText1
+ .bodyLarge
?.color)),
),
suffixIcon: result != null
@@ -2146,7 +2148,7 @@ class ToolbarWidgetState extends State {
style: TextStyle(
color: Theme.of(context)
.textTheme
- .bodyText1
+ .bodyLarge
?.color)),
),
suffixIcon: result != null
@@ -2298,7 +2300,7 @@ class ToolbarWidgetState extends State {
style: TextStyle(
color: Theme.of(context)
.textTheme
- .bodyText1
+ .bodyLarge
?.color)),
),
suffixIcon: result != null
@@ -2450,7 +2452,7 @@ class ToolbarWidgetState extends State {
style: TextStyle(
color: Theme.of(context)
.textTheme
- .bodyText1
+ .bodyLarge
?.color)),
),
suffixIcon: result != null
@@ -2600,6 +2602,14 @@ 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) {
+ await widget.controller.openMathDialog(context);
+ }
+ }
},
isSelected: List.filled(t.getIcons().length, false),
children: t.getIcons(),
@@ -2998,4 +3008,48 @@ class ToolbarWidgetState extends State {
}
return toolbarChildren;
}
+//
+// openMathDialog() async {
+// final c = CustomMathFieldEditingController();
+// if (!kIsWeb) {
+// widget.controller.clearFocus();
+// }
+// await showDialog(
+// context: context,
+// builder: (context) => MathKeyboardDialog(
+// controller: c,
+// mathField: widget.controller.mathField,
+// ));
+// if (!kIsWeb) {
+// widget.controller.setFocus();
+// }
+// var math = c.texString;
+// if (math != '') {
+// var texAsFun = c.texStringAsFun;
+// var result = await _latexToHtml(math.replaceAll('\\', '\\\\'));
+// result = '$result ';
+// _latexMap.addAll({
+// result: texAsFun,
+// });
+// widget.controller.addToHashMap(result, texAsFun);
+// widget.controller.insertHtml(result);
+// widget.controller.insertText(' ');
+// }
+// }
+//
+// Future _latexToHtml(String latex) async {
+// await _webController.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/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/custom_math_field_controller.dart b/lib/utils/custom_math_field_controller.dart
new file mode 100644
index 00000000..223d6cc0
--- /dev/null
+++ b/lib/utils/custom_math_field_controller.dart
@@ -0,0 +1,35 @@
+import 'package:flutter/material.dart';
+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\\)';
+
+ @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/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/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 91b491fd..2e71b2b5 100644
--- a/lib/utils/toolbar.dart
+++ b/lib/utils/toolbar.dart
@@ -1,3 +1,4 @@
+import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
/// Abstract class that all the toolbar classes extend
@@ -153,6 +154,7 @@ class InsertButtons extends Toolbar {
final bool otherFile;
final bool table;
final bool hr;
+ final bool fn;
const InsertButtons({
this.link = true,
@@ -162,6 +164,7 @@ class InsertButtons extends Toolbar {
this.otherFile = false,
this.table = true,
this.hr = true,
+ this.fn = true,
});
List getIcons() {
@@ -173,6 +176,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 && !kIsWeb) icons.add(Icon(Icons.functions));
return icons;
}
}
diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart
index 8d9c6c8d..43100f9f 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(
@@ -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;
@@ -949,7 +951,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 +1011,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 +1092,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,
),
));
diff --git a/pubspec.lock b/pubspec.lock
index 88f4be47..9e50104b 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -1,76 +1,102 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
+ args:
+ dependency: transitive
+ description:
+ name: args
+ sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.6.0"
async:
dependency: transitive
description:
name: async
- url: "https://pub.dartlang.org"
+ sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
+ url: "https://pub.dev"
source: hosted
- version: "2.9.0"
+ version: "2.11.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
- url: "https://pub.dartlang.org"
+ sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.0"
+ version: "2.1.1"
characters:
dependency: transitive
description:
name: characters
- url: "https://pub.dartlang.org"
+ sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
+ url: "https://pub.dev"
source: hosted
- version: "1.2.1"
+ version: "1.3.0"
clock:
dependency: transitive
description:
name: clock
- url: "https://pub.dartlang.org"
+ sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
+ url: "https://pub.dev"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
- url: "https://pub.dartlang.org"
+ sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.18.0"
+ cross_file:
+ dependency: transitive
+ description:
+ name: cross_file
+ sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670"
+ url: "https://pub.dev"
source: hosted
- version: "1.16.0"
+ version: "0.3.4+2"
fake_async:
dependency: transitive
description:
name: fake_async
- url: "https://pub.dartlang.org"
+ sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
+ url: "https://pub.dev"
source: hosted
version: "1.3.1"
ffi:
dependency: transitive
description:
name: ffi
- url: "https://pub.dartlang.org"
+ sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
+ url: "https://pub.dev"
source: hosted
- version: "2.0.1"
+ version: "2.1.3"
file_picker:
dependency: "direct main"
description:
name: file_picker
- url: "https://pub.dartlang.org"
+ sha256: "04a7b85852255759fd3010530cafac250eaa1f8202546670834d25057bb3251a"
+ url: "https://pub.dev"
source: hosted
- version: "5.2.5"
+ version: "8.0.0"
flex_color_picker:
dependency: "direct main"
description:
name: flex_color_picker
- url: "https://pub.dartlang.org"
+ sha256: "5c846437069fb7afdd7ade6bf37e628a71d2ab0787095ddcb1253bf9345d5f3a"
+ url: "https://pub.dev"
source: hosted
- version: "3.0.2"
+ version: "3.4.1"
flex_seed_scheme:
dependency: transitive
description:
name: flex_seed_scheme
- url: "https://pub.dartlang.org"
+ sha256: "4cee2f1d07259f77e8b36f4ec5f35499d19e74e17c7dce5b819554914082bc01"
+ url: "https://pub.dev"
source: hosted
- version: "1.1.0"
+ version: "1.5.0"
flutter:
dependency: "direct main"
description: flutter
@@ -80,58 +106,87 @@ packages:
dependency: "direct main"
description:
name: flutter_inappwebview
- url: "https://pub.dartlang.org"
+ 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
- url: "https://pub.dartlang.org"
+ sha256: "98664be7be0e3ffca00de50f7f6a287ab62c763fc8c762e0a21584584a3ff4f8"
+ url: "https://pub.dev"
source: hosted
- version: "5.4.0"
+ version: "6.0.0"
flutter_keyboard_visibility_linux:
dependency: transitive
description:
name: flutter_keyboard_visibility_linux
- url: "https://pub.dartlang.org"
+ sha256: "6fba7cd9bb033b6ddd8c2beb4c99ad02d728f1e6e6d9b9446667398b2ac39f08"
+ url: "https://pub.dev"
source: hosted
version: "1.0.0"
flutter_keyboard_visibility_macos:
dependency: transitive
description:
name: flutter_keyboard_visibility_macos
- url: "https://pub.dartlang.org"
+ sha256: c5c49b16fff453dfdafdc16f26bdd8fb8d55812a1d50b0ce25fc8d9f2e53d086
+ url: "https://pub.dev"
source: hosted
version: "1.0.0"
flutter_keyboard_visibility_platform_interface:
dependency: transitive
description:
name: flutter_keyboard_visibility_platform_interface
- url: "https://pub.dartlang.org"
+ sha256: e43a89845873f7be10cb3884345ceb9aebf00a659f479d1c8f4293fcb37022a4
+ url: "https://pub.dev"
source: hosted
version: "2.0.0"
flutter_keyboard_visibility_web:
dependency: transitive
description:
name: flutter_keyboard_visibility_web
- url: "https://pub.dartlang.org"
+ sha256: d3771a2e752880c79203f8d80658401d0c998e4183edca05a149f5098ce6e3d1
+ url: "https://pub.dev"
source: hosted
version: "2.0.0"
flutter_keyboard_visibility_windows:
dependency: transitive
description:
name: flutter_keyboard_visibility_windows
- url: "https://pub.dartlang.org"
+ sha256: fc4b0f0b6be9b93ae527f3d527fb56ee2d918cd88bbca438c478af7bcfd0ef73
+ url: "https://pub.dev"
source: hosted
version: "1.0.0"
+ flutter_localizations:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ flutter_math_fork:
+ dependency: transitive
+ description:
+ name: flutter_math_fork
+ sha256: "94bee4642892a94939af0748c6a7de0ff8318feee588379dcdfea7dc5cba06c8"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.7.2"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
- url: "https://pub.dartlang.org"
+ sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.17"
+ flutter_svg:
+ dependency: transitive
+ description:
+ name: flutter_svg
+ sha256: f991fdb1533c3caeee0cdc14b04f50f0c3916f0dbcbc05237ccbe4e3c6b93f3f
+ url: "https://pub.dev"
source: hosted
- version: "2.0.7"
+ version: "2.0.5"
flutter_test:
dependency: "direct dev"
description: flutter
@@ -142,76 +197,190 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
+ get:
+ dependency: "direct main"
+ description:
+ name: get
+ sha256: "2ba20a47c8f1f233bed775ba2dd0d3ac97b4cf32fc17731b3dfc672b06b0e92a"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.6.5"
+ holding_gesture:
+ dependency: transitive
+ description:
+ name: holding_gesture
+ sha256: "6d12a991c498357f9c8a532656facf97c47858be9a7249d5caaa84707aecc052"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.0"
infinite_listview:
dependency: transitive
description:
name: infinite_listview
- url: "https://pub.dartlang.org"
+ sha256: f6062c1720eb59be553dfa6b89813d3e8dd2f054538445aaa5edaddfa5195ce6
+ url: "https://pub.dev"
source: hosted
version: "1.1.0"
- js:
+ intl:
dependency: transitive
description:
- name: js
- url: "https://pub.dartlang.org"
+ name: intl
+ sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
+ url: "https://pub.dev"
source: hosted
- version: "0.6.4"
+ version: "0.18.1"
+ leak_tracker:
+ dependency: transitive
+ description:
+ name: leak_tracker
+ sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
+ url: "https://pub.dev"
+ source: hosted
+ version: "10.0.0"
+ leak_tracker_flutter_testing:
+ dependency: transitive
+ description:
+ name: leak_tracker_flutter_testing
+ sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
+ leak_tracker_testing:
+ dependency: transitive
+ description:
+ name: leak_tracker_testing
+ sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
matcher:
dependency: transitive
description:
name: matcher
- url: "https://pub.dartlang.org"
+ sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
+ url: "https://pub.dev"
source: hosted
- version: "0.12.12"
+ version: "0.12.16+1"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
- url: "https://pub.dartlang.org"
+ sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.8.0"
+ math_expressions:
+ dependency: transitive
+ description:
+ name: math_expressions
+ sha256: "3576593617c3870d75728a751f6ec6e606706d44e363f088ac394b5a28a98064"
+ url: "https://pub.dev"
source: hosted
- version: "0.1.5"
+ version: "2.4.0"
+ math_keyboard:
+ dependency: "direct main"
+ description:
+ name: math_keyboard
+ sha256: "7a7a644ce4313f31b74bc31c9d522dbdc08e5462dfa7beb4d0973cd4232e9ba3"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.2.0"
meta:
dependency: "direct main"
description:
name: meta
- url: "https://pub.dartlang.org"
+ sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
+ url: "https://pub.dev"
source: hosted
- version: "1.8.0"
+ version: "1.11.0"
+ nested:
+ dependency: transitive
+ description:
+ name: nested
+ sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.0"
numberpicker:
dependency: "direct main"
description:
name: numberpicker
- url: "https://pub.dartlang.org"
+ sha256: "4c129154944b0f6b133e693f8749c3f8bfb67c4d07ef9dcab48b595c22d1f156"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.1"
+ version: "2.1.2"
path:
dependency: transitive
description:
name: path
- url: "https://pub.dartlang.org"
+ sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
+ url: "https://pub.dev"
source: hosted
- version: "1.8.2"
- pedantic:
- dependency: "direct main"
+ version: "1.9.0"
+ path_parsing:
+ dependency: transitive
description:
- name: pedantic
- url: "https://pub.dartlang.org"
+ name: path_parsing
+ sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf
+ url: "https://pub.dev"
source: hosted
- version: "1.11.1"
+ version: "1.0.1"
+ petitparser:
+ dependency: transitive
+ description:
+ name: petitparser
+ sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.1.0"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
- url: "https://pub.dartlang.org"
+ sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.3"
+ version: "2.1.8"
pointer_interceptor:
dependency: "direct main"
description:
name: pointer_interceptor
- url: "https://pub.dartlang.org"
+ sha256: "57210410680379aea8b1b7ed6ae0c3ad349bfd56fe845b8ea934a53344b9d523"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.10.1+2"
+ pointer_interceptor_ios:
+ dependency: transitive
+ description:
+ name: pointer_interceptor_ios
+ sha256: a6906772b3205b42c44614fcea28f818b1e5fdad73a4ca742a7bd49818d9c917
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.10.1"
+ pointer_interceptor_platform_interface:
+ dependency: transitive
+ description:
+ name: pointer_interceptor_platform_interface
+ sha256: "0597b0560e14354baeb23f8375cd612e8bd4841bf8306ecb71fcd0bb78552506"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.10.0+1"
+ pointer_interceptor_web:
+ dependency: transitive
+ description:
+ name: pointer_interceptor_web
+ sha256: "7a7087782110f8c1827170660b09f8aa893e0e9a61431dbbe2ac3fc482e8c044"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.10.2+1"
+ provider:
+ dependency: transitive
+ description:
+ name: provider
+ sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096"
+ url: "https://pub.dev"
source: hosted
- version: "0.9.3+3"
+ version: "6.1.1"
sky_engine:
dependency: transitive
description: flutter
@@ -221,65 +390,162 @@ packages:
dependency: transitive
description:
name: source_span
- url: "https://pub.dartlang.org"
+ sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
+ url: "https://pub.dev"
source: hosted
- version: "1.9.0"
+ version: "1.10.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
- url: "https://pub.dartlang.org"
+ sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
+ url: "https://pub.dev"
source: hosted
- version: "1.10.0"
+ version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
- url: "https://pub.dartlang.org"
+ sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
+ url: "https://pub.dev"
source: hosted
- version: "2.1.0"
+ version: "2.1.2"
string_scanner:
dependency: transitive
description:
name: string_scanner
- url: "https://pub.dartlang.org"
+ sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
+ url: "https://pub.dev"
source: hosted
- version: "1.1.1"
+ version: "1.2.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
- url: "https://pub.dartlang.org"
+ sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
+ url: "https://pub.dev"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
- url: "https://pub.dartlang.org"
+ sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
+ url: "https://pub.dev"
source: hosted
- version: "0.4.12"
+ version: "0.6.1"
+ tuple:
+ dependency: transitive
+ description:
+ name: tuple
+ sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.2"
+ vector_graphics:
+ dependency: transitive
+ description:
+ name: vector_graphics
+ sha256: ea8d3fc7b2e0f35de38a7465063ecfcf03d8217f7962aa2a6717132cb5d43a79
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.5"
+ vector_graphics_codec:
+ dependency: transitive
+ description:
+ name: vector_graphics_codec
+ sha256: a5eaa5d19e123ad4f61c3718ca1ed921c4e6254238d9145f82aa214955d9aced
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.5"
+ vector_graphics_compiler:
+ dependency: transitive
+ description:
+ name: vector_graphics_compiler
+ sha256: "15edc42f7eaa478ce854eaf1fbb9062a899c0e4e56e775dd73b7f4709c97c4ca"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.5"
vector_math:
dependency: transitive
description:
name: vector_math
- url: "https://pub.dartlang.org"
+ sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.2"
+ version: "2.1.4"
visibility_detector:
dependency: "direct main"
description:
name: visibility_detector
- url: "https://pub.dartlang.org"
+ sha256: dd5cc11e13494f432d15939c3aa8ae76844c42b723398643ce9addb88a5ed420
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.4.0+2"
+ vm_service:
+ dependency: transitive
+ description:
+ name: vm_service
+ sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
+ url: "https://pub.dev"
source: hosted
- version: "0.3.3"
+ version: "13.0.0"
+ web:
+ dependency: transitive
+ description:
+ name: web
+ sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.5.1"
+ webview_flutter:
+ dependency: "direct main"
+ description:
+ name: webview_flutter
+ sha256: "42393b4492e629aa3a88618530a4a00de8bb46e50e7b3993fedbfdc5352f0dbf"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.4.2"
+ webview_flutter_android:
+ dependency: transitive
+ description:
+ name: webview_flutter_android
+ sha256: "8326ee235f87605a2bfc444a4abc897f4abc78d83f054ba7d3d1074ce82b4fbf"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.12.1"
+ webview_flutter_platform_interface:
+ dependency: transitive
+ description:
+ name: webview_flutter_platform_interface
+ sha256: "6d9213c65f1060116757a7c473247c60f3f7f332cac33dc417c9e362a9a13e4f"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.6.0"
+ webview_flutter_wkwebview:
+ dependency: transitive
+ description:
+ name: webview_flutter_wkwebview
+ sha256: accdaaa49a2aca2dc3c3230907988954cdd23fed0a19525d6c9789d380f4dc76
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.9.4"
win32:
dependency: transitive
description:
name: win32
- url: "https://pub.dartlang.org"
+ sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.5.0"
+ xml:
+ dependency: transitive
+ description:
+ name: xml
+ sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5"
+ url: "https://pub.dev"
source: hosted
- version: "3.1.3"
+ version: "6.2.2"
sdks:
- dart: ">=2.18.0 <3.0.0"
- flutter: ">=3.3.0"
+ dart: ">=3.3.0 <4.0.0"
+ flutter: ">=3.19.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index 82d4a1ad..e7433d91 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,37 +1,41 @@
-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: 4.0.0
homepage: https://github.com/tneotia/html-editor-enhanced
+repository: https://github.com/AhmadKhateebq/html-editor-enhanced-with-latex.git
environment:
- sdk: '>=2.12.0 <3.0.0'
+ sdk: '>=2.15.0 <4.0.0'
flutter: ">=3.0.0"
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
+ flutter_keyboard_visibility: ^6.0.0
# plugin to show a color picker for foreground/highlight color
- flex_color_picker: ^3.0.2
+ flex_color_picker: ^3.4.0
# plugin to get files from filesystem
- file_picker: ^5.2.0+1
+ file_picker: 8.0.0
# 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.1+2
# plugin to help maintain effective Dart standards
- pedantic: ^1.11.1
+
# plugin for @internal annotation
- meta: '>=1.0.0 <2.0.0'
+ meta: ^1.11.0
+ math_keyboard: 0.2.0
+ webview_flutter: ^4.0.0
+ get: ^4.0.0
dev_dependencies:
flutter_test:
@@ -44,15 +48,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