flat-ui-sass 2.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.gitmodules +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +256 -0
- data/Rakefile +14 -0
- data/app/helpers/flat_ui/rails/icon_helper.rb +60 -0
- data/bin/fui_convert +9 -0
- data/flat-ui-sass.gemspec +28 -0
- data/lib/flat-ui-sass.rb +98 -0
- data/lib/flat-ui-sass/cli.rb +56 -0
- data/lib/flat-ui-sass/engine.rb +13 -0
- data/lib/flat-ui-sass/sass_functions.rb +56 -0
- data/lib/flat-ui-sass/version.rb +4 -0
- data/lib/tasks/converter.rb +99 -0
- data/lib/tasks/converter/filesystem.rb +16 -0
- data/lib/tasks/converter/flat_ui_fonts_conversion.rb +19 -0
- data/lib/tasks/converter/flat_ui_images_conversion.rb +19 -0
- data/lib/tasks/converter/flat_ui_js_conversion.rb +28 -0
- data/lib/tasks/converter/flat_ui_less_conversion.rb +328 -0
- data/lib/tasks/converter/logger.rb +61 -0
- data/lib/tasks/flat-ui-sass.rake +8 -0
- data/templates/project/_variables.scss.erb +5 -0
- data/templates/project/manifest.rb +57 -0
- data/templates/project/styles.scss +4 -0
- data/vendor/assets/fonts/flat-ui/flat-ui-icons-regular.eot +0 -0
- data/vendor/assets/fonts/flat-ui/flat-ui-icons-regular.svg +140 -0
- data/vendor/assets/fonts/flat-ui/flat-ui-icons-regular.ttf +0 -0
- data/vendor/assets/fonts/flat-ui/flat-ui-icons-regular.woff +0 -0
- data/vendor/assets/images/flat-ui/icons/png/Book.png +0 -0
- data/vendor/assets/images/flat-ui/icons/png/Calendar.png +0 -0
- data/vendor/assets/images/flat-ui/icons/png/Chat.png +0 -0
- data/vendor/assets/images/flat-ui/icons/png/Clipboard.png +0 -0
- data/vendor/assets/images/flat-ui/icons/png/Compas.png +0 -0
- data/vendor/assets/images/flat-ui/icons/png/Gift-Box.png +0 -0
- data/vendor/assets/images/flat-ui/icons/png/Infinity-Loop.png +0 -0
- data/vendor/assets/images/flat-ui/icons/png/Mail.png +0 -0
- data/vendor/assets/images/flat-ui/icons/png/Map.png +0 -0
- data/vendor/assets/images/flat-ui/icons/png/Pensils.png +0 -0
- data/vendor/assets/images/flat-ui/icons/png/Pocket.png +0 -0
- data/vendor/assets/images/flat-ui/icons/png/Retina-Ready.png +0 -0
- data/vendor/assets/images/flat-ui/icons/png/Toilet-Paper.png +0 -0
- data/vendor/assets/images/flat-ui/icons/png/Watches.png +0 -0
- data/vendor/assets/images/flat-ui/icons/svg/book.svg +1 -0
- data/vendor/assets/images/flat-ui/icons/svg/calendar.svg +1 -0
- data/vendor/assets/images/flat-ui/icons/svg/chat.svg +1 -0
- data/vendor/assets/images/flat-ui/icons/svg/clipboard.svg +1 -0
- data/vendor/assets/images/flat-ui/icons/svg/clocks.svg +9 -0
- data/vendor/assets/images/flat-ui/icons/svg/compas.svg +1 -0
- data/vendor/assets/images/flat-ui/icons/svg/gift-box.svg +1 -0
- data/vendor/assets/images/flat-ui/icons/svg/loop.svg +5 -0
- data/vendor/assets/images/flat-ui/icons/svg/mail.svg +1 -0
- data/vendor/assets/images/flat-ui/icons/svg/map.svg +1 -0
- data/vendor/assets/images/flat-ui/icons/svg/paper-bag.svg +1 -0
- data/vendor/assets/images/flat-ui/icons/svg/pencils.svg +1 -0
- data/vendor/assets/images/flat-ui/icons/svg/retina.svg +1 -0
- data/vendor/assets/images/flat-ui/icons/svg/toilet-paper.svg +1 -0
- data/vendor/assets/images/flat-ui/login/icon.png +0 -0
- data/vendor/assets/images/flat-ui/login/imac-2x.png +0 -0
- data/vendor/assets/images/flat-ui/login/imac.png +0 -0
- data/vendor/assets/images/flat-ui/switch/mask-square.png +0 -0
- data/vendor/assets/images/flat-ui/switch/mask.png +0 -0
- data/vendor/assets/images/flat-ui/tile/ribbon-2x.png +0 -0
- data/vendor/assets/images/flat-ui/tile/ribbon.png +0 -0
- data/vendor/assets/images/flat-ui/todo/done-2x.png +0 -0
- data/vendor/assets/images/flat-ui/todo/done.png +0 -0
- data/vendor/assets/images/flat-ui/todo/search-2x.png +0 -0
- data/vendor/assets/images/flat-ui/todo/search.png +0 -0
- data/vendor/assets/images/flat-ui/todo/todo-2x.png +0 -0
- data/vendor/assets/images/flat-ui/todo/todo.png +0 -0
- data/vendor/assets/images/flat-ui/video/fullscreen-2x.png +0 -0
- data/vendor/assets/images/flat-ui/video/fullscreen.png +0 -0
- data/vendor/assets/images/flat-ui/video/pause-2x.png +0 -0
- data/vendor/assets/images/flat-ui/video/pause.png +0 -0
- data/vendor/assets/images/flat-ui/video/play-2x.png +0 -0
- data/vendor/assets/images/flat-ui/video/play.png +0 -0
- data/vendor/assets/images/flat-ui/video/poster.jpg +0 -0
- data/vendor/assets/images/flat-ui/video/volume-full-2x.png +0 -0
- data/vendor/assets/images/flat-ui/video/volume-full.png +0 -0
- data/vendor/assets/images/flat-ui/video/volume-off-2x.png +0 -0
- data/vendor/assets/images/flat-ui/video/volume-off.png +0 -0
- data/vendor/assets/javascripts/flat-ui.js +2 -0
- data/vendor/assets/javascripts/flat-ui/flatui-checkbox.js +112 -0
- data/vendor/assets/javascripts/flat-ui/flatui-radio.js +139 -0
- data/vendor/assets/stylesheets/flat-ui.scss +1 -0
- data/vendor/assets/stylesheets/flat-ui/_mixins.scss +878 -0
- data/vendor/assets/stylesheets/flat-ui/_spaces.scss +172 -0
- data/vendor/assets/stylesheets/flat-ui/_variables.scss +509 -0
- data/vendor/assets/stylesheets/flat-ui/flat-ui.scss +45 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_button-groups.scss +110 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_buttons.scss +151 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_caret.scss +30 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_checkbox-and-radio.scss +143 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_code.scss +49 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_dropdown.scss +223 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_footer.scss +76 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_forms.scss +188 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_glyphicons.scss +135 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_input-groups.scss +153 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_input-icons.scss +72 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_local-fonts.scss +69 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_login.scss +111 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_navbar.scss +876 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_pager.scss +51 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_pagination.scss +166 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_palette.scss +71 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_progress-bars.scss +34 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_scaffolding.scss +64 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_select.scss +145 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_share.scss +44 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_slider.scss +105 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_switch.scss +150 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_tagsinput.scss +121 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_thumbnails.scss +38 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_tile.scss +54 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_todo.scss +110 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_tooltip.scss +56 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_type.scss +208 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_typeahead.scss +41 -0
- data/vendor/assets/stylesheets/flat-ui/modules/_video.scss +458 -0
- metadata +251 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'tasks/converter'
|
3
|
+
require 'flat-ui-sass/version'
|
4
|
+
|
5
|
+
module FlatUI
|
6
|
+
class CLI
|
7
|
+
class << self
|
8
|
+
def start(*args)
|
9
|
+
options = parse_options!(*args)
|
10
|
+
Converter.new(options[:type], options[:input], options).process_flat_ui!
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def parse_options!(*args)
|
16
|
+
options = {
|
17
|
+
type: :pro,
|
18
|
+
input: 'flat-ui-pro',
|
19
|
+
log_level: 1
|
20
|
+
}
|
21
|
+
|
22
|
+
opt_parser = OptionParser.new do |opts|
|
23
|
+
opts.banner = "Usage: fui_convert [options]"
|
24
|
+
opts.separator ""
|
25
|
+
opts.separator "Options:"
|
26
|
+
|
27
|
+
opts.on("--type [TYPE]", "-t", [:free, :pro], "Specify the type of conversion to perform (free or pro).","Default is pro") do |type|
|
28
|
+
if type
|
29
|
+
options[:type] = type.to_sym
|
30
|
+
options[:input] = "flat-ui" if type == :free
|
31
|
+
end
|
32
|
+
end
|
33
|
+
opts.on("--log_level [LEVEL]", "-l", OptionParser::DecimalInteger, "Specify the verbosity of the log output", "Default is 1. Levels are 0-3.") do |level|
|
34
|
+
options[:log_level] = level if level
|
35
|
+
end
|
36
|
+
opts.on("--input [DIR]", "-i", "The Flat-UI root directory.","Default is flat-ui-pro") do |dir|
|
37
|
+
options[:input] = dir if dir
|
38
|
+
end
|
39
|
+
opts.on_tail("-h", "--help", "Show help") do
|
40
|
+
puts opts
|
41
|
+
exit
|
42
|
+
end
|
43
|
+
opts.on_tail("--version", "Show version") do
|
44
|
+
puts "Flat-UI Compatibility:"
|
45
|
+
puts " Free v#{FlatUI::VERSION}"
|
46
|
+
puts " Pro v#{FlatUI::PRO_VERSION}"
|
47
|
+
exit
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
opt_parser.parse!(args)
|
52
|
+
options
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module FlatUI
|
2
|
+
module Rails
|
3
|
+
class Engine < ::Rails::Engine
|
4
|
+
initializer "flat-ui-sass.assets.precompile" do |app|
|
5
|
+
if Dir.exist? File.join(::Rails.root, 'vendor', 'assets', 'fonts', 'flat-ui-pro')
|
6
|
+
app.config.assets.precompile << %r(flat-ui-pro/flat-ui-icons-regular\.(?:eot|svg|ttf|woff)$)
|
7
|
+
else
|
8
|
+
app.config.assets.precompile << %r(flat-ui/flat-ui-icons-regular\.(?:eot|svg|ttf|woff)$)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# Based on bootstrap-sass
|
2
|
+
# https://github.com/twbs/bootstrap-sass/blob/master/lib/bootstrap-sass/sass_functions.rb
|
3
|
+
|
4
|
+
require 'sass'
|
5
|
+
|
6
|
+
module Sass::Script::Functions
|
7
|
+
def flat_ui_font_path(source)
|
8
|
+
flat_ui_asset_path source, :font
|
9
|
+
end
|
10
|
+
declare :flat_ui_font_path, [:source]
|
11
|
+
|
12
|
+
def flat_ui_image_path(source)
|
13
|
+
flat_ui_asset_path source, :image
|
14
|
+
end
|
15
|
+
declare :flat_ui_image_path, [:source]
|
16
|
+
|
17
|
+
def flat_ui_asset_path(source, type)
|
18
|
+
return Sass::Script::String.new('', :string) if source.to_s.empty?
|
19
|
+
url = if FlatUI.asset_pipeline? && (context = sprockets_context)
|
20
|
+
context.send(:"#{type}_path", source.value)
|
21
|
+
elsif FlatUI.compass?
|
22
|
+
send(:"#{type}_url", source, Sass::Script::Bool.new(true)).value.sub /url\((.*)\)$/, '\1'
|
23
|
+
end
|
24
|
+
|
25
|
+
# sass-only
|
26
|
+
url ||= source.value.gsub('"', '')
|
27
|
+
Sass::Script::String.new(url, :string)
|
28
|
+
end
|
29
|
+
declare :flat_ui_asset_path, [:source, :type]
|
30
|
+
|
31
|
+
unless Sass::Script::Functions.instance_methods.include?(:tint)
|
32
|
+
def tint(color, percentage)
|
33
|
+
assert_type color, :Color
|
34
|
+
assert_type percentage, :Number
|
35
|
+
white = Sass::Script::Color.new([255, 255, 255])
|
36
|
+
mix(white, color, percentage)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
unless Sass::Script::Functions.instance_methods.include?(:fade)
|
41
|
+
def fade(color, amount)
|
42
|
+
if amount.is_a?(Sass::Script::Number) && amount.unit_str == "%"
|
43
|
+
amount = Sass::Script::Number.new(1 - amount.value / 100.0)
|
44
|
+
end
|
45
|
+
fade_out(color, amount)
|
46
|
+
end
|
47
|
+
declare :fade, [:color, :amount]
|
48
|
+
end
|
49
|
+
|
50
|
+
# Based on https://github.com/edwardoriordan/sass-utilities/blob/master/lib/sass-utilities.rb
|
51
|
+
# For Sass < 3.3.0, just echo back the variable since we can't interpolate it
|
52
|
+
def interpolate_variable(name)
|
53
|
+
assert_type name, :String
|
54
|
+
::Sass::VERSION >= '3.3.0' ? environment.var(name.value) : name
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Based on the conversion script used for bootstrap-sass
|
4
|
+
# https://github.com/twbs/bootstrap-sass/blob/master/tasks/converter.rb
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this work except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License in the LICENSE file, or at:
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
require 'json'
|
19
|
+
require 'fileutils'
|
20
|
+
require 'forwardable'
|
21
|
+
require 'sass'
|
22
|
+
|
23
|
+
# Pull in stuff from bootstrap-sass
|
24
|
+
spec = Gem::Specification.find_by_name('bootstrap-sass')
|
25
|
+
%w{char_string_scanner less_conversion}.each do |file|
|
26
|
+
require File.join(spec.gem_dir, 'tasks', 'converter', file)
|
27
|
+
end
|
28
|
+
|
29
|
+
require_relative 'converter/flat_ui_less_conversion'
|
30
|
+
require_relative 'converter/flat_ui_js_conversion'
|
31
|
+
require_relative 'converter/flat_ui_fonts_conversion'
|
32
|
+
require_relative 'converter/flat_ui_images_conversion'
|
33
|
+
require_relative 'converter/filesystem'
|
34
|
+
require_relative 'converter/logger'
|
35
|
+
|
36
|
+
class Converter
|
37
|
+
extend Forwardable
|
38
|
+
include FileSystem
|
39
|
+
include FlatUILessConversion
|
40
|
+
include FlatUIJsConversion
|
41
|
+
include FlatUIFontsConversion
|
42
|
+
include FlatUIImageConversion
|
43
|
+
|
44
|
+
def initialize(type = :free, src_path = './flat-ui', options = {})
|
45
|
+
@logger = Logger.new(options[:log_level])
|
46
|
+
@src_path = File.expand_path(src_path)
|
47
|
+
@type = type
|
48
|
+
@output_dir = type == :free ? 'flat-ui' : 'flat-ui-pro'
|
49
|
+
@dest_path = {
|
50
|
+
js: File.join('vendor/assets/javascripts', @output_dir),
|
51
|
+
scss: File.join('vendor/assets/stylesheets', @output_dir),
|
52
|
+
fonts: File.join('vendor/assets/fonts', @output_dir),
|
53
|
+
images: File.join('vendor/assets/images', @output_dir)
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
def_delegators :@logger, :log, :log_status, :log_processing, :log_transform, :log_file_info, :log_processed
|
58
|
+
|
59
|
+
def process_flat_ui!
|
60
|
+
log_status 'Convert Flat UI from LESS to SASS'
|
61
|
+
log " type: #{@output_dir}"
|
62
|
+
log " input: #{@src_path}"
|
63
|
+
log " output:"
|
64
|
+
log " js: #{@dest_path[:js]}"
|
65
|
+
log " scss: #{@dest_path[:scss]}"
|
66
|
+
log " fonts: #{@dest_path[:fonts]}"
|
67
|
+
log " images: #{@dest_path[:images]}"
|
68
|
+
|
69
|
+
setup_file_structure!
|
70
|
+
|
71
|
+
process_flat_ui_stylesheet_assets!
|
72
|
+
process_flat_ui_javascript_assets!
|
73
|
+
process_flat_ui_font_assets!
|
74
|
+
process_flat_ui_image_assets!
|
75
|
+
end
|
76
|
+
|
77
|
+
def save_file(path, content, mode='w')
|
78
|
+
File.open(path, mode) { |file| file.write(content) }
|
79
|
+
end
|
80
|
+
|
81
|
+
def free?
|
82
|
+
!pro?
|
83
|
+
end
|
84
|
+
|
85
|
+
def pro?
|
86
|
+
@type == :pro
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def setup_file_structure!
|
92
|
+
@dest_path.each do |_, v|
|
93
|
+
FileUtils.rm_rf(v)
|
94
|
+
FileUtils.mkdir_p(v)
|
95
|
+
end
|
96
|
+
|
97
|
+
FileUtils.mkdir_p("#{@dest_path[:scss]}/modules")
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Converter
|
2
|
+
module FileSystem
|
3
|
+
def read_files(path, files)
|
4
|
+
contents = {}
|
5
|
+
|
6
|
+
full_path = File.join(@src_path, path)
|
7
|
+
|
8
|
+
if File.directory?(full_path)
|
9
|
+
files.each do |file|
|
10
|
+
contents[file] = File.read(File.join(full_path, file), mode: 'rb') || ''
|
11
|
+
end
|
12
|
+
contents
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
class Converter
|
4
|
+
module FlatUIFontsConversion
|
5
|
+
def process_flat_ui_font_assets!
|
6
|
+
log_status 'Processing fonts...'
|
7
|
+
save_to = @dest_path[:fonts]
|
8
|
+
flat_ui_font_files.each do |file|
|
9
|
+
FileUtils.cp "#{@src_path}/fonts/#{file}", "#{save_to}/#{file}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def flat_ui_font_files
|
14
|
+
@flat_ui_font_files ||= Dir.chdir "#{@src_path}/fonts" do
|
15
|
+
Dir['*.{eot,svg,ttf,woff}'].reject{|f| f =~ /\.dev/}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Converter
|
2
|
+
module FlatUIImageConversion
|
3
|
+
def process_flat_ui_image_assets!
|
4
|
+
log_status 'Processing images...'
|
5
|
+
save_to = @dest_path[:images]
|
6
|
+
flat_ui_image_files.each do |file|
|
7
|
+
new_file = "#{save_to}/#{file}"
|
8
|
+
FileUtils.mkdir_p(File.dirname(new_file))
|
9
|
+
FileUtils.cp "#{@src_path}/images/#{file}", new_file
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def flat_ui_image_files
|
14
|
+
@flat_ui_image_files ||= Dir.chdir "#{@src_path}/images" do
|
15
|
+
Dir['{switch,tile,todo,icons,login,video}/**/*.*']
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class Converter
|
2
|
+
module FlatUIJsConversion
|
3
|
+
def process_flat_ui_javascript_assets!
|
4
|
+
log_status 'Processing javascripts...'
|
5
|
+
save_to = @dest_path[:js]
|
6
|
+
read_files('js', flat_ui_js_files).each do |name, file|
|
7
|
+
save_file("#{save_to}/#{name}", file)
|
8
|
+
end
|
9
|
+
log_processed "#{flat_ui_js_files * ' '}"
|
10
|
+
|
11
|
+
log_status 'Updating javascript manifest'
|
12
|
+
content = ''
|
13
|
+
flat_ui_js_files.each do |name|
|
14
|
+
name = name.gsub(/\.js$/, '')
|
15
|
+
content << "//= require #{@output_dir}/#{name}\n"
|
16
|
+
end
|
17
|
+
manifest = File.expand_path(File.join(@dest_path[:js], '..', "#{@output_dir}.js"))
|
18
|
+
save_file(manifest, content)
|
19
|
+
log_processed manifest
|
20
|
+
end
|
21
|
+
|
22
|
+
def flat_ui_js_files
|
23
|
+
@flat_ui_js_files ||= Dir.chdir "#{@src_path}/js" do
|
24
|
+
Dir['flatui-*.js']
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,328 @@
|
|
1
|
+
class Converter
|
2
|
+
module FlatUILessConversion
|
3
|
+
include Converter::LessConversion
|
4
|
+
|
5
|
+
# Mixins that are added by FlatUI
|
6
|
+
FLAT_UI_MIXINS = %w{placeholder-height mask background-clip dropdown-arrow form-controls-corners-reset
|
7
|
+
label-variant navbar-vertical-align social-button-variant}
|
8
|
+
|
9
|
+
# Mixins that FlatUI has modified
|
10
|
+
FLAT_UI_OVERRIDE_MIXINS = %w{placeholder text-hide scale animation horizontal
|
11
|
+
vertical directional horizontal-three-colors vertical-three-colors
|
12
|
+
radial striped button-variant input-size form-control
|
13
|
+
form-control-focus}
|
14
|
+
|
15
|
+
# Modules missing from Flat UI Pro that are in Flat UI Free
|
16
|
+
FLAT_UI_PRO_MISSING_MODULES = %w{}
|
17
|
+
|
18
|
+
# This is similar to the process_stylesheet_assets
|
19
|
+
# utilized by bootstrap-sass except it is specific to
|
20
|
+
# flatui
|
21
|
+
def process_flat_ui_stylesheet_assets!
|
22
|
+
log_status 'Processing stylesheets...'
|
23
|
+
files = read_files('less', flat_ui_less_files)
|
24
|
+
|
25
|
+
log_status ' Converting LESS files to Scss:'
|
26
|
+
files.each do |name, file|
|
27
|
+
log_processing name
|
28
|
+
|
29
|
+
# apply common conversions
|
30
|
+
# icon-font bombs on this so skip it
|
31
|
+
file = convert_less(file) unless name =~ /flat-ui|glyphicons/
|
32
|
+
file = replace_file_imports(file)
|
33
|
+
file = cleanup_whitespace(file)
|
34
|
+
case name
|
35
|
+
when 'flat-ui.less'
|
36
|
+
lines = file.split "\n"
|
37
|
+
lines.reject! {|line|
|
38
|
+
#kill the fonts lines, those are up to the user
|
39
|
+
#kill variables since those need to be manually imported before bootstrap
|
40
|
+
line =~ /fonts|url|variables/
|
41
|
+
}
|
42
|
+
|
43
|
+
# Add a comment for the icon font
|
44
|
+
icon_font_import = lines.index {|line| line =~ /glyphicons/}
|
45
|
+
lines.insert(icon_font_import, '// Flat-UI-Icons')
|
46
|
+
lines.delete_at(icon_font_import+2)
|
47
|
+
|
48
|
+
file = lines.join "\n"
|
49
|
+
when 'mixins.less'
|
50
|
+
NESTED_MIXINS.each do |selector, prefix|
|
51
|
+
file = flatten_mixins(file, selector, prefix)
|
52
|
+
end
|
53
|
+
file = varargify_mixin_definitions(file, *VARARG_MIXINS)
|
54
|
+
file = deinterpolate_vararg_mixins(file)
|
55
|
+
%w(responsive-(in)?visibility input-size text-emphasis-variant bg-variant).each do |mixin|
|
56
|
+
file = parameterize_mixin_parent_selector file, mixin
|
57
|
+
end
|
58
|
+
file = replace_ms_filters(file)
|
59
|
+
if pro?
|
60
|
+
file = replace_all file, /(?<=[.-])\$state/, '#{$state}'
|
61
|
+
else
|
62
|
+
# calc-color mixin only exists in Flat-UI free
|
63
|
+
file = replace_all file, /-(\$.+-color)/, '-#{\1}'
|
64
|
+
file = replace_all file, /#\{\$\$\{(.+)\}\}/, 'interpolate_variable($\1)'
|
65
|
+
end
|
66
|
+
file = replace_rules(file, ' .list-group-item-') { |rule| extract_nested_rule rule, 'a&' }
|
67
|
+
file = replace_all file, /,\s*\.open \.dropdown-toggle& \{(.*?)\}/m,
|
68
|
+
" {\\1}\n .open & { &.dropdown-toggle {\\1} }"
|
69
|
+
file = replace_all file, '$ratio, $ratio-y', '$scale-args'
|
70
|
+
file = convert_grid_mixins file
|
71
|
+
when 'variables.less'
|
72
|
+
file = insert_default_vars(file)
|
73
|
+
if ::Sass::VERSION >= '3.3.0'
|
74
|
+
file = unindent <<-SCSS + file, 14
|
75
|
+
// a flag to toggle asset pipeline / compass integration
|
76
|
+
$flat-ui-sass-asset-helper: function-exists(flat-ui-font-path) !default;
|
77
|
+
|
78
|
+
SCSS
|
79
|
+
else
|
80
|
+
file = unindent <<-SCSS + file, 14
|
81
|
+
// a flag to toggle asset pipeline / compass integration
|
82
|
+
// defaults to true if flat-ui-font-path function is present (no function => twbs-font-path('') parsed as string == right side)
|
83
|
+
$flat-ui-sass-asset-helper: (flat-ui-font-path("") != unquote('flat-ui-font-path("")')) !default;
|
84
|
+
|
85
|
+
SCSS
|
86
|
+
end
|
87
|
+
file = fix_variable_declaration_order file
|
88
|
+
file = replace_all file, /(\$icon-font-path:\s+).*(!default)/, '\1"'+@output_dir+'/" \2'
|
89
|
+
when 'modules/buttons.less'
|
90
|
+
file = extract_nested_rule file, '.btn-xs&'
|
91
|
+
file = extract_nested_rule file, '.btn-hg&'
|
92
|
+
when 'modules/forms.less'
|
93
|
+
# Fix mixin regex not supporting non-variable arguments
|
94
|
+
file.gsub! /@include input-size\((?:\$.+)\);/ do |match|
|
95
|
+
match.gsub /; /, ', '
|
96
|
+
end
|
97
|
+
file = apply_mixin_parent_selector(file, '\.input-(?:sm|lg|hg)')
|
98
|
+
when 'modules/input-groups.less'
|
99
|
+
file = replace_rules(file, '.input-group-rounded') do |rule|
|
100
|
+
extract_and_combine_nested_rules rule
|
101
|
+
end
|
102
|
+
when 'modules/glyphicons.less'
|
103
|
+
file = replace_vars(file)
|
104
|
+
file = replace_escaping(file)
|
105
|
+
file = replace_all file, /\#\{(url\(.*?\))}/, '\1'
|
106
|
+
file = replace_rules(file, '@font-face') { |rule|
|
107
|
+
rule = replace_all rule, /(\$icon-font(?:-\w+)+)/, '#{\1}'
|
108
|
+
replace_asset_url rule, :font
|
109
|
+
}
|
110
|
+
when 'modules/login.less'
|
111
|
+
file = fix_flat_ui_image_assets file
|
112
|
+
when 'modules/navbar.less'
|
113
|
+
# Fix mixin regex not supporting non-variable arguments
|
114
|
+
file.gsub! /@include input-size\((?:\$.+)\);/ do |match|
|
115
|
+
match.gsub /; /, ', '
|
116
|
+
end
|
117
|
+
file = apply_mixin_parent_selector(file, '\.navbar-input')
|
118
|
+
when 'modules/palette.less'
|
119
|
+
file.gsub! /@include calc-color\((.+)\);/ do |match|
|
120
|
+
match.gsub /#\{([\w\-]+)\}/, '"\1"'
|
121
|
+
end
|
122
|
+
when 'modules/select.less'
|
123
|
+
# Fix the include that the converter makes an extend
|
124
|
+
file = replace_all file, /@extend \.caret/, '@include caret'
|
125
|
+
when 'modules/spinner.less'
|
126
|
+
# Fix mixin regex not supporting non-variable arguments
|
127
|
+
file.gsub! /@include spinner-variant\((?:\$?.+)\);/ do |match|
|
128
|
+
match.gsub /; /, ', '
|
129
|
+
end
|
130
|
+
when 'modules/switch.less'
|
131
|
+
file = fix_flat_ui_image_assets file
|
132
|
+
when 'modules/tile.less'
|
133
|
+
file = fix_flat_ui_image_assets file
|
134
|
+
when 'modules/todo.less'
|
135
|
+
file = fix_flat_ui_image_assets file
|
136
|
+
when 'modules/thumbnails.less'
|
137
|
+
file = extract_nested_rule file, 'a&'
|
138
|
+
when 'modules/type.less'
|
139
|
+
# Since .bg-primary has a color associated with it we need to divide it into
|
140
|
+
# two selectors
|
141
|
+
file = replace_rules(file, '.bg-primary') do |rule|
|
142
|
+
parts = rule.split "\n"
|
143
|
+
selector = parts.index {|line| line =~ /\.bg-primary/}
|
144
|
+
mixin = parts.index {|line| line =~ /@include/}
|
145
|
+
parts.insert(mixin, "}\n#{parts[selector]}")
|
146
|
+
rule = parts.join "\n"
|
147
|
+
end
|
148
|
+
file = apply_mixin_parent_selector(file, '\.(text|bg)-(success|primary|info|warning|danger)')
|
149
|
+
when 'modules/video.less'
|
150
|
+
file = replace_rules(file, /\s*\.vjs(?:-(?:control|time))?(?!-\w+)/) do |rule|
|
151
|
+
selector = get_selector(rule).scan(/\.vjs(?:-(?:control|time))?(?!-\w+)/).first
|
152
|
+
convert_arbitrary_less_ampersand(rule, selector)
|
153
|
+
end
|
154
|
+
file = fix_flat_ui_image_assets file
|
155
|
+
end
|
156
|
+
|
157
|
+
name = name.sub(/\.less$/, '.scss')
|
158
|
+
base = File.basename(name)
|
159
|
+
name.gsub!(base, "_#{base}") unless base == 'flat-ui.scss'
|
160
|
+
path = File.join(@dest_path[:scss], name)
|
161
|
+
save_file(path, file)
|
162
|
+
log_processed File.basename(path)
|
163
|
+
end
|
164
|
+
|
165
|
+
manifest = File.join(@dest_path[:scss], '..', "#{@output_dir}.scss")
|
166
|
+
save_file(manifest, "@import \"#{@output_dir}/flat-ui\";")
|
167
|
+
end
|
168
|
+
|
169
|
+
def flat_ui_less_files
|
170
|
+
@flat_ui_less_files ||= Dir.chdir "#{@src_path}/less" do
|
171
|
+
Dir['**/*.less'].reject{|f| f =~ /(?:demo|docs)\.less$/ }
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# Set load_shared to read from mixins.less again since bootstrap converted to
|
176
|
+
# modular mixins.
|
177
|
+
def load_shared
|
178
|
+
@shared_mixins ||= begin
|
179
|
+
log_status ' Reading shared mixins from mixins.less'
|
180
|
+
read_mixins read_files('less', ['mixins.less'])['mixins.less'], nested: NESTED_MIXINS
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def extract_and_combine_nested_rules(file)
|
185
|
+
matches = Hash.new {|k,v| k[v] = []}
|
186
|
+
file = file.dup
|
187
|
+
file.scan(/\.[\w-]+&/x) do |selector|
|
188
|
+
#first find the rules, and remove them
|
189
|
+
file = replace_rules(file, "\s*#{selector}") do |rule, pos, css|
|
190
|
+
selector = selector.gsub(/&$/, '')
|
191
|
+
styles = rule.split(/[{}]/).last.strip
|
192
|
+
parent = selector_for_pos(css, pos.begin).split('{').last.strip
|
193
|
+
matches[selector] << create_rule(parent, styles)
|
194
|
+
|
195
|
+
# Return an empty string to blank out this rule
|
196
|
+
""
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# Generate the combined nested rules
|
201
|
+
rules = matches.inject("") do |s, (rule, children)|
|
202
|
+
s += create_rule "&#{rule}", *children
|
203
|
+
end
|
204
|
+
close = close_brace_pos file, 0
|
205
|
+
|
206
|
+
file.insert(close, indent(rules))
|
207
|
+
end
|
208
|
+
|
209
|
+
def create_rule(name, *styles)
|
210
|
+
rule = "#{unindent(name)} {\n"
|
211
|
+
styles.each {|s| rule += indent "#{s}\n"}
|
212
|
+
rule += "}\n"
|
213
|
+
end
|
214
|
+
|
215
|
+
# TODO this method is on the brittle side
|
216
|
+
# look into make it more robust
|
217
|
+
def fix_variable_declaration_order(file)
|
218
|
+
# Spinner needs to be moved after Buttons
|
219
|
+
# since it depends on $btn-default-bg
|
220
|
+
#
|
221
|
+
# also spinner-btn-hover-bg needs to be
|
222
|
+
# before spinner-up-btn-border
|
223
|
+
if file.include? 'Spinner'
|
224
|
+
lines = file.split "\n"
|
225
|
+
spinner_start = lines.index {|l| l =~ /Spinner/}
|
226
|
+
spinner_end = lines.index {|l| l =~ /Pagination/} - 1
|
227
|
+
buttons_end = lines.index {|l| l =~ /Navs/} - 1
|
228
|
+
|
229
|
+
(spinner_end - spinner_start).times do
|
230
|
+
lines.insert(buttons_end, lines.delete_at(spinner_start))
|
231
|
+
end
|
232
|
+
|
233
|
+
spinner_btn_bg = lines.index {|l| l =~ /spinner-btn-bg:/}-1
|
234
|
+
3.times do
|
235
|
+
lines.insert(spinner_btn_bg+5, lines.delete_at(spinner_btn_bg))
|
236
|
+
end
|
237
|
+
|
238
|
+
file = lines.join("\n")
|
239
|
+
end
|
240
|
+
file
|
241
|
+
end
|
242
|
+
|
243
|
+
def fix_relative_asset_url(rule, type)
|
244
|
+
# Use a really naive pluralization
|
245
|
+
replace_all rule, /url\(['"]?\.\.\/#{type}s\/([a-zA-Z0-9\-\/\.\?#]+)['"]?\)/, "url(\"#{@output_dir}/\\1\")"
|
246
|
+
end
|
247
|
+
|
248
|
+
def fix_flat_ui_image_assets(file)
|
249
|
+
file = replace_all file, /\#\{(url\(.*?\).*?)}/, '\1'
|
250
|
+
file = fix_relative_asset_url file, :image
|
251
|
+
file = replace_asset_url file, :image
|
252
|
+
end
|
253
|
+
|
254
|
+
def cleanup_whitespace(file)
|
255
|
+
file.gsub(/\r|\t/, "")
|
256
|
+
end
|
257
|
+
|
258
|
+
# Based on the original convert_less_ampersand but modified
|
259
|
+
# for flat_ui_sass
|
260
|
+
def convert_arbitrary_less_ampersand(less, selector)
|
261
|
+
return less unless less.include?(selector)
|
262
|
+
|
263
|
+
styles = less.dup
|
264
|
+
tmp = "\n"
|
265
|
+
less.scan(/^(\s*&)(-[\w\[\]-]+\s*\{.+?})/m) do |ampersand, css|
|
266
|
+
tmp << "#{selector}#{unindent(css)}\n"
|
267
|
+
styles.gsub! "#{ampersand}#{css}", ""
|
268
|
+
end
|
269
|
+
|
270
|
+
if tmp.length > 1
|
271
|
+
styles.gsub!(/\s*#{"\\"+selector}\s*\{\s*}/m, '')
|
272
|
+
styles << tmp
|
273
|
+
else
|
274
|
+
styles = less
|
275
|
+
end
|
276
|
+
|
277
|
+
styles
|
278
|
+
end
|
279
|
+
|
280
|
+
#
|
281
|
+
# Methods overridden from the bootstrap-sass converter
|
282
|
+
#
|
283
|
+
|
284
|
+
def replace_asset_url(rule, type)
|
285
|
+
replace_all rule, /url\((.*?)\)/, "url(if($flat-ui-sass-asset-helper, flat-ui-#{type}-path(\\1), \\1))"
|
286
|
+
end
|
287
|
+
|
288
|
+
# @import "file" to "#{@output_dir)}/file"
|
289
|
+
def replace_file_imports(file)
|
290
|
+
file.gsub %r([@\$]import ["|'](.*)["|'];),
|
291
|
+
%Q(@import "#{@output_dir}/\\1";)
|
292
|
+
end
|
293
|
+
|
294
|
+
# Regex will match things like spinner-input-width
|
295
|
+
# by default.
|
296
|
+
#
|
297
|
+
# Fix the first lookaround to be a positive
|
298
|
+
# lookaround and also check for word chars
|
299
|
+
# after the word 'spin'
|
300
|
+
def replace_spin(less)
|
301
|
+
less.gsub(/(?<![\-$@.])spin(?![\-\w])/, 'adjust-hue')
|
302
|
+
end
|
303
|
+
|
304
|
+
# Fix to support replacing mixin definitions with default args
|
305
|
+
# https://github.com/twbs/bootstrap-sass/blob/master/tasks/converter/less_conversion.rb#L293
|
306
|
+
#
|
307
|
+
# @mixin a() { tr& { color:white } }
|
308
|
+
# to:
|
309
|
+
# @mixin a($parent) { tr#{$parent} { color: white } }
|
310
|
+
def parameterize_mixin_parent_selector(file, rule_sel)
|
311
|
+
log_transform rule_sel
|
312
|
+
param = '$parent'
|
313
|
+
replace_rules(file, '^\s*@mixin\s*' + rule_sel) do |mxn_css|
|
314
|
+
mxn_css.sub! /(?=@mixin)/, "// [converter] $parent hack\n"
|
315
|
+
# insert param into mixin def
|
316
|
+
mxn_css.sub!(/(@mixin [\w-]+)\(([\$\w\-:,\s]*)\)/) { "#{$1}(#{param}#{', ' if $2 && !$2.empty?}#{$2})" }
|
317
|
+
# wrap properties in #{$parent} { ... }
|
318
|
+
replace_properties(mxn_css) { |props|
|
319
|
+
next props if props.strip.empty?
|
320
|
+
spacer = ' ' * indent_width(props)
|
321
|
+
"#{spacer}\#{#{param}} {\n#{indent(props.sub(/\s+\z/, ''), 2)}\n#{spacer}}"
|
322
|
+
}
|
323
|
+
# change nested& rules to nested#{$parent}
|
324
|
+
replace_rules(mxn_css, /.*&[ ,:]/) { |rule| replace_in_selector rule, /&/, "\#{#{param}}" }
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|