gem_2345 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. data/lib/gem_2345/import-once.rb +28 -0
  2. data/lib/gem_2345/import-once/activate.rb +20 -0
  3. data/lib/gem_2345/import-once/engine.rb +36 -0
  4. data/lib/gem_2345/import-once/importer.rb +81 -0
  5. data/lib/gem_2345/import-once/version.rb +5 -0
  6. data/lib/gem_2345/version.rb +1 -1
  7. data/stylesheets/_compass.scss +3 -0
  8. data/stylesheets/_lemonade.scss +38 -0
  9. data/stylesheets/compass/_configuration.scss +54 -0
  10. data/stylesheets/compass/_css3.scss +21 -0
  11. data/stylesheets/compass/_layout.scss +3 -0
  12. data/stylesheets/compass/_reset-legacy.scss +3 -0
  13. data/stylesheets/compass/_reset.scss +3 -0
  14. data/stylesheets/compass/_support.scss +447 -0
  15. data/stylesheets/compass/_typography.scss +4 -0
  16. data/stylesheets/compass/_utilities.scss +9 -0
  17. data/stylesheets/compass/css3/_animation.scss +122 -0
  18. data/stylesheets/compass/css3/_appearance.scss +17 -0
  19. data/stylesheets/compass/css3/_background-clip.scss +35 -0
  20. data/stylesheets/compass/css3/_background-origin.scss +37 -0
  21. data/stylesheets/compass/css3/_background-size.scss +19 -0
  22. data/stylesheets/compass/css3/_border-radius.scss +107 -0
  23. data/stylesheets/compass/css3/_box-shadow.scss +88 -0
  24. data/stylesheets/compass/css3/_box-sizing.scss +21 -0
  25. data/stylesheets/compass/css3/_box.scss +85 -0
  26. data/stylesheets/compass/css3/_columns.scss +212 -0
  27. data/stylesheets/compass/css3/_deprecated-support.scss +272 -0
  28. data/stylesheets/compass/css3/_filter.scss +50 -0
  29. data/stylesheets/compass/css3/_flexbox.scss +156 -0
  30. data/stylesheets/compass/css3/_font-face.scss +48 -0
  31. data/stylesheets/compass/css3/_hyphenation.scss +71 -0
  32. data/stylesheets/compass/css3/_images.scss +152 -0
  33. data/stylesheets/compass/css3/_inline-block.scss +31 -0
  34. data/stylesheets/compass/css3/_opacity.scss +27 -0
  35. data/stylesheets/compass/css3/_pie.scss +1 -0
  36. data/stylesheets/compass/css3/_regions.scss +27 -0
  37. data/stylesheets/compass/css3/_selection.scss +59 -0
  38. data/stylesheets/compass/css3/_shared.scss +5 -0
  39. data/stylesheets/compass/css3/_text-shadow.scss +82 -0
  40. data/stylesheets/compass/css3/_transform.scss +590 -0
  41. data/stylesheets/compass/css3/_transition.scss +190 -0
  42. data/stylesheets/compass/css3/_user-interface.scss +71 -0
  43. data/stylesheets/compass/layout/_grid-background.scss +178 -0
  44. data/stylesheets/compass/layout/_sticky-footer.scss +23 -0
  45. data/stylesheets/compass/layout/_stretching.scss +24 -0
  46. data/stylesheets/compass/reset/_utilities-legacy.scss +135 -0
  47. data/stylesheets/compass/reset/_utilities.scss +142 -0
  48. data/stylesheets/compass/typography/_links.scss +3 -0
  49. data/stylesheets/compass/typography/_lists.scss +4 -0
  50. data/stylesheets/compass/typography/_text.scss +4 -0
  51. data/stylesheets/compass/typography/_units.scss +183 -0
  52. data/stylesheets/compass/typography/_vertical_rhythm.scss +300 -0
  53. data/stylesheets/compass/typography/links/_hover-link.scss +5 -0
  54. data/stylesheets/compass/typography/links/_link-colors.scss +28 -0
  55. data/stylesheets/compass/typography/links/_unstyled-link.scss +7 -0
  56. data/stylesheets/compass/typography/lists/_bullets.scss +34 -0
  57. data/stylesheets/compass/typography/lists/_horizontal-list.scss +63 -0
  58. data/stylesheets/compass/typography/lists/_inline-block-list.scss +50 -0
  59. data/stylesheets/compass/typography/lists/_inline-list.scss +47 -0
  60. data/stylesheets/compass/typography/text/_ellipsis.scss +25 -0
  61. data/stylesheets/compass/typography/text/_force-wrap.scss +12 -0
  62. data/stylesheets/compass/typography/text/_nowrap.scss +2 -0
  63. data/stylesheets/compass/typography/text/_replacement.scss +74 -0
  64. data/stylesheets/compass/utilities/_color.scss +1 -0
  65. data/stylesheets/compass/utilities/_general.scss +6 -0
  66. data/stylesheets/compass/utilities/_links.scss +5 -0
  67. data/stylesheets/compass/utilities/_lists.scss +6 -0
  68. data/stylesheets/compass/utilities/_print.scss +17 -0
  69. data/stylesheets/compass/utilities/_sass.scss +2 -0
  70. data/stylesheets/compass/utilities/_sprites.scss +2 -0
  71. data/stylesheets/compass/utilities/_tables.scss +3 -0
  72. data/stylesheets/compass/utilities/_text.scss +5 -0
  73. data/stylesheets/compass/utilities/color/_brightness.scss +20 -0
  74. data/stylesheets/compass/utilities/color/_contrast.scss +52 -0
  75. data/stylesheets/compass/utilities/general/_clearfix.scss +44 -0
  76. data/stylesheets/compass/utilities/general/_float.scss +38 -0
  77. data/stylesheets/compass/utilities/general/_hacks.scss +65 -0
  78. data/stylesheets/compass/utilities/general/_min.scss +16 -0
  79. data/stylesheets/compass/utilities/general/_reset.scss +2 -0
  80. data/stylesheets/compass/utilities/general/_tabs.scss +1 -0
  81. data/stylesheets/compass/utilities/general/_tag-cloud.scss +18 -0
  82. data/stylesheets/compass/utilities/links/_hover-link.scss +3 -0
  83. data/stylesheets/compass/utilities/links/_link-colors.scss +3 -0
  84. data/stylesheets/compass/utilities/links/_unstyled-link.scss +3 -0
  85. data/stylesheets/compass/utilities/lists/_bullets.scss +3 -0
  86. data/stylesheets/compass/utilities/lists/_horizontal-list.scss +3 -0
  87. data/stylesheets/compass/utilities/lists/_inline-block-list.scss +3 -0
  88. data/stylesheets/compass/utilities/lists/_inline-list.scss +3 -0
  89. data/stylesheets/compass/utilities/sass/_lists.scss +16 -0
  90. data/stylesheets/compass/utilities/sass/_maps.scss +19 -0
  91. data/stylesheets/compass/utilities/sprites/_base.scss +92 -0
  92. data/stylesheets/compass/utilities/sprites/_sprite-img.scss +81 -0
  93. data/stylesheets/compass/utilities/tables/_alternating-rows-and-columns.scss +22 -0
  94. data/stylesheets/compass/utilities/tables/_borders.scss +38 -0
  95. data/stylesheets/compass/utilities/tables/_scaffolding.scss +9 -0
  96. data/stylesheets/compass/utilities/text/_ellipsis.scss +3 -0
  97. data/stylesheets/compass/utilities/text/_nowrap.scss +3 -0
  98. data/stylesheets/compass/utilities/text/_replacement.scss +3 -0
  99. data/templates/ellipsis/ellipsis.sass +9 -0
  100. data/templates/ellipsis/manifest.rb +27 -0
  101. data/templates/ellipsis/xml/ellipsis.xml +14 -0
  102. data/templates/extension/manifest.rb +26 -0
  103. data/templates/extension/stylesheets/main.sass +1 -0
  104. data/templates/extension/templates/project/manifest.rb +2 -0
  105. data/templates/extension/templates/project/screen.sass +2 -0
  106. data/templates/project/USAGE.markdown +32 -0
  107. data/templates/project/ie.sass +6 -0
  108. data/templates/project/manifest.rb +4 -0
  109. data/templates/project/print.sass +6 -0
  110. data/templates/project/screen.sass +7 -0
  111. metadata +113 -10
  112. data/.gitignore +0 -14
  113. data/Gemfile +0 -4
  114. data/LICENSE.txt +0 -22
  115. data/README.md +0 -31
  116. data/Rakefile +0 -9
  117. data/gem_2345.gemspec +0 -25
