[flutter_tools] Add web support through MethodChannels. (#60116)

This commit is contained in:
David Iglesias 2020-06-23 13:53:01 -07:00 committed by GitHub
parent 30d97d89e0
commit 8fce4ce974
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 85 additions and 0 deletions

View file

@ -0,0 +1,45 @@
import 'dart:async';
// In order to *not* need this ignore, consider extracting the "web" version
// of your plugin as a separate package, instead of inlining it in the same
// package as the core of your plugin.
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html show window;
import 'package:flutter/services.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
/// A web implementation of the {{pluginDartClass}} plugin.
class {{pluginDartClass}}Web {
static void registerWith(Registrar registrar) {
final MethodChannel channel = MethodChannel(
'{{projectName}}',
const StandardMethodCodec(),
registrar.messenger,
);
final pluginInstance = {{pluginDartClass}}Web();
channel.setMethodCallHandler(pluginInstance.handleMethodCall);
}
/// Handles method calls over the MethodChannel of this plugin.
/// Note: Check the "federated" architecture for a new way of doing this:
/// https://flutter.dev/go/federated-plugins
Future<dynamic> handleMethodCall(MethodCall call) async {
switch (call.method) {
case 'getPlatformVersion':
return getPlatformVersion();
break;
default:
throw PlatformException(
code: 'Unimplemented',
details: '{{projectName}} for web doesn\'t implement \'${call.method}\'',
);
}
}
/// Returns a [String] containing the version of the platform.
Future<String> getPlatformVersion() {
final version = html.window.navigator.userAgent;
return Future.value(version);
}
}

View file

@ -11,6 +11,10 @@ environment:
dependencies:
flutter:
sdk: flutter
{{#web}}
flutter_web_plugins:
sdk: flutter
{{/web}}
dev_dependencies:
flutter_test:
@ -40,6 +44,11 @@ flutter:
macos:
pluginClass: {{pluginClass}}
{{/macos}}
{{#web}}
web:
pluginClass: {{pluginDartClass}}Web
fileName: {{projectName}}_web.dart
{{/web}}
# To add assets to your plugin package, add an assets section, like this:
# assets:

View file

@ -391,6 +391,9 @@ void main() {
'ios/Classes/FlutterProjectPlugin.m',
'lib/flutter_project.dart',
],
unexpectedPaths: <String>[
'lib/flutter_project_web.dart',
],
);
return _runFlutterTest(projectDir.childDirectory('example'));
}, overrides: <Type, Generator>{
@ -404,6 +407,34 @@ void main() {
),
});
testUsingContext('plugin project supports web', () async {
await _createAndAnalyzeProject(
projectDir,
<String>['--template=plugin'],
<String>[
'lib/flutter_project.dart',
'lib/flutter_project_web.dart',
],
);
final String rawPubspec = await projectDir.childFile('pubspec.yaml').readAsString();
final Pubspec pubspec = Pubspec.parse(rawPubspec);
// Expect the dependency on flutter_web_plugins exists
expect(pubspec.dependencies, contains('flutter_web_plugins'));
// The platform is correctly registered
expect(pubspec.flutter['plugin']['platforms']['web']['pluginClass'], 'FlutterProjectWeb');
expect(pubspec.flutter['plugin']['platforms']['web']['fileName'], 'flutter_project_web.dart');
}, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
Pub: () => Pub(
fileSystem: globals.fs,
logger: globals.logger,
processManager: globals.processManager,
usage: globals.flutterUsage,
botDetector: globals.botDetector,
platform: globals.platform,
),
});
testUsingContext('plugin example app depends on plugin', () async {
await _createProject(
projectDir,