Unverified Commit bb29c88a authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Simplify the flutter_web_plugins plugin registration API. (#70337) (#70722)

In principle this is backwards compatible; I just merged all the classes into one and deprecated everything that became redundant as a result.
parent 2c3ba5b6
...@@ -135,7 +135,7 @@ import '$generatedImport'; ...@@ -135,7 +135,7 @@ import '$generatedImport';
import '$mainImport' as entrypoint; import '$mainImport' as entrypoint;
Future<void> main() async { Future<void> main() async {
registerPlugins(webPluginRegistry); registerPlugins(webPluginRegistrar);
await ui.webOnlyInitializePlatform(); await ui.webOnlyInitializePlatform();
entrypoint.main(); entrypoint.main();
} }
......
...@@ -686,7 +686,7 @@ class _ResidentWebRunner extends ResidentWebRunner { ...@@ -686,7 +686,7 @@ class _ResidentWebRunner extends ResidentWebRunner {
'typedef _NullaryFunction = dynamic Function();', 'typedef _NullaryFunction = dynamic Function();',
'Future<void> main() async {', 'Future<void> main() async {',
if (hasWebPlugins) if (hasWebPlugins)
' registerPlugins(webPluginRegistry);', ' registerPlugins(webPluginRegistrar);',
' await ui.webOnlyInitializePlatform();', ' await ui.webOnlyInitializePlatform();',
' if (entrypoint.main is _UnaryFunction) {', ' if (entrypoint.main is _UnaryFunction) {',
' return (entrypoint.main as _UnaryFunction)(<String>[]);', ' return (entrypoint.main as _UnaryFunction)(<String>[]);',
......
...@@ -779,9 +779,6 @@ const String _dartPluginRegistryTemplate = ''' ...@@ -779,9 +779,6 @@ const String _dartPluginRegistryTemplate = '''
// Generated file. Do not edit. // Generated file. Do not edit.
// //
// ignore: unused_import
import 'dart:ui';
{{#plugins}} {{#plugins}}
import 'package:{{name}}/{{file}}'; import 'package:{{name}}/{{file}}';
{{/plugins}} {{/plugins}}
...@@ -789,11 +786,11 @@ import 'package:{{name}}/{{file}}'; ...@@ -789,11 +786,11 @@ import 'package:{{name}}/{{file}}';
import 'package:flutter_web_plugins/flutter_web_plugins.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart';
// ignore: public_member_api_docs // ignore: public_member_api_docs
void registerPlugins(PluginRegistry registry) { void registerPlugins(Registrar registrar) {
{{#plugins}} {{#plugins}}
{{class}}.registerWith(registry.registrarFor({{class}})); {{class}}.registerWith(registrar);
{{/plugins}} {{/plugins}}
registry.registerMessageHandler(); registrar.registerMessageHandler();
} }
'''; ''';
......
...@@ -14,7 +14,7 @@ class {{pluginDartClass}}Web { ...@@ -14,7 +14,7 @@ class {{pluginDartClass}}Web {
final MethodChannel channel = MethodChannel( final MethodChannel channel = MethodChannel(
'{{projectName}}', '{{projectName}}',
const StandardMethodCodec(), const StandardMethodCodec(),
registrar.messenger, registrar,
); );
final pluginInstance = {{pluginDartClass}}Web(); final pluginInstance = {{pluginDartClass}}Web();
......
...@@ -83,7 +83,7 @@ void main() { ...@@ -83,7 +83,7 @@ void main() {
// Plugins // Plugins
expect(generated, contains("import 'package:foo/generated_plugin_registrant.dart';")); expect(generated, contains("import 'package:foo/generated_plugin_registrant.dart';"));
expect(generated, contains('registerPlugins(webPluginRegistry);')); expect(generated, contains('registerPlugins(webPluginRegistrar);'));
// Main // Main
expect(generated, contains('entrypoint.main();')); expect(generated, contains('entrypoint.main();'));
...@@ -185,7 +185,7 @@ void main() { ...@@ -185,7 +185,7 @@ void main() {
// Plugins // Plugins
expect(generated, contains("import 'package:foo/generated_plugin_registrant.dart';")); expect(generated, contains("import 'package:foo/generated_plugin_registrant.dart';"));
expect(generated, contains('registerPlugins(webPluginRegistry);')); expect(generated, contains('registerPlugins(webPluginRegistrar);'));
// Main // Main
expect(generated, contains('entrypoint.main();')); expect(generated, contains('entrypoint.main();'));
...@@ -208,7 +208,7 @@ void main() { ...@@ -208,7 +208,7 @@ void main() {
// Plugins // Plugins
expect(generated, isNot(contains("import 'package:foo/generated_plugin_registrant.dart';"))); expect(generated, isNot(contains("import 'package:foo/generated_plugin_registrant.dart';")));
expect(generated, isNot(contains('registerPlugins(webPluginRegistry);'))); expect(generated, isNot(contains('registerPlugins(webPluginRegistrar);')));
// Main // Main
expect(generated, contains('entrypoint.main();')); expect(generated, contains('entrypoint.main();'));
})); }));
...@@ -253,7 +253,7 @@ void main() { ...@@ -253,7 +253,7 @@ void main() {
// Plugins // Plugins
expect(generated, isNot(contains("import 'package:foo/generated_plugin_registrant.dart';"))); expect(generated, isNot(contains("import 'package:foo/generated_plugin_registrant.dart';")));
expect(generated, isNot(contains('registerPlugins(webPluginRegistry);'))); expect(generated, isNot(contains('registerPlugins(webPluginRegistrar);')));
// Main // Main
expect(generated, contains('entrypoint.main();')); expect(generated, contains('entrypoint.main();'));
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
/// describing how the `url_launcher` package was created using [flutter_web_plugins]. /// describing how the `url_launcher` package was created using [flutter_web_plugins].
library flutter_web_plugins; library flutter_web_plugins;
export 'src/navigation/js_url_strategy.dart';
export 'src/navigation/url_strategy.dart'; export 'src/navigation/url_strategy.dart';
export 'src/navigation/utils.dart';
export 'src/plugin_event_channel.dart'; export 'src/plugin_event_channel.dart';
export 'src/plugin_registry.dart'; export 'src/plugin_registry.dart';
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
import 'dart:html'; import 'dart:html';
// TODO(mdebbar): Use the `URI` class instead?
final AnchorElement _urlParsingNode = AnchorElement(); final AnchorElement _urlParsingNode = AnchorElement();
/// Extracts the pathname part of a full [url]. /// Extracts the pathname part of a full [url].
......
...@@ -8,34 +8,54 @@ import 'dart:ui' as ui; ...@@ -8,34 +8,54 @@ import 'dart:ui' as ui;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
// TODO(hterkelsen): Why is this _MessageHandler duplicated here? /// A registrar for Flutter plugins implemented in Dart.
typedef _MessageHandler = Future<ByteData?>? Function(ByteData?);
/// This class registers web platform plugins.
/// ///
/// An instance of this class is available as [webPluginRegistry]. /// Plugins for the web platform are implemented in Dart and are
class PluginRegistry { /// registered with this class by code generated by the `flutter` tool
/// Creates a plugin registry. /// when compiling the application.
/// ///
/// The argument selects the [BinaryMessenger] to use. An /// This class implements [BinaryMessenger] to route messages from the
/// appropriate value would be [pluginBinaryMessenger]. /// framework to registered plugins.
PluginRegistry(this._binaryMessenger); ///
/// Use this [BinaryMessenger] when creating platform channels in order for
final BinaryMessenger _binaryMessenger; /// them to receive messages from the platform side. For example:
///
/// Creates a registrar for the given plugin implementation class. /// ```dart
Registrar registrarFor(Type key) => Registrar(_binaryMessenger); /// class MyPlugin {
/// static void registerWith(Registrar registrar) {
/// Registers this plugin handler with the engine, so that unrecognized /// final MethodChannel channel = MethodChannel(
/// platform messages are forwarded to the registry, where they can be /// 'com.my_plugin/my_plugin',
/// correctly dispatched to one of the registered plugins. /// const StandardMethodCodec(),
/// registrar, // the registrar is used as the BinaryMessenger
/// );
/// final MyPlugin instance = MyPlugin();
/// channel.setMethodCallHandler(instance.handleMethodCall);
/// }
/// // ...
/// }
/// ```
class Registrar extends BinaryMessenger {
/// Creates a [Registrar].
/// ///
/// Code generated by the `flutter` tool automatically calls this method /// The argument is ignored. To create a test [Registrar] with custom behavior,
/// for the global [webPluginRegistry] at startup. /// subclass the [Registrar] class and override methods as appropriate.
Registrar([
@Deprecated(
'This argument is ignored. '
'This feature was deprecated after v1.24.0-7.0.pre.'
)
BinaryMessenger? binaryMessenger,
]);
/// Registers the registrar's message handler
/// ([handlePlatformMessage]) with the engine, so that plugin
/// messages are correctly dispatched to the relevant registered
/// plugin.
/// ///
/// Only one [PluginRegistry] can be registered at a time. Calling this /// Only one handler can be registered at a time. Calling this
/// method a second time silently unregisters the first [PluginRegistry] /// method a second time silently unregisters any
/// and replaces it with the new one. /// previously-registered handler and replaces it with the handler
/// from this object.
/// ///
/// This method uses a function called `webOnlySetPluginHandler` in /// This method uses a function called `webOnlySetPluginHandler` in
/// the [dart:ui] library. That function is only available when /// the [dart:ui] library. That function is only available when
...@@ -43,58 +63,47 @@ class PluginRegistry { ...@@ -43,58 +63,47 @@ class PluginRegistry {
void registerMessageHandler() { void registerMessageHandler() {
// The function below is only defined in the Web dart:ui. // The function below is only defined in the Web dart:ui.
// ignore: undefined_function // ignore: undefined_function
ui.webOnlySetPluginHandler(_binaryMessenger.handlePlatformMessage); ui.webOnlySetPluginHandler(handleFrameworkMessage);
} }
}
/// A registrar for a particular plugin. /// Receives a platform message from the framework.
/// ///
/// Gives access to a [BinaryMessenger] which has been configured to receive /// This method has been replaced with the more clearly-named [handleFrameworkMessage].
/// platform messages from the framework side. @Deprecated(
class Registrar { 'Use handleFrameworkMessage instead. '
/// Creates a registrar with the given [BinaryMessenger]. 'This feature was deprecated after v1.24.0-7.0.pre.'
Registrar(this.messenger); )
@override
/// A [BinaryMessenger] configured to receive platform messages from the Future<void> handlePlatformMessage(
/// framework side. String channel,
ByteData? data,
ui.PlatformMessageResponseCallback? callback,
) => handleFrameworkMessage(channel, data, callback);
/// Message handler for web plugins.
///
/// This method is called when handling messages from the framework.
/// ///
/// Use this [BinaryMessenger] when creating platform channels in order for /// If a handler has been registered for the given `channel`, it is
/// them to receive messages from the platform side. For example: /// invoked, and the value it returns is passed to `callback` (if that
/// is non-null). Then, the method's future is completed.
///
/// If no handler has been registered for that channel, then the
/// callback (if any) is invoked with null, then the method's future
/// is completed.
///
/// Messages are not buffered (unlike platform messages headed to
/// the framework, which are managed by [ChannelBuffers]).
///
/// This method is registered as the message handler by code
/// autogenerated by the `flutter` tool when the application is
/// compiled, if any web plugins are used. The code in question is
/// the following:
/// ///
/// ```dart /// ```dart
/// class MyPlugin { /// ui.webOnlySetPluginHandler(webPluginRegistrar.handleFrameworkMessage);
/// static void registerWith(Registrar registrar) {
/// final MethodChannel channel = MethodChannel(
/// 'com.my_plugin/my_plugin',
/// const StandardMethodCodec(),
/// registrar.messenger,
/// );
/// final MyPlugin instance = MyPlugin();
/// channel.setMethodCallHandler(instance.handleMethodCall);
/// }
/// // ...
/// }
/// ``` /// ```
final BinaryMessenger messenger; Future<void> handleFrameworkMessage(
}
/// The default plugin registry for the web.
///
/// Uses [pluginBinaryMessenger] as the [BinaryMessenger].
final PluginRegistry webPluginRegistry = PluginRegistry(pluginBinaryMessenger);
/// A [BinaryMessenger] which does the inverse of the default framework
/// messenger.
///
/// Instead of sending messages from the framework to the engine, this
/// receives messages from the framework and dispatches them to registered
/// plugins.
class _PlatformBinaryMessenger extends BinaryMessenger {
final Map<String, _MessageHandler> _handlers = <String, _MessageHandler>{};
/// Receives a platform message from the framework.
@override
Future<void> handlePlatformMessage(
String channel, String channel,
ByteData? data, ByteData? data,
ui.PlatformMessageResponseCallback? callback, ui.PlatformMessageResponseCallback? callback,
...@@ -119,6 +128,15 @@ class _PlatformBinaryMessenger extends BinaryMessenger { ...@@ -119,6 +128,15 @@ class _PlatformBinaryMessenger extends BinaryMessenger {
} }
} }
/// Returns `this`.
@Deprecated(
'This property is redundant. It returns the object on which it is called. '
'This feature was deprecated after v1.24.0-7.0.pre.'
)
BinaryMessenger get messenger => this;
final Map<String, MessageHandler> _handlers = <String, MessageHandler>{};
/// Sends a platform message from the platform side back to the framework. /// Sends a platform message from the platform side back to the framework.
@override @override
Future<ByteData?> send(String channel, ByteData? message) { Future<ByteData?> send(String channel, ByteData? message) {
...@@ -167,8 +185,45 @@ class _PlatformBinaryMessenger extends BinaryMessenger { ...@@ -167,8 +185,45 @@ class _PlatformBinaryMessenger extends BinaryMessenger {
} }
} }
/// The default [BinaryMessenger] for Flutter web plugins. /// This class was previously separate from [Registrar] but was merged into it
/// /// as part of a simplification of the web plugins API.
/// This is the value used for [webPluginRegistry]'s [PluginRegistry] @Deprecated(
/// constructor argument. 'Use Registrar instead. '
final BinaryMessenger pluginBinaryMessenger = _PlatformBinaryMessenger(); 'This feature was deprecated after v1.24.0-7.0.pre.'
)
class PluginRegistry extends Registrar {
/// Creates a [Registrar].
///
/// The argument is ignored.
PluginRegistry([
@Deprecated(
'This argument is ignored. '
'This feature was deprecated after v1.24.0-7.0.pre.'
)
BinaryMessenger? binaryMessenger,
]) : super(); // ignore: avoid_unused_constructor_parameters
/// Returns `this`. The argument is ignored.
@Deprecated(
'This method is redundant. It returns the object on which it is called. '
'This feature was deprecated after v1.24.0-7.0.pre.'
)
Registrar registrarFor(Type key) => this;
}
/// The default plugin registrar for the web.
final Registrar webPluginRegistrar = PluginRegistry();
/// A deprecated alias for [webPluginRegistrar].
@Deprecated(
'Use webPluginRegistrar instead. '
'This feature was deprecated after v1.24.0-7.0.pre.'
)
PluginRegistry get webPluginRegistry => webPluginRegistrar as PluginRegistry;
/// A deprecated alias for [webPluginRegistrar].
@Deprecated(
'Use webPluginRegistrar instead. '
'This feature was deprecated after v1.24.0-7.0.pre.'
)
BinaryMessenger get pluginBinaryMessenger => webPluginRegistrar;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment