diff options
author | Gleb Mazovetskiy <glex.spb@gmail.com> | 2013-11-14 21:26:08 +0400 |
---|---|---|
committer | Gleb Mazovetskiy <glex.spb@gmail.com> | 2013-11-15 00:55:26 +0400 |
commit | c58415eef00a708b25f6f7ee32573de038be4a50 (patch) | |
tree | af5876be9460f80d8b9402327d2a0e331436c1d2 | |
parent | 263dc713ff89de6f5784e8cfd0d22aa2bc2aaef0 (diff) |
Sass-only support
-rw-r--r-- | README.md | 41 | ||||
-rw-r--r-- | Rakefile | 4 | ||||
-rw-r--r-- | lib/bootstrap-sass.rb | 53 | ||||
-rw-r--r-- | lib/bootstrap-sass/compass_functions.rb | 24 | ||||
-rw-r--r-- | lib/bootstrap-sass/sass_functions.rb | 40 | ||||
-rw-r--r-- | lib/bootstrap-sass/version.rb | 2 | ||||
-rw-r--r-- | tasks/converter/less_conversion.rb | 14 | ||||
-rw-r--r-- | templates/project/manifest.rb | 13 | ||||
-rw-r--r-- | test/dummy_sass_only/Gemfile | 4 | ||||
-rw-r--r-- | test/dummy_sass_only/compile.rb | 13 | ||||
-rw-r--r-- | test/dummy_sass_only/import_all.sass | 2 | ||||
-rw-r--r-- | test/sass_test.rb | 23 | ||||
-rw-r--r-- | test/test_helper.rb | 1 | ||||
-rw-r--r-- | vendor/assets/stylesheets/bootstrap/_glyphicons.scss | 10 | ||||
-rw-r--r-- | vendor/assets/stylesheets/bootstrap/_mixins.scss | 12 | ||||
-rw-r--r-- | vendor/assets/stylesheets/bootstrap/_progress-bars.scss | 12 |
16 files changed, 182 insertions, 86 deletions
@@ -36,13 +36,13 @@ require 'bootstrap-sass' ``` ```console -compass install bootstrap +bundle exec compass install bootstrap ``` If you are creating a new Compass project, you can generate it with bootstrap-sass support: ```console -compass create my-new-project -r bootstrap-sass --using bootstrap +bundle exec compass create my-new-project -r bootstrap-sass --using bootstrap ``` This will create a new Compass project with the following files in it: @@ -51,6 +51,43 @@ This will create a new Compass project with the following files in it: * [styles.scss](/templates/project/styles.scss) - main project SCSS file, import `variables` and `bootstrap`. +### c. Sass-only (no Compass, nor Rails) + +Require the gem, and load paths and Sass helpers will be configured automatically: + +```ruby +require 'bootstrap-sass' +``` + +#### JS and fonts + +If you are using Rails or Sprockets, see Usage. + +If none of Rails/Sprockets/Compass were detected the fonts will be referenced as: + +```sass +"#{$icon-font-path}/#{$icon-font-name}.eot" +``` + +`$icon-font-path` defaults to `bootstrap/`. + +When not using an asset pipeline, you have to copy fonts and javascripts from the gem. + +```bash +mkdir public/fonts +cp -r $(bundle show bootstrap-sass)/vendor/assets/fonts/ public/fonts/ +mkdir public/javascripts +cp -r $(bundle show bootstrap-sass)/vendor/assets/javascripts/ public/javascripts/ +``` + +In ruby you can get the assets' location in the filesystem like this: + +```ruby +Bootstrap.stylesheets_path +Bootstrap.fonts_path +Bootstrap.javascripts_path +``` + ## Usage ### Sass @@ -8,9 +8,8 @@ end desc 'Dumps output to a CSS file for testing' task :debug do require 'sass' - require './lib/bootstrap-sass/compass_functions' require './lib/bootstrap-sass/sass_functions' - path = './vendor/assets/stylesheets' + path = Bootstrap.stylesheets_path %w(bootstrap).each do |file| engine = Sass::Engine.for_file("#{path}/#{file}.scss", syntax: :scss, load_paths: [path]) File.open("./#{file}.css", 'w') { |f| f.write(engine.render) } @@ -29,7 +28,6 @@ task :compile, :css_path do |t, args| lib_path = File.join(File.dirname(__FILE__), 'lib') $:.unshift(lib_path) unless $:.include?(lib_path) require 'sass' - require 'bootstrap-sass/compass_functions' require 'bootstrap-sass/sass_functions' require 'term/ansicolor' diff --git a/lib/bootstrap-sass.rb b/lib/bootstrap-sass.rb index 66251f8..947e4ec 100644 --- a/lib/bootstrap-sass.rb +++ b/lib/bootstrap-sass.rb @@ -4,32 +4,49 @@ module Bootstrap class << self # Inspired by Kaminari def load! - if compass? - require 'bootstrap-sass/compass_functions' - register_compass_extension - elsif asset_pipeline? - require 'bootstrap-sass/sass_functions' - end + require 'bootstrap-sass/sass_functions' + register_compass_extension if compass? if rails? require 'sass-rails' register_rails_engine end - unless rails? || compass? - raise Bootstrap::FrameworkNotFound, - 'bootstrap-sass requires either Rails > 3.1 or Compass, neither of which are loaded' - end - configure_sass end + # Paths def gem_path @gem_path ||= File.expand_path '..', File.dirname(__FILE__) end def stylesheets_path - @stylesheets_path ||= File.join gem_path, 'vendor', 'assets', 'stylesheets' + File.join assets_path, 'stylesheets' + end + + def fonts_path + File.join assets_path, 'fonts' + end + + def javascripts_path + File.join assets_path, 'javascripts' + end + + def assets_path + @assets_path ||= File.join gem_path, 'vendor', 'assets' + end + + # Environment detection helpers + def asset_pipeline? + defined?(::Sprockets) + end + + def compass? + defined?(::Compass) + end + + def rails? + defined?(::Rails) end private @@ -53,18 +70,6 @@ module Bootstrap def register_rails_engine require 'bootstrap-sass/engine' end - - def asset_pipeline? - defined?(::Sprockets) - end - - def compass? - defined?(::Compass) - end - - def rails? - defined?(::Rails) - end end end diff --git a/lib/bootstrap-sass/compass_functions.rb b/lib/bootstrap-sass/compass_functions.rb deleted file mode 100644 index b83d735..0000000 --- a/lib/bootstrap-sass/compass_functions.rb +++ /dev/null @@ -1,24 +0,0 @@ -# This contains functions for use with a project *only* using Compass. -module Sass::Script::Functions - def image_path(source, options = {}) - if defined?(::Sprockets) - ::Sass::Script::String.new sprockets_context.image_path(source.value).to_s, :string - elsif defined?(::Compass) - image_url(source, Sass::Script::Bool.new(true)) - else - # Revert to the old compass-agnostic path determination - asset_sans_quotes = source.value.gsub('"', '') - Sass::Script::String.new("/images/#{asset_sans_quotes}", :string) - end - end - - protected - def sprockets_context # :nodoc: - if options.key?(:sprockets) - options[:sprockets][:context] - else - # Compatibility with sprockets pre 2.10.0 - options[:importer].context - end - end -end diff --git a/lib/bootstrap-sass/sass_functions.rb b/lib/bootstrap-sass/sass_functions.rb index 51bb904..ce1eda6 100644 --- a/lib/bootstrap-sass/sass_functions.rb +++ b/lib/bootstrap-sass/sass_functions.rb @@ -1,14 +1,50 @@ require 'sass' +require 'bootstrap-sass' module Sass::Script::Functions + def twbs_font_path(source) + twbs_asset_path source, :font + end + declare :twbs_font_path, [:source] + + def twbs_image_path(source) + twbs_asset_path source, :image + end + declare :twbs_image_path, [:source] + + def twbs_asset_path(source, type) + url = if Bootstrap.asset_pipeline? && (context = sprockets_context) + context.send(:"#{type}_path", source.value) + elsif Bootstrap.compass? + send(:"#{type}_url", source, Sass::Script::Bool.new(true)).value + end + + # sass-only + url ||= source.value.gsub('"', '') + Sass::Script::String.new(url, :string) + end + declare :twbs_asset_path, [:source] + # LARS: Snatched from compass - 2011-11-29 - used for gradients in IE6-9 # returns an IE hex string for a color with an alpha channel # suitable for passing to IE filters. - def ie_hex_str(color) + def twbs_ie_hex_str(color) assert_type color, :Color alpha = (color.alpha * 255).round alphastr = alpha.to_s(16).rjust(2, '0') Sass::Script::String.new("##{alphastr}#{color.send(:hex_str)[1..-1]}".upcase) end - declare :ie_hex_str, [:color] + declare :twbs_ie_hex_str, [:color] + + protected + + def sprockets_context + # Modern way to get context: + if options.key?(:sprockets) + options[:sprockets][:context] + # Compatibility with sprockets pre 2.10.0: + elsif (importer = options[:importer]) && importer.respond_to?(:context) + importer.context + end + end end
\ No newline at end of file diff --git a/lib/bootstrap-sass/version.rb b/lib/bootstrap-sass/version.rb index d4ffcff..d12119d 100644 --- a/lib/bootstrap-sass/version.rb +++ b/lib/bootstrap-sass/version.rb @@ -1,4 +1,4 @@ module Bootstrap VERSION = '3.0.2.1' - BOOTSTRAP_SHA = '4cbc8d49b10f707029019aaa5eba50e56390a3c5' + BOOTSTRAP_SHA = '27b62d39e2ba62e2d70ef2f5322edd584adc726e' end diff --git a/tasks/converter/less_conversion.rb b/tasks/converter/less_conversion.rb index fc2e315..725a32f 100644 --- a/tasks/converter/less_conversion.rb +++ b/tasks/converter/less_conversion.rb @@ -3,7 +3,9 @@ require_relative 'char_string_scanner' # This module transforms LESS into SCSS. # It is implemented via lots of string manipulation: scanning back and forwards for regexps and doing substitions. # Since it does not parse the LESS into an AST, bits of it may assume LESS to be formatted a certain way, and only limited, -# static analysis can be performed. This approach has so far been enough to automatically convert all of twbs/bootstrap. +# static analysis can be performed. This approach has so far been mostly enough to automatically convert most all of twbs/bootstrap. +# There is some bootstrap-specific to make up for lack of certain features in Sass 3.2 (recursion, mixin namespacing) +# and vice versa in LESS (vararg mixins). class Converter module LessConversion # Some regexps for matching bits of SCSS: @@ -85,7 +87,7 @@ class Converter when 'glyphicons.less' file = replace_rules(file, '@font-face') { |rule| rule = replace_all rule, /(\$icon-font-\w+)/, '#{\1}' - replace_all rule, /url\(/, 'font-url(' + replace_asset_url rule, :font } end @@ -117,6 +119,10 @@ class Converter file end + def replace_asset_url(rule, type) + replace_all rule, /url\((.*?)\)/, "url(twbs-#{type}-path(\\1))" + end + # convert grid mixins LESS when => SASS @if def convert_grid_mixins(file) file = replace_rules file, /@mixin make-grid-columns/, comments: false do |css, pos| @@ -349,7 +355,7 @@ class Converter log_transform file.gsub( /filter: e\(%\("progid:DXImageTransform.Microsoft.gradient\(startColorstr='%d', endColorstr='%d', GradientType=(\d)\)",argb\(([\-$\w]+)\),argb\(([\-$\w]+)\)\)\);/, - %Q(filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='\#{ie-hex-str(\\2)}', endColorstr='\#{ie-hex-str(\\3)}', GradientType=\\1);) + %Q(filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='\#{twbs-ie-hex-str(\\2)}', endColorstr='\#{twbs-ie-hex-str(\\3)}', GradientType=\\1);) ) end @@ -391,7 +397,7 @@ class Converter end def replace_image_urls(less) - less.gsub(/background-image: url\("?(.*?)"?\);/) { |s| "background-image: image-url(\"#{$1}\");" } + less.gsub(/background-image: url\("?(.*?)"?\);/) { |s| replace_asset_url s, :image } end def replace_image_paths(less) diff --git a/templates/project/manifest.rb b/templates/project/manifest.rb index 9025d71..730694c 100644 --- a/templates/project/manifest.rb +++ b/templates/project/manifest.rb @@ -4,13 +4,22 @@ description 'Bootstrap for Sass' stylesheet 'styles.scss' # SCSS: -bs_stylesheets = "../../vendor/assets/stylesheets/bootstrap" + +assets = "../../vendor/assets" + +bs_stylesheets = "#{assets}/stylesheets/bootstrap" stylesheet '_variables.scss.erb', :to => '_variables.scss', :erb => true, :bs_variables_path => File.expand_path("#{bs_stylesheets}/_variables.scss", File.dirname(__FILE__)) # JS: -bs_javascripts = "../../vendor/assets/javascripts/bootstrap" +bs_javascripts = "#{assets}/javascripts/bootstrap" Dir.glob File.expand_path("#{bs_javascripts}/*.js", File.dirname(__FILE__)) do |path| file = File.basename(path) javascript "#{bs_javascripts}/#{file}", :to => "bootstrap/#{file}" end + +bs_fonts = "#{assets}/fonts/bootstrap" +Dir.glob File.expand_path("#{bs_fonts}/*", File.dirname(__FILE__)) do |path| + file = File.basename(path) + font "#{bs_fonts}/#{file}", :to => "bootstrap/#{file}" +end diff --git a/test/dummy_sass_only/Gemfile b/test/dummy_sass_only/Gemfile new file mode 100644 index 0000000..75d2496 --- /dev/null +++ b/test/dummy_sass_only/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +gem 'sass', '~> 3.2' +gem 'bootstrap-sass', path: '../..' diff --git a/test/dummy_sass_only/compile.rb b/test/dummy_sass_only/compile.rb new file mode 100644 index 0000000..8710aa0 --- /dev/null +++ b/test/dummy_sass_only/compile.rb @@ -0,0 +1,13 @@ +require 'sass' +require 'bootstrap-sass' + +css = Sass.compile( + File.read(File.expand_path('./import_all.sass', File.dirname(__FILE__))), + :syntax => 'sass' +) + +if ARGV[0] + File.open(ARGV[0], 'w') { |f| f.write css } +else + puts css +end diff --git a/test/dummy_sass_only/import_all.sass b/test/dummy_sass_only/import_all.sass new file mode 100644 index 0000000..a44a6e3 --- /dev/null +++ b/test/dummy_sass_only/import_all.sass @@ -0,0 +1,2 @@ +@import 'bootstrap' +@import 'bootstrap/theme'
\ No newline at end of file diff --git a/test/sass_test.rb b/test/sass_test.rb new file mode 100644 index 0000000..1239c34 --- /dev/null +++ b/test/sass_test.rb @@ -0,0 +1,23 @@ +require 'test_helper' + +class SassTest < Test::Unit::TestCase + DUMMY_PATH = 'test/dummy_sass_only' + + def test_font_helper + assert_match %r(url\(['"]?.*eot['"]?\)), @css + end + + def setup + Dir.chdir DUMMY_PATH do + %x[bundle] + end + css_path = File.join Bootstrap.gem_path, 'tmp/bootstrap-sass-only.css' + command = "bundle exec ruby compile.rb #{css_path}" + Dir.chdir DUMMY_PATH do + assert silence_stream(STDOUT) { + system(command) + }, 'Sass-only compilation failed' + end + @css = File.read(css_path) + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 0200d58..2d874cc 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -6,7 +6,6 @@ require File.expand_path('dummy/config/environment', File.dirname(__FILE__)) require 'test/unit' require 'sass' -require 'lib/bootstrap-sass/compass_functions' require 'lib/bootstrap-sass/sass_functions' require 'rails/test_help' diff --git a/vendor/assets/stylesheets/bootstrap/_glyphicons.scss b/vendor/assets/stylesheets/bootstrap/_glyphicons.scss index de96f87..ab596fd 100644 --- a/vendor/assets/stylesheets/bootstrap/_glyphicons.scss +++ b/vendor/assets/stylesheets/bootstrap/_glyphicons.scss @@ -10,11 +10,11 @@ // Import the fonts @font-face { font-family: 'Glyphicons Halflings'; - src: font-url('#{$icon-font-path}#{$icon-font-name}.eot'); - src: font-url('#{$icon-font-path}#{$icon-font-name}.eot?#iefix') format('embedded-opentype'), - font-url('#{$icon-font-path}#{$icon-font-name}.woff') format('woff'), - font-url('#{$icon-font-path}#{$icon-font-name}.ttf') format('truetype'), - font-url('#{$icon-font-path}#{$icon-font-name}.svg#glyphicons_halflingsregular') format('svg'); + src: url(twbs-font-path('#{$icon-font-path}#{$icon-font-name}.eot')); + src: url(twbs-font-path('#{$icon-font-path}#{$icon-font-name}.eot?#iefix')) format('embedded-opentype'), + url(twbs-font-path('#{$icon-font-path}#{$icon-font-name}.woff')) format('woff'), + url(twbs-font-path('#{$icon-font-path}#{$icon-font-name}.ttf')) format('truetype'), + url(twbs-font-path('#{$icon-font-path}#{$icon-font-name}.svg#glyphicons_halflingsregular')) format('svg'); } // Catchall baseclass diff --git a/vendor/assets/stylesheets/bootstrap/_mixins.scss b/vendor/assets/stylesheets/bootstrap/_mixins.scss index f6275ed..4ca16a7 100644 --- a/vendor/assets/stylesheets/bootstrap/_mixins.scss +++ b/vendor/assets/stylesheets/bootstrap/_mixins.scss @@ -282,7 +282,7 @@ background-image: -moz-linear-gradient(left, $start-color $start-percent, $end-color $end-percent); // FF 3.6+ background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent); // Standard, IE10 background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=1); // IE9 and down + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{twbs-ie-hex-str($start-color)}', endColorstr='#{twbs-ie-hex-str($end-color)}', GradientType=1); // IE9 and down } // Vertical gradient, from top to bottom @@ -295,7 +295,7 @@ background-image: -moz-linear-gradient(top, $start-color $start-percent, $end-color $end-percent); // FF 3.6+ background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent); // Standard, IE10 background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=0); // IE9 and down + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{twbs-ie-hex-str($start-color)}', endColorstr='#{twbs-ie-hex-str($end-color)}', GradientType=0); // IE9 and down } @mixin gradient-directional($start-color: #555, $end-color: #333, $deg: 45deg) { @@ -310,7 +310,7 @@ background-image: -moz-linear-gradient(left, $start-color, $mid-color $color-stop, $end-color); background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color); background-repeat: no-repeat; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=1); // IE9 and down, gets no color-stop at all for proper fallback + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{twbs-ie-hex-str($start-color)}', endColorstr='#{twbs-ie-hex-str($end-color)}', GradientType=1); // IE9 and down, gets no color-stop at all for proper fallback } @mixin gradient-vertical-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) { background-image: -webkit-gradient(linear, 0 0, 0 100%, from($start-color), color-stop($color-stop, $mid-color), to($end-color)); @@ -318,7 +318,7 @@ background-image: -moz-linear-gradient(top, $start-color, $mid-color $color-stop, $end-color); background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color); background-repeat: no-repeat; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=0); // IE9 and down, gets no color-stop at all for proper fallback + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{twbs-ie-hex-str($start-color)}', endColorstr='#{twbs-ie-hex-str($end-color)}', GradientType=0); // IE9 and down, gets no color-stop at all for proper fallback } @mixin gradient-radial($inner-color: #555, $outer-color: #333) { background-image: -webkit-gradient(radial, center center, 0, center center, 460, from($inner-color), to($outer-color)); @@ -349,7 +349,7 @@ // Short retina mixin for setting background-image and -size @mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) { - background-image: image-url("#{$file-1x}"); + background-image: url(twbs-image-path("#{$file-1x}")); @media only screen and (-webkit-min-device-pixel-ratio: 2), @@ -358,7 +358,7 @@ only screen and ( min-device-pixel-ratio: 2), only screen and ( min-resolution: 192dpi), only screen and ( min-resolution: 2dppx) { - background-image: image-url("#{$file-2x}"); + background-image: url(twbs-image-path("#{$file-2x}")); background-size: $width-1x $height-1x; } } diff --git a/vendor/assets/stylesheets/bootstrap/_progress-bars.scss b/vendor/assets/stylesheets/bootstrap/_progress-bars.scss index 6e4bd28..7302b72 100644 --- a/vendor/assets/stylesheets/bootstrap/_progress-bars.scss +++ b/vendor/assets/stylesheets/bootstrap/_progress-bars.scss @@ -12,18 +12,6 @@ to { background-position: 0 0; } } -// Firefox -@-moz-keyframes progress-bar-stripes { - from { background-position: 40px 0; } - to { background-position: 0 0; } -} - -// Opera -@-o-keyframes progress-bar-stripes { - from { background-position: 0 0; } - to { background-position: 40px 0; } -} - // Spec and IE10+ @keyframes progress-bar-stripes { from { background-position: 40px 0; } |