Skip to content

Commit

Permalink
Merge pull request #916 from openkraken/fix/resize-style-fail
Browse files Browse the repository at this point in the history
fix: style fail after resize
  • Loading branch information
answershuto committed Dec 9, 2021
2 parents e28f68a + c97b5a9 commit ab8e2d4
Show file tree
Hide file tree
Showing 13 changed files with 146 additions and 135 deletions.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions integration_tests/specs/css/css-flexbox/align-items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1130,6 +1130,46 @@ describe('align-items', () => {
await snapshot();
});

it('does not work with stretch when align-self of flex item changed from auto to flex-start', async (done) => {
let flexbox;
let flexitem;

flexbox = createElement(
'div',
{
style: {
display: 'flex',
'background-color': '#aaa',
position: 'relative',
flexDirection: 'column',
width: '200px',
height: '120px',
'box-sizing': 'border-box',
},
},
[
(flexitem = createElement('div', {
style: {
'height': '50px',
'background-color': 'lightblue',
'box-sizing': 'border-box',
// 'align-self': 'flex-start',
},
})),
]
);

BODY.appendChild(flexbox);

await snapshot();

requestAnimationFrame(async () => {
flexitem.style.alignSelf = 'flex-start';
await snapshot();
done();
});
});

it('should works with img with no size set', async () => {
const container = createElement(
'div',
Expand Down
29 changes: 29 additions & 0 deletions integration_tests/specs/dom/elements/img.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,35 @@ describe('Tags img', () => {
img.src = imageURL;
});

it('width property change should work when width of style is not set', async (done) => {
let img = createElement('img', {
src: 'assets/300x150-green.png',
width: 100,
height: 100,
});
BODY.appendChild(img);

requestAnimationFrame(async () => {
img.width = 200;
await snapshot(0.1);
done();
});
});

it('width property should not work when width of style is auto', async () => {
let img = createElement('img', {
src: 'assets/300x150-green.png',
width: 100,
height: 100,
style: {
width: 'auto'
}
});
BODY.appendChild(img);

await snapshot(0.1);
});

it('can get natualSize from repeat image url', async (done) => {
const flutterContainer = document.createElement('div');
flutterContainer.style.height = '100vh';
Expand Down
1 change: 1 addition & 0 deletions kraken/lib/rendering.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ export 'src/rendering/opacity.dart';
export 'src/rendering/transform.dart';
export 'src/rendering/viewport.dart';
export 'src/rendering/paragraph.dart';
export 'src/rendering/image.dart';
6 changes: 4 additions & 2 deletions kraken/lib/src/css/display.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,12 @@ mixin CSSDisplayMixin on RenderStyle {
parentRenderStyle.flexDirection == FlexDirection.columnReverse;
// Flex item will not stretch in stretch alignment when flex wrap is set to wrap or wrap-reverse
bool isFlexNoWrap = parentRenderStyle.flexWrap == FlexWrap.nowrap;
bool isAlignItemsStretch = parentRenderStyle.effectiveAlignItems == AlignItems.stretch;
bool isStretchSelf = alignSelf != AlignSelf.auto
? alignSelf == AlignSelf.stretch
: parentRenderStyle.effectiveAlignItems == AlignItems.stretch;

// Display as block if flex vertical layout children and stretch children
if (!marginLeft.isAuto && !marginRight.isAuto && isVerticalDirection && isFlexNoWrap && isAlignItemsStretch) {
if (!marginLeft.isAuto && !marginRight.isAuto && isVerticalDirection && isFlexNoWrap && isStretchSelf) {
transformedDisplay = CSSDisplay.block;
}
}
Expand Down
6 changes: 0 additions & 6 deletions kraken/lib/src/dom/elements/body.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@ class BodyElement extends Element {
BodyElement(int targetId, Pointer<NativeEventTarget> nativePtr, ElementManager elementManager)
: super( targetId, nativePtr, elementManager, defaultStyle: _defaultStyle);

@override
void willAttachRenderer() {
super.willAttachRenderer();
renderBoxModel!.renderStyle.width = CSSLengthValue(elementManager.viewportWidth, CSSLengthType.PX);
}

@override
void addEvent(String eventType) {
// Scroll event not working on body.
Expand Down
105 changes: 43 additions & 62 deletions kraken/lib/src/dom/elements/img.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import 'package:kraken/painting.dart';
import 'package:kraken/rendering.dart';

const String IMAGE = 'IMG';
const String NATURAL_WIDTH = 'naturalWidth';
const String NATURAL_HEIGHT = 'naturalHeight';

// FIXME: should be inline default.
const Map<String, dynamic> _defaultStyle = {
Expand All @@ -25,7 +27,7 @@ const Map<String, dynamic> _defaultStyle = {
// The HTMLImageElement.
class ImageElement extends Element {
// The render box to draw image.
RenderImage? _renderImage;
KrakenRenderImage? _renderImage;

ImageProvider? _cachedImageProvider;
dynamic _imageProviderKey;
Expand All @@ -34,9 +36,14 @@ class ImageElement extends Element {
ImageInfo? _cachedImageInfo;
Uri? _resolvedUri;

// Width and height set through property.
double? _propertyWidth;
double? _propertyHeight;

// Width and height set through style.
double? _styleWidth;
double? _styleHeight;

ui.Image? get image => _cachedImageInfo?.image;

/// Number of image frame, used to identify multi frame image after loaded.
Expand Down Expand Up @@ -133,29 +140,33 @@ class ImageElement extends Element {
}

double get width {
if (_renderImage != null && _renderImage!.width != null) {
return _renderImage!.width!;
}
double? width = _styleWidth ?? _propertyWidth;

if (width == null) {
width = naturalWidth;
double? height = _styleHeight ?? _propertyHeight;

if (renderBoxModel != null && renderBoxModel!.hasSize) {
return renderBoxModel!.clientWidth;
if (height != null && naturalHeight != 0) {
width = height * naturalWidth / naturalHeight;
}
}

// Fallback to natural width, if image is not on screen.
return naturalWidth;
return width;
}

double get height {
if (_renderImage != null && _renderImage!.height != null) {
return _renderImage!.height!;
}
double? height = _styleHeight ?? _propertyHeight;

if (renderBoxModel != null && renderBoxModel!.hasSize) {
return renderBoxModel!.clientHeight;
if (height == null) {
height = naturalHeight;
double? width = _styleWidth ?? _propertyWidth;

if (width != null && naturalWidth != 0) {
height = width * naturalHeight / naturalWidth;
}
}

// Fallback to natural height, if image is not on screen.
return naturalHeight;
return height;
}

double get naturalWidth {
Expand Down Expand Up @@ -223,38 +234,15 @@ class ImageElement extends Element {
void _resizeImage() {
assert(isRendererAttached);

double? width = renderStyle.width.isAuto ? _propertyWidth : renderStyle.width.computedValue;
double? height = renderStyle.height.isAuto ? _propertyHeight : renderStyle.height.computedValue;

if (renderStyle.width.isAuto && _propertyWidth != null) {
if (_styleWidth == null && _propertyWidth != null) {
// The intrinsic width of the image in pixels. Must be an integer without a unit.
renderStyle.width = CSSLengthValue(_propertyWidth, CSSLengthType.PX);
}
if (renderStyle.height.isAuto && _propertyHeight != null) {
if (_styleHeight == null && _propertyHeight != null) {
// The intrinsic height of the image, in pixels. Must be an integer without a unit.
renderStyle.height = CSSLengthValue(_propertyHeight, CSSLengthType.PX);
}

if (width == null && height == null) {
width = naturalWidth;
height = naturalHeight;
} else if (width != null && height == null && naturalWidth != 0) {
height = width * naturalHeight / naturalWidth;
} else if (width == null && height != null && naturalHeight != 0) {
width = height * naturalWidth / naturalHeight;
}

if (height == null || !height.isFinite) {
height = 0.0;
}

if (width == null || !width.isFinite) {
width = 0.0;
}

// Try to update image size if image already resolved.
_renderImage?.width = width;
_renderImage?.height = height;
renderStyle.intrinsicWidth = naturalWidth;
renderStyle.intrinsicHeight = naturalHeight;

Expand All @@ -265,12 +253,12 @@ class ImageElement extends Element {
}
}

RenderImage _createRenderImageBox() {
KrakenRenderImage _createRenderImageBox() {
RenderStyle renderStyle = renderBoxModel!.renderStyle;
BoxFit objectFit = renderStyle.objectFit;
Alignment objectPosition = renderStyle.objectPosition;

return RenderImage(
return KrakenRenderImage(
image: _cachedImageInfo?.image,
fit: objectFit,
alignment: objectPosition,
Expand Down Expand Up @@ -338,19 +326,8 @@ class ImageElement extends Element {
if (resolvedUri == null) return;

// Try to make sure that this image can be encoded into a smaller size.
double? width = null;
double? height = null;

if (isRendererAttached) {
width = renderStyle.width.isAuto ? _propertyWidth : renderStyle.width.computedValue;
height = renderStyle.height.isAuto ? _propertyHeight : renderStyle.height.computedValue;
} else {
width = _propertyWidth;
height = _propertyHeight;
}

int? cachedWidth = (width != null && width > 0) ? (width * ui.window.devicePixelRatio).toInt() : null;
int? cachedHeight = (height != null && height > 0) ? (height * ui.window.devicePixelRatio).toInt() : null;
int? cachedWidth = width > 0 ? (width * ui.window.devicePixelRatio).toInt() : null;
int? cachedHeight = height > 0 ? (height * ui.window.devicePixelRatio).toInt() : null;

ImageProvider? provider = _cachedImageProvider;
if (updateImageProvider || provider == null) {
Expand Down Expand Up @@ -465,22 +442,26 @@ class ImageElement extends Element {
dynamic getProperty(String key) {
switch (key) {
case WIDTH:
return _renderImage?.width ?? 0;
return width;
case HEIGHT:
return _renderImage?.height ?? 0;
case 'naturalWidth':
return height;
case NATURAL_WIDTH:
return naturalWidth;
case 'naturalHeight':
case NATURAL_HEIGHT:
return naturalHeight;
}

return super.getProperty(key);
}

void _stylePropertyChanged(String property, String? original, String present) {
if (property == WIDTH || property == HEIGHT) {
// Resize renderBox
if (isRendererAttached) _resizeImage();
if (property == WIDTH) {
_styleWidth = renderStyle.width.value == null && renderStyle.width.isNotAuto
? null : renderStyle.width.computedValue;
} else if (property == HEIGHT) {
_styleHeight = renderStyle.height.value == null && renderStyle.height.isNotAuto
? null : renderStyle.height.computedValue;
}
// Resize image
_resolveImage(_resolvedUri, updateImageProvider: true);
} else if (property == OBJECT_FIT && _renderImage != null) {
Expand Down
26 changes: 26 additions & 0 deletions kraken/lib/src/rendering/image.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (C) 2019-present Alibaba Inc. All rights reserved.
* Author: Kraken Team.
*/
import 'dart:ui' as ui show Image;
import 'package:flutter/rendering.dart';

class KrakenRenderImage extends RenderImage {
KrakenRenderImage({
ui.Image? image,
BoxFit? fit,
AlignmentGeometry alignment = Alignment.center,
}) : super(
image: image,
fit: fit,
alignment: alignment,
);

@override
void performLayout() {
Size trySize = constraints.biggest;
size = trySize.isInfinite ? constraints.smallest : trySize;
}
}


0 comments on commit ab8e2d4

Please sign in to comment.