Skip to content

Commit

Permalink
Merge pull request #379 from DioxusLabs/main
Browse files Browse the repository at this point in the history
Update 0.3.x for 0.3.4 release
  • Loading branch information
nicoburns authored Mar 7, 2023
2 parents b3015f4 + deac6dc commit 1e4b80d
Show file tree
Hide file tree
Showing 49 changed files with 1,164 additions and 148 deletions.
23 changes: 23 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ jobs:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: build
args: --no-default-features
- uses: actions-rs/cargo@v1
with:
command: test
Expand All @@ -33,6 +37,9 @@ jobs:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: build
- uses: actions-rs/cargo@v1
with:
command: test
Expand All @@ -47,6 +54,10 @@ jobs:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: build
args: --features serde
- uses: actions-rs/cargo@v1
with:
command: test
Expand All @@ -62,6 +73,10 @@ jobs:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: build
args: --no-default-features --features alloc,grid
- uses: actions-rs/cargo@v1
with:
command: test
Expand All @@ -77,6 +92,10 @@ jobs:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: build
args: --no-default-features --features alloc
- uses: actions-rs/cargo@v1
with:
command: test
Expand All @@ -92,6 +111,10 @@ jobs:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: build
args: --no-default-features --features std
- uses: actions-rs/cargo@v1
with:
command: test
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "taffy"
version = "0.3.2"
version = "0.3.4"
authors = [
"Alice Cecile <alice.i.cecile@gmail.com>",
"Johnathan Kelley <jkelleyrtp@gmail.com>",
Expand All @@ -23,7 +23,7 @@ grid = { version = "0.9.0", optional = true }

[features]
default = ["std", "grid"]
grid = ["dep:grid"]
grid = ["alloc", "dep:grid"]
alloc = []
std = ["num-traits/std"]
serde = ["dep:serde"]
Expand Down
18 changes: 18 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Release Notes

## 0.3.4

### Fixes

- Fix `display: none` when it is set for the only node in the hierarchy (#377)

## 0.3.3

### Added

- Added `enable_rounding` and `disable_rounding` methods to the `Taffy` struct which enable consumers of Taffy to obtain unrounded `f32` values for the computed layouts if they want them. Rounding remains enabled by default.

### Fixes

- Fixed rounding algorithm such that it never leaves gaps between adjacent nodes (#369)
- Fixed compiling with the `grid` feature disabled (#370)
- Fixed compiling with the `std` feature disabled

## 0.3.2

### Fixes
Expand Down
40 changes: 28 additions & 12 deletions scripts/gentest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,11 @@ async fn test_root_element(client: Client, name: String, fixture_path: impl AsRe
fn generate_test(name: impl AsRef<str>, description: &Value) -> TokenStream {
let name = name.as_ref();
let name = Ident::new(name, Span::call_site());
let use_rounding = description["useRounding"].as_bool().unwrap();
let assertions = generate_assertions("node", description, use_rounding);
let node_description = generate_node("node", description);
let assertions = generate_assertions("node", description);

let set_rounding_mode = if use_rounding { quote!() } else { quote!(taffy.disable_rounding();) };

quote!(
#[test]
Expand All @@ -131,6 +134,7 @@ fn generate_test(name: impl AsRef<str>, description: &Value) -> TokenStream {
use taffy::{layout::Layout, prelude::*};
use slotmap::Key;
let mut taffy = taffy::Taffy::new();
#set_rounding_mode
#node_description
taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();

Expand All @@ -143,8 +147,8 @@ fn generate_test(name: impl AsRef<str>, description: &Value) -> TokenStream {
)
}

fn generate_assertions(ident: &str, node: &Value) -> TokenStream {
let layout = &node["layout"];
fn generate_assertions(ident: &str, node: &Value, use_rounding: bool) -> TokenStream {
let layout = if use_rounding { &node["smartRoundedLayout"] } else { &node["unroundedLayout"] };

let read_f32 = |s: &str| layout[s].as_f64().unwrap() as f32;
let width = read_f32("width");
Expand All @@ -156,23 +160,35 @@ fn generate_assertions(ident: &str, node: &Value) -> TokenStream {
let mut c = Vec::new();
if let Value::Array(ref value) = node["children"] {
for (idx, child) in value.iter().enumerate() {
c.push(generate_assertions(&format!("{ident}{idx}"), child));
c.push(generate_assertions(&format!("{ident}{idx}"), child, use_rounding));
}
};
c.into_iter().fold(quote!(), |a, b| quote!(#a #b))
};

let ident = Ident::new(ident, Span::call_site());

quote!(
let Layout { size, location, .. } = taffy.layout(#ident).unwrap();
assert_eq!(size.width, #width, "width of node {:?}. Expected {}. Actual {}", #ident.data(), #width, size.width);
assert_eq!(size.height, #height, "height of node {:?}. Expected {}. Actual {}", #ident.data(), #height, size.height);
assert_eq!(location.x, #x, "x of node {:?}. Expected {}. Actual {}", #ident.data(), #x, location.x);
assert_eq!(location.y, #y, "y of node {:?}. Expected {}. Actual {}", #ident.data(), #y, location.y);
if use_rounding {
quote!(
let Layout { size, location, .. } = taffy.layout(#ident).unwrap();
assert_eq!(size.width, #width, "width of node {:?}. Expected {}. Actual {}", #ident.data(), #width, size.width);
assert_eq!(size.height, #height, "height of node {:?}. Expected {}. Actual {}", #ident.data(), #height, size.height);
assert_eq!(location.x, #x, "x of node {:?}. Expected {}. Actual {}", #ident.data(), #x, location.x);
assert_eq!(location.y, #y, "y of node {:?}. Expected {}. Actual {}", #ident.data(), #y, location.y);

#children
)
#children
)
} else {
quote!(
let Layout { size, location, .. } = taffy.layout(#ident).unwrap();
assert!(size.width - #width < 0.1, "width of node {:?}. Expected {}. Actual {}", #ident.data(), #width, size.width);
assert!(size.height - #height < 0.1, "height of node {:?}. Expected {}. Actual {}", #ident.data(), #height, size.height);
assert!(location.x - #x < 0.1, "x of node {:?}. Expected {}. Actual {}", #ident.data(), #x, location.x);
assert!(location.y - #y < 0.1, "y of node {:?}. Expected {}. Actual {}", #ident.data(), #y, location.y);

#children
)
}
}

macro_rules! dim_quoted_renamed {
Expand Down
29 changes: 28 additions & 1 deletion scripts/gentest/test_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ function parseGridPosition(input) {

function describeElement(e) {

// Get precise, unrounded dimensions for the current element and it's parent
let boundingRect = e.getBoundingClientRect();
let parentBoundingRect = e.parentNode.getBoundingClientRect();

return {
style: {
display: parseEnum(e.style.display),
Expand Down Expand Up @@ -249,13 +253,36 @@ function describeElement(e) {
// So we're only interested in the text content of leaf nodes
textContent: e.childElementCount === 0 && e.textContent.length && e.textContent !== "\n" ? e.textContent : undefined,

layout: {
// The layout of the node in full precision (floating-point)
unroundedLayout: {
width: boundingRect.width,
height: boundingRect.height,
x: boundingRect.x - parentBoundingRect.x,
y: boundingRect.y - parentBoundingRect.y,
},

// The naively rounded layout of the node. This is equivalent to calling Math.round() on
// each value in the unrounded layout individually
naivelyRoundedLayout: {
width: e.offsetWidth,
height: e.offsetHeight,
x: e.offsetLeft + e.parentNode.clientLeft,
y: e.offsetTop + e.parentNode.clientTop,
},

// The naive rounding can result in 1px gaps in the layout, so Taffy uses a smarter algorithm to avoid this.
// Chrome also uses a smarter algorithm, but it doesn't expose the output of that rounding.
// So we just emulate Taffy's computation here.
smartRoundedLayout: {
width: Math.round(boundingRect.right) - Math.round(boundingRect.left),
height: Math.round(boundingRect.bottom) - Math.round(boundingRect.top),
x: Math.round(boundingRect.x - parentBoundingRect.x),
y: Math.round(boundingRect.y - parentBoundingRect.y),
},

// Whether the test should enable rounding
useRounding: e.getAttribute("data-test-rounding") !== "false",

children: Array.from(e.children).map(c => describeElement(c)),
}
}
Expand Down
1 change: 1 addition & 0 deletions src/axis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ pub(crate) struct InBothAbsAxis<T> {
}

impl<T: Copy> InBothAbsAxis<T> {
#[cfg(feature = "grid")]
/// Get the contained item based on the AbsoluteAxis passed
pub fn get(&self, axis: AbsoluteAxis) -> T {
match axis {
Expand Down
14 changes: 9 additions & 5 deletions src/compute/flexbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ use crate::style::{
LengthPercentageAuto, Position,
};
use crate::style::{FlexDirection, Style};
use crate::sys::f32_max;
use crate::sys::Vec;
use crate::sys::{f32_max, new_vec_with_capacity};
use crate::tree::LayoutTree;

#[cfg(feature = "debug")]
Expand Down Expand Up @@ -735,18 +735,22 @@ fn collect_flex_lines<'a>(
flex_items: &'a mut Vec<FlexItem>,
) -> Vec<FlexLine<'a>> {
if tree.style(node).flex_wrap == FlexWrap::NoWrap {
vec![FlexLine { items: flex_items.as_mut_slice(), cross_size: 0.0, offset_cross: 0.0 }]
let mut lines = new_vec_with_capacity(1);
lines.push(FlexLine { items: flex_items.as_mut_slice(), cross_size: 0.0, offset_cross: 0.0 });
lines
} else {
match available_space.main(constants.dir) {
// If we're sizing under a max-content constraint then the flex items will never wrap
// (at least for now - future extensions to the CSS spec may add provisions for forced wrap points)
AvailableSpace::MaxContent => {
vec![FlexLine { items: flex_items.as_mut_slice(), cross_size: 0.0, offset_cross: 0.0 }]
let mut lines = new_vec_with_capacity(1);
lines.push(FlexLine { items: flex_items.as_mut_slice(), cross_size: 0.0, offset_cross: 0.0 });
lines
}
// If flex-wrap is Wrap and we're sizing under a min-content constraint, then we take every possible wrapping opportunity
// and place each item in it's own line
AvailableSpace::MinContent => {
let mut lines = crate::sys::new_vec_with_capacity(flex_items.len());
let mut lines = new_vec_with_capacity(flex_items.len());
let mut items = &mut flex_items[..];
while !items.is_empty() {
let (line_items, rest) = items.split_at_mut(1);
Expand All @@ -756,7 +760,7 @@ fn collect_flex_lines<'a>(
lines
}
AvailableSpace::Definite(main_axis_available_space) => {
let mut lines = crate::sys::new_vec_with_capacity(1);
let mut lines = new_vec_with_capacity(1);
let mut flex_items = &mut flex_items[..];
let main_axis_gap = constants.gap.main(constants.dir);

Expand Down
2 changes: 1 addition & 1 deletion src/compute/grid/track_sizing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::resolve::ResolveOrZero;
use crate::style::{
AlignContent, AlignSelf, AvailableSpace, LengthPercentage, MaxTrackSizingFunction, MinTrackSizingFunction,
};
use crate::sys::{f32_max, f32_min};
use crate::sys::{f32_max, f32_min, Vec};
use core::cmp::Ordering;

/// Takes an axis, and a list of grid items sorted firstly by whether they cross a flex track
Expand Down
Loading

0 comments on commit 1e4b80d

Please sign in to comment.