Skip to content

Commit

Permalink
Roll web sdk (flutter#9146)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonahwilliams authored May 30, 2019
1 parent 9ca7edc commit e07fc69
Show file tree
Hide file tree
Showing 56 changed files with 4,458 additions and 3,973 deletions.
16 changes: 14 additions & 2 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ FILE: ../../../flutter/lib/stub_ui/lib/src/engine/alarm_clock.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/assets.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/bitmap_canvas.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/browser_detection.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/browser_location.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/compositor/engine_delegate.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/compositor/layer.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/compositor/layer_scene_builder.dart
Expand All @@ -253,6 +254,7 @@ FILE: ../../../flutter/lib/stub_ui/lib/src/engine/path_to_svg.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/pointer_binding.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/recording_canvas.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/semantics/checkable.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/semantics/image.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/semantics/incrementable.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/semantics/label_and_value.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/semantics/scrollable.dart
Expand All @@ -262,7 +264,17 @@ FILE: ../../../flutter/lib/stub_ui/lib/src/engine/semantics/text_field.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/services/message_codec.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/services/message_codecs.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/shadow.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/surface/clip.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/surface/debug_canvas_reuse_overlay.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/surface/offset.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/surface/opacity.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/surface/picture.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/surface/scene.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/surface/surface.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/surface/transform.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/test_embedding.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/text/font_collection.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/text/line_breaker.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/text/measurement.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/text/ruler.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/text/unicode_range.dart
Expand All @@ -272,10 +284,9 @@ FILE: ../../../flutter/lib/stub_ui/lib/src/engine/text_editing.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/util.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/validators.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/vector_math.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/ui/browser_location.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/engine/window.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/ui/canvas.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/ui/compositing.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/ui/debug_canvas_reuse_overlay.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/ui/geometry.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/ui/hash_codes.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/ui/initialization.dart
Expand All @@ -284,6 +295,7 @@ FILE: ../../../flutter/lib/stub_ui/lib/src/ui/natives.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/ui/painting.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/ui/pointer.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/ui/semantics.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/ui/test_embedding.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/ui/text.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/ui/tile_mode.dart
FILE: ../../../flutter/lib/stub_ui/lib/src/ui/window.dart
Expand Down
17 changes: 17 additions & 0 deletions lib/stub_ui/lib/src/engine.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ part 'engine/alarm_clock.dart';
part 'engine/assets.dart';
part 'engine/bitmap_canvas.dart';
part 'engine/browser_detection.dart';
part 'engine/browser_location.dart';
part 'engine/compositor/engine_delegate.dart';
part 'engine/compositor/layer.dart';
part 'engine/compositor/layer_scene_builder.dart';
Expand All @@ -45,6 +46,7 @@ part 'engine/path_to_svg.dart';
part 'engine/pointer_binding.dart';
part 'engine/recording_canvas.dart';
part 'engine/semantics/checkable.dart';
part 'engine/semantics/image.dart';
part 'engine/semantics/incrementable.dart';
part 'engine/semantics/label_and_value.dart';
part 'engine/semantics/scrollable.dart';
Expand All @@ -54,7 +56,17 @@ part 'engine/semantics/text_field.dart';
part 'engine/services/message_codec.dart';
part 'engine/services/message_codecs.dart';
part 'engine/shadow.dart';
part 'engine/surface/clip.dart';
part 'engine/surface/debug_canvas_reuse_overlay.dart';
part 'engine/surface/offset.dart';
part 'engine/surface/opacity.dart';
part 'engine/surface/picture.dart';
part 'engine/surface/scene.dart';
part 'engine/surface/surface.dart';
part 'engine/surface/transform.dart';
part 'engine/test_embedding.dart';
part 'engine/text/font_collection.dart';
part 'engine/text/line_breaker.dart';
part 'engine/text/measurement.dart';
part 'engine/text/ruler.dart';
part 'engine/text/unicode_range.dart';
Expand All @@ -64,6 +76,7 @@ part 'engine/text_editing.dart';
part 'engine/util.dart';
part 'engine/validators.dart';
part 'engine/vector_math.dart';
part 'engine/window.dart';

bool _engineInitialized = false;

Expand Down Expand Up @@ -141,3 +154,7 @@ void webOnlyInitializeEngine() {

Keyboard.initialize();
}

class _NullTreeSanitizer implements html.NodeTreeSanitizer {
void sanitizeTree(html.Node node) {}
}
32 changes: 32 additions & 0 deletions lib/stub_ui/lib/src/engine/assets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,35 @@ class AssetManagerException implements Exception {
@override
String toString() => 'Failed to load asset at "$url" ($httpStatus)';
}

/// An asset manager that gives fake empty responses for assets.
class WebOnlyMockAssetManager implements AssetManager {
String defaultAssetsDir = '';
String defaultAssetManifest = '{}';
String defaultFontManifest = '[]';

@override
String get assetsDir => defaultAssetsDir;

@override
String getAssetUrl(String asset) => '$asset';

@override
Future<ByteData> load(String asset) {
if (asset == getAssetUrl('AssetManifest.json')) {
return Future.value(_toByteData(utf8.encode(defaultAssetManifest)));
}
if (asset == getAssetUrl('FontManifest.json')) {
return Future.value(_toByteData(utf8.encode(defaultFontManifest)));
}
throw new AssetManagerException(asset, 404);
}

ByteData _toByteData(List<int> bytes) {
final byteData = ByteData(bytes.length);
for (var i = 0; i < bytes.length; i++) {
byteData.setUint8(i, bytes[i]);
}
return byteData;
}
}
79 changes: 9 additions & 70 deletions lib/stub_ui/lib/src/engine/bitmap_canvas.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ class BitmapCanvas extends EngineCanvas with SaveStackTracking {
// Cached current filter, fill and stroke style to reduce updates to
// CanvasRenderingContext2D that are slow even when resetting to null.
String _prevFilter = 'none';
Object _prevFillStyle = null;
Object _prevStrokeStyle = null;
Object _prevFillStyle;
Object _prevStrokeStyle;

/// Allocates a canvas with enough memory to paint a picture within the given
/// [bounds].
Expand Down Expand Up @@ -277,7 +277,7 @@ class BitmapCanvas extends EngineCanvas with SaveStackTracking {
return _saveCount++;
}

void saveLayer(ui.Rect bounds, _) {
void saveLayer(ui.Rect bounds, ui.Paint paint) {
save();
}

Expand Down Expand Up @@ -774,44 +774,8 @@ class BitmapCanvas extends EngineCanvas with SaveStackTracking {
return;
}

// This will cause a new canvas to be created for the next painting
// operation. This ensures that shapes that appear on top of text are
// rendered correctly.
// TODO(yjbanov): as our sample apps show it is a very common case for text
// drawing operations to interleave non-text operations,
// which generates a lot of HTML canvases for a single
// Flutter Picture. This kills performance. We need a smarter
// strategy, such as deducing painting bounds from paint ops
// and/or sinking non-intersecting graphics down the canvas
// chain.
// _canvas = null;

html.Element paragraphElement =
paragraph.webOnlyGetParagraphElement().clone(true);

final html.CssStyleDeclaration paragraphStyle = paragraphElement.style;
paragraphStyle
..position = 'absolute'
..whiteSpace = 'pre-wrap'
..width = '${paragraph.width}px';

// TODO(flutter_web): Implement the ellipsis overflow for multi-line text
// too. As a pre-requisite, we need to be able to programmatically find
// line breaks.
if (style.ellipsis != null &&
(style.maxLines == null || style.maxLines == 1)) {
paragraphStyle
..height = '${paragraph.webOnlyMaxLinesHeight}px'
..whiteSpace = 'pre'
..overflow = 'hidden'
..textOverflow = 'ellipsis';
} else if (paragraph.didExceedMaxLines) {
paragraphStyle
..height = '${paragraph.webOnlyMaxLinesHeight}px'
..overflowY = 'hidden';
} else {
paragraphStyle.height = '${paragraph.height}px';
}
final html.Element paragraphElement =
_drawParagraphElement(paragraph, offset);

if (isClipped) {
List<html.Element> clipElements =
Expand All @@ -823,7 +787,7 @@ class BitmapCanvas extends EngineCanvas with SaveStackTracking {
} else {
String cssTransform =
matrix4ToCssTransform(transformWithOffset(currentTransform, offset));
paragraphStyle.transform = cssTransform;
paragraphElement.style.transform = cssTransform;
rootElement.append(paragraphElement);
}
_children.add(paragraphElement);
Expand Down Expand Up @@ -1036,9 +1000,9 @@ List<html.Element> _clipContent(List<_SaveClipEntry> clipStack,
html.Element clipElement =
html.Element.html(svgClipPath, treeSanitizer: _NullTreeSanitizer());
domRenderer.setElementStyle(
curElement, 'clip-path', 'url(#svgClipText${_clipTextCounter})');
domRenderer.setElementStyle(curElement, '-webkit-clip-path',
'url(#svgClipText${_clipTextCounter})');
curElement, 'clip-path', 'url(#svgClip${_clipIdCounter})');
domRenderer.setElementStyle(
curElement, '-webkit-clip-path', 'url(#svgClip${_clipIdCounter})');
clipDefs.add(clipElement);
}
// Reverse the transform of the clipping element so children can use
Expand Down Expand Up @@ -1066,28 +1030,3 @@ String _cssTransformAtOffset(
return matrix4ToCssTransform(
transformWithOffset(transform, ui.Offset(offsetX, offsetY)));
}

class _NullTreeSanitizer implements html.NodeTreeSanitizer {
void sanitizeTree(html.Node node) {}
}

int _clipTextCounter = 0;

/// Converts Path to svg element that contains a clip-path definition.
/// TODO(flutter_web): unify with version used in compositing.dart.
String _pathToSvgClipPath(ui.Path path,
{double offsetX = 0, double offsetY = 0}) {
ui.Rect bounds = path.getBounds();
StringBuffer sb = new StringBuffer();
sb.write('<svg width="${bounds.right}" height="${bounds.bottom}" '
'style="position:absolute">');
sb.write('<defs>');

String clipId = 'svgClipText${++_clipTextCounter}';
sb.write('<clipPath id=${clipId}>');

sb.write('<path fill="#FFFFFF" d="');
pathToSvg(path, sb, offsetX: offsetX, offsetY: offsetY);
sb.write('"></path></clipPath></defs></svg');
return sb.toString();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

part of ui;
part of engine;

// TODO(mdebbar): add other strategies.

Expand Down Expand Up @@ -37,14 +37,14 @@ abstract class LocationStrategy {

/// Subscribes to popstate events and returns a function that could be used to
/// unsubscribe from popstate events.
VoidCallback onPopState(html.EventListener fn);
ui.VoidCallback onPopState(html.EventListener fn);

/// The active path in the browser history.
String get path;

/// Given a path that's [internal] to the app, create the external url that
/// Given a path that's internal to the app, create the external url that
/// will be used in the browser.
String prepareExternalUrl(String internal);
String prepareExternalUrl(String internalUrl);

/// Push a new history entry.
void pushState(dynamic state, String title, String url);
Expand Down Expand Up @@ -79,7 +79,7 @@ class HashLocationStrategy extends LocationStrategy {
[this._platformLocation = const BrowserPlatformLocation()]);

@override
VoidCallback onPopState(html.EventListener fn) {
ui.VoidCallback onPopState(html.EventListener fn) {
_platformLocation.onPopState(fn);
return () => _platformLocation.offPopState(fn);
}
Expand All @@ -98,14 +98,14 @@ class HashLocationStrategy extends LocationStrategy {
}

@override
String prepareExternalUrl(String url) {
String prepareExternalUrl(String internalUrl) {
// It's convention that if the hash path is empty, we omit the `#`; however,
// if the empty URL is pushed it won't replace any existing fragment. So
// when the hash path is empty, we instead return the location's path and
// query.
return url.isEmpty
return internalUrl.isEmpty
? '${_platformLocation.pathname}${_platformLocation.search}'
: '#$url';
: '#$internalUrl';
}

@override
Expand All @@ -127,8 +127,8 @@ class HashLocationStrategy extends LocationStrategy {
/// Waits until the next popstate event is fired. This is useful for example
/// to wait until the browser has handled the `history.back` transition.
Future<void> _waitForPopState() {
Completer<void> completer = Completer<void>();
VoidCallback unsubscribe;
final Completer<void> completer = Completer<void>();
ui.VoidCallback unsubscribe;
unsubscribe = onPopState((_) {
unsubscribe();
completer.complete();
Expand Down
8 changes: 4 additions & 4 deletions lib/stub_ui/lib/src/engine/compositor/layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,8 @@ class TransformLayer extends ContainerLayer {

@override
void preroll(PrerollContext context, Matrix4 matrix) {
final childMatrix = matrix * _transform;
final childPaintBounds = prerollChildren(context, childMatrix);
final Matrix4 childMatrix = matrix * _transform;
final ui.Rect childPaintBounds = prerollChildren(context, childMatrix);
paintBounds = _transformRect(_transform, childPaintBounds);
}

Expand Down Expand Up @@ -251,11 +251,11 @@ class PictureLayer extends Layer {

@override
void preroll(PrerollContext context, Matrix4 matrix) {
final cache = context.rasterCache;
final RasterCache cache = context.rasterCache;
if (cache != null) {
final translateMatrix = Matrix4.identity()
..setTranslationRaw(offset.dx, offset.dy, 0);
final cacheMatrix = translateMatrix * matrix;
final Matrix4 cacheMatrix = translateMatrix * matrix;
cache.prepare(picture, cacheMatrix, isComplex, willChange);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ class LayerSceneBuilder implements ui.SceneBuilder {
}

@override
void addPerformanceOverlay(int enabledOptions, ui.Rect bounds) {
void addPerformanceOverlay(int enabledOptions, ui.Rect bounds,
{Object webOnlyPaintedBy}) {
// We don't plan to implement this on the web.
throw UnimplementedError();
}
Expand Down
Loading

0 comments on commit e07fc69

Please sign in to comment.