1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
SVGJS_VERSION = '0.1a'
# all available modules in the correct loading order
ALL = %w[ svg container element group arrange clip doc defs shape rect circle ellipse path image sugar ]
# required modules to make the library operational
CORE = %w[ circle container defs doc element ellipse image path rect shape svg ]
# optional modules
OPTIONAL = %w[ clip group arrange sugar ]
# modules used in the curren build
MODULES = CORE.concat(OPTIONAL).sort { |a,b| ALL.index(a) <=> ALL.index(b) }
# how many bytes in a "kilobyte"
KILO = 1024
task :default => :dist
# module-aware file task
class BuildTask < Rake::FileTask
def modules
prerequisites.map { |f| File.basename(f, '.js') }
end
def remove_prerequisites to_remove
@prerequisites -= to_remove
return self
end
def needed?() super or modules_mismatch? end
def modules_mismatch?
previous_modules != modules
end
def previous_modules
first_line =~ / - ([\w,\s]+) - / && $1.split(/\W+/)
end
def first_line
File.open(name, 'r') { |f| f.gets }
end
end
BuildTask.define_task 'dist/svg.js' => MODULES.map {|m| "src/#{ m }.js" } do |task|
mkdir_p 'dist', :verbose => false
svgjs = ''
task.prerequisites.each do |src|
# bring in source files one by one, but without copyright info
copyright = true
File.open(src).each_line do |line|
copyright = false if copyright and line !~ %r{^(/|\s*$)}
svgjs << " #{ line }" unless copyright
end
svgjs << "\n\n"
end
File.open(task.name, 'w') do |file|
file.puts "/* svg.js %s - %s - svgjs.com/license */" % [version_string, task.modules.join(' ')]
file.puts '(function() {'
file.puts "\n"
file.puts svgjs
file.puts '}).call(this);'
end
end
file 'dist/svg.min.js' => 'dist/svg.js' do |task|
require 'rubygems'
begin require 'uglifier'
rescue LoadError; fail "Uglifier not available: #{$!}"
else
File.open(task.name, 'w') do |min|
min << Uglifier.new.compile(File.read(task.prerequisites.first))
end
end
end
file 'dist/svg.min.gz' => 'dist/svg.min.js' do |task|
verbose false do
tmp_file = task.name.sub('.gz', '')
cp task.prerequisites.first, tmp_file
sh 'gzip', '--best', tmp_file
end
end
desc "Concatenate source files to build svg.js"
task :concat, [:modules] do |task, args|
modules = args[:modules].to_s.split(':')
to_add, to_exclude = modules.partition {|m| m.sub!(/^(-)?(.+)/, 'src/\2.js'); !$1 }
Rake::Task['dist/svg.js'].
remove_prerequisites(to_exclude).enhance(to_add).
invoke
end
desc "Generate svg.js distribution files and report size statistics"
task :dist => ['dist/svg.js', 'dist/svg.min.js', 'dist/svg.min.gz'] do |task|
orig_size, min_size, gz_size = task.prerequisites.map {|f| File.size(f) }
puts "Original version: %.3fk" % (orig_size.to_f / KILO)
puts "Minified: %.3fk" % (min_size.to_f / KILO)
puts "Minified and gzipped: %.3fk, compression factor %.3f" % [gz_size.to_f / KILO, orig_size.to_f / gz_size]
rm_f 'dist/svg.min.gz', :verbose => false
end
desc "List available modules"
task :modules do
Dir['src/**/*.js'].each do |file|
name = file.gsub(/^src\//,'').gsub(/.js$/,'')
puts name + (MODULES.include?(name) ? '*' : '')
end
puts "\n*included in default build"
end
task(:clean) { rm_rf 'dist' }
desc "Run tests with PhantomJS"
task :test do
sh 'script/test'
Rake::Task[:check_whitespace].invoke
end
desc "Strip trailing whitespace and ensure each file ends with a newline"
task :whitespace do
verbose false do
files = Dir['{src,test,examples}/**/*.{js,html}']
ruby(*%w'-p -i -e $_.sub!(/\s*\Z/,"\n")'.concat(files))
end
end
desc "Checks for trailing whitespace in source files and tests"
task :check_whitespace do
flunked = false
flunk = lambda {|file, num| flunked = true; puts "#{file}:#{num}" }
Dir['{src,test,examples}/**/*.{js,html}'].each do |file|
File.open(file, 'r') {|f| f.each_with_index {|ln, num| flunk.call(file, num + 1) if ln.chomp =~ /\s+$/ } }
end
fail if flunked
end
# desc "Generate docco documentation from source files"
# task :docco do
# verbose false do
# sh 'docco', *Dir['src/*.js']
# end
# end
# svg.js version number + git sha if available
def version_string
desc = `git describe --tags HEAD 2>&1`.chomp
if $?.success?
desc
else
suffix, dir = '', File.basename(Dir.pwd)
# detect git sha from directory name of GitHub zip/tarball
suffix = "-g#{$1}" if dir =~ /^wout-svg.js-([a-f0-9]{7,40})$/
SVGJS_VERSION + suffix
end
end
|