@@ -0,0 +1,28 @@
1
+ require "gem_2345/import-once/version"
2
+ require "gem_2345/import-once/importer"
3
+ require "gem_2345/import-once/engine"
4
+ require 'set'
5
+
6
+ module Gem2345
7
+ # although this is part of the compass suite of gems, it doesn't depend on compass,
8
+ # so any sass-based project can use to to get import-once behavior for all of their
9
+ # importers.
10
+ module ImportOnce
11
+ class << self
12
+ # A map of css filenames to a set of engine cache keys that uniquely identify what has
13
+ # been imported. The lifecycle of each key is handled by code wrapped around Sass's
14
+ # render, to_css and render_with_sourcemap methods on the Sass::Engine.
15
+ #
16
+ # Ideally, Sass would provide a place in it's public API to put
17
+ # information that persists for only the duration of a single compile and would be accessible
18
+ # for all sass engines and sass functions written in ruby.
19
+ def import_tracker
20
+ Thread.current[:import_once_tracker] ||= {}
21
+ end
22
+
23
+ def activate!
24
+ require 'gem_2345/import-once/activate'
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,20 @@
1
+ require 'gem_2345/import-once'
2
+ module Sass
3
+ class Engine
4
+ def self.new(*args)
5
+ instance = super
6
+ instance.extend(Gem2345::ImportOnce::Engine)
7
+ if i = instance.options[:importer]
8
+ i.extend(Gem2345::ImportOnce::Importer) unless i.is_a?(Gem2345::ImportOnce::Importer)
9
+ end
10
+ instance.options[:load_paths].each do |path|
11
+ if path.is_a?(Sass::Importers::Base) && !path.is_a?(Gem2345::ImportOnce::Importer)
12
+ path.extend(Gem2345::ImportOnce::Importer)
13
+ elsif !path.is_a?(Sass::Importers::Base)
14
+ Sass::Util.sass_warn "WARNING: #{path.inspect} is on the load path and is not an importer."
15
+ end
16
+ end
17
+ instance
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,36 @@
1
+ module Gem2345
2
+ # although this is part of the Gem2345 suite of gems, it doesn't depend on compass,
3
+ # so any sass-based project can use to to get import-once behavior for all of their
4
+ # importers.
5
+ module ImportOnce
6
+ # All sass engines will be extended with this module to manage the lifecycle
7
+ # around each
8
+ module Engine
9
+ def to_css
10
+ with_import_scope(options[:css_filename]) do
11
+ super
12
+ end
13
+ end
14
+
15
+ def render
16
+ with_import_scope(options[:css_filename]) do
17
+ super
18
+ end
19
+ end
20
+
21
+ def render_with_sourcemap(sourcemap_uri)
22
+ with_import_scope(options[:css_filename]) do
23
+ super
24
+ end
25
+ end
26
+
27
+ def with_import_scope(css_filename)
28
+ Gem2345::ImportOnce.import_tracker[css_filename] = Set.new
29
+ yield
30
+ ensure
31
+ Gem2345::ImportOnce.import_tracker.delete(css_filename)
32
+ end
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,81 @@
1
+ module Gem2345
2
+ module ImportOnce
3
+ # Any importer object that is extended with this module will get the import once behavior.
4
+ module Importer
5
+ def find_relative(uri, base, options, *args)
6
+ uri, force_import = handle_force_import(uri)
7
+ maybe_replace_with_dummy_engine(super(uri, base, options, *args), options, force_import)
8
+ end
9
+
10
+ def find(uri, options, *args)
11
+ uri, force_import = handle_force_import(uri)
12
+ maybe_replace_with_dummy_engine(super(uri, options, *args), options, force_import)
13
+ end
14
+
15
+ def key(uri, options, *args)
16
+ if uri =~ /^\(NOT IMPORTED\) (.*)$/
17
+ ["(import-once)", $1]
18
+ else
19
+ super
20
+ end
21
+ end
22
+
23
+ def mtime(uri, options, *args)
24
+ if uri =~ /^\(NOT IMPORTED\) (.*)$/
25
+ File.mtime($1) if File.exist?($1)
26
+ else
27
+ super
28
+ end
29
+ end
30
+
31
+ protected
32
+
33
+ # any uri that ends with an exclamation mark will be forced to import
34
+ def handle_force_import(uri)
35
+ if uri.end_with?("!")
36
+ [uri[0...-1], true]
37
+ else
38
+ [uri, false]
39
+ end
40
+ end
41
+
42
+ def maybe_replace_with_dummy_engine(engine, options, force_import)
43
+ if engine && !force_import && imported?(engine, options)
44
+ engine = dummy_engine(engine, options)
45
+ elsif engine
46
+ imported!(engine, options)
47
+ end
48
+ engine
49
+ end
50
+
51
+ def tracker(options)
52
+ Gem2345::ImportOnce.import_tracker[options[:css_filename]] ||= Set.new
53
+ end
54
+
55
+ # Giant hack to support sass-globbing.
56
+ # Need to find a better fix.
57
+ def normalize_filesystem_importers(key)
58
+ key.map do |part|
59
+ part.sub(/Glob:/, 'Sass::Importers::Filesystem:')
60
+ end
61
+ end
62
+
63
+ def import_tracker_key(engine, options)
64
+ normalize_filesystem_importers(key(engine.options[:filename], options)).join("|").freeze
65
+ end
66
+
67
+ def dummy_engine(engine, options)
68
+ new_options = engine.options.merge(:filename => "(NOT IMPORTED) #{engine.options[:filename]}" )
69
+ Sass::Engine.new("", new_options)
70
+ end
71
+
72
+ def imported?(engine, options)
73
+ tracker(options).include?(import_tracker_key(engine, options))
74
+ end
75
+
76
+ def imported!(engine, options)
77
+ tracker(options) << import_tracker_key(engine, options)
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,5 @@
1
+ module Gem2345
2
+ module ImportOnce
3
+ VERSION = '0.1.2'
4
+ end
5
+ end
@@ -1,5 +1,5 @@
1
1
  module Gem2345
