@@ -600,6 +600,34 @@ impl<'i> BorderHandler<'i> {
600600 $inline_end: expr,
601601 $is_logical: expr
602602 ) => {
603+ macro_rules! shorthand {
604+ ( $prop: ident, $key: ident) => { {
605+ let has_prop = $block_start. $key. is_some( ) && $block_end. $key. is_some( ) && $inline_start. $key. is_some( ) && $inline_end. $key. is_some( ) ;
606+ if has_prop {
607+ if !$is_logical || ( $block_start. $key == $block_end. $key && $block_end. $key == $inline_start. $key && $inline_start. $key == $inline_end. $key) {
608+ let rect = Rect :: new(
609+ std:: mem:: take( & mut $block_start. $key) . unwrap( ) ,
610+ std:: mem:: take( & mut $inline_end. $key) . unwrap( ) ,
611+ std:: mem:: take( & mut $block_end. $key) . unwrap( ) ,
612+ std:: mem:: take( & mut $inline_start. $key) . unwrap( )
613+ ) ;
614+ prop!( $prop => rect) ;
615+ }
616+ }
617+ } } ;
618+ }
619+
620+ macro_rules! logical_shorthand {
621+ ( $prop: ident, $key: ident, $start: expr, $end: expr) => { {
622+ let has_prop = $start. $key. is_some( ) && $start. $key == $end. $key;
623+ if has_prop {
624+ prop!( $prop => std:: mem:: take( & mut $start. $key) . unwrap( ) ) ;
625+ $end. $key = None ;
626+ }
627+ has_prop
628+ } } ;
629+ }
630+
603631 if $block_start. is_valid( ) && $block_end. is_valid( ) && $inline_start. is_valid( ) && $inline_end. is_valid( ) {
604632 let top_eq_bottom = $block_start == $block_end;
605633 let left_eq_right = $inline_start == $inline_end;
@@ -608,6 +636,34 @@ impl<'i> BorderHandler<'i> {
608636 let bottom_eq_left = $block_end == $inline_start;
609637 let bottom_eq_right = $block_end == $inline_end;
610638
639+ macro_rules! is_eq {
640+ ( $key: ident) => {
641+ $block_start. $key == $block_end. $key &&
642+ $inline_start. $key == $inline_end. $key &&
643+ $inline_start. $key == $block_start. $key
644+ } ;
645+ }
646+
647+ macro_rules! prop_diff {
648+ ( $border: expr, $fallback: expr, $border_fallback: literal) => {
649+ if !$is_logical && is_eq!( color) && is_eq!( style) {
650+ dest. push( Property :: Border ( $border. to_border( ) ) ) ;
651+ shorthand!( BorderWidth , width) ;
652+ } else if !$is_logical && is_eq!( width) && is_eq!( style) {
653+ dest. push( Property :: Border ( $border. to_border( ) ) ) ;
654+ shorthand!( BorderColor , color) ;
655+ } else if !$is_logical && is_eq!( width) && is_eq!( color) {
656+ dest. push( Property :: Border ( $border. to_border( ) ) ) ;
657+ shorthand!( BorderStyle , style) ;
658+ } else {
659+ if $border_fallback {
660+ dest. push( Property :: Border ( $border. to_border( ) ) ) ;
661+ }
662+ $fallback
663+ }
664+ } ;
665+ }
666+
611667 macro_rules! side_diff {
612668 ( $border: expr, $other: expr, $prop: ident, $width: ident, $style: ident, $color: ident) => {
613669 let eq_width = $border. width == $other. width;
@@ -643,52 +699,63 @@ impl<'i> BorderHandler<'i> {
643699 dest. push( Property :: Border ( $inline_start. to_border( ) ) ) ;
644700 side_diff!( $inline_start, $block_end, $block_end_prop, $block_end_width, $block_end_style, $block_end_color) ;
645701 } else if top_eq_bottom {
646- dest. push( Property :: Border ( $block_start. to_border( ) ) ) ;
647- side_diff!( $block_start, $inline_start, $inline_start_prop, $inline_start_width, $inline_start_style, $inline_start_color) ;
648- side_diff!( $block_start, $inline_end, $inline_end_prop, $inline_end_width, $inline_end_style, $inline_end_color) ;
649- } else if left_eq_right {
650- dest. push( Property :: Border ( $inline_start. to_border( ) ) ) ;
651- side_diff!( $inline_start, $block_start, $block_start_prop, $block_start_width, $block_start_style, $block_start_color) ;
652- side_diff!( $inline_start, $block_end, $block_end_prop, $block_end_width, $block_end_style, $block_end_color) ;
653- } else if bottom_eq_right {
654- dest. push( Property :: Border ( $block_end. to_border( ) ) ) ;
655- side_diff!( $block_end, $block_start, $block_start_prop, $block_start_width, $block_start_style, $block_start_color) ;
656- side_diff!( $block_end, $inline_start, $inline_start_prop, $inline_start_width, $inline_start_style, $inline_start_color) ;
657- } else {
658- prop!( $block_start_prop => $block_start. to_border( ) ) ;
659- prop!( $block_end_prop => $block_end. to_border( ) ) ;
660- prop!( $inline_start_prop => $inline_start. to_border( ) ) ;
661- prop!( $inline_end_prop => $inline_end. to_border( ) ) ;
662- }
663- } else {
664- macro_rules! shorthand {
665- ( $prop: ident, $key: ident) => { {
666- let has_prop = $block_start. $key. is_some( ) && $block_end. $key. is_some( ) && $inline_start. $key. is_some( ) && $inline_end. $key. is_some( ) ;
667- if has_prop {
668- if !$is_logical || ( $block_start. $key == $block_end. $key && $block_end. $key == $inline_start. $key && $inline_start. $key == $inline_end. $key) {
669- let rect = Rect :: new(
670- std:: mem:: take( & mut $block_start. $key) . unwrap( ) ,
671- std:: mem:: take( & mut $inline_end. $key) . unwrap( ) ,
672- std:: mem:: take( & mut $block_end. $key) . unwrap( ) ,
673- std:: mem:: take( & mut $inline_start. $key) . unwrap( )
674- ) ;
675- prop!( $prop => rect) ;
702+ prop_diff!( $block_start, {
703+ // Try to use border-inline shorthands for the opposide direction if possible.
704+ let mut handled = false ;
705+ if $is_logical {
706+ let mut diff = 0 ;
707+ if $inline_start. width != $block_start. width || $inline_end. width != $block_start. width {
708+ diff += 1 ;
709+ }
710+ if $inline_start. style != $block_start. style || $inline_end. style != $block_start. style {
711+ diff += 1 ;
712+ }
713+ if $inline_start. color != $block_start. color || $inline_end. color != $block_start. color {
714+ diff += 1 ;
715+ }
716+
717+ if diff == 1 {
718+ if $inline_start. width != $block_start. width && $inline_start. width == $inline_end. width {
719+ prop!( BorderInlineWidth => $inline_start. width. clone( ) . unwrap( ) ) ;
720+ handled = true ;
721+ } else if $inline_start. style != $block_start. style && $inline_start. style == $inline_end. style {
722+ prop!( BorderInlineStyle => $inline_start. style. clone( ) . unwrap( ) ) ;
723+ handled = true ;
724+ } else if $inline_start. color != $block_start. color && $inline_start. color == $inline_end. color {
725+ prop!( BorderInlineColor => $inline_start. color. clone( ) . unwrap( ) ) ;
726+ handled = true ;
727+ }
728+ } else if diff > 1 && $inline_start. width == $inline_end. width && $inline_start. style == $inline_end. style && $inline_start. color == $inline_end. color {
729+ prop!( BorderInline => $inline_start. to_border( ) ) ;
730+ handled = true ;
676731 }
677732 }
678- } } ;
679- }
680733
681- macro_rules! logical_shorthand {
682- ( $prop: ident, $key: ident, $start: expr, $end: expr) => { {
683- let has_prop = $start. $key. is_some( ) && $start. $key == $end. $key;
684- if has_prop {
685- prop!( $prop => std:: mem:: take( & mut $start. $key) . unwrap( ) ) ;
686- $end. $key = None ;
734+ if !handled {
735+ side_diff!( $block_start, $inline_start, $inline_start_prop, $inline_start_width, $inline_start_style, $inline_start_color) ;
736+ side_diff!( $block_start, $inline_end, $inline_end_prop, $inline_end_width, $inline_end_style, $inline_end_color) ;
687737 }
688- has_prop
689- } } ;
738+ } , true ) ;
739+ } else if left_eq_right {
740+ prop_diff!( $inline_start, {
741+ // We know already that top != bottom, so no need to try to use border-block.
742+ side_diff!( $inline_start, $block_start, $block_start_prop, $block_start_width, $block_start_style, $block_start_color) ;
743+ side_diff!( $inline_start, $block_end, $block_end_prop, $block_end_width, $block_end_style, $block_end_color) ;
744+ } , true ) ;
745+ } else if bottom_eq_right {
746+ prop_diff!( $block_end, {
747+ side_diff!( $block_end, $block_start, $block_start_prop, $block_start_width, $block_start_style, $block_start_color) ;
748+ side_diff!( $block_end, $inline_start, $inline_start_prop, $inline_start_width, $inline_start_style, $inline_start_color) ;
749+ } , true ) ;
750+ } else {
751+ prop_diff!( $block_start, {
752+ prop!( $block_start_prop => $block_start. to_border( ) ) ;
753+ prop!( $block_end_prop => $block_end. to_border( ) ) ;
754+ prop!( $inline_start_prop => $inline_start. to_border( ) ) ;
755+ prop!( $inline_end_prop => $inline_end. to_border( ) ) ;
756+ } , false ) ;
690757 }
691-
758+ } else {
692759 shorthand!( BorderStyle , style) ;
693760 shorthand!( BorderWidth , width) ;
694761 shorthand!( BorderColor , color) ;
0 commit comments