// The browser usage threshold for features that gracefully degrade // Defaults to 1 user in 1,000. $graceful-usage-threshold: 0.1 !default; $debug-browser-support: false !default; // @private $default-capability-options: ( (full-support: 1), (partial-support: 1) ); // Yields to the mixin content once for each prefix required. // The current prefix is set to the $current-prefix global for use by the included content. // Also yields to the content once with $current-prefix set to null for the official version // as long as there's not already a prefix in scope. @mixin with-each-prefix($capability, $threshold) { @each $prefix, $should-use-prefix in prefixes-for-capability($capability, $threshold) { @if $should-use-prefix { @if $debug-browser-support and type-of($should-use-prefix) == list { /* Capability #{$capability} is prefixed with #{$prefix} because #{$should-use-prefix} is required. */ } @else if $debug-browser-support and type-of($should-use-prefix) == number { /* Capability #{$capability} is prefixed with #{$prefix} because #{$should-use-prefix}% of users need it which is more than the threshold of #{$threshold}%. */ } @include with-prefix($prefix) { @include with-browser-ranges($capability) { @content; } } } @else if $debug-browser-support { /* Capability #{$capability} is not prefixed with #{$prefix} because #{prefix-usage($prefix, $capability, $capability-options)}% of users are affected which is less than the threshold of #{$threshold}. */ } } @include with-prefix(null) { @include with-browser-ranges($capability) { @content; } } } // If there's a prefix context in scope, this will only output the content if the prefix matches. // Otherwise, sets the current prefix scope and outputs the content. @mixin with-prefix($prefix) { @if $current-prefix or $prefix-context { @if $current-prefix == $prefix or $prefix-context == $prefix { @if $debug-browser-support { @if $prefix { /* content for #{$prefix} because #{$current-prefix or $prefix-context} is already in scope. */ } @else { /* unprefixed content. #{$current-prefix or $prefix-context} is already in scope. */ } } $old-prefix-context: $prefix-context; $old-prefix: $current-prefix; $prefix-context: $prefix-context or $current-prefix !global; $current-prefix: $prefix !global; @content; $prefix-context: $old-prefix-context !global; $current-prefix: $old-prefix !global; } @else if $prefix == null { $old-prefix-context: $prefix-context; $prefix-context: $prefix-context or $current-prefix !global; $current-prefix: null !global; @if $debug-browser-support { /* Content for official syntax. Prefix context is still #{$prefix-context}. */ } @content; $current-prefix: $prefix-context !global; $prefix-context: $old-prefix-context !global; } @else if $debug-browser-support { /* Omitting content for #{$prefix} because #{$current-prefix} is already in scope. */ } } @else { @if $debug-browser-support and $prefix { /* Creating new #{$prefix} context. */ } $prefix-context: $prefix !global; $current-prefix: $prefix !global; @content; $current-prefix: null !global; $prefix-context: null !global; } } // If passed a map, that will be the new browser ranges. // Otherwise a range map will be created based on the given capability and prefix // using the `browser-ranges($capability, $prefix)` function. // // If there are current ranges in scope and the new ranges have some overlap // with the current, // // If there is no overlap, then the content will not be rendered. @mixin with-browser-ranges($capability, $prefix: $current-prefix) { $new-ranges: null; @if type-of($capability) == map { $new-ranges: $capability; } @else { $new-ranges: browser-ranges($capability, $prefix); } @if has-browser-subset($current-browser-versions, $new-ranges) { $old-ranges: $current-browser-versions; $current-browser-versions: intersect-browser-ranges($old-ranges, $new-ranges) !global; @content; $current-browser-versions: $old-ranges !global; } @else if $debug-browser-support { /* Excluding content because #{inspect($new-ranges)} is not included within #{inspect($current-browser-versions)} */ } } // Output a property and value using the current prefix. // It will be unprefixed if $current-prefix is null. @mixin prefix-prop($property, $value, $prefix: $current-prefix) { #{prefix-identifier($property, $prefix)}: $value; }