Skip to content

Commit

Permalink
mask-image property added and code refactor (#1396)
Browse files Browse the repository at this point in the history
* mask property added

* mask-composite property

* mask mode property and test fixes

* mask-image property added

* mask-image -> mask.image

* fixed tests

* mask-position, repeat, size properties

* fixed tests

* fixed stackoverflow issue caused by default_bag
  • Loading branch information
harshdoesdev authored Oct 26, 2023
1 parent 2454e07 commit 7a94e51
Show file tree
Hide file tree
Showing 13 changed files with 917 additions and 39 deletions.
196 changes: 187 additions & 9 deletions fastn-js/js/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ fastn_dom.propertyMap = {
"-webkit-box-orient": "wbo",
"-webkit-line-clamp": "wlc",
"backdrop-filter": "bdf",
"mask-image": "mi",
"-webkit-mask-image": "wmi",
"mask-size": "ms",
"-webkit-mask-size": "wms",
"mask-repeat": "mre",
"-webkit-mask-repeat": "wmre",
"mask-position": "mp",
"-webkit-mask-position": "wmp",
};

// dynamic-class-css.md
Expand Down Expand Up @@ -282,6 +290,7 @@ fastn_dom.PropertyKind = {
TextShadow: 117,
Selectable: 118,
BackdropFilter: 119,
Mask: 120,
};


Expand Down Expand Up @@ -657,7 +666,46 @@ fastn_dom.Length = {
}
}

fastn_dom.Mask = {
Image: (value) => {
return [1, value];
},
Multi: (value) => {
return [2, value]
},
}

fastn_dom.MaskSize = {
Auto: "auto",
Cover: "cover",
Contain: "contain",
Fixed: (value) => { return value }
}

fastn_dom.MaskRepeat = {
Repeat: "repeat",
RepeatX: "repeat-x",
RepeatY: "repeat-y",
NoRepeat: "no-repeat",
Space: "space",
Round: "round",
}

fastn_dom.MaskPosition = {
Left: "left",
Right: "right",
Center: "center",
LeftTop: "left top",
LeftCenter: "left center",
LeftBottom: "left bottom",
CenterTop: "center top",
CenterCenter: "center center",
CenterBottom: "center bottom",
RightTop: "right top",
RightCenter: "right center",
RightBottom: "right bottom",
Length: (value) => { return value; },
}

