blob: e2e86e811c5f1e800eb5f68887db12f91eff7f51 [file] [log] [blame]
// Copyright 2019 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;
import 'package:flutter/widgets.dart';
import 'shim/dart_ui.dart' as ui;
const String _viewType = '__webPointerInterceptorViewType__';
const String _debug = 'debug__';
// Computes a "view type" for different configurations of the widget.
String _getViewType({bool debug = false}) {
return debug ? _viewType + _debug : _viewType;
}
// Registers a viewFactory for this widget.
void _registerFactory({bool debug = false}) {
final String viewType = _getViewType(debug: debug);
ui.platformViewRegistry.registerViewFactory(viewType, (int viewId) {
final html.Element htmlElement = html.DivElement()
..style.top = '0'
..style.right = '0'
..style.bottom = '0'
..style.left = '0'
..style.position = 'relative';
if (debug) {
htmlElement.style.backgroundColor = 'rgba(255, 0, 0, .5)';
}
return htmlElement;
});
}
/// The web implementation of the `PointerInterceptor` widget.
///
/// A `Widget` that prevents clicks from being swallowed by [HtmlElementView]s.
class PointerInterceptor extends StatelessWidget {
/// Creates a PointerInterceptor for the web.
PointerInterceptor({
@required this.child,
this.debug = false,
Key key,
}) : super(key: key) {
if (!_registered) {
_register();
}
}
/// The `Widget` that is being wrapped by this `PointerInterceptor`.
final Widget child;
/// When true, the widget renders with a semi-transparent red background, for debug purposes.
///
/// This is useful when rendering this as a "layout" widget, like the root child
/// of a [Drawer].
final bool debug;
// Keeps track if this widget has already registered its view factories or not.
static bool _registered = false;
// Registers the view factories for the interceptor widgets.
static void _register() {
assert(!_registered);
_registerFactory();
_registerFactory(debug: true);
_registered = true;
}
@override
Widget build(BuildContext context) {
final String viewType = _getViewType(debug: debug);
return Stack(
alignment: Alignment.center,
children: <Widget>[
Positioned.fill(
child: HtmlElementView(
viewType: viewType,
),
),
child,
],
);
}
}