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';
import '$mainImport' as entrypoint;
Future<void> main() async {
registerPlugins(webPluginRegistry);
registerPlugins(webPluginRegistrar);
await ui.webOnlyInitializePlatform();
entrypoint.main();
}
......
......@@ -686,7 +686,7 @@ class _ResidentWebRunner extends ResidentWebRunner {
'typedef _NullaryFunction = dynamic Function();',
'Future<void> main() async {',
if (hasWebPlugins)
' registerPlugins(webPluginRegistry);',
' registerPlugins(webPluginRegistrar);',
' await ui.webOnlyInitializePlatform();',
' if (entrypoint.main is _UnaryFunction) {',
' return (entrypoint.main as _UnaryFunction)(<String>[]);',
......
......@@ -779,9 +779,6 @@ const String _dartPluginRegistryTemplate = '''
// Generated file. Do not edit.
//
// ignore: unused_import
import 'dart:ui';
{{#plugins}}
import 'package:{{name}}/{{file}}';
{{/plugins}}
......@@ -789,11 +786,11 @@ import 'package:{{name}}/{{file}}';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
// ignore: public_member_api_docs
void registerPlugins(PluginRegistry registry) {
void registerPlugins(Registrar registrar) {
{{#plugins}}
{{class}}.registerWith(registry.registrarFor({{class}}));
{{class}}.registerWith(registrar);
{{/plugins}}
registry.registerMessageHandler();
registrar.registerMessageHandler();
}
''';
......
......@@ -14,7 +14,7 @@ class {{pluginDartClass}}Web {
final MethodChannel channel = MethodChannel(
'{{projectName}}',
const StandardMethodCodec(),
registrar.messenger,
registrar,
);
final pluginInstance = {{pluginDartClass}}Web();
......
......@@ -83,7 +83,7 @@ void main() {
// Plugins
expect(generated, contains("import 'package:foo/generated_plugin_registrant.dart';"));
expect(generated, contains('registerPlugins(webPluginRegistry);'));
expect(generated, contains('registerPlugins(webPluginRegistrar);'));
// Main
expect(generated, contains('entrypoint.main();'));
......@@ -185,7 +185,7 @@ void main() {
// Plugins
expect(generated, contains("import 'package:foo/generated_plugin_registrant.dart';"));
expect(generated, contains('registerPlugins(webPluginRegistry);'));
expect(generated, contains('registerPlugins(webPluginRegistrar);'));
// Main
expect(generated, contains('entrypoint.main();'));
......@@ -208,7 +208,7 @@ void main() {
// Plugins
expect(generated, isNot(contains("import 'package:foo/generated_plugin_registrant.dart';")));
expect(generated, isNot(contains('registerPlugins(webPluginRegistry);')));
expect(generated, isNot(contains('registerPlugins(webPluginRegistrar);')));
// Main
expect(generated, contains('entrypoint.main();'));
}));
......@@ -253,7 +253,7 @@ void main() {
// Plugins
expect(generated, isNot(contains("import 'package:foo/generated_plugin_registrant.dart';")));
expect(generated, isNot(contains('registerPlugins(webPluginRegistry);')));
expect(generated, isNot(contains('registerPlugins(webPluginRegistrar);')));
// Main
expect(generated, contains('entrypoint.main();'));
......
......@@ -15,6 +15,8 @@
/// describing how the `url_launcher` package was created using [flutter_web_plugins].
library flutter_web_plugins;
export 'src/navigation/js_url_strategy.dart';
export 'src/navigation/url_strategy.dart';
export 'src/navigation/utils.dart';
export 'src/plugin_event_channel.dart';
export 'src/plugin_registry.dart';
......@@ -4,7 +4,6 @@
import 'dart:html';
// TODO(mdebbar): Use the `URI` class instead?
final AnchorElement _urlParsingNode = AnchorElement();
/// Extracts the pathname part of a full [url].
......
......@@ -8,34 +8,54 @@ import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
// TODO(hterkelsen): Why is this _MessageHandler duplicated here?
typedef _MessageHandler = Future<ByteData?>? Function(ByteData?);
/// This class registers web platform plugins.
/// A registrar for Flutter plugins implemented in Dart.
///
/// An instance of this class is available as [webPluginRegistry].
class PluginRegistry {
/// Creates a plugin registry.
///
/// The argument selects the [BinaryMessenger] to use. An
/// appropriate value would be [pluginBinaryMessenger].
PluginRegistry(this._binaryMessenger);
final BinaryMessenger _binaryMessenger;
/// Creates a registrar for the given plugin implementation class.
Registrar registrarFor(Type key) => Registrar(_binaryMessenger);
/// Registers this plugin handler with the engine, so that unrecognized
/// platform messages are forwarded to the registry, where they can be
/// correctly dispatched to one of the registered plugins.
/// Plugins for the web platform are implemented in Dart and are
/// registered with this class by code generated by the `flutter` tool
/// when compiling the application.
///
/// This class implements [BinaryMessenger] to route messages from the
/// framework to registered plugins.
///
/// Use this [BinaryMessenger] when creating platform channels in order for
/// them to receive messages from the platform side. For example:
///
/// ```dart
/// class MyPlugin {
/// static void registerWith(Registrar registrar) {
/// final MethodChannel channel = MethodChannel(
/// 'com.my_plugin/my_plugin',
/// 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
/// for the global [webPluginRegistry] at startup.
/// The argument is ignored. To create a test [Registrar] with custom behavior,
/// 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
/// method a second time silently unregisters the first [PluginRegistry]
/// and replaces it with the new one.
/// Only one handler can be registered at a time. Calling this
/// method a second time silently unregisters any
/// previously-registered handler and replaces it with the handler
/// from this object.
///
/// This method uses a function called `webOnlySetPluginHandler` in
/// the [dart:ui] library. That function is only available when
......@@ -43,58 +63,47 @@ class PluginRegistry {
void registerMessageHandler() {
// The function below is only defined in the Web dart:ui.
// ignore: undefined_function
ui.webOnlySetPluginHandler(_binaryMessenger.handlePlatformMessage);
ui.webOnlySetPluginHandler(handleFrameworkMessage);
}
}
/// A registrar for a particular plugin.
///
/// Gives access to a [BinaryMessenger] which has been configured to receive
/// platform messages from the framework side.
class Registrar {
/// Creates a registrar with the given [BinaryMessenger].
Registrar(this.messenger);
/// A [BinaryMessenger] configured to receive platform messages from the
/// framework side.
/// Receives a platform message from the framework.
///
/// This method has been replaced with the more clearly-named [handleFrameworkMessage].
@Deprecated(
'Use handleFrameworkMessage instead. '
'This feature was deprecated after v1.24.0-7.0.pre.'
)
@override
Future<void> handlePlatformMessage(
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
/// them to receive messages from the platform side. For example:
/// If a handler has been registered for the given `channel`, it is
/// 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
/// class MyPlugin {
/// 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);
/// }
/// // ...
/// }
/// ui.webOnlySetPluginHandler(webPluginRegistrar.handleFrameworkMessage);
/// ```
final BinaryMessenger messenger;
}
/// 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(
Future<void> handleFrameworkMessage(
String channel,
ByteData? data,
ui.PlatformMessageResponseCallback? callback,
......@@ -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.
@override
Future<ByteData?> send(String channel, ByteData? message) {
......@@ -167,8 +185,45 @@ class _PlatformBinaryMessenger extends BinaryMessenger {
}
}
/// The default [BinaryMessenger] for Flutter web plugins.
///
/// This is the value used for [webPluginRegistry]'s [PluginRegistry]
/// constructor argument.
final BinaryMessenger pluginBinaryMessenger = _PlatformBinaryMessenger();
/// This class was previously separate from [Registrar] but was merged into it
/// as part of a simplification of the web plugins API.
@Deprecated(
'Use Registrar instead. '
'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