From 38d1da61c5dbd6865d042dd6ed69d9219841875b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20Bu=CC=88hlmann?= Date: Tue, 18 Oct 2016 10:49:34 +0200 Subject: [PATCH 01/10] Implement proof-of-concept for recurse support of or-conditions --- dist/_include-media.scss | 97 +++++++++++++++++++++++++++++++++++--- src/_config.scss | 4 +- src/_media.scss | 12 +++++ src/helpers/_no-media.scss | 2 + src/helpers/_parser.scss | 79 +++++++++++++++++++++++++++++-- 5 files changed, 182 insertions(+), 12 deletions(-) diff --git a/dist/_include-media.scss b/dist/_include-media.scss index 370764c..5f4c4a6 100644 --- a/dist/_include-media.scss +++ b/dist/_include-media.scss @@ -55,8 +55,8 @@ $media-expressions: ( 'handheld': 'handheld', 'landscape': '(orientation: landscape)', 'portrait': '(orientation: portrait)', - 'retina2x': '(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi), (min-resolution: 2dppx)', - 'retina3x': '(-webkit-min-device-pixel-ratio: 3), (min-resolution: 350dpi), (min-resolution: 3dppx)' + 'retina2x': ('(-webkit-min-device-pixel-ratio: 2)', '(min-resolution: 192dpi)', '(min-resolution: 2dppx)'), + 'retina3x': ('(-webkit-min-device-pixel-ratio: 3)', '(min-resolution: 350dpi)', '(min-resolution: 3dppx)') ) !default; @@ -216,6 +216,8 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; /// @function noop() {} +/// TODO: Check + /// /// Determines whether a list of conditions is intercepted by the static breakpoint. /// @@ -255,7 +257,6 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; /// @access private //// - /// /// Get operator of an expression /// @@ -278,7 +279,6 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; $_: log('No operator found in `#{$expression}`.'); } - /// /// Get dimension of an expression, based on a found operator /// @@ -299,7 +299,6 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; @return $dimension; } - /// /// Get dimension prefix based on an operator /// @@ -311,7 +310,6 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; @return if(index(('<', '<=', '≤'), $operator), 'max', 'min'); } - /// /// Get value of an expression, based on a found operator /// @@ -350,6 +348,81 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; @return $value; } +/// +/// TODO: Documentation +/// +/// @param {String} $feature-queries - (TODO: documentation) +/// +/// @return {String} - (TODO: documentation) +/// +@function chain-feature-queries($feature-queries, $do-parse: true) { + $separator: list-separator($feature-queries); + $parsed-feature-queries: if($separator == 'comma', (), ((),)); + + @each $query in $feature-queries { + $new-parsed-feature-queries: (); + + @if (type-of($query) == 'list') { + // List item is a list itself + $intermediary-queries: chain-feature-queries($query); // Returns a nested list in the form: ((a b), (c)) + + @if ($separator == 'space') { + @each $intermediary-query in $intermediary-queries { + @each $parsed-feature-query in $parsed-feature-queries { + $parsed-feature-query: join($parsed-feature-query, $intermediary-query, $separator); + $new-parsed-feature-queries: append($new-parsed-feature-queries, $parsed-feature-query, 'comma'); + } + } + } @else { + $new-parsed-feature-queries: $parsed-feature-queries; + + @each $intermediary-query in $intermediary-queries { + $new-parsed-feature-queries: append($new-parsed-feature-queries, $intermediary-query, 'comma'); + } + } + } @else { + // List item is a string + $parsed-current-query: if($do-parse, parse-expression($query), $query); + + @if (type-of($parsed-current-query) == 'list') { + // Parsed expression is a list + $intermediary-queries: chain-feature-queries($parsed-current-query, false); + + @if ($separator == 'space') { + @each $intermediary-query in $intermediary-queries { + @each $parsed-feature-query in $parsed-feature-queries { + $parsed-feature-query: append($parsed-feature-query, $intermediary-query, $separator); + $new-parsed-feature-queries: append($new-parsed-feature-queries, $parsed-feature-query, 'comma'); + } + } + } @else { + $new-parsed-feature-queries: $parsed-feature-queries; + + @each $intermediary-query in $intermediary-queries { + $new-parsed-feature-queries: append($new-parsed-feature-queries, $intermediary-query, 'comma'); + } + } + } @else { + // Parsed expression is a string + @if ($separator == 'space') { + @each $parsed-feature-query in $parsed-feature-queries { + $parsed-feature-query: append($parsed-feature-query, $parsed-current-query, $separator); + $new-parsed-feature-queries: append($new-parsed-feature-queries, $parsed-feature-query, 'comma'); + } + } @else { + $new-parsed-feature-queries: $parsed-feature-queries; + + $new-parsed-feature-queries: append($new-parsed-feature-queries, ($parsed-current-query), 'comma'); + } + } + + } + + $parsed-feature-queries: $new-parsed-feature-queries; + } + + @return $parsed-feature-queries; +} /// /// Parse an expression to return a valid media-query expression @@ -558,7 +631,19 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; @if ($im-media-support and length($conditions) == 0) or (not $im-media-support and im-intercepts-static-breakpoint($conditions...)) { @content; + } @else if ($im-media-support and length($conditions) == 1 and type-of(nth($conditions, 1)) == 'list') { + // List mode with AND / OR conditions + //@debug 'List mode:'; + //@debug 'List: #{nth($conditions, 1)}'; + //@debug 'length: #{length(nth($conditions, 1))}'; + //@debug 'Separator: #{list-separator(nth($conditions, 1))}'; + + $test: chain-feature-queries(nth($conditions, 1)); + @debug $test; + + } @else if ($im-media-support and length($conditions) > 0) { + // Legacy mode @media #{unquote(parse-expression(nth($conditions, 1)))} { // Recursive call @include media(slice($conditions, 2)...) { diff --git a/src/_config.scss b/src/_config.scss index b55fd03..bc34d41 100644 --- a/src/_config.scss +++ b/src/_config.scss @@ -35,8 +35,8 @@ $media-expressions: ( 'handheld': 'handheld', 'landscape': '(orientation: landscape)', 'portrait': '(orientation: portrait)', - 'retina2x': '(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi), (min-resolution: 2dppx)', - 'retina3x': '(-webkit-min-device-pixel-ratio: 3), (min-resolution: 350dpi), (min-resolution: 3dppx)' + 'retina2x': ('(-webkit-min-device-pixel-ratio: 2)', '(min-resolution: 192dpi)', '(min-resolution: 2dppx)'), + 'retina3x': ('(-webkit-min-device-pixel-ratio: 3)', '(min-resolution: 350dpi)', '(min-resolution: 3dppx)') ) !default; diff --git a/src/_media.scss b/src/_media.scss index 120b003..63f91de 100644 --- a/src/_media.scss +++ b/src/_media.scss @@ -33,7 +33,19 @@ @if ($im-media-support and length($conditions) == 0) or (not $im-media-support and im-intercepts-static-breakpoint($conditions...)) { @content; + } @else if ($im-media-support and length($conditions) == 1 and type-of(nth($conditions, 1)) == 'list') { + // List mode with AND / OR conditions + //@debug 'List mode:'; + //@debug 'List: #{nth($conditions, 1)}'; + //@debug 'length: #{length(nth($conditions, 1))}'; + //@debug 'Separator: #{list-separator(nth($conditions, 1))}'; + + $test: chain-feature-queries(nth($conditions, 1)); + @debug $test; + + } @else if ($im-media-support and length($conditions) > 0) { + // Legacy mode @media #{unquote(parse-expression(nth($conditions, 1)))} { // Recursive call @include media(slice($conditions, 2)...) { diff --git a/src/helpers/_no-media.scss b/src/helpers/_no-media.scss index 47974e8..3b08197 100644 --- a/src/helpers/_no-media.scss +++ b/src/helpers/_no-media.scss @@ -1,3 +1,5 @@ +/// TODO: Check + /// /// Determines whether a list of conditions is intercepted by the static breakpoint. /// diff --git a/src/helpers/_parser.scss b/src/helpers/_parser.scss index 28c906a..4f65ae3 100644 --- a/src/helpers/_parser.scss +++ b/src/helpers/_parser.scss @@ -4,7 +4,6 @@ /// @access private //// - /// /// Get operator of an expression /// @@ -27,7 +26,6 @@ $_: log('No operator found in `#{$expression}`.'); } - /// /// Get dimension of an expression, based on a found operator /// @@ -48,7 +46,6 @@ @return $dimension; } - /// /// Get dimension prefix based on an operator /// @@ -60,7 +57,6 @@ @return if(index(('<', '<=', '≤'), $operator), 'max', 'min'); } - /// /// Get value of an expression, based on a found operator /// @@ -99,6 +95,81 @@ @return $value; } +/// +/// TODO: Documentation +/// +/// @param {String} $feature-queries - (TODO: documentation) +/// +/// @return {String} - (TODO: documentation) +/// +@function chain-feature-queries($feature-queries, $do-parse: true) { + $separator: list-separator($feature-queries); + $parsed-feature-queries: if($separator == 'comma', (), ((),)); + + @each $query in $feature-queries { + $new-parsed-feature-queries: (); + + @if (type-of($query) == 'list') { + // List item is a list itself + $intermediary-queries: chain-feature-queries($query); // Returns a nested list in the form: ((a b), (c)) + + @if ($separator == 'space') { + @each $intermediary-query in $intermediary-queries { + @each $parsed-feature-query in $parsed-feature-queries { + $parsed-feature-query: join($parsed-feature-query, $intermediary-query, $separator); + $new-parsed-feature-queries: append($new-parsed-feature-queries, $parsed-feature-query, 'comma'); + } + } + } @else { + $new-parsed-feature-queries: $parsed-feature-queries; + + @each $intermediary-query in $intermediary-queries { + $new-parsed-feature-queries: append($new-parsed-feature-queries, $intermediary-query, 'comma'); + } + } + } @else { + // List item is a string + $parsed-current-query: if($do-parse, parse-expression($query), $query); + + @if (type-of($parsed-current-query) == 'list') { + // Parsed expression is a list + $intermediary-queries: chain-feature-queries($parsed-current-query, false); + + @if ($separator == 'space') { + @each $intermediary-query in $intermediary-queries { + @each $parsed-feature-query in $parsed-feature-queries { + $parsed-feature-query: append($parsed-feature-query, $intermediary-query, $separator); + $new-parsed-feature-queries: append($new-parsed-feature-queries, $parsed-feature-query, 'comma'); + } + } + } @else { + $new-parsed-feature-queries: $parsed-feature-queries; + + @each $intermediary-query in $intermediary-queries { + $new-parsed-feature-queries: append($new-parsed-feature-queries, $intermediary-query, 'comma'); + } + } + } @else { + // Parsed expression is a string + @if ($separator == 'space') { + @each $parsed-feature-query in $parsed-feature-queries { + $parsed-feature-query: append($parsed-feature-query, $parsed-current-query, $separator); + $new-parsed-feature-queries: append($new-parsed-feature-queries, $parsed-feature-query, 'comma'); + } + } @else { + $new-parsed-feature-queries: $parsed-feature-queries; + + $new-parsed-feature-queries: append($new-parsed-feature-queries, ($parsed-current-query), 'comma'); + } + } + + } + + $parsed-feature-queries: $new-parsed-feature-queries; + } + + @return $parsed-feature-queries; +} /// /// Parse an expression to return a valid media-query expression From 5d05d2e949a9e248b11c134bf88b82c3d55dc985 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20Bu=CC=88hlmann?= Date: Tue, 18 Oct 2016 12:22:05 +0200 Subject: [PATCH 02/10] Simplify chain-feature-query parser --- src/helpers/_parser.scss | 82 ++++++++++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 25 deletions(-) diff --git a/src/helpers/_parser.scss b/src/helpers/_parser.scss index 4f65ae3..31ff5cb 100644 --- a/src/helpers/_parser.scss +++ b/src/helpers/_parser.scss @@ -134,33 +134,41 @@ @if (type-of($parsed-current-query) == 'list') { // Parsed expression is a list $intermediary-queries: chain-feature-queries($parsed-current-query, false); - - @if ($separator == 'space') { - @each $intermediary-query in $intermediary-queries { - @each $parsed-feature-query in $parsed-feature-queries { - $parsed-feature-query: append($parsed-feature-query, $intermediary-query, $separator); - $new-parsed-feature-queries: append($new-parsed-feature-queries, $parsed-feature-query, 'comma'); - } - } - } @else { - $new-parsed-feature-queries: $parsed-feature-queries; - - @each $intermediary-query in $intermediary-queries { - $new-parsed-feature-queries: append($new-parsed-feature-queries, $intermediary-query, 'comma'); - } - } + $new-parsed-feature-queries: append-feature-query($parsed-feature-queries, $intermediary-queries, $separator); + + //@if ($separator == 'space') { + // @each $intermediary-query in $intermediary-queries { + // @each $parsed-feature-query in $parsed-feature-queries { + // $parsed-feature-query: append($parsed-feature-query, $intermediary-query, $separator); + // $new-parsed-feature-queries: append($new-parsed-feature-queries, $parsed-feature-query, 'comma'); + // } + // } + //} @else { + // $new-parsed-feature-queries: $parsed-feature-queries; + // + // @each $intermediary-query in $intermediary-queries { + // $new-parsed-feature-queries: append($new-parsed-feature-queries, $intermediary-query, 'comma'); + // } + //} } @else { // Parsed expression is a string - @if ($separator == 'space') { - @each $parsed-feature-query in $parsed-feature-queries { - $parsed-feature-query: append($parsed-feature-query, $parsed-current-query, $separator); - $new-parsed-feature-queries: append($new-parsed-feature-queries, $parsed-feature-query, 'comma'); - } - } @else { - $new-parsed-feature-queries: $parsed-feature-queries; - - $new-parsed-feature-queries: append($new-parsed-feature-queries, ($parsed-current-query), 'comma'); - } + $intermediary-queries: ($parsed-current-query); + $new-parsed-feature-queries: append-feature-query($parsed-feature-queries, $intermediary-queries, $separator); + + //@if ($separator == 'space') { + // @each $intermediary-query in $intermediary-queries { + // @each $parsed-feature-query in $parsed-feature-queries { + // $parsed-feature-query: append($parsed-feature-query, $intermediary-query, $separator); + // $new-parsed-feature-queries: append($new-parsed-feature-queries, $parsed-feature-query, 'comma'); + // } + // } + //} @else { + // $new-parsed-feature-queries: $parsed-feature-queries; + // + // @each $intermediary-query in $intermediary-queries { + // $new-parsed-feature-queries: append($new-parsed-feature-queries, $intermediary-query, 'comma'); + // } + //} } } @@ -171,6 +179,30 @@ @return $parsed-feature-queries; } +/// +/// TODO: Documentation +/// +@function append-feature-query($parent-queries, $child-queries, $separator) { + $result: if($separator == 'space', (), $parent-queries); + + @if ($separator == 'space') { + // Logical AND + @each $child-query in $child-queries { + @each $parent-query in $parent-queries { + $q: append($parent-query, $child-query, $separator); + $result: append($result, $q, 'comma'); + } + } + } @else { + // Logical OR + @each $child-query in $child-queries { + $result: append($result, $child-query, 'comma'); + } + } + + @return $result; +} + /// /// Parse an expression to return a valid media-query expression /// From 5f49ad9ac606711b0dbd6cef97bfffc7193ec06e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20Bu=CC=88hlmann?= Date: Tue, 18 Oct 2016 14:11:27 +0200 Subject: [PATCH 03/10] Finish basic implementation and code refactoring --- dist/_include-media.scss | 130 ++++++++++++++++++++----------------- src/_media.scss | 18 ++--- src/helpers/_no-media.scss | 2 - src/helpers/_parser.scss | 116 +++++++++++++-------------------- 4 files changed, 124 insertions(+), 142 deletions(-) diff --git a/dist/_include-media.scss b/dist/_include-media.scss index 5f4c4a6..92b014d 100644 --- a/dist/_include-media.scss +++ b/dist/_include-media.scss @@ -351,77 +351,85 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; /// /// TODO: Documentation /// -/// @param {String} $feature-queries - (TODO: documentation) +/// @param {String} $queries - (TODO: documentation) +/// @param {Boolean} $do-parse - (TODO: documentation) /// /// @return {String} - (TODO: documentation) /// -@function chain-feature-queries($feature-queries, $do-parse: true) { - $separator: list-separator($feature-queries); - $parsed-feature-queries: if($separator == 'comma', (), ((),)); +@function resolve-feature-queries($queries, $do-parse: true) { + $separator: list-separator($queries); + $result: if($separator == 'space', ((),), ()); - @each $query in $feature-queries { - $new-parsed-feature-queries: (); + @each $query in $queries { + $chainable-queries: (); @if (type-of($query) == 'list') { // List item is a list itself - $intermediary-queries: chain-feature-queries($query); // Returns a nested list in the form: ((a b), (c)) - - @if ($separator == 'space') { - @each $intermediary-query in $intermediary-queries { - @each $parsed-feature-query in $parsed-feature-queries { - $parsed-feature-query: join($parsed-feature-query, $intermediary-query, $separator); - $new-parsed-feature-queries: append($new-parsed-feature-queries, $parsed-feature-query, 'comma'); - } - } - } @else { - $new-parsed-feature-queries: $parsed-feature-queries; - - @each $intermediary-query in $intermediary-queries { - $new-parsed-feature-queries: append($new-parsed-feature-queries, $intermediary-query, 'comma'); - } - } + $chainable-queries: resolve-feature-queries($query); } @else { // List item is a string - $parsed-current-query: if($do-parse, parse-expression($query), $query); + $parsed-query: if($do-parse, parse-expression($query), $query); - @if (type-of($parsed-current-query) == 'list') { + @if (type-of($parsed-query) == 'list') { // Parsed expression is a list - $intermediary-queries: chain-feature-queries($parsed-current-query, false); - - @if ($separator == 'space') { - @each $intermediary-query in $intermediary-queries { - @each $parsed-feature-query in $parsed-feature-queries { - $parsed-feature-query: append($parsed-feature-query, $intermediary-query, $separator); - $new-parsed-feature-queries: append($new-parsed-feature-queries, $parsed-feature-query, 'comma'); - } - } - } @else { - $new-parsed-feature-queries: $parsed-feature-queries; - - @each $intermediary-query in $intermediary-queries { - $new-parsed-feature-queries: append($new-parsed-feature-queries, $intermediary-query, 'comma'); - } - } + $chainable-queries: resolve-feature-queries($parsed-query, false); } @else { // Parsed expression is a string - @if ($separator == 'space') { - @each $parsed-feature-query in $parsed-feature-queries { - $parsed-feature-query: append($parsed-feature-query, $parsed-current-query, $separator); - $new-parsed-feature-queries: append($new-parsed-feature-queries, $parsed-feature-query, 'comma'); - } - } @else { - $new-parsed-feature-queries: $parsed-feature-queries; - - $new-parsed-feature-queries: append($new-parsed-feature-queries, ($parsed-current-query), 'comma'); - } + $chainable-queries: ($parsed-query); + } + } + + $result: append-feature-query($result, $chainable-queries, $separator); + } + + @return $result; +} + +/// +/// TODO: Documentation +/// +@function append-feature-query($parent-queries, $child-queries, $separator) { + $result: if($separator == 'space', (), $parent-queries); + + @each $child-query in $child-queries { + @if ($separator == 'space') { + // Logical AND + @each $parent-query in $parent-queries { + $updated-query: join($parent-query, $child-query, $separator); + $result: append($result, $updated-query, 'comma'); } + } @else { + // Logical OR + $result: append($result, $child-query, 'comma'); + } + } + + @return $result; +} + +/// +/// TODO: Documentation +/// +@function parse-media-query($queries) { + $result: null; + $flat-queries: (); + $separator: list-separator($queries); + $conjunction: if($separator == 'space', ' and ', ', '); + @each $query in $queries { + @if (type-of($query) == 'list') { + $flat-queries: append($flat-queries, parse-media-query($query)); + } @else { + $flat-queries: append($flat-queries, $query); } + } - $parsed-feature-queries: $new-parsed-feature-queries; + @for $i from 1 through length($flat-queries) { + $e: nth($flat-queries, $i); + $result: if($i != length($flat-queries), $result#{$e}#{$conjunction}, $result#{$e}); } - @return $parsed-feature-queries; + @return $result; } /// @@ -627,20 +635,20 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; /// @include media('>=350px', ' 0) { // Legacy mode diff --git a/src/_media.scss b/src/_media.scss index 63f91de..d371973 100644 --- a/src/_media.scss +++ b/src/_media.scss @@ -29,20 +29,20 @@ /// @include media('>=350px', ' 0) { // Legacy mode diff --git a/src/helpers/_no-media.scss b/src/helpers/_no-media.scss index 3b08197..47974e8 100644 --- a/src/helpers/_no-media.scss +++ b/src/helpers/_no-media.scss @@ -1,5 +1,3 @@ -/// TODO: Check - /// /// Determines whether a list of conditions is intercepted by the static breakpoint. /// diff --git a/src/helpers/_parser.scss b/src/helpers/_parser.scss index 31ff5cb..8a25327 100644 --- a/src/helpers/_parser.scss +++ b/src/helpers/_parser.scss @@ -98,85 +98,38 @@ /// /// TODO: Documentation /// -/// @param {String} $feature-queries - (TODO: documentation) +/// @param {String} $queries - (TODO: documentation) +/// @param {Boolean} $do-parse - (TODO: documentation) /// /// @return {String} - (TODO: documentation) /// -@function chain-feature-queries($feature-queries, $do-parse: true) { - $separator: list-separator($feature-queries); - $parsed-feature-queries: if($separator == 'comma', (), ((),)); +@function resolve-feature-queries($queries, $do-parse: true) { + $separator: list-separator($queries); + $result: if($separator == 'space', ((),), ()); - @each $query in $feature-queries { - $new-parsed-feature-queries: (); + @each $query in $queries { + $chainable-queries: (); @if (type-of($query) == 'list') { // List item is a list itself - $intermediary-queries: chain-feature-queries($query); // Returns a nested list in the form: ((a b), (c)) - - @if ($separator == 'space') { - @each $intermediary-query in $intermediary-queries { - @each $parsed-feature-query in $parsed-feature-queries { - $parsed-feature-query: join($parsed-feature-query, $intermediary-query, $separator); - $new-parsed-feature-queries: append($new-parsed-feature-queries, $parsed-feature-query, 'comma'); - } - } - } @else { - $new-parsed-feature-queries: $parsed-feature-queries; - - @each $intermediary-query in $intermediary-queries { - $new-parsed-feature-queries: append($new-parsed-feature-queries, $intermediary-query, 'comma'); - } - } + $chainable-queries: resolve-feature-queries($query); } @else { // List item is a string - $parsed-current-query: if($do-parse, parse-expression($query), $query); + $parsed-query: if($do-parse, parse-expression($query), $query); - @if (type-of($parsed-current-query) == 'list') { + @if (type-of($parsed-query) == 'list') { // Parsed expression is a list - $intermediary-queries: chain-feature-queries($parsed-current-query, false); - $new-parsed-feature-queries: append-feature-query($parsed-feature-queries, $intermediary-queries, $separator); - - //@if ($separator == 'space') { - // @each $intermediary-query in $intermediary-queries { - // @each $parsed-feature-query in $parsed-feature-queries { - // $parsed-feature-query: append($parsed-feature-query, $intermediary-query, $separator); - // $new-parsed-feature-queries: append($new-parsed-feature-queries, $parsed-feature-query, 'comma'); - // } - // } - //} @else { - // $new-parsed-feature-queries: $parsed-feature-queries; - // - // @each $intermediary-query in $intermediary-queries { - // $new-parsed-feature-queries: append($new-parsed-feature-queries, $intermediary-query, 'comma'); - // } - //} + $chainable-queries: resolve-feature-queries($parsed-query, false); } @else { // Parsed expression is a string - $intermediary-queries: ($parsed-current-query); - $new-parsed-feature-queries: append-feature-query($parsed-feature-queries, $intermediary-queries, $separator); - - //@if ($separator == 'space') { - // @each $intermediary-query in $intermediary-queries { - // @each $parsed-feature-query in $parsed-feature-queries { - // $parsed-feature-query: append($parsed-feature-query, $intermediary-query, $separator); - // $new-parsed-feature-queries: append($new-parsed-feature-queries, $parsed-feature-query, 'comma'); - // } - // } - //} @else { - // $new-parsed-feature-queries: $parsed-feature-queries; - // - // @each $intermediary-query in $intermediary-queries { - // $new-parsed-feature-queries: append($new-parsed-feature-queries, $intermediary-query, 'comma'); - // } - //} + $chainable-queries: ($parsed-query); } - } - $parsed-feature-queries: $new-parsed-feature-queries; + $result: append-feature-query($result, $chainable-queries, $separator); } - @return $parsed-feature-queries; + @return $result; } /// @@ -185,17 +138,15 @@ @function append-feature-query($parent-queries, $child-queries, $separator) { $result: if($separator == 'space', (), $parent-queries); - @if ($separator == 'space') { - // Logical AND - @each $child-query in $child-queries { + @each $child-query in $child-queries { + @if ($separator == 'space') { + // Logical AND @each $parent-query in $parent-queries { - $q: append($parent-query, $child-query, $separator); - $result: append($result, $q, 'comma'); + $updated-query: join($parent-query, $child-query, $separator); + $result: append($result, $updated-query, 'comma'); } - } - } @else { - // Logical OR - @each $child-query in $child-queries { + } @else { + // Logical OR $result: append($result, $child-query, 'comma'); } } @@ -203,6 +154,31 @@ @return $result; } +/// +/// TODO: Documentation +/// +@function parse-media-query($queries) { + $result: null; + $flat-queries: (); + $separator: list-separator($queries); + $conjunction: if($separator == 'space', ' and ', ', '); + + @each $query in $queries { + @if (type-of($query) == 'list') { + $flat-queries: append($flat-queries, parse-media-query($query)); + } @else { + $flat-queries: append($flat-queries, $query); + } + } + + @for $i from 1 through length($flat-queries) { + $e: nth($flat-queries, $i); + $result: if($i != length($flat-queries), $result#{$e}#{$conjunction}, $result#{$e}); + } + + @return $result; +} + /// /// Parse an expression to return a valid media-query expression /// From a2c1b06efd29084468deb18ef9925f5b67350830 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20Bu=CC=88hlmann?= Date: Tue, 18 Oct 2016 16:39:00 +0200 Subject: [PATCH 04/10] Externalize list-parser related functions --- src/helpers/_list-parser.scss | 83 ++++++++++++++++++++++++++++++++++ src/helpers/_parser.scss | 84 ----------------------------------- 2 files changed, 83 insertions(+), 84 deletions(-) create mode 100644 src/helpers/_list-parser.scss diff --git a/src/helpers/_list-parser.scss b/src/helpers/_list-parser.scss new file mode 100644 index 0000000..6ec8c0c --- /dev/null +++ b/src/helpers/_list-parser.scss @@ -0,0 +1,83 @@ +/// +/// TODO: Documentation +/// +/// @param {String} $queries - (TODO: documentation) +/// @param {Boolean} $do-parse - (TODO: documentation) +/// +/// @return {String} - (TODO: documentation) +/// +@function resolve-feature-queries($queries, $do-parse: true) { + $separator: list-separator($queries); + $result: if($separator == 'space', ((),), ()); + + @each $query in $queries { + $chainable-queries: (); + + @if (type-of($query) == 'list') { + // List item is a list itself + $chainable-queries: resolve-feature-queries($query); + } @else { + // List item is a string + $parsed-query: if($do-parse, parse-expression($query), $query); + + @if (type-of($parsed-query) == 'list') { + // Parsed expression is a list + $chainable-queries: resolve-feature-queries($parsed-query, false); + } @else { + // Parsed expression is a string + $chainable-queries: ($parsed-query); + } + } + + $result: append-feature-query($result, $chainable-queries, $separator); + } + + @return $result; +} + +/// +/// TODO: Documentation +/// +@function append-feature-query($parent-queries, $child-queries, $separator) { + $result: if($separator == 'space', (), $parent-queries); + + @each $child-query in $child-queries { + @if ($separator == 'space') { + // Logical AND + @each $parent-query in $parent-queries { + $updated-query: join($parent-query, $child-query, $separator); + $result: append($result, $updated-query, 'comma'); + } + } @else { + // Logical OR + $result: append($result, $child-query, 'comma'); + } + } + + @return $result; +} + +/// +/// TODO: Documentation +/// +@function parse-media-query($queries) { + $result: null; + $flat-queries: (); + $separator: list-separator($queries); + $conjunction: if($separator == 'space', ' and ', ', '); + + @each $query in $queries { + @if (type-of($query) == 'list') { + $flat-queries: append($flat-queries, parse-media-query($query)); + } @else { + $flat-queries: append($flat-queries, $query); + } + } + + @for $i from 1 through length($flat-queries) { + $e: nth($flat-queries, $i); + $result: if($i != length($flat-queries), $result#{$e}#{$conjunction}, $result#{$e}); + } + + @return $result; +} diff --git a/src/helpers/_parser.scss b/src/helpers/_parser.scss index 8a25327..e3840b4 100644 --- a/src/helpers/_parser.scss +++ b/src/helpers/_parser.scss @@ -95,90 +95,6 @@ @return $value; } -/// -/// TODO: Documentation -/// -/// @param {String} $queries - (TODO: documentation) -/// @param {Boolean} $do-parse - (TODO: documentation) -/// -/// @return {String} - (TODO: documentation) -/// -@function resolve-feature-queries($queries, $do-parse: true) { - $separator: list-separator($queries); - $result: if($separator == 'space', ((),), ()); - - @each $query in $queries { - $chainable-queries: (); - - @if (type-of($query) == 'list') { - // List item is a list itself - $chainable-queries: resolve-feature-queries($query); - } @else { - // List item is a string - $parsed-query: if($do-parse, parse-expression($query), $query); - - @if (type-of($parsed-query) == 'list') { - // Parsed expression is a list - $chainable-queries: resolve-feature-queries($parsed-query, false); - } @else { - // Parsed expression is a string - $chainable-queries: ($parsed-query); - } - } - - $result: append-feature-query($result, $chainable-queries, $separator); - } - - @return $result; -} - -/// -/// TODO: Documentation -/// -@function append-feature-query($parent-queries, $child-queries, $separator) { - $result: if($separator == 'space', (), $parent-queries); - - @each $child-query in $child-queries { - @if ($separator == 'space') { - // Logical AND - @each $parent-query in $parent-queries { - $updated-query: join($parent-query, $child-query, $separator); - $result: append($result, $updated-query, 'comma'); - } - } @else { - // Logical OR - $result: append($result, $child-query, 'comma'); - } - } - - @return $result; -} - -/// -/// TODO: Documentation -/// -@function parse-media-query($queries) { - $result: null; - $flat-queries: (); - $separator: list-separator($queries); - $conjunction: if($separator == 'space', ' and ', ', '); - - @each $query in $queries { - @if (type-of($query) == 'list') { - $flat-queries: append($flat-queries, parse-media-query($query)); - } @else { - $flat-queries: append($flat-queries, $query); - } - } - - @for $i from 1 through length($flat-queries) { - $e: nth($flat-queries, $i); - $result: if($i != length($flat-queries), $result#{$e}#{$conjunction}, $result#{$e}); - } - - @return $result; -} - /// /// Parse an expression to return a valid media-query expression /// From dc7088f700d201cda17919de9a1dc05e409eed93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20Bu=CC=88hlmann?= Date: Tue, 18 Oct 2016 17:03:39 +0200 Subject: [PATCH 05/10] Add documentation, rename `parser` to `expression-parser` --- .../{_parser.scss => _expression-parser.scss} | 0 src/helpers/_list-parser.scss | 30 ++++++++++++------- 2 files changed, 20 insertions(+), 10 deletions(-) rename src/helpers/{_parser.scss => _expression-parser.scss} (100%) diff --git a/src/helpers/_parser.scss b/src/helpers/_expression-parser.scss similarity index 100% rename from src/helpers/_parser.scss rename to src/helpers/_expression-parser.scss diff --git a/src/helpers/_list-parser.scss b/src/helpers/_list-parser.scss index 6ec8c0c..21e22ae 100644 --- a/src/helpers/_list-parser.scss +++ b/src/helpers/_list-parser.scss @@ -1,10 +1,10 @@ /// -/// TODO: Documentation +/// Get a shallow list of resolved feature queries /// -/// @param {String} $queries - (TODO: documentation) -/// @param {Boolean} $do-parse - (TODO: documentation) +/// @param {String} $queries - A nested list structure +/// @param {Boolean} $do-parse - Try to parse expressions /// -/// @return {String} - (TODO: documentation) +/// @return {List} - A one item deep nested list like `(a b, c d e)` /// @function resolve-feature-queries($queries, $do-parse: true) { $separator: list-separator($queries); @@ -36,15 +36,21 @@ } /// -/// TODO: Documentation +/// Combine two query lists as a logical AND / OR operation /// -@function append-feature-query($parent-queries, $child-queries, $separator) { - $result: if($separator == 'space', (), $parent-queries); +/// @param {List} $base-queries - The host list +/// @param {List} $append-queries - The list that is being appended +/// @param {String} $separator - Either `space` or `comma` +/// +/// @return {List} - A one item deep nested list like `(a b, c d e)` +/// +@function append-feature-query($base-queries, $append-queries, $separator) { + $result: if($separator == 'space', (), $base-queries); - @each $child-query in $child-queries { + @each $child-query in $append-queries { @if ($separator == 'space') { // Logical AND - @each $parent-query in $parent-queries { + @each $parent-query in $base-queries { $updated-query: join($parent-query, $child-query, $separator); $result: append($result, $updated-query, 'comma'); } @@ -58,7 +64,11 @@ } /// -/// TODO: Documentation +/// Parse a list of resolved expressions to return a valid media-query +/// +/// @param {List} $queries - A one item deep nested list like `(a b, c d e)` +/// +/// @return {String} - A valid media-query string /// @function parse-media-query($queries) { $result: null; From 7016f17e222c14f30df15000d33bee90b579cae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20Bu=CC=88hlmann?= Date: Tue, 18 Oct 2016 17:15:31 +0200 Subject: [PATCH 06/10] Fix lint errors --- dist/_include-media.scss | 221 +++++++++++++++++----------------- src/_media.scss | 3 - src/helpers/_list-parser.scss | 4 +- 3 files changed, 115 insertions(+), 113 deletions(-) diff --git a/dist/_include-media.scss b/dist/_include-media.scss index 92b014d..b15c4e1 100644 --- a/dist/_include-media.scss +++ b/dist/_include-media.scss @@ -171,86 +171,6 @@ $im-no-media-breakpoint: 'desktop' !default; /// $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; -//// -/// Cross-engine logging engine -/// @author Hugo Giraudel -/// @access private -//// - - -/// -/// Log a message either with `@error` if supported -/// else with `@warn`, using `feature-exists('at-error')` -/// to detect support. -/// -/// @param {String} $message - Message to log -/// -@function log($message) { - @if feature-exists('at-error') { - @error $message; - } @else { - @warn $message; - $_: noop(); - } - - @return $message; -} - - -/// -/// Wrapper mixin for the log function so it can be used with a more friendly -/// API than `@if log('..') {}` or `$_: log('..')`. Basically, use the function -/// within functions because it is not possible to include a mixin in a function -/// and use the mixin everywhere else because it's much more elegant. -/// -/// @param {String} $message - Message to log -/// -@mixin log($message) { - @if log($message) {} -} - - -/// -/// Function with no `@return` called next to `@warn` in Sass 3.3 -/// to trigger a compiling error and stop the process. -/// -@function noop() {} - -/// TODO: Check - -/// -/// Determines whether a list of conditions is intercepted by the static breakpoint. -/// -/// @param {Arglist} $conditions - Media query conditions -/// -/// @return {Boolean} - Returns true if the conditions are intercepted by the static breakpoint -/// -@function im-intercepts-static-breakpoint($conditions...) { - $no-media-breakpoint-value: map-get($breakpoints, $im-no-media-breakpoint); - - @if not $no-media-breakpoint-value { - @if log('`#{$im-no-media-breakpoint}` is not a valid breakpoint.') {} - } - - @each $condition in $conditions { - @if not map-has-key($media-expressions, $condition) { - $operator: get-expression-operator($condition); - $prefix: get-expression-prefix($operator); - $value: get-expression-value($condition, $operator); - - // scss-lint:disable SpaceAroundOperator - @if ($prefix == 'max' and $value <= $no-media-breakpoint-value) or - ($prefix == 'min' and $value > $no-media-breakpoint-value) { - @return false; - } - } @else if not index($im-no-media-expressions, $condition) { - @return false; - } - } - - @return true; -} - //// /// Parsing engine /// @author Hugo Giraudel @@ -349,16 +269,38 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; } /// -/// TODO: Documentation +/// Parse an expression to return a valid media-query expression +/// +/// @param {String} $expression - Expression to parse +/// +/// @return {String} - Valid media query +/// +@function parse-expression($expression) { + // If it is part of $media-expressions, it has no operator + // then there is no need to go any further, just return the value + @if map-has-key($media-expressions, $expression) { + @return map-get($media-expressions, $expression); + } + + $operator: get-expression-operator($expression); + $dimension: get-expression-dimension($expression, $operator); + $prefix: get-expression-prefix($operator); + $value: get-expression-value($expression, $operator); + + @return '(#{$prefix}-#{$dimension}: #{$value})'; +} + +/// +/// Get a shallow list of resolved feature queries /// -/// @param {String} $queries - (TODO: documentation) -/// @param {Boolean} $do-parse - (TODO: documentation) +/// @param {String} $queries - A nested list structure +/// @param {Boolean} $do-parse - Try to parse expressions /// -/// @return {String} - (TODO: documentation) +/// @return {List} - A one item deep nested list like `(a b, c d e)` /// @function resolve-feature-queries($queries, $do-parse: true) { $separator: list-separator($queries); - $result: if($separator == 'space', ((),), ()); + $result: if($separator == 'space', ((), ), ()); @each $query in $queries { $chainable-queries: (); @@ -386,15 +328,21 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; } /// -/// TODO: Documentation +/// Combine two query lists as a logical AND / OR operation +/// +/// @param {List} $base-queries - The host list +/// @param {List} $append-queries - The list that is being appended +/// @param {String} $separator - Either `space` or `comma` +/// +/// @return {List} - A one item deep nested list like `(a b, c d e)` /// -@function append-feature-query($parent-queries, $child-queries, $separator) { - $result: if($separator == 'space', (), $parent-queries); +@function append-feature-query($base-queries, $append-queries, $separator) { + $result: if($separator == 'space', (), $base-queries); - @each $child-query in $child-queries { + @each $child-query in $append-queries { @if ($separator == 'space') { // Logical AND - @each $parent-query in $parent-queries { + @each $parent-query in $base-queries { $updated-query: join($parent-query, $child-query, $separator); $result: append($result, $updated-query, 'comma'); } @@ -408,7 +356,11 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; } /// -/// TODO: Documentation +/// Parse a list of resolved expressions to return a valid media-query +/// +/// @param {List} $queries - A one item deep nested list like `(a b, c d e)` +/// +/// @return {String} - A valid media-query string /// @function parse-media-query($queries) { $result: null; @@ -426,32 +378,88 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; @for $i from 1 through length($flat-queries) { $e: nth($flat-queries, $i); - $result: if($i != length($flat-queries), $result#{$e}#{$conjunction}, $result#{$e}); + $result: unquote('#{$result}#{$e}#{if($i != length($flat-queries), $conjunction, '')}'); } @return $result; } +//// +/// Cross-engine logging engine +/// @author Hugo Giraudel +/// @access private +//// + + /// -/// Parse an expression to return a valid media-query expression +/// Log a message either with `@error` if supported +/// else with `@warn`, using `feature-exists('at-error')` +/// to detect support. /// -/// @param {String} $expression - Expression to parse +/// @param {String} $message - Message to log /// -/// @return {String} - Valid media query +@function log($message) { + @if feature-exists('at-error') { + @error $message; + } @else { + @warn $message; + $_: noop(); + } + + @return $message; +} + + /// -@function parse-expression($expression) { - // If it is part of $media-expressions, it has no operator - // then there is no need to go any further, just return the value - @if map-has-key($media-expressions, $expression) { - @return map-get($media-expressions, $expression); +/// Wrapper mixin for the log function so it can be used with a more friendly +/// API than `@if log('..') {}` or `$_: log('..')`. Basically, use the function +/// within functions because it is not possible to include a mixin in a function +/// and use the mixin everywhere else because it's much more elegant. +/// +/// @param {String} $message - Message to log +/// +@mixin log($message) { + @if log($message) {} +} + + +/// +/// Function with no `@return` called next to `@warn` in Sass 3.3 +/// to trigger a compiling error and stop the process. +/// +@function noop() {} + +/// +/// Determines whether a list of conditions is intercepted by the static breakpoint. +/// +/// @param {Arglist} $conditions - Media query conditions +/// +/// @return {Boolean} - Returns true if the conditions are intercepted by the static breakpoint +/// +@function im-intercepts-static-breakpoint($conditions...) { + $no-media-breakpoint-value: map-get($breakpoints, $im-no-media-breakpoint); + + @if not $no-media-breakpoint-value { + @if log('`#{$im-no-media-breakpoint}` is not a valid breakpoint.') {} } - $operator: get-expression-operator($expression); - $dimension: get-expression-dimension($expression, $operator); - $prefix: get-expression-prefix($operator); - $value: get-expression-value($expression, $operator); + @each $condition in $conditions { + @if not map-has-key($media-expressions, $condition) { + $operator: get-expression-operator($condition); + $prefix: get-expression-prefix($operator); + $value: get-expression-value($condition, $operator); - @return '(#{$prefix}-#{$dimension}: #{$value})'; + // scss-lint:disable SpaceAroundOperator + @if ($prefix == 'max' and $value <= $no-media-breakpoint-value) or + ($prefix == 'min' and $value > $no-media-breakpoint-value) { + @return false; + } + } @else if not index($im-no-media-expressions, $condition) { + @return false; + } + } + + @return true; } /// @@ -643,9 +651,6 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; @content; } @else if ($im-media-support and $is-list-mode) { // List mode with AND / OR conditions - @debug 'Parsed MQ:'; - @debug #{unquote(parse-media-query(resolve-feature-queries(nth($conditions, 1))))}; - @media #{unquote(parse-media-query(resolve-feature-queries(nth($conditions, 1))))} { @content; } diff --git a/src/_media.scss b/src/_media.scss index d371973..6dc1cb0 100644 --- a/src/_media.scss +++ b/src/_media.scss @@ -37,9 +37,6 @@ @content; } @else if ($im-media-support and $is-list-mode) { // List mode with AND / OR conditions - @debug 'Parsed MQ:'; - @debug #{unquote(parse-media-query(resolve-feature-queries(nth($conditions, 1))))}; - @media #{unquote(parse-media-query(resolve-feature-queries(nth($conditions, 1))))} { @content; } diff --git a/src/helpers/_list-parser.scss b/src/helpers/_list-parser.scss index 21e22ae..2d63ecb 100644 --- a/src/helpers/_list-parser.scss +++ b/src/helpers/_list-parser.scss @@ -8,7 +8,7 @@ /// @function resolve-feature-queries($queries, $do-parse: true) { $separator: list-separator($queries); - $result: if($separator == 'space', ((),), ()); + $result: if($separator == 'space', ((), ), ()); @each $query in $queries { $chainable-queries: (); @@ -86,7 +86,7 @@ @for $i from 1 through length($flat-queries) { $e: nth($flat-queries, $i); - $result: if($i != length($flat-queries), $result#{$e}#{$conjunction}, $result#{$e}); + $result: unquote('#{$result}#{$e}#{if($i != length($flat-queries), $conjunction, '')}'); } @return $result; From b4617a153fd0cee068b5e2c9d018b90cd02d6e73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20Bu=CC=88hlmann?= Date: Tue, 18 Oct 2016 23:13:30 +0200 Subject: [PATCH 07/10] Fix usage of list type media-expressions in legacy mode --- dist/_include-media.scss | 6 +++++- src/_media.scss | 2 +- src/helpers/_list-parser.scss | 4 ++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/dist/_include-media.scss b/dist/_include-media.scss index b15c4e1..9ea0fed 100644 --- a/dist/_include-media.scss +++ b/dist/_include-media.scss @@ -368,6 +368,10 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; $separator: list-separator($queries); $conjunction: if($separator == 'space', ' and ', ', '); + @if (type-of($queries) == 'string') { + @return $queries; + } + @each $query in $queries { @if (type-of($query) == 'list') { $flat-queries: append($flat-queries, parse-media-query($query)); @@ -657,7 +661,7 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; } @else if ($im-media-support and length($conditions) > 0) { // Legacy mode - @media #{unquote(parse-expression(nth($conditions, 1)))} { + @media #{unquote(parse-media-query(parse-expression(nth($conditions, 1))))} { // Recursive call @include media(slice($conditions, 2)...) { @content; diff --git a/src/_media.scss b/src/_media.scss index 6dc1cb0..2f9b6d6 100644 --- a/src/_media.scss +++ b/src/_media.scss @@ -43,7 +43,7 @@ } @else if ($im-media-support and length($conditions) > 0) { // Legacy mode - @media #{unquote(parse-expression(nth($conditions, 1)))} { + @media #{unquote(parse-media-query(parse-expression(nth($conditions, 1))))} { // Recursive call @include media(slice($conditions, 2)...) { @content; diff --git a/src/helpers/_list-parser.scss b/src/helpers/_list-parser.scss index 2d63ecb..93e5b76 100644 --- a/src/helpers/_list-parser.scss +++ b/src/helpers/_list-parser.scss @@ -76,6 +76,10 @@ $separator: list-separator($queries); $conjunction: if($separator == 'space', ' and ', ', '); + @if (type-of($queries) == 'string') { + @return $queries; + } + @each $query in $queries { @if (type-of($query) == 'list') { $flat-queries: append($flat-queries, parse-media-query($query)); From 6f64db45f153b15b4c34e8dd949790d41c039c7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20Bu=CC=88hlmann?= Date: Tue, 18 Oct 2016 23:14:41 +0200 Subject: [PATCH 08/10] Add tests --- tests/parse-media-query.scss | 11 +++++++++++ tests/resolve-feature-queries.scss | 30 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 tests/parse-media-query.scss create mode 100644 tests/resolve-feature-queries.scss diff --git a/tests/parse-media-query.scss b/tests/parse-media-query.scss new file mode 100644 index 0000000..83f73d1 --- /dev/null +++ b/tests/parse-media-query.scss @@ -0,0 +1,11 @@ +@import '../dist/include-media'; +@import 'helpers/SassyTester'; + +$tests-parse-media-query: ( + (('a' 'b'),): 'a and b', + (('a', 'b'),): 'a, b', + (('a' 'b', 'c' 'd'),): 'a and b, c and d', + (('a', 'b', 'c' 'd'),): 'a, b, c and d', +); + +@include run(test('parse-media-query', $tests-parse-media-query)); diff --git a/tests/resolve-feature-queries.scss b/tests/resolve-feature-queries.scss new file mode 100644 index 0000000..48abb4e --- /dev/null +++ b/tests/resolve-feature-queries.scss @@ -0,0 +1,30 @@ +@import '../dist/include-media'; +@import 'helpers/SassyTester'; + +$tests-resolve-feature-queries: ( + (('screen' '>desktop'), ): ( + ('screen' '(min-width: 1025px)'), + ), + (('screen', '>desktop'), ): ( + ('screen'), ('(min-width: 1025px)'), + ), + (('screen' ('>phone', 'phone'), ): ( + ('(-webkit-min-device-pixel-ratio: 2)' '(min-width: 321px)'), + ('(min-resolution: 192dpi)' '(min-width: 321px)'), + ('(min-resolution: 2dppx)' '(min-width: 321px)'), + ), + (('screen' ('height>300px' 'landscape')), ): ( + ('screen' '(min-height: 301px)' '(orientation: landscape)'), + ), + ((('screen', 'portrait') ('height>300px', 'landscape')), ): ( + ('screen' '(min-height: 301px)'), + ('(orientation: portrait)' '(min-height: 301px)'), + ('screen' '(orientation: landscape)'), + ('(orientation: portrait)' '(orientation: landscape)'), + ), +); + +@include run(test('resolve-feature-queries', $tests-resolve-feature-queries)); From de5160070756a0ea16e5c7270b278563dd6b25ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20Bu=CC=88hlmann?= Date: Tue, 18 Oct 2016 23:45:00 +0200 Subject: [PATCH 09/10] Fix inconsistent naming in each loops --- src/helpers/_list-parser.scss | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/helpers/_list-parser.scss b/src/helpers/_list-parser.scss index 93e5b76..41f95e7 100644 --- a/src/helpers/_list-parser.scss +++ b/src/helpers/_list-parser.scss @@ -47,16 +47,16 @@ @function append-feature-query($base-queries, $append-queries, $separator) { $result: if($separator == 'space', (), $base-queries); - @each $child-query in $append-queries { + @each $append-query in $append-queries { @if ($separator == 'space') { // Logical AND - @each $parent-query in $base-queries { - $updated-query: join($parent-query, $child-query, $separator); + @each $base-query in $base-queries { + $updated-query: join($base-query, $append-query, $separator); $result: append($result, $updated-query, 'comma'); } } @else { // Logical OR - $result: append($result, $child-query, 'comma'); + $result: append($result, $append-query, 'comma'); } } From 92bd1ea18ca21530a042b4c0ae297de6de463963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20Bu=CC=88hlmann?= Date: Tue, 18 Oct 2016 23:45:35 +0200 Subject: [PATCH 10/10] Bump dist file --- dist/_include-media.scss | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dist/_include-media.scss b/dist/_include-media.scss index 9ea0fed..db8de50 100644 --- a/dist/_include-media.scss +++ b/dist/_include-media.scss @@ -339,16 +339,16 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; @function append-feature-query($base-queries, $append-queries, $separator) { $result: if($separator == 'space', (), $base-queries); - @each $child-query in $append-queries { + @each $append-query in $append-queries { @if ($separator == 'space') { // Logical AND - @each $parent-query in $base-queries { - $updated-query: join($parent-query, $child-query, $separator); + @each $base-query in $base-queries { + $updated-query: join($base-query, $append-query, $separator); $result: append($result, $updated-query, 'comma'); } } @else { // Logical OR - $result: append($result, $child-query, 'comma'); + $result: append($result, $append-query, 'comma'); } }