flat-ui-sass 2.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|