blob: 981c8882f75da4bb37ea2798c017801475da3c59 [file] [log] [blame]
// Copyright 2013 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.
// @dart = 2.6
part of engine;
/// A surface containing a platform view, which is an HTML element.
class PersistedPlatformView extends PersistedLeafSurface {
final int viewId;
final double dx;
final double dy;
final double width;
final double height;
html.ShadowRoot _shadowRoot;
PersistedPlatformView(this.viewId, this.dx, this.dy, this.width, this.height);
@override
html.Element createElement() {
html.Element element = defaultCreateElement('flt-platform-view');
// Allow the platform view host element to receive pointer events.
//
// This is to allow platform view HTML elements to be interactive.
//
// ACCESSIBILITY NOTE: The way we enable accessibility on Flutter for web
// is to have a full-page button which waits for a double tap. Placing this
// full-page button in front of the scene would cause platform views not
// to receive pointer events. The tradeoff is that by placing the scene in
// front of the semantics placeholder will cause platform views to block
// pointer events from reaching the placeholder. This means that in order
// to enable accessibility, you must double tap the app *outside of a
// platform view*. As a consequence, a full-screen platform view will make
// it impossible to enable accessibility.
element.style.pointerEvents = 'auto';
// Enforce the effective size of the PlatformView.
element.style.overflow = 'hidden';
_shadowRoot = element.attachShadow(<String, String>{'mode': 'open'});
final html.StyleElement _styleReset = html.StyleElement();
_styleReset.innerHtml = '''
:host {
all: initial;
}''';
_shadowRoot.append(_styleReset);
final html.Element platformView =
platformViewRegistry.getCreatedView(viewId);
if (platformView != null) {
_shadowRoot.append(platformView);
} else {
html.window.console.warn('No platform view created for id $viewId');
}
return element;
}
@override
Matrix4 get localTransformInverse => null;
@override
void apply() {
rootElement.style
..transform = 'translate(${dx}px, ${dy}px)'
..width = '${width}px'
..height = '${height}px';
// Set size of the root element created by the PlatformView.
final html.Element platformView =
platformViewRegistry.getCreatedView(viewId);
if (platformView != null) {
platformView.style
..width = '${width}px'
..height = '${height}px';
}
}
@override
double matchForUpdate(PersistedPlatformView existingSurface) {
return existingSurface.viewId == viewId ? 0.0 : 1.0;
}
@override
void update(PersistedPlatformView oldSurface) {
super.update(oldSurface);
if (viewId != oldSurface.viewId) {
// The content of the surface has to be rebuild if the viewId is changed.
build();
} else if (dx != oldSurface.dx ||
dy != oldSurface.dy ||
width != oldSurface.width ||
height != oldSurface.height) {
// A change in any of the dimensions is performed by calling apply.
apply();
}
}
}