2
2
  module ImportOnce
3
- VERSION = '0.1.1'
3
+ VERSION = '0.1.2'
4
4
  end
5
5
  end
@@ -0,0 +1,3 @@
1
+ @import "compass/utilities";
2
+ @import "compass/typography";
3
+ @import "compass/css3";
@@ -0,0 +1,38 @@
1
+ @mixin image-dimensions($file) {
2
+ height: image-height($file);
3
+ width: image-width($file);
4
+ }
5
+
6
+ @mixin sprite-image($file) {
7
+ background: sprite-image($file) $repeat;
8
+ }
9
+
10
+ @mixin sized-sprite-image($file) {
11
+ background: sprite-image($file);
12
+ @include image-dimensions($file);
13
+ }
14
+
15
+ @mixin sprite-folder($folder, $image-dimensions: false) {
16
+ .#{$folder} {
17
+ @if $image-dimensions {
18
+ background: sprite-url($folder);
19
+ }
20
+ @else {
21
+ background: sprite-url($folder) no-repeat;
22
+ }
23
+ }
24
+ @for $i from 0 to sprite-files-in-folder($folder) {
25
+ $file: sprite-file-from-folder($folder, $i);
26
+ .#{$folder}-#{image-basename($file)} {
27
+ @extend .#{$folder};
28
+ background-position: sprite-position(sprite-file-from-folder($folder, $i));
29
+ @if $image-dimensions {
30
+ @include image-dimensions($file);
31
+ }
32
+ }
33
+ }
34
+ }
35
+
36
+ @mixin sized-sprite-folder($folder) {
37
+ @include sprite-folder($folder, true);
38
+ }
@@ -0,0 +1,54 @@
1
+ $project-path: null !default;
2
+ $debug-configuration: false !default;
3
+ $compass-initialized: false !default;
4
+ $compass-configured: false !default;
5
+
6
+ @mixin debug-compass-configuration {
7
+ @if $debug-configuration {
8
+ /* Compass Configuration: */
9
+ @each $setting, $value in compass-configuration() {
10
+ /* #{$setting}: #{inspect($value)} */
11
+ }
12
+ }
13
+ }
14
+
15
+ // This mixin resets the compass configuration
16
+ // and then initializes it with the sass options
17
+ // set in the environment. It is immediately called during import.
18
+ // It's unlikely you'll need to call this mixin yourself.
19
+ @mixin compass-initializer($project-path: $project-path) {
20
+ @if not $compass-initialized and not using-compass-compiler() {
21
+ $default-configuration: reset-configuration();
22
+ $default-configuration: add-sass-configuration($project-path);
23
+ }
24
+ $compass-initialized: true !global;
25
+ @include debug-compass-configuration;
26
+ }
27
+ @include compass-initializer;
28
+
29
+ // `$options`:
30
+ // A map of compass configuration options.
31
+ // E.g. @include compass-configuration((asset-host:
32
+ // Keywords style ar
33
+ // `$reconfigure`:
34
+ // When unset, if compass-configuration is called more than once, a warning will
35
+ // be issued and all calls after the first will be ignored.
36
+ // When set to `false`, all subsequent calls will be ignored without a warning.
37
+ // When set to `true`, the configuration will be added to any existing configuration.
38
+ @mixin compass-configuration($options: (), $reconfigure: null, $arguments...) {
39
+ @if not at-stylesheet-root() {
40
+ // this should be @error once that exists.
41
+ @warn "include compass-configuration from the root level of your stylesheet."
42
+ }
43
+ @if not $compass-configured or $reconfigure {
44
+ $options: map-merge($options, keywords($arguments));
45
+ @if length($arguments) > 0 {
46
+ @warn "compass-configuration accepts keyword arguments or a single map of options. Got: #{inspect($arguments)}."
47
+ }
48
+ $invoke: add-configuration($options);
49
+ @include debug-compass-configuration;
50
+ $compass-configured: true !global;
51
+ } @else if $reconfigure == null {
52
+ @warn "Compass was already configured for this stylesheet."
53
+ }
54
+ }
@@ -0,0 +1,21 @@
1
+ @import "css3/border-radius";
2
+ @import "css3/inline-block";
3
+ @import "css3/opacity";
4
+ @import "css3/box-shadow";
5
+ @import "css3/text-shadow";
6
+ @import "css3/columns";
7
+ @import "css3/box-sizing";
8
+ @import "css3/flexbox";
9
+ @import "css3/images";
10
+ @import "css3/background-clip";
11
+ @import "css3/background-origin";
12
+ @import "css3/background-size";
13
+ @import "css3/font-face";
14
+ @import "css3/transform";
15
+ @import "css3/transition";
16
+ @import "css3/appearance";
17
+ @import "css3/animation";
18
+ @import "css3/regions";
19
+ @import "css3/hyphenation";
20
+ @import "css3/filter";
21
+ @import "css3/user-interface";
@@ -0,0 +1,3 @@
1
+ @import "layout/grid-background";
2
+ @import "layout/sticky-footer";
3
+ @import "layout/stretching";
@@ -0,0 +1,3 @@
1
+ @import "reset/utilities-legacy";
2
+
3
+ @include global-reset;
@@ -0,0 +1,3 @@
1
+ @import "reset/utilities";
2
+
3
+ @include global-reset;
@@ -0,0 +1,447 @@
1
+ // Map of compass extensions that are loaded. The value will either be
2
+ // the version of the extension or `true` if the version is unknown.
3
+ $compass-extensions: compass-extensions() !default;
4
+
5
+ // The list of browsers you want to support.
6
+ // Defaults to all.
7
+ $supported-browsers: browsers() !default;
8
+
9
+ // The browser usage threshold for features that gracefully degrade
10
+ // Defaults to 1 user in 1,000.
11
+ $graceful-usage-threshold: 0.1 !default;
12
+
13
+ // The browser usage threshold for features that cannot degrade gracefully
14
+ // Defaults to 1 user in 10,000.
15
+ $critical-usage-threshold: 0.01 !default;
16
+
17
+ // Set this to true to generate comments that will explain why a prefix was included or omitted.
18
+ $debug-browser-support: false !default;
19
+
20
+ // Minimum browser versions that must be supported.
21
+ // The keys of this map are any valid browser according to `browsers()`.
22
+ // The values of this map are the min version that is valid for that browser
23
+ // according to `browser-versions($browser)`
24
+ $browser-minimum-versions: (
25
+ 'chrome': null,
26
+ 'firefox': null,
27
+ 'ie': null,
28
+ 'safari': null,
29
+ 'opera': null
30
+ ) !default;
31
+
32
+
33
+ // @private
34
+ $default-capability-options: (
35
+ (full-support: true),
36
+ (partial-support: true)
37
+ );
38
+
39
+ // When a prefix in in context, but there is no current prefix
40
+ // That context is recorded here so other prefixes can be avoided.
41
+ $prefix-context: null;
42
+
43
+ // When a prefix is in a selector or directive scope, this is set to the
44
+ // current prefix value. When `null`, either there is no prefix in scope
45
+ // or the official prefix is being rendered. The `$prefix-context`
46
+ // variable can be used to make that distinction.
47
+ $current-prefix: null;
48
+
49
+ // When in a context that only exists in a particular version
50
+ // this variable is set to those versions.
51
+ $current-browser-versions: ();
52
+
53
+ // The legacy support CSS 2.1 Selectors.
54
+ // Defaults to the $critical-usage-threshold.
55
+ $css-sel2-support-threshold: $critical-usage-threshold !default;
56
+
57
+ // Check if the browser is in scope given the browser support and current prefix minimums.
58
+ @function browser-out-of-scope($browser, $version: null) {
59
+ @if not index($supported-browsers, $browser) {
60
+ @if $debug-browser-support {
61
+ @return "#{$browser} is not listed as a supported browser."
62
+ } @else {
63
+ @return true;
64
+ }
65
+ } @else if not ($current-prefix == null or $current-prefix == browser-prefix($browser)) {
66
+ @if $debug-browser-support {
67
+ @return "#{$browser} #{$version} is incompatible with #{$current-prefix}."
68
+ } @else {
69
+ @return true;
70
+ }
71
+ }
72
+ $current-range: map-get($current-browser-versions, $browser);
73
+ $current-min: if($current-range, nth($current-range, 1), null);
74
+ $current-max: if($current-range, nth($current-range, 2), null);
75
+ @if not ($version and $current-max) {
76
+ // We don't have any versions to compare
77
+ @return false;
78
+ } @else {
79
+ // If the version is less than the current min, it is not supported
80
+ $too-old: compare-browser-versions($browser, $version, $current-min) < 0;
81
+ $too-new: compare-browser-versions($browser, $version, $current-max) > 0;
82
+ @if $too-old or $too-new {
83
+ @if $debug-browser-support {
84
+ @return "The current scope only works with #{display-browser-range($browser, $current-min, $current-max)}.";
85
+ } @else {
86
+ @return true;
87
+ }
88
+ } @else {
89
+ @return false;
90
+ }
91
+ }
92
+ }
93
+
94
+ // Check whether the browser is supported according to the supported browsers,
95
+ // declared minimum support and usage thresholds.
96
+ @function support-legacy-browser($browser, $min-version, $max-version: null, $threshold: $critical-usage-threshold) {
97
+ @if not index($supported-browsers, $browser) {
98
+ @return false;
99
+ }
100
+ // Check agaist usage stats and declared minimums
101
+ $min-required-version: map-get($browser-minimum-versions, $browser);
102
+ $usage: if($max-version,
103
+ omitted-usage($browser, $min-version, $max-version),
104
+ omitted-usage($browser, $min-version));
105
+ @return $usage > $threshold or
106
+ ($min-required-version and
107
+ compare-browser-versions($browser, $max-version or $min-version, $min-required-version) >= 0);
108
+ }
109
+
110
+ // Include content for a legacy browser
111
+ // Version can be a single version string or a list of versions ordered from oldest to newest.
112
+ @mixin for-legacy-browser($browser, $min-version, $max-version: $min-version,
113
+ $threshold: $critical-usage-threshold,
114
+ $ranges: ($browser: $min-version $max-version)) {
115
+ @if not browser-out-of-scope($browser, $max-version) and
116
+ support-legacy-browser($browser, $min-version, $max-version, $threshold)
117
+ {
118
+ @if $debug-browser-support {
119
+ /* Content for #{display-browser-range($browser, $min-version, $max-version)}.
120
+ Min version: #{map-get($browser-minimum-versions, $browser) or unspecified}.
121
+ User threshold to keep: #{$threshold}%. If #{display-browser-range($browser, $min-version, $max-version)} are omitted: #{omitted-usage($browser, $min-version, $max-version)}%. */
122
+ }
123
+ @include with-browser-ranges(intersect-browser-ranges($current-browser-versions, $ranges)) {
124
+ @content;
125
+ }
126
+ } @else if $debug-browser-support and browser-out-of-scope($browser, $max-version) {
127
+ /* Content for #{display-browser-range($browser, $min-version, $max-version)} omitted.
128
+ Not allowed in the current scope: #{browser-out-of-scope($browser, $max-version)} */
129
+ } @else if $debug-browser-support and not
130
+ support-legacy-browser($browser, $min-version, $max-version, $threshold) {
131
+ @if omitted-usage($browser, $min-version, $max-version) > $threshold {
132
+ /* Content for #{display-browser-range($browser, $min-version, $max-version)} omitted.
133
+ User threshold to keep: #{$threshold}%. If #{display-browser-range($browser, $min-version, $max-version)} and below are omitted: #{omitted-usage($browser, $min-version, $max-version)}%. */
134
+ } @else {
135
+ /* Content for #{display-browser-range($browser, $min-version, $max-version)} omitted.
136
+ Minimum support is #{map-get($browser-minimum-versions, $browser)}. */
137
+ }
138
+ }
139
+ }
140
+
141
+ @function display-browser-range($browser, $min-version, $max-version: $min-version) {
142
+ @return "#{unquote($browser)} #{unquote($min-version)}#{if($max-version != $min-version, unquote(' -') unquote($max-version), null)}";
143
+ }
144
+
145
+
146
+ // Renders the content once if any of the legacy browsers are supported.
147
+ // $browsers is a map of browser name to version ranges
148
+ @mixin for-legacy-browsers($browsers, $threshold: $critical-usage-threshold) {
149
+ $rendered: false;
150
+ @each $browser, $range in $browsers {
151
+ @if not $rendered {
152
+ @include for-legacy-browser($browser, $range..., $threshold: $threshold, $ranges: $browsers) {
153
+ $rendered: true;
154
+ @content;
155
+ }
156
+ }
157
+ }
158
+ }
159
+
160
+ // If there's a prefix context in scope, this will only output the content if the prefix matches.
161
+ // Otherwise, sets the current prefix scope and outputs the content.
162
+ @mixin with-prefix($prefix) {
163
+ @if $current-prefix or $prefix-context {
164
+ @if $current-prefix == $prefix or $prefix-context == $prefix {
165
+ @if $debug-browser-support {
166
+ @if $prefix {
167
+ /* content for #{$prefix} because #{$current-prefix or $prefix-context} is already in scope. */
168
+ } @else {
169
+ /* unprefixed content. #{$current-prefix or $prefix-context} is already in scope. */
170
+ }
171
+ }
172
+ $old-prefix-context: $prefix-context;
173
+ $old-prefix: $current-prefix;
174
+ $prefix-context: $prefix-context or $current-prefix !global;
175
+ $current-prefix: $prefix !global;
176
+ @content;
177
+ $prefix-context: $old-prefix-context !global;
178
+ $current-prefix: $old-prefix !global;
179
+ } @else if $prefix == null {
180
+ $old-prefix-context: $prefix-context;
181
+ $prefix-context: $prefix-context or $current-prefix !global;
182
+ $current-prefix: null !global;
183
+ @if $debug-browser-support {
184
+ /* Content for official syntax. Prefix context is still #{$prefix-context}. */
185
+ }
186
+ @content;
187
+ $current-prefix: $prefix-context !global;
188
+ $prefix-context: $old-prefix-context !global;
189
+ } @else if $debug-browser-support {
190
+ /* Omitting content for #{$prefix} because #{$current-prefix} is already in scope. */
191
+ }
192
+ } @else {
193
+ @if $debug-browser-support and $prefix {
194
+ /* Creating new #{$prefix} context. */
195
+ }
196
+ $prefix-context: $prefix !global;
197
+ $current-prefix: $prefix !global;
198
+ @content;
199
+ $current-prefix: null !global;
200
+ $prefix-context: null !global;
201
+ }
202
+ }
203
+
204
+ @function prefixes-for-capability($capability, $threshold, $capability-options: $default-capability-options) {
205
+ $result: ();
206
+ @each $prefix in browser-prefixes($supported-browsers) {
207
+ $result: map-merge($result,
208
+ ($prefix: use-prefix($prefix, $capability, $threshold, $capability-options)));
209
+ }
210
+ @return $result;
211
+ }
212
+
213
+ // Yields to the mixin content once for each prefix required.
214
+ // The current prefix is set to the $current-prefix global for use by the included content.
215
+ // Also yields to the content once with $current-prefix set to null for the official version
216
+ // as long as there's not already a prefix in scope.
217
+ @mixin with-each-prefix($capability, $threshold, $capability-options: $default-capability-options) {
218
+ @each $prefix, $should-use-prefix in prefixes-for-capability($capability, $threshold, $capability-options) {
219
+ @if $should-use-prefix {
220
+ @if $debug-browser-support and type-of($should-use-prefix) == list {
221
+ /* Capability #{$capability} is prefixed with #{$prefix} because #{$should-use-prefix} is required. */
222
+ } @else if $debug-browser-support and type-of($should-use-prefix) == number {
223
+ /* Capability #{$capability} is prefixed with #{$prefix} because #{$should-use-prefix}% of users need it which is more than the threshold of #{$threshold}%. */
224
+ }
225
+ @include with-prefix($prefix) {
226
+ @include with-browser-ranges($capability) {
227
+ @content;
228
+ }
229
+ }
230
+ } @else if $debug-browser-support {
231
+ /* 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}. */
232
+ }
233
+ }
234
+ @include with-prefix(null) {
235
+ @include with-browser-ranges($capability) {
236
+ @content;
237
+ }
238
+ }
239
+ }
240
+
241
+ // Returns true if at least one browser-version pair in $subset-ranges
242
+ // is a higher (or same) version than the browser-version pairs in
243
+ // $ranges.
244
+ @function has-browser-subset($ranges, $subset-ranges) {
245
+ $found-mismatch: false;
246
+ @each $browser, $subset-range in $subset-ranges {
247
+ $range: map-get($ranges, $browser);
248
+ @if $range {
249
+ $min-1: nth($subset-range, 1);
250
+ $max-1: nth($subset-range, 2);
251
+ $min-2: nth($range, 1);
252
+ $max-2: nth($range, 2);
253
+ @if (compare-browser-versions($browser, $min-2, $min-1) <= 0 and
254
+ compare-browser-versions($browser, $min-1, $max-2) <= 0) or
255
+ (compare-browser-versions($browser, $min-2, $max-1) <= 0 and
256
+ compare-browser-versions($browser, $max-1, $max-2) <= 0) or
257
+ (compare-browser-versions($browser, $min-1, $min-2) <= 0 and
258
+ compare-browser-versions($browser, $max-1, $max-2) >= 0) or
259
+ (compare-browser-versions($browser, $min-1, $min-2) >= 0 and
260
+ compare-browser-versions($browser, $max-1, $max-2) <= 0) {
261
+ @return true;
262
+ } @else {
263
+ $found-mismatch: true
264
+ }
265
+ }
266
+ }
267
+ @return not $found-mismatch;
268
+ }
269
+
270
+ // When the same browser is in both maps, then the minimum will be set
271
+ // to the maximum of the two minimum versions, and the maximum will be
272
+ // set to the minmum of the two maximum versions.
273
+ @function intersect-browser-ranges($ranges, $new-ranges) {
274
+ @each $browser, $new-range in $new-ranges {
275
+ $old-range: map-get($ranges, $browser);
276
+ @if $old-range {
277
+ $old-min: nth($old-range, 1);
278
+ $old-max: if(length($old-range) == 1, $old-min, nth($old-range, 2));
279
+ $new-min: nth($new-range, 1);
280
+ $new-max: if(length($new-range) == 1, $new-min, nth($new-range, 2));
281
+ $maximin: if(compare-browser-versions($browser, $old-min, $new-min) > 0,
282
+ $old-min, $new-min);
283
+ $minimax: if(compare-browser-versions($browser, $old-max, $new-max) < 0,
284
+ $old-max, $new-max);
285
+ $ranges: map-merge($ranges, ($browser: $maximin $minimax));
286
+ } @else {
287
+ $ranges: map-merge($ranges, ($browser: $new-range));
288
+ }
289
+ }
290
+ @return $ranges;
291
+ }
292
+
293
+ // If passed a map, that will be the new browser ranges.
294
+ // Otherwise a range map will be created based on the given capability and prefix
295
+ // using the `browser-ranges($capability, $prefix)` function.
296
+ //
297
+ // If there are current ranges in scope and the new ranges have some overlap
298
+ // with the current,
299
+ //
300
+ // If there is no overlap, then the content will not be rendered.
301
+ @mixin with-browser-ranges($capability, $prefix: $current-prefix) {
302
+ $new-ranges: null;
303
+ @if type-of($capability) == map {
304
+ $new-ranges: $capability;
305
+ } @else {
306
+ $new-ranges: browser-ranges($capability, $prefix);
307
+ }
308
+
309
+ @if has-browser-subset($current-browser-versions, $new-ranges) {
310
+ $old-ranges: $current-browser-versions;
311
+ $current-browser-versions: intersect-browser-ranges($old-ranges, $new-ranges) !global;
312
+ @content;
313
+ $current-browser-versions: $old-ranges !global;
314
+ } @else if $debug-browser-support {
315
+ /* Excluding content because #{inspect($new-ranges)} is not included within
316
+ #{inspect($current-browser-versions)} */
317
+ }
318
+ }
319
+
320
+ // Returns true if the prefixed usage stats for the capability exceed the threshold
321
+ // or if the minimum version for a supported browser would require a prefix for the capability.
322
+ @function use-prefix($prefix, $capability, $threshold, $capability-options: $default-capability-options) {
323
+ $usage: prefix-usage($prefix, $capability, $capability-options);
324
+ @if $usage > $threshold {
325
+ @return $usage;
326
+ } @else {
327
+ @each $browser in browsers($prefix) {
328
+ @if index($supported-browsers, $browser) {
329
+ $min-version: map-get($browser-minimum-versions, $browser);
330
+ @if $min-version {
331
+ $actual-prefix: browser-requires-prefix($browser, $min-version, $capability, $capability-options);
332
+ @if $actual-prefix and $prefix == $actual-prefix {
333
+ @return $browser $min-version;
334
+ }
335
+ }
336
+ }
337
+ }
338
+ }
339
+ @return false;
340
+ }
341
+
342
+ @function prefix-identifier($ident, $prefix: $current-prefix) {
343
+ @return unquote("#{$prefix}#{if($prefix, '-', null)}#{$ident}");
344
+ }
345
+
346
+ // Output a property and value using the current prefix.
347
+ // It will be unprefixed if $current-prefix is null.
348
+ @mixin prefix-prop($property, $value, $prefix: $current-prefix) {
349
+ #{prefix-identifier($property, $prefix)}: $value;
350
+ }
351
+
352
+ // Emit a set of properties with the prefix governed by the capability and usage threshold given.
353
+ //
354
+ // Example:
355
+ //
356
+ // @include prefixed-properties(css-animation, $animation-support-threshold,
357
+ // (animation-name: foo, animation-duration: 2s)
358
+ // );
359
+ @mixin prefixed-properties($capability, $threshold, $properties, $capability-options: $default-capability-options) {
360
+ @include with-each-prefix($capability, $threshold, $capability-options) {
361
+ @each $prop, $value in $properties {
362
+ @include prefix-prop($prop, $value);
363
+ }
364
+ }
365
+ }
366
+
367
+
368
+ // @private
369
+ @function warn-about-old-variables() {
370
+ $old-variables-in-use: ();
371
+ @each $old-variable-name in
372
+ (legacy-support-for-ie, legacy-support-for-ie6, legacy-support-for-ie7,
373
+ legacy-support-for-ie8, legacy-support-for-mozilla, legacy-support-for-webkit,
374
+ experimental-support-for-mozilla, experimental-support-for-webkit,
375
+ experimental-support-for-opera, experimental-support-for-microsoft,
376
+ experimental-support-for-khtml, experimental-support-for-svg)
377
+ {
378
+ @if global-variable-exists($old-variable-name) {
379
+ $old-variables-in-use: append($old-variables-in-use,
380
+ unquote("$#{$old-variable-name}"), comma);
381
+ }
382
+ }
383
+ @if length($old-variables-in-use) > 0 {
384
+ @warn "Compass has changed how browser support is configured. " +
385
+ "The following configuration variables " +
386
+ "are no longer supported: #{$old-variables-in-use}." +
387
+ "Details: http://compass-style.org/help/documentation/tuning-vendor-prefixes/"
388
+ }
389
+ @return $old-variables-in-use;
390
+ }
391
+
392
+ // @private
393
+ @function warn-about-pie-removal() {
394
+ @if global-variable-exists(experimental-support-for-pie) {
395
+ @warn "Compass no longer supports css3pie.";
396
+ }
397
+ @return true;
398
+ }
399
+
400
+ // Enable browser support debugging within the content block.
401
+ // Or you can enable it for the whole stylesheet by setting `$debug-browser-support` to true.
402
+ @mixin with-browser-support-debugging {
403
+ $current-status: $debug-browser-support;
404
+ $debug-browser-support: true !global;
405
+ @content;
406
+ $debug-browser-support: $current-status !global;
407
+ }
408
+
409
+ // Set a default value if the given arglist is empty
410
+ @function set-arglist-default($arglist, $default) {
411
+ $default-index: index($arglist, default);
412
+ @if $default-index {
413
+ $arglist: set-nth($arglist, $default-index, $default)
414
+ }
415
+ @return if(length($arglist) > 0, $arglist, $default);
416
+ }
417
+
418
+
419
+ // @private
420
+ $old-variable-warnings-issued: warn-about-old-variables() !default;
421
+
422
+ // @private
423
+ $pie-removal-warning-issued: warn-about-pie-removal() !default;
424
+
425
+ // @private
426
+ @function warn-about-useless-prefix-arguments($moz: null, $webkit: null, $o: null, $khtml: null, $official: null) {
427
+ @if $moz != null or $webkit != null or $o != null or $khtml != null or $official != null {
428
+ @warn "Browser prefix arguments to this mixin are no longer used and " +
429
+ "will be removed in the next release.";
430
+ }
431
+ @return true;
432
+ }
433
+
434
+ // coerce a list to be comma delimited or make a new, empty comma delimited list.
435
+ @function comma-list($list: ()) {
436
+ @return join((), $list, comma);
437
+ }
438
+
439
+ // @private Returns the legacy value for a given box-model
440
+ // - Used by background-clip and -origin.
441
+ @function legacy-box($box) {
442
+ $box: unquote($box);
443
+ @if $box == padding-box { $box: padding; }
444
+ @if $box == border-box { $box: border; }
445
+ @if $box == content-box { $box: content; }
446
+ @return $box;
447
+ }