From 00a27dc37b1e33ec2448ae59d5e2c375e13de32e Mon Sep 17 00:00:00 2001 From: Brandy Carney Date: Tue, 21 May 2019 14:42:57 -0400 Subject: [PATCH] fix(css): update rtl function to prepend selectors with host-context properly (#18315) references #17012 --- core/src/themes/ionic.functions.string.scss | 73 +++++++++++++++------ core/src/themes/ionic.mixins.scss | 20 ++---- 2 files changed, 59 insertions(+), 34 deletions(-) diff --git a/core/src/themes/ionic.functions.string.scss b/core/src/themes/ionic.functions.string.scss index 8013b99de8..7bf56c5032 100644 --- a/core/src/themes/ionic.functions.string.scss +++ b/core/src/themes/ionic.functions.string.scss @@ -1,9 +1,9 @@ -// String Util Functions -// -------------------------------------------------- +// String Utility Functions +// -------------------------------------------------------------------------------- // String Replace Function -// -------------------------------------------------- +// -------------------------------------------------------------------------------- @function str-replace($string, $search, $replace: "") { $index: str-index($string, $search); @@ -16,7 +16,8 @@ } // String Split Function -// -------------------------------------------------- +// -------------------------------------------------------------------------------- + @function str-split($string, $separator) { // empty array/list @@ -41,8 +42,8 @@ } -// Str Extract Function -// -------------------------------------------------- +// String Extract Function +// -------------------------------------------------------------------------------- @function str-extract($string, $start, $end) { $start-index: str-index($string, $start); @@ -60,8 +61,8 @@ } -// Str Contains Function -// -------------------------------------------------- +// String Contains Function +// -------------------------------------------------------------------------------- @function str-contains($string, $needle) { @if (type-of($string) == string) { @@ -73,7 +74,7 @@ // URL Encode Function -// -------------------------------------------------- +// -------------------------------------------------------------------------------- @function url-encode($val) { $spaces: str-replace($val, " ", "%20"); @@ -82,28 +83,58 @@ } -// Add Selector -// -------------------------------------------------- -// Used to cleanly add selectors to :host and :host() +// Add Root Selector +// -------------------------------------------------------------------------------- +// Adds a root selector using host-context based on the selector passed +// +// Examples +// -------------------------------------------------------------------------------- +// @include add-root-selector("[dir=rtl]", ":host") +// --> :host-context([dir=rtl]) +// +// @include add-root-selector("[dir=rtl]", ":host(.fixed)") +// --> :host-context([dir=rtl]).fixed +// +// @include add-root-selector("[dir=rtl]", ":host(.tab-layout-icon-hide) ::slotted(ion-badge)") +// --> :host-context([dir=rtl]).tab-layout-icon-hide ::slotted(ion-badge) +// +// @include add-root-selector("[dir=rtl]", ".shadow") +// --> [dir=rtl] .shadow +// --> :host-context([dir=rtl]) .shadow +// -------------------------------------------------------------------------------- -@function add-root-selector($root, $addHostSelector, $shadowDom: false) { +@function add-root-selector($root, $addHostSelector) { $selectors: str-split($root, ","); $list: (); @each $selector in $selectors { + // If the selector contains :host( it means it is targeting a class on the host + // element so we need to change how we target it @if str-contains($selector, ":host(") { - $updated-host: str-replace($selector, ":host(", ":host(#{$addHostSelector}"); - $list: append($list, $updated-host, comma); + $new-element: (); + $elements: str-split($selector, " "); + @each $element in $elements { + @if str-contains($element, ":host(") { + $updated-element: str-replace($element, ")", ""); + $updated-element: str-replace($updated-element, ":host(", ":host-context(#{$addHostSelector})"); + + $new-element: append($new-element, $updated-element, space); + } @else { + $new-element: append($new-element, $element, space); + } + } + + $list: append($list, $new-element, comma); + // If the selector contains :host it means it is targeting just the host + // element so we can change it to look for host-context } @else if str-contains($selector, ":host") { - $list: append($list, ":host(#{$addHostSelector}) + b", comma); - - } @else if $shadowDom == true { - $list: append($list, ":host(#{$addHostSelector}) #{$selector}", comma); - + $list: append($list, ":host-context(#{$addHostSelector})", comma); + // If the selector does not contain host at all it is either a shadow + // or normal element so append both the dir check and host-context } @else { - // TODO host-context should be for scoped only + $list: append($list, "#{$addHostSelector} #{$selector}", comma); $list: append($list, ":host-context(#{$addHostSelector}) #{$selector}", comma); } } diff --git a/core/src/themes/ionic.mixins.scss b/core/src/themes/ionic.mixins.scss index eac527fb84..91524ecd09 100644 --- a/core/src/themes/ionic.mixins.scss +++ b/core/src/themes/ionic.mixins.scss @@ -134,25 +134,19 @@ // Text Direction - ltr / rtl -// $app-direction: multi | rtl | ltr | null (default) -// multi: Both [dir=ltr] and [dir=rtl] are applied to css selectors. -// rtl: Always assumes rtl and only includes rtl css. No [dir] selectors. -// ltr: Always assumes ltr and only includes ltr css. No [dir] selectors. -// null: CSS defaults to use the ltr css, and adds [dir=rtl] selectors to override ltr defaults. +// +// CSS defaults to use the ltr css, and adds [dir=rtl] selectors +// to override ltr defaults. // ---------------------------------------------------------- @mixin multi-dir() { @content; - // @if $app-direction == multi { - // $root: #{&}; - // @at-root [dir] { - // #{$root} { - // @content; - // } + // $root: #{&}; + // @at-root [dir] { + // #{$root} { + // @content; // } - // } @else { - // @content; // } }