fastn_dom.Event = {
Click: 0,
Expand Down Expand Up @@ -1055,16 +1103,11 @@ class Node2 {
this.attachCss("text-shadow", darkShadowCss, true, `body.dark .${lightClass}`);
}
}
attachLinearGradientCss(value) {
if (fastn_utils.isNull(value)) {
this.attachCss("background-image", value);
return;
}
getLinearGradientString(value) {
var lightGradientString = "";
var darkGradientString = "";

let colorsList = value.get("colors").get().getList();
let direction = fastn_utils.getStaticValue(value.get("direction"));
colorsList.map(function (element) {
// LinearGradient RecordInstance
let lg_color = element.item;
Expand Down Expand Up @@ -1101,6 +1144,18 @@ class Node2 {
lightGradientString = lightGradientString.trim().slice(0, -1);
darkGradientString = darkGradientString.trim().slice(0, -1);

return [lightGradientString, darkGradientString];
}
attachLinearGradientCss(value) {
if (fastn_utils.isNull(value)) {
this.attachCss("background-image", value);
return;
}

let direction = fastn_utils.getStaticValue(value.get("direction"));

const [lightGradientString, darkGradientString] = this.getLinearGradientString(value);

if (lightGradientString === darkGradientString) {
this.attachCss("background-image", `linear-gradient(${direction}, ${lightGradientString})`, false);
} else {
Expand Down Expand Up @@ -1160,6 +1215,112 @@ class Node2 {
this.attachCss("background-image", `url(${darkValue})`, true, `body.dark .${lightClass}`);
}
}
attachMaskImageCss(value, vendorPrefix) {
const propertyWithPrefix = vendorPrefix ? `${vendorPrefix}-mask-image` : "mask-image";

if (fastn_utils.isNull(value)) {
this.attachCss(propertyWithPrefix, value);
return;
}

let src = fastn_utils.getStaticValue(value.get("src"));
let linearGradient = fastn_utils.getStaticValue(value.get("linear_gradient"));
let color = fastn_utils.getStaticValue(value.get("color"));

const maskLightImageValues = [];
const maskDarkImageValues = [];

if(!fastn_utils.isNull(src)) {
let lightValue = fastn_utils.getStaticValue(src.get("light"));
let darkValue = fastn_utils.getStaticValue(src.get("dark"));

const lightUrl = `url(${lightValue})`;
const darkUrl = `url(${darkValue})`;

if(!fastn_utils.isNull(linearGradient)) {
const lightImageValues = [lightUrl];
const darkImageValues = [darkUrl];

if(!fastn_utils.isNull(color)) {
const lightColor = fastn_utils.getStaticValue(color.get("light"));
const darkColor = fastn_utils.getStaticValue(color.get("dark"));

lightImageValues.push(lightColor);
darkImageValues.push(darkColor);
}
maskLightImageValues.push(`image(${lightImageValues.join(", ")})`);
maskDarkImageValues.push(`image(${darkImageValues.join(", ")})`);
} else {
maskLightImageValues.push(lightUrl);
maskDarkImageValues.push(darkUrl);
}
}

if(!fastn_utils.isNull(linearGradient)) {
let direction = fastn_utils.getStaticValue(linearGradient.get("direction"));

const [lightGradientString, darkGradientString] = this.getLinearGradientString(linearGradient);

maskLightImageValues.push(`linear-gradient(${direction}, ${lightGradientString})`);
maskDarkImageValues.push(`linear-gradient(${direction}, ${darkGradientString})`);
}

const maskLightImageString = maskLightImageValues.join(", ");
const maskDarkImageString = maskDarkImageValues.join(", ");

if(maskLightImageString === maskDarkImageString) {
this.attachCss(propertyWithPrefix, maskLightImageString, false);
} else {
let lightClass = this.attachCss(propertyWithPrefix, maskLightImageString, true);
this.attachCss(propertyWithPrefix, maskDarkImageString, true, `body.dark .${lightClass}`);
}
}
attachMaskSizeCss(value, vendorPrefix) {
const propertyNameWithPrefix = vendorPrefix ? `${vendorPrefix}-mask-size` : "mask-size";
if(fastn_utils.isNull(value)) {
this.attachCss(propertyNameWithPrefix, value);
}
const [size, ...two_values] = ["size", "size_x", "size_y"]
.map(size => fastn_utils.getStaticValue(value.get(size)));

if(!fastn_utils.isNull(size)) {
this.attachCss(propertyNameWithPrefix, size, true);
} else {
const [size_x, size_y] = two_values.map(value => value || "auto");
this.attachCss(propertyNameWithPrefix, `${size_x} ${size_y}`, true);
}
}
attachMaskMultiCss(value, vendorPrefix) {
if (fastn_utils.isNull(value)) {
this.attachCss("mask-repeat", value);
this.attachCss("mask-position", value);
this.attachCss("mask-size", value);
this.attachCss("mask-image", value);
return;
}

const maskImage = fastn_utils.getStaticValue(value.get("image"));
this.attachMaskImageCss(maskImage);
this.attachMaskImageCss(maskImage, vendorPrefix);
this.attachMaskSizeCss(value);
this.attachMaskSizeCss(value, vendorPrefix);
const maskRepeatValue = fastn_utils.getStaticValue(value.get("repeat"));
if(fastn_utils.isNull(maskRepeatValue)) {
this.attachCss("mask-repeat", maskRepeatValue);
this.attachCss("-webkit-mask-repeat", maskRepeatValue);
} else {
this.attachCss("mask-repeat", maskRepeatValue);
this.attachCss("-webkit-mask-repeat", maskRepeatValue);
}
const maskPositionValue = fastn_utils.getStaticValue(value.get("position"));
if(fastn_utils.isNull(maskPositionValue)) {
this.attachCss("mask-position", maskPositionValue);
this.attachCss("-webkit-mask-position", maskPositionValue);
} else {
this.attachCss("mask-position", maskPositionValue);
this.attachCss("-webkit-mask-position", maskPositionValue);
}
}
attachExternalCss(css) {
if (hydrating) {
let css_tag = document.createElement('link');
Expand Down Expand Up @@ -1496,8 +1657,8 @@ class Node2 {
} else if (kind === fastn_dom.PropertyKind.TextShadow) {
this.attachTextShadow(staticValue);
} else if (kind === fastn_dom.PropertyKind.BackdropFilter) {
if (fastn_utils.isNull(value)) {
this.attachCss("backdrop-filter", value);
if (fastn_utils.isNull(staticValue)) {
this.attachCss("backdrop-filter", staticValue);
return;
}

Expand Down Expand Up @@ -1528,10 +1689,27 @@ class Node2 {
this.attachCss("backdrop-filter", `saturate(${fastn_utils.getStaticValue(staticValue[1])})`);
break;
case 9:
console.log("Here");
this.attachBackdropMultiFilter(staticValue[1]);
break;
}
} else if (kind === fastn_dom.PropertyKind.Mask) {
if (fastn_utils.isNull(staticValue)) {
this.attachCss("mask-image", staticValue);
return;
}

const [backgroundType, value] = staticValue;

switch (backgroundType) {
case fastn_dom.Mask.Image()[0]:
this.attachMaskImageCss(value);
this.attachMaskImageCss(value, "-webkit");
break;
case fastn_dom.Mask.Multi()[0]:
this.attachMaskMultiCss(value);
this.attachMaskMultiCss(value, "-webkit");
break;
}
} else if (kind === fastn_dom.PropertyKind.Classes) {
fastn_utils.removeNonFastnClasses(this);
if (!fastn_utils.isNull(staticValue)) {
Expand Down
2 changes: 2 additions & 0 deletions fastn-js/src/property.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ pub enum PropertyKind {
Favicon,
Selectable,
BackdropFilter,
Mask,
}

impl PropertyKind {
Expand Down Expand Up @@ -566,6 +567,7 @@ impl PropertyKind {
PropertyKind::Favicon => "fastn_dom.PropertyKind.Favicon",
PropertyKind::Selectable => "fastn_dom.PropertyKind.Selectable",
PropertyKind::BackdropFilter => "fastn_dom.PropertyKind.BackdropFilter",
PropertyKind::Mask => "fastn_dom.PropertyKind.Mask",
}
}
}
2 changes: 1 addition & 1 deletion ftd/src/executor/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ fn p(s: &str, t: &str, fix: bool, file_location: &std::path::PathBuf) {
let doc = interpret_helper("foo", s).unwrap_or_else(|e| panic!("{:?}", e));
let mut executor =
ftd::executor::ExecuteDoc::from_interpreter(doc).unwrap_or_else(|e| panic!("{:?}", e));
for thing in ftd::interpreter::default::default_bag().keys() {
for thing in ftd::interpreter::default::get_default_bag().keys() {
executor.bag.remove(thing);
}
let expected_json = serde_json::to_string_pretty(&executor).unwrap();
Expand Down
39 changes: 39 additions & 0 deletions ftd/src/interpreter/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,42 @@ pub const FTD_BACKDROP_FILTER_OPACITY: &str = "ftd#backdrop-filter.opacity";
pub const FTD_BACKDROP_FILTER_SEPIA: &str = "ftd#backdrop-filter.sepia";
pub const FTD_BACKDROP_FILTER_SATURATE: &str = "ftd#backdrop-filter.saturate";
pub const FTD_BACKDROP_FILTER_MULTI: &str = "ftd#backdrop-filter.multi";

pub const FTD_MASK_IMAGE_DATA: &str = "ftd#mask-image";
pub const FTD_MASK_IMAGE_DATA_SRC: &str = "ftd#mask-image.src";
pub const FTD_MASK_IMAGE_DATA_LINEAR_GRADIENT: &str = "ftd#mask-image.linear-gradient";

pub const FTD_MASK: &str = "ftd#mask";
pub const FTD_MASK_IMAGE: &str = "ftd#mask.image";
pub const FTD_MASK_MULTI: &str = "ftd#mask.multi";

pub const FTD_MASK_MULTI_DATA: &str = "ftd#mask-multi";

pub const FTD_MASK_SIZE: &str = "ftd#mask-size";
pub const FTD_MASK_SIZE_FIXED: &str = "ftd#mask-size.fixed";
pub const FTD_MASK_SIZE_COVER: &str = "ftd#mask-size.cover";
pub const FTD_MASK_SIZE_CONTAIN: &str = "ftd#mask-size.contain";
pub const FTD_MASK_SIZE_AUTO: &str = "ftd#mask-size.auto";

pub const FTD_MASK_REPEAT: &str = "ftd#mask-repeat";
pub const FTD_MASK_REPEAT_BOTH_REPEAT: &str = "ftd#mask-repeat.repeat";
pub const FTD_MASK_REPEAT_X_REPEAT: &str = "ftd#mask-repeat.repeat-x";
pub const FTD_MASK_REPEAT_Y_REPEAT: &str = "ftd#mask-repeat.repeat-y";
pub const FTD_MASK_REPEAT_NO_REPEAT: &str = "ftd#mask-repeat.no-repeat";
pub const FTD_MASK_REPEAT_SPACE: &str = "ftd#mask-repeat.space";
pub const FTD_MASK_REPEAT_ROUND: &str = "ftd#mask-repeat.round";

pub const FTD_MASK_POSITION: &str = "ftd#mask-position";
pub const FTD_MASK_POSITION_LEFT: &str = "ftd#mask-position.left";
pub const FTD_MASK_POSITION_CENTER: &str = "ftd#mask-position.center";
pub const FTD_MASK_POSITION_RIGHT: &str = "ftd#mask-position.right";
pub const FTD_MASK_POSITION_LEFT_TOP: &str = "ftd#mask-position.left-top";
pub const FTD_MASK_POSITION_LEFT_CENTER: &str = "ftd#mask-position.left-center";
pub const FTD_MASK_POSITION_LEFT_BOTTOM: &str = "ftd#mask-position.left-bottom";
pub const FTD_MASK_POSITION_CENTER_TOP: &str = "ftd#mask-position.center-top";
pub const FTD_MASK_POSITION_CENTER_CENTER: &str = "ftd#mask-position.center-center";
pub const FTD_MASK_POSITION_CENTER_BOTTOM: &str = "ftd#mask-position.center-bottom";
pub const FTD_MASK_POSITION_RIGHT_TOP: &str = "ftd#mask-position.right-top";
pub const FTD_MASK_POSITION_RIGHT_CENTER: &str = "ftd#mask-position.right-center";
pub const FTD_MASK_POSITION_RIGHT_BOTTOM: &str = "ftd#mask-position.right-bottom";
pub const FTD_MASK_POSITION_LENGTH: &str = "ftd#mask-position.length";
2 changes: 1 addition & 1 deletion ftd/src/interpreter/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl InterpreterState {
fn new(id: String) -> InterpreterState {
InterpreterState {
id,
bag: ftd::interpreter::default::default_bag(),
bag: ftd::interpreter::default::get_default_bag().clone(),
..Default::default()
}
}
Expand Down
2 changes: 1 addition & 1 deletion ftd/src/interpreter/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub fn interpret_helper(
#[track_caller]
fn p(s: &str, t: &str, fix: bool, file_location: &std::path::PathBuf) {
let mut i = interpret_helper("foo", s).unwrap_or_else(|e| panic!("{:?}", e));
for thing in ftd::interpreter::default::default_bag().keys() {
for thing in ftd::interpreter::default::get_default_bag().keys() {
i.data.remove(thing);
}
let expected_json = serde_json::to_string_pretty(&i).unwrap();
Expand Down
Loading

0 comments on commit 7a94e51

Please sign in to comment.