JQUERY_MESSAGE1 = "# Generated by compass-jquery-plugin/gem-tasks/jquery.rake\n# Install with: compass install jquery/jquery . --force\n\n" JQUERY_MESSAGE2 = "// Generated by compass-jquery-plugin/gem-tasks/jquery.rake\n" AUTOCOMPLETE_FIX = "\n\n/* Fix Autocomplete */\n\n.ui-autocomplete-loading { background: white/*{bgColorLoading}*/ url(images/ui-anim_basic_16x16.gif)/*{bgImgUrlLoading}*/ right/*{bgLoadingXPos}*/ center/*{bgLoadingYPos}*/ no-repeat/*{bgLoadingRepeat}*/; }" WIDGET_BORDER = "\n\n/* Add .ui-widget-border*/\n\n.ui-widget-border { border: 1px solid #aaaaaa/*{borderColorContent}*/; }" class JqueryUiTheme VARIABLE_NAME_BASE = 'ui_' VARIABLE_MATCHER = /(\S*)\/\*\{(\w*)\}\*\// attr_accessor :base_theme # Initialize with the base theme def initialize(base_theme_directory) @prefix = 'jquery.ui' @theme_filename = "#{@prefix}.theme.css" @base_theme_directory = base_theme_directory @base_theme = File.read(File.join(@base_theme_directory, @theme_filename)) # Fix opacity issue print "Fixing overlays\n" @base_theme.sub!(/\/\*\{bgOverlayRepeat\}\*\/\; opacity: (\.\d+)\;filter:/, "/*{bgOverlayRepeat}*/; opacity: \\1/*{bgOverlayOpacity}*/; filter: ") @base_theme.sub!(/\{opacityOverlay\}/, '{bgOverlayFilter}') @base_theme.sub!(/\/\*\{bgShadowRepeat\}\*\/\; opacity: (\.\d+)\;filter:/, "/*{bgShadowRepeat}*/; opacity: \\1/*{bgShadowOpacity}*/; filter: ") @base_theme.sub!(/\{opacityShadow\}/, '{bgShadowFilter}') # addf .ui-widget-border @base_theme += WIDGET_BORDER # Fix AutoComplete @base_theme += AUTOCOMPLETE_FIX end # This sets up the Regexp that will extract the variables from a theme def regexp return @regexp if @regexp placeholder = '___PLACEHOLDER___' @regexp = @base_theme.dup # Install placeholders for the variable data @regexp.gsub!(VARIABLE_MATCHER) { placeholder } # Strip the header comments @regexp.gsub! /.*^\*\/\s*/m, '' # Collapse all whitespace @regexp.gsub! /\s+/, ' ' # Escape the literal strings @regexp = Regexp.escape(@regexp) # Whitespace means nothing @regexp.gsub! /\\\ /, '\s+' # Fast variable finder @regexp.gsub! placeholder, '([^;]*|\S*)' # Get 'er done @regexp = Regexp.new(@regexp) end # You can zip this with the regexp captures to create a variable hash def regexp_variables return @regexp_variables if @regexp_variables @regexp_variables = Array.new @base_theme.scan(VARIABLE_MATCHER) { @regexp_variables << $2 } @regexp_variables end # Convert all the ui.*.css files into sass goodness def convert_css(stylesheets) FileUtils.mkdir_p(File.join(stylesheets)) Dir.foreach @base_theme_directory do |file| next unless /^#{@prefix}\..*\.css$/ =~ file next if ["{#{@prefix}.all.css", "#{@prefix}.base.css"].include? file css = File.read(File.join(@base_theme_directory, file)) if "{#{@prefix}.autocomplete.css".include? file # Removing autocomplete image to add it later by script if css[112..135] == ".ui-autocomplete-loading" css[220, 0] = "*/" css[112, 0] = "/*" end end open File.join(stylesheets, '_' + file.gsub(/\.css$/, '.scss').gsub(/^#{@prefix}\./, '')), 'w' do |f| if file == @theme_filename f.print(self.class.theme_css2sass(@base_theme)) else f.print(self.class.css2sass(css)) end f.close end end end # Create a sass file of variables names and copy the images def convert_theme(name, dir, stylesheets) if name == 'base' theme = @base_theme else theme = File.read(File.join(dir, @theme_filename)) # Fix Overlay stuff theme.gsub!(/\;filter:Alpha/, "; filter: Alpha") theme += WIDGET_BORDER theme += AUTOCOMPLETE_FIX end FileUtils.mkdir_p stylesheets # Figure out the variables with the regexp vars = Hash.new regexp.match(theme).captures.each_with_index do |capture, index| # Remove variable comments capture.gsub! /\/\*\{\w*\}\*\/$/, '' # Update url capture.gsub! /^url\(images(.*)\)/, "image_url(\"jquery/ui/#{name}\\1\")" # Quote most things capture = "\"#{capture}\"" if capture =~ /[^#%0-9a-fptxm\-\.]/ and !(capture =~ /^image_url/) and !(capture =~ /^[A-Za-z]+/) vars[VARIABLE_NAME_BASE + regexp_variables[index]] ||= capture end # Write out the theme sass open File.join(stylesheets, "#{name}.scss"), 'w' do |f| f.print JQUERY_MESSAGE2 f.print "\n" vars.each do |variable_name, value| f.print "$#{variable_name}: #{value} !default;\n" end f.print "\n@import \"jquery/ui/_theme\"\n" end end # Converter for ui.theme.css which has the variable names def self.theme_css2sass(theme_css) # Install variable names and convert to sass sass = css2sass(theme_css.gsub(VARIABLE_MATCHER) { "$#{VARIABLE_NAME_BASE}#{$2}" }) # Convert select lines from literal to programatic syntax sass.gsub!(/.*/) { |x| /\!/=~x ? x.gsub(/:/, '=').gsub(/ solid /, ' "solid" ') : x } sass end # Sass is simply awesome def self.css2sass(css) sass = '' IO.popen("sass-convert -F scss -T scss", 'r+') { |f| f.print(css); f.close_write; sass = f.read } return sass end end