From da4f0efeafc605c567d55f95bd34326108f077b8 Mon Sep 17 00:00:00 2001 From: Cat <114286961+CatHood0@users.noreply.github.com> Date: Sun, 18 Aug 2024 20:15:11 -0400 Subject: [PATCH] Chore: Move spellchecker service to extensions (#2120) * Removed dependency from pubspec.yaml * Chore: moved simple_spell_checker_service to extensions * Chore: dart fixes and formatting * Fix: imports --------- Co-authored-by: CatHood0 --- .../lib/flutter_quill_extensions.dart | 23 ++++++++++++++ .../simple_spell_checker_service.dart | 31 ++++++++++++++----- flutter_quill_extensions/pubspec.yaml | 3 +- lib/flutter_quill.dart | 1 - .../default_spellchecker_service.dart | 23 ++++++++++---- .../spellchecker/spellchecker_service.dart | 15 +++++++-- .../spellchecker_service_provider.dart | 23 +++++++++----- lib/src/editor/widgets/text/text_line.dart | 4 +-- pubspec.yaml | 3 +- 9 files changed, 97 insertions(+), 29 deletions(-) rename lib/src/editor/spellchecker/simple_spellchecker_impl.dart => flutter_quill_extensions/lib/src/editor/spell_checker/simple_spell_checker_service.dart (55%) diff --git a/flutter_quill_extensions/lib/flutter_quill_extensions.dart b/flutter_quill_extensions/lib/flutter_quill_extensions.dart index 3817f97d..b5a703dd 100644 --- a/flutter_quill_extensions/lib/flutter_quill_extensions.dart +++ b/flutter_quill_extensions/lib/flutter_quill_extensions.dart @@ -1,9 +1,12 @@ library flutter_quill_extensions; +// ignore: implementation_imports +import 'package:flutter_quill/src/editor/spellchecker/spellchecker_service_provider.dart'; // ignore: implementation_imports import 'package:flutter_quill/src/editor_toolbar_controller_shared/clipboard/clipboard_service_provider.dart'; import 'package:meta/meta.dart' show immutable; +import 'src/editor/spell_checker/simple_spell_checker_service.dart'; import 'src/editor_toolbar_controller_shared/clipboard/super_clipboard_service.dart'; export 'src/common/extensions/controller_ext.dart'; @@ -13,6 +16,7 @@ export 'src/editor/image/image_embed_types.dart'; export 'src/editor/image/image_web_embed.dart'; export 'src/editor/image/models/image_configurations.dart'; export 'src/editor/image/models/image_web_configurations.dart'; +export 'src/editor/spell_checker/simple_spell_checker_service.dart'; export 'src/editor/table/table_cell_embed.dart'; export 'src/editor/table/table_embed.dart'; export 'src/editor/table/table_models.dart'; @@ -39,6 +43,25 @@ export 'src/toolbar/video/video_button.dart'; class FlutterQuillExtensions { const FlutterQuillExtensions._(); + /// override the default implementation of [SpellCheckerServiceProvider] + /// to allow a `flutter quill` support a better check spelling + /// + /// # !WARNING + /// To avoid memory leaks, ensure to use [dispose()] method to + /// close stream controllers that used by this custom implementation + /// when them no longer needed + /// + /// Example: + /// + ///```dart + ///// set partial true if you only need to close the controllers + ///SpellCheckerServiceProvider.dispose(onlyPartial: false); + ///``` + static void useSpellCheckerService(String language) { + SpellCheckerServiceProvider.setNewCheckerService( + SimpleSpellCheckerService(language: language)); + } + /// Override default implementation of [ClipboardServiceProvider.instance] /// to allow `flutter_quill` package to use `super_clipboard` plugin /// to support rich text features, gif and images. diff --git a/lib/src/editor/spellchecker/simple_spellchecker_impl.dart b/flutter_quill_extensions/lib/src/editor/spell_checker/simple_spell_checker_service.dart similarity index 55% rename from lib/src/editor/spellchecker/simple_spellchecker_impl.dart rename to flutter_quill_extensions/lib/src/editor/spell_checker/simple_spell_checker_service.dart index 117ec2be..fe36678b 100644 --- a/lib/src/editor/spellchecker/simple_spellchecker_impl.dart +++ b/flutter_quill_extensions/lib/src/editor/spell_checker/simple_spell_checker_service.dart @@ -1,13 +1,13 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_quill/flutter_quill.dart'; import 'package:simple_spell_checker/simple_spell_checker.dart'; -import 'spellchecker_service.dart'; - -/// SimpleSpellCheckerImpl is a simple spell checker for get +/// SimpleSpellChecker is a simple spell checker for get /// all words divide on different objects if them are wrong or not -class SimpleSpellCheckerImpl extends SpellcheckerService { - SimpleSpellCheckerImpl({required super.language}) +class SimpleSpellCheckerService + extends SpellCheckerService { + SimpleSpellCheckerService({required super.language}) : checker = SimpleSpellChecker( language: language, safeDictionaryLoad: true, @@ -19,7 +19,7 @@ class SimpleSpellCheckerImpl extends SpellcheckerService { final SimpleSpellChecker checker; @override - List? fetchSpellchecker( + List? checkSpelling( String text, { LongPressGestureRecognizer Function(String word)? customLongPressRecognizerOnWrongSpan, @@ -37,6 +37,23 @@ class SimpleSpellCheckerImpl extends SpellcheckerService { checker.disposeControllers(); return; } - checker.dispose(closeDirectionary: true); + checker.dispose(); + } + + @override + void addCustomLanguage({required languageIdentifier}) { + checker + ..registerLanguage(languageIdentifier.language) + ..addCustomLanguage(languageIdentifier); + } + + @override + void setNewLanguageState({required String language}) { + checker.setNewLanguageToState(language); + } + + @override + void updateCustomLanguageIfExist({required languageIdentifier}) { + checker.updateCustomLanguageIfExist(languageIdentifier); } } diff --git a/flutter_quill_extensions/pubspec.yaml b/flutter_quill_extensions/pubspec.yaml index 186ffcac..4ea6468f 100644 --- a/flutter_quill_extensions/pubspec.yaml +++ b/flutter_quill_extensions/pubspec.yaml @@ -35,12 +35,13 @@ dependencies: universal_html: ^2.2.4 cross_file: ^0.3.3+6 - flutter_quill: ^10.0.0 + flutter_quill: ^10.3.0 photo_view: ^0.15.0 youtube_explode_dart: ^2.2.1 # Plugins video_player: ^2.8.1 + simple_spell_checker: ^1.0.9 youtube_player_flutter: ^9.0.1 url_launcher: ^6.2.1 super_clipboard: ^0.8.15 diff --git a/lib/flutter_quill.dart b/lib/flutter_quill.dart index 349ca110..ded85364 100644 --- a/lib/flutter_quill.dart +++ b/lib/flutter_quill.dart @@ -24,7 +24,6 @@ export 'src/editor/raw_editor/config/raw_editor_configurations.dart'; export 'src/editor/raw_editor/quill_single_child_scroll_view.dart'; export 'src/editor/raw_editor/raw_editor.dart'; export 'src/editor/raw_editor/raw_editor_state.dart'; -export 'src/editor/spellchecker/simple_spellchecker_impl.dart'; export 'src/editor/spellchecker/spellchecker_service.dart'; export 'src/editor/spellchecker/spellchecker_service_provider.dart'; export 'src/editor/style_widgets/style_widgets.dart'; diff --git a/lib/src/editor/spellchecker/default_spellchecker_service.dart b/lib/src/editor/spellchecker/default_spellchecker_service.dart index 95e457d8..cfeb1a12 100644 --- a/lib/src/editor/spellchecker/default_spellchecker_service.dart +++ b/lib/src/editor/spellchecker/default_spellchecker_service.dart @@ -1,20 +1,31 @@ import 'package:flutter/gestures.dart' show LongPressGestureRecognizer; import 'package:flutter/material.dart' show TextSpan; -import 'spellchecker_service.dart' show SpellcheckerService; +import 'spellchecker_service.dart' show SpellCheckerService; /// A default implementation of the [SpellcheckerService] /// that always will return null since Spell checking /// is not a standard feature -class DefaultSpellcheckerService extends SpellcheckerService { - DefaultSpellcheckerService() : super(language: 'en'); +class DefaultSpellCheckerService extends SpellCheckerService { + DefaultSpellCheckerService() : super(language: 'en'); @override void dispose({bool onlyPartial = false}) {} @override - List? fetchSpellchecker(String text, - {LongPressGestureRecognizer Function(String p1)? - customLongPressRecognizerOnWrongSpan}) { + List? checkSpelling( + String text, { + LongPressGestureRecognizer Function(String p1)? + customLongPressRecognizerOnWrongSpan, + }) { return null; } + + @override + void addCustomLanguage({languageIdentifier}) {} + + @override + void setNewLanguageState({required String language}) {} + + @override + void updateCustomLanguageIfExist({languageIdentifier}) {} } diff --git a/lib/src/editor/spellchecker/spellchecker_service.dart b/lib/src/editor/spellchecker/spellchecker_service.dart index 495a28dd..b8331420 100644 --- a/lib/src/editor/spellchecker/spellchecker_service.dart +++ b/lib/src/editor/spellchecker/spellchecker_service.dart @@ -2,8 +2,8 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; /// A representation a custom SpellCheckService. -abstract class SpellcheckerService { - SpellcheckerService({required this.language}); +abstract class SpellCheckerService { + SpellCheckerService({required this.language}); final String language; @@ -15,10 +15,19 @@ abstract class SpellcheckerService { /// if [onlyPartial] is false dispose all resources void dispose({bool onlyPartial = false}); + /// set a new language state used for SpellcheckerService + void setNewLanguageState({required String language}); + + /// set a new language state used for SpellcheckerService + void updateCustomLanguageIfExist({required T languageIdentifier}); + + /// set a new custom language for SpellcheckerService + void addCustomLanguage({required T languageIdentifier}); + /// Facilitates a spell check request. /// /// Returns a [List] with all misspelled words divide from the right words. - List? fetchSpellchecker(String text, + List? checkSpelling(String text, {LongPressGestureRecognizer Function(String)? customLongPressRecognizerOnWrongSpan}); } diff --git a/lib/src/editor/spellchecker/spellchecker_service_provider.dart b/lib/src/editor/spellchecker/spellchecker_service_provider.dart index 2e4eb2f0..24a51ebf 100644 --- a/lib/src/editor/spellchecker/spellchecker_service_provider.dart +++ b/lib/src/editor/spellchecker/spellchecker_service_provider.dart @@ -3,17 +3,26 @@ import 'default_spellchecker_service.dart'; import 'spellchecker_service.dart'; @immutable -class SpellcheckerServiceProvider { - const SpellcheckerServiceProvider._(); - static SpellcheckerService _instance = DefaultSpellcheckerService(); +class SpellCheckerServiceProvider { + const SpellCheckerServiceProvider._(); + static SpellCheckerService _instance = DefaultSpellCheckerService(); - static SpellcheckerService get instance => _instance; + static SpellCheckerService get instance => _instance; - static void setInstance(SpellcheckerService service) { + static void setNewCheckerService(SpellCheckerService service) { _instance = service; } - static void setInstanceToDefault() { - _instance = DefaultSpellcheckerService(); + static void dispose({bool onlyPartial = false}) { + _instance.dispose(onlyPartial: onlyPartial); + } + + static void setNewLanguageState({required String language}) { + assert(language.isNotEmpty); + _instance.setNewLanguageState(language: language); + } + + static void turnOffService() { + _instance = DefaultSpellCheckerService(); } } diff --git a/lib/src/editor/widgets/text/text_line.dart b/lib/src/editor/widgets/text/text_line.dart index f1f30b2e..7c4f3c07 100644 --- a/lib/src/editor/widgets/text/text_line.dart +++ b/lib/src/editor/widgets/text/text_line.dart @@ -408,8 +408,8 @@ class _TextLineState extends State { !widget.readOnly && !widget.line.style.attributes.containsKey('code-block') && !kIsWeb) { - final service = SpellcheckerServiceProvider.instance; - final spellcheckedSpans = service.fetchSpellchecker(textNode.value); + final service = SpellCheckerServiceProvider.instance; + final spellcheckedSpans = service.checkSpelling(textNode.value); if (spellcheckedSpans != null && spellcheckedSpans.isNotEmpty) { return TextSpan( children: spellcheckedSpans, diff --git a/pubspec.yaml b/pubspec.yaml index 10dbd3ff..9ffcea8b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -45,7 +45,6 @@ dependencies: # Dart Packages intl: ^0.19.0 dart_quill_delta: ^10.0.0 - simple_spell_checker: ^1.0.6 collection: ^1.17.0 quiver: ^3.2.1 equatable: ^2.0.5 @@ -55,7 +54,7 @@ dependencies: flutter_colorpicker: ^1.1.0 # For converting HTML to Quill delta - flutter_quill_delta_from_html: ^1.3.13 + flutter_quill_delta_from_html: ^1.4.0 markdown: ^7.2.1 charcode: ^1.3.1