weaver 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 64d0021b8ab6a2f1c556c7708d40daa45c13b508
4
- data.tar.gz: c3b8f985efa4e770335708c0f59653de2fab749e
2
+ SHA256:
3
+ metadata.gz: 58b4fd7e453a9af4450002b361dd04c8470bf5df46c0efa0b2fa22d5b6ba0291
4
+ data.tar.gz: cb2eab30ee9995f172650fb38ea2eb8425518b930712018b8e8d155544aa6231
5
5
  SHA512:
6
- metadata.gz: 4e5339d77dcd36e560dd84ce6448a81fd07837d4a1da90a8cbbe94f38e52bff1634f40d50aa698278b4d3b460c467269aa5f0fc16283fabf3e5ce7ab62958f67
7
- data.tar.gz: 9d04d3c42cc0a707d9302dac8c47b2f2911d5807b1a1a8c82c0a2b030af2c330b0f156b03d48915aa5bd2416664d8107161f74ed5593e8394b588aa8bc55ac54
6
+ metadata.gz: 9fcf769a71319280c0b2b0373baaf22547d7e09d250513d3dcc033c09c7b18915dc86ab97f683b286e7fcc5906791bc6e7db8a044ea0bcf901fe49a5d3a5d0d8
7
+ data.tar.gz: 8ac7ecf0c589fed852fd973395d056f867d444e5c77ab5576b689d6402086f730bce10ed5866136904ee8f247b1bb9a5a83fbbb6e4894cefa16a8d607ae32982
data/Rakefile CHANGED
@@ -1 +1 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "weaver"
3
+ require 'bundler/setup'
4
+ require 'weaver'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,5 @@ require "weaver"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
13
+ require 'irb'
14
14
  IRB.start
data/exe/weaver CHANGED
@@ -5,160 +5,150 @@ require 'optimist'
5
5
  require 'sinatra/base'
6
6
 
7
7
  class Website < Sinatra::Base
8
+ set :static, true # set up static file routing
9
+ set :public_folder, File.join(Gem.loaded_specs['weaver'].full_gem_path, 'data', 'weaver') # set up the static dir (with images/js/css inside)
10
+ set :bind, '0.0.0.0'
11
+ set :port, ENV['PORT'] || 4567
8
12
 
9
- set :static, true # set up static file routing
10
- set :public_folder, File.join(Gem.loaded_specs['weaver'].full_gem_path, "data", "weaver") # set up the static dir (with images/js/css inside)
11
- set :bind, '0.0.0.0'
12
- set :port, ENV['PORT'] || 4567
13
+ def getWeavefile(viewname)
14
+ pathToFile = viewname.split('/').delete_if(&:empty?)
13
15
 
14
- def getWeavefile(viewname)
16
+ viewFile = nil
15
17
 
16
- pathToFile = viewname.split("/").delete_if(&:empty?)
18
+ remainingPath = []
17
19
 
18
- viewFile = nil
20
+ loop do
21
+ path = "#{File.join(['source'] + pathToFile)}.weave"
22
+ indexPath = File.join(['source'] + pathToFile + ['index.weave'])
19
23
 
20
- remainingPath = []
24
+ # puts path
25
+ # puts indexPath
21
26
 
22
- loop do
23
- path = "#{File.join(['source'] + pathToFile)}.weave"
24
- indexPath = File.join(["source"] + pathToFile + ["index.weave"])
27
+ viewFile = path if File.exist?(path)
28
+ viewFile = indexPath if File.exist?(indexPath)
25
29
 
26
- #puts path
27
- #puts indexPath
30
+ break if viewFile || pathToFile.empty?
28
31
 
29
- viewFile = path if File.exists?(path)
30
- viewFile = indexPath if File.exists?(indexPath)
32
+ remainingPath << pathToFile.last
31
33
 
32
- break if viewFile or pathToFile.length == 0
34
+ pathToFile = pathToFile.first pathToFile.size - 1
35
+ end
33
36
 
34
- remainingPath << pathToFile.last
37
+ { viewFile: viewFile, path: remainingPath }
38
+ end
35
39
 
36
- pathToFile = pathToFile.first pathToFile.size-1
37
- end
40
+ get '/*' do
41
+ if params[:splat].first.start_with? 'images/'
42
+ return send_file(params[:splat].first, disposition: 'inline')
43
+ end
38
44
 
39
- { viewFile: viewFile, path: remainingPath }
40
- end
41
-
42
- get '/*' do
43
-
44
- if params[:splat].first.start_with? "images/"
45
- return send_file(params[:splat].first, :disposition => 'inline')
46
- end
45
+ if params[:splat].first.start_with? 'js/'
46
+ return send_file(params[:splat].first, disposition: 'inline')
47
+ end
47
48
 
48
- if params[:splat].first.start_with? "js/"
49
- return send_file(params[:splat].first, :disposition => 'inline')
50
- end
49
+ if params[:splat].first.start_with? 'css/'
50
+ return send_file(params[:splat].first, disposition: 'inline')
51
+ end
51
52
 
52
- if params[:splat].first.start_with? "css/"
53
- return send_file(params[:splat].first, :disposition => 'inline')
54
- end
53
+ viewname = params[:splat].first
54
+ result = getWeavefile viewname
55
+ viewFile = result[:viewFile]
56
+ path = File.join(result[:path].reverse)
55
57
 
58
+ if viewFile
56
59
 
57
- viewname = params[:splat].first
58
- result = getWeavefile viewname
59
- viewFile = result[:viewFile]
60
- path = File.join(result[:path].reverse)
60
+ site = Weaver::Weave.new(viewFile)
61
61
 
62
- if viewFile
62
+ if site.pages.key?(path)
63
63
 
64
- site = Weaver::Weave.new(viewFile)
65
-
66
- if site.pages.has_key?(path)
67
-
68
- level = viewname.split(/\//, 0).length
69
- site.pages[path].generate(level)
70
-
71
- else
72
- puts "Not found: #{viewname} in #{viewFile}"
73
- puts "Path is: #{path}"
74
- status 404
75
- end
76
- else
77
- puts "Not found: #{viewname} in #{viewFile}"
78
- puts "Path is: #{path}"
79
- status 404
80
- end
81
- end
64
+ level = viewname.split(%r{/}, 0).length
65
+ site.pages[path].generate(level)
82
66
 
67
+ else
68
+ puts "Not found: #{viewname} in #{viewFile}"
69
+ puts "Path is: #{path}"
70
+ status 404
71
+ end
72
+ else
73
+ puts "Not found: #{viewname} in #{viewFile}"
74
+ puts "Path is: #{path}"
75
+ status 404
76
+ end
77
+ end
83
78
  end
84
79
 
85
- def build!(args)
86
-
87
- opts = Optimist::options do
88
- banner <<-EOS
80
+ def build!(_args)
81
+ opts = Optimist.options do
82
+ banner <<-EOS
89
83
  Generate website
90
84
 
91
85
  Usage:
92
86
  weaver build [options]
93
87
  where [options] are:
94
- EOS
88
+ EOS
95
89
 
96
- opt :root, "The root URL to be used in links (e.g.) https://astrobunny.net", type: :string, default: "/"
97
- end
90
+ opt :root, 'The root URL to be used in links (e.g.) https://astrobunny.net', type: :string, default: '/'
91
+ end
98
92
 
99
- puts "Building site..."
100
-
101
- buildDir = "#{Dir.pwd}/build"
93
+ puts 'Building site...'
102
94
 
103
- cp_r_options = {preserve: true}
95
+ buildDir = "#{Dir.pwd}/build"
104
96
 
105
- FileUtils::rm_rf buildDir
106
- FileUtils.cp_r(File.join(Gem.loaded_specs['weaver'].full_gem_path, "data", "weaver"), buildDir, cp_r_options)
107
- if Dir.exist? "images"
108
- FileUtils.cp_r("images", buildDir, cp_r_options)
109
- end
110
- if Dir.exist? "js"
111
- Dir["js/*.*"].each do |x|
112
- FileUtils.cp_r(x, File.join(buildDir, "js"), cp_r_options)
113
- end
114
- end
115
- if Dir.exist? "css"
116
- Dir["css/*.*"].each do |x|
117
- FileUtils.cp_r(x, File.join(buildDir, "css"), cp_r_options)
118
- end
119
- end
97
+ cp_r_options = { preserve: true }
120
98
 
121
- files = Dir["source/**/*.weave"]
122
- files.each do |file|
123
- baseDir = file.chomp('.weave').chomp('index').sub(/^source\//, "")
99
+ FileUtils.rm_rf buildDir
100
+ FileUtils.cp_r(File.join(Gem.loaded_specs['weaver'].full_gem_path, 'data', 'weaver'), buildDir, cp_r_options)
101
+ FileUtils.cp_r('images', buildDir, cp_r_options) if Dir.exist? 'images'
102
+ if Dir.exist? 'js'
103
+ Dir['js/*.*'].each do |x|
104
+ FileUtils.cp_r(x, File.join(buildDir, 'js'), cp_r_options)
105
+ end
106
+ end
107
+ if Dir.exist? 'css'
108
+ Dir['css/*.*'].each do |x|
109
+ FileUtils.cp_r(x, File.join(buildDir, 'css'), cp_r_options)
110
+ end
111
+ end
124
112
 
125
- site = Weaver::Weave.new(file, opts)
113
+ files = Dir['source/**/*.weave']
114
+ files.each do |file|
115
+ baseDir = file.chomp('.weave').chomp('index').sub(%r{^source/}, '')
126
116
 
127
- site.pages.each do |localPath, page|
128
- resultPath = File.join(baseDir, localPath)
117
+ site = Weaver::Weave.new(file, opts)
129
118
 
130
- level = resultPath.split(/\//, 0).select{|x| x.length != 0}.length
119
+ site.pages.each do |localPath, page|
120
+ resultPath = File.join(baseDir, localPath)
131
121
 
132
- puts "Writing: #{file} -> #{resultPath} (Level: #{level})"
122
+ level = resultPath.split(%r{/}, 0).reject(&:empty?).length
133
123
 
134
- fileName = File.join([buildDir, resultPath, "index.html"])
135
- FileUtils::mkdir_p File.dirname(fileName)
136
- File.write(fileName, page.generate(level))
137
- end
138
- end
124
+ puts "Writing: #{file} -> #{resultPath} (Level: #{level})"
139
125
 
126
+ fileName = File.join([buildDir, resultPath, 'index.html'])
127
+ FileUtils.mkdir_p File.dirname(fileName)
128
+ File.write(fileName, page.generate(level))
129
+ end
130
+ end
140
131
  end
141
132
 
142
133
  def preview!
143
- puts "Weaver Preview Mode in: #{Dir.pwd}"
134
+ puts "Weaver Preview Mode in: #{Dir.pwd}"
144
135
 
145
- Website.run!
136
+ Website.run!
146
137
  end
147
138
 
148
139
  def create!(args)
140
+ if args.length != 1
141
+ puts 'Usage: weaver create <folder>'
142
+ return
143
+ end
149
144
 
150
- if args.length != 1
151
- puts "Usage: weaver create <folder>"
152
- return
153
- end
154
-
155
- gemfile = <<-GEMFILE
145
+ gemfile = <<-GEMFILE
156
146
  source 'https://rubygems.org'
157
147
 
158
148
  gem 'weaver', '~> #{Weaver::VERSION}'
159
- GEMFILE
149
+ GEMFILE
160
150
 
161
- source = <<-SOURCE
151
+ source = <<-SOURCE
162
152
  topnav_page "", "My first weaver page" do
163
153
  header do
164
154
  col 12 do
@@ -174,25 +164,25 @@ topnav_page "", "My first weaver page" do
174
164
  end
175
165
  end
176
166
  end
177
- SOURCE
178
-
179
- to_create = "#{args[0]}"
180
- FileUtils::mkdir_p "#{to_create}"
181
- FileUtils::mkdir_p "#{to_create}/cache"
182
- File.write("#{to_create}/cache/this_directory_is_used_by_weaver_as_a_cache","")
183
- FileUtils::mkdir_p "#{to_create}/source"
184
- FileUtils::mkdir_p "#{to_create}/images"
185
- FileUtils::mkdir_p "#{to_create}/js"
186
- FileUtils::mkdir_p "#{to_create}/css"
187
- File.write "#{to_create}/Gemfile", gemfile
188
- File.write "#{to_create}/source/index.weave", source
167
+ SOURCE
168
+
169
+ to_create = (args[0]).to_s
170
+ FileUtils.mkdir_p to_create.to_s
171
+ FileUtils.mkdir_p "#{to_create}/cache"
172
+ File.write("#{to_create}/cache/this_directory_is_used_by_weaver_as_a_cache", '')
173
+ FileUtils.mkdir_p "#{to_create}/source"
174
+ FileUtils.mkdir_p "#{to_create}/images"
175
+ FileUtils.mkdir_p "#{to_create}/js"
176
+ FileUtils.mkdir_p "#{to_create}/css"
177
+ File.write "#{to_create}/Gemfile", gemfile
178
+ File.write "#{to_create}/source/index.weave", source
189
179
  end
190
180
 
191
181
  command = ARGV.shift
192
- if command == "build"
193
- build!(ARGV)
194
- elsif command == "create"
195
- create!(ARGV)
182
+ if command == 'build'
183
+ build!(ARGV)
184
+ elsif command == 'create'
185
+ create!(ARGV)
196
186
  else
197
- preview!
187
+ preview!
198
188
  end
@@ -1,2659 +1,29 @@
1
- require "weaver/version"
1
+ require 'weaver/version'
2
2
 
3
3
  require 'fileutils'
4
4
  require 'json'
5
5
  require 'active_support/core_ext/object/to_query'
6
6
 
7
- module Weaver
8
-
9
- class Elements
10
-
11
- def initialize(page, anchors)
12
- @inner_content = []
13
- @anchors = anchors
14
- @page = page
15
- end
16
-
17
- def method_missing(name, *args, &block)
18
- tag = "<#{name} />"
19
-
20
- if args[0].is_a? String
21
- inner = args.shift
22
- end
23
- if block
24
- elem = Elements.new(@page, @anchors)
25
- elem.instance_eval(&block)
26
- inner = elem.generate
27
- end
28
-
29
- if !inner
30
-
31
- options = args[0] || []
32
- opts = options.map { |key,value| "#{key}=\"#{value}\"" }.join " "
33
-
34
- tag = "<#{name} #{opts} />"
35
- elsif args.length == 0
36
- tag = "<#{name}>#{inner}</#{name}>"
37
- elsif args.length == 1 and args[0].is_a? Hash
38
- options = args[0]
39
- opts = options.map { |key,value| "#{key}=\"#{value}\"" }.join " "
40
- tag = "<#{name} #{opts}>#{inner}</#{name}>"
41
- end
42
-
43
- @inner_content << tag
44
- tag
45
- end
46
-
47
- def root
48
- @page.root
49
- end
50
-
51
- def request_js(path)
52
- @page.request_js(path)
53
- end
54
-
55
- def request_css(path)
56
- @page.request_css(path)
57
- end
58
-
59
- def on_page_load(script)
60
- @page.on_page_load(script)
61
- end
62
-
63
- def write_script_once(script)
64
- @page.write_script_once(script)
65
- end
66
-
67
- def background(&block)
68
- @page.background(block)
69
- end
70
-
71
- def on_page_load(script)
72
- @page.on_page_load(script)
73
- end
74
-
75
- def icon(type)
76
- iconname = type.to_s.gsub(/_/, "-")
77
- if type.is_a? Symbol
78
- i class: "fa fa-#{iconname}" do
79
- end
80
- else
81
- i class: "fa" do
82
- text type
83
- end
84
- end
85
- end
86
-
87
- def wform(options={}, &block)
88
- theform = Form.new(@page, @anchors, options, &block)
89
- @inner_content << theform.generate
90
- @page.scripts << theform.generate_script
91
- end
92
-
93
- def ibox(options={}, &block)
94
- panel = Panel.new(@page, @anchors, options)
95
- panel.instance_eval(&block)
96
- @inner_content << panel.generate
97
- end
98
-
99
- def center(content=nil, options={}, &block)
100
-
101
- if !options[:style]
102
- options[:style] = ""
103
- end
104
-
105
- options[:style] += "; text-align: center;"
106
- if !content
107
- div options, &block
108
- else
109
- div content, options, &block
110
- end
111
- end
112
-
113
- def panel(title, &block)
114
- div class: "panel panel-default" do
115
- div class: "panel-heading" do
116
- h5 title
117
- end
118
- div class: "panel-body", &block
119
- end
120
- end
121
-
122
- def tabs(&block)
123
- tabs = Tabs.new(@page, @anchors)
124
- tabs.instance_eval(&block)
125
-
126
- @inner_content << tabs.generate
127
- end
128
-
129
- def syntax(lang=:javascript, &block)
130
- code = Code.new(@page, @anchors, lang)
131
- code.instance_eval(&block)
132
-
133
- @inner_content << code.generate
134
-
135
- @page.scripts << code.generate_script
136
- end
137
-
138
- def image(name, options={})
139
-
140
- style = "#{options[:style]}"
141
- if options[:rounded_corners] == true
142
- style += " border-radius: 8px"
143
- elsif options[:rounded_corners] == :top
144
- style += " border-radius: 8px 8px 0px 0px"
145
- else
146
- style += " border-radius: #{options[:rounded_corners]}px" if options[:rounded_corners]
147
-
148
- end
149
-
150
- img_options = {
151
- class: "img-responsive #{options[:class]}",
152
- src: "#{@page.root}images/#{name}",
153
- style: style
154
- }
155
- img_options[:id] = options[:id] if options[:id]
156
-
157
- img img_options
158
- end
159
-
160
- def crossfade_image(image_normal, image_hover)
161
- div class: "crossfade" do
162
- image image_hover, class: "bottom"
163
- image image_normal, class: "top"
164
- end
165
- image image_hover
166
- @page.request_css "css/crossfade_style.css"
167
- end
168
-
169
- def gallery(images, thumbnails=images, options={}, &block)
170
-
171
- @page.request_css "css/plugins/blueimp/css/blueimp-gallery.min.css"
172
-
173
- div class:"lightBoxGallery" do
174
- (0...images.length).to_a.each do |index|
175
-
176
- title = options[:titles][index] if options[:titles]
177
-
178
- a href:"#{images[index]}", title: "#{title}", :"data-gallery"=> "" do
179
- img src:"#{thumbnails[index]}", style: "margin: 5px;"
180
- end
181
- end
182
-
183
- div id:"blueimp-gallery", class:"blueimp-gallery" do
184
- div class:"slides" do end
185
- h3 class:"title" do end
186
- a class:"prev" do end
187
- a class:"next" do end
188
- a class:"close" do end
189
- a class:"play-pause" do end
190
- ol class:"indicator" do end
191
- end
192
- end
193
-
194
- @page.request_js "js/plugins/blueimp/jquery.blueimp-gallery.min.js"
195
-
196
- end
197
-
198
- def breadcrumb(patharray)
199
- ol class: "breadcrumb" do
200
- patharray.each do |path|
201
- li path
202
- end
203
- end
204
- end
205
-
206
- def p(*args, &block)
207
- method_missing(:p, *args, &block)
208
- end
209
-
210
- def text(theText)
211
- @inner_content << theText
212
- end
213
-
214
- def badge(label, options={})
215
- options[:type] ||= "plain"
216
-
217
- kind = "label"
218
- kind = "badge" if options[:rounded]
219
- tag_options = options.clone
220
- tag_options[:class] = "#{kind} #{kind}-#{options[:type]}"
221
-
222
- span tag_options do
223
- text label
224
- end
225
- end
226
-
227
- def hyperlink(url, title=nil, &block)
228
- if !title
229
- title = url
230
- end
231
-
232
- if url.start_with? "/"
233
- url.sub!(/^\//, @page.root)
234
- if block
235
- a href: url, &block
236
- else
237
- a title, href: url
238
- end
239
- else
240
-
241
- if block
242
- a href: url, target: "_blank" do
243
- span do
244
- span &block
245
- icon :external_link
246
- end
247
- end
248
- else
249
- a href: url, target: "_blank" do
250
- span do
251
- text title
252
- text " "
253
- icon :external_link
254
- end
255
- end
256
- end
257
- end
258
-
259
-
260
-
261
- end
262
-
263
- def accordion(&block)
264
- acc = Accordion.new(@page, @anchors)
265
- acc.instance_eval(&block)
266
-
267
- @inner_content << acc.generate
268
- end
269
-
270
- def widget(options={}, &block)
271
- #gray-bg
272
- #white-bg
273
- #navy-bg
274
- #blue-bg
275
- #lazur-bg
276
- #yellow-bg
277
- #red-bg
278
- #black-bg
279
-
280
- color = "#{options[:color]}-bg" || "navy-bg"
281
-
282
- div :class => "widget style1 #{color}", &block
283
- end
284
-
285
- def row(options={}, &block)
286
- options[:class] = "row"
287
- div options do
288
- instance_eval(&block)
289
- end
290
- end
291
-
292
- def twothirds(&block)
293
- opts =
294
- {
295
- xs: 12,
296
- sm: 12,
297
- md: 8,
298
- lg: 8
299
- }
300
- col(4, opts, &block)
301
- end
302
-
303
- def half(&block)
304
- opts =
305
- {
306
- xs: 12,
307
- sm: 12,
308
- md: 12,
309
- lg: 6
310
- }
311
- col(4, opts, &block)
312
- end
313
-
314
- def third(&block)
315
- opts =
316
- {
317
- xs: 12,
318
- sm: 12,
319
- md: 4,
320
- lg: 4
321
- }
322
- col(4, opts, &block)
323
- end
324
-
325
- def quarter(&block)
326
- opts =
327
- {
328
- xs: 12,
329
- sm: 12,
330
- md: 6,
331
- lg: 3
332
- }
333
- col(3, opts, &block)
334
- end
335
-
336
- def col(occupies, options={}, &block)
337
-
338
- xs = options[:xs] || occupies
339
- sm = options[:sm] || occupies
340
- md = options[:md] || occupies
341
- lg = options[:lg] || occupies
342
-
343
- hidden = ""
344
-
345
- xs_style = "col-xs-#{xs}" unless options[:xs] == 0
346
- sm_style = "col-sm-#{sm}" unless options[:sm] == 0
347
- md_style = "col-md-#{md}" unless options[:md] == 0
348
- lg_style = "col-lg-#{lg}" unless options[:lg] == 0
349
-
350
- hidden += "hidden-xs " if options[:xs] == 0
351
- hidden += "hidden-sm " if options[:sm] == 0
352
- hidden += "hidden-md " if options[:md] == 0
353
- hidden += "hidden-lg " if options[:lg] == 0
354
-
355
- div_options = {
356
- class: "#{xs_style} #{sm_style} #{md_style} #{lg_style} #{hidden}",
357
- style: options[:style]
358
- }
359
-
360
- div div_options do
361
- instance_eval(&block)
362
- end
363
- end
364
-
365
-
366
- def jumbotron(options={}, &block)
367
-
368
- additional_style = ""
369
-
370
- if options[:background]
371
- additional_style += " background-image: url('#{@page.root}images/#{options[:background]}'); background-position: center center; background-size: cover;"
372
- end
373
-
374
- if options[:height]
375
- additional_style += " height: #{options[:height]}px;"
376
- end
377
-
378
- if options[:min_height]
379
- additional_style += " min-height: #{options[:min_height]}px;"
380
- end
381
-
382
- if options[:max_height]
383
- additional_style += " max-height: #{options[:max_height]}px;"
384
- end
385
-
386
- div :class => "jumbotron", style: additional_style, &block
387
- end
388
-
389
- def modal(id=nil, &block)
390
- mm = ModalDialog.new(@page, @anchors, id, &block)
391
- @inner_content << mm.generate
392
- end
393
-
394
- def _button(options={}, &block)
395
-
396
- anIcon = options[:icon]
397
- title = options[:title]
398
-
399
- if title.is_a? Hash
400
- options.merge! title
401
- title = anIcon
402
- anIcon = nil
403
- end
404
-
405
- style = options[:style] || :primary
406
- size = "btn-#{options[:size]}" if options[:size]
407
- blockstyle = "btn-block" if options[:block]
408
- outline = "btn-outline" if options[:outline]
409
- dim = "dim" if options[:threedee]
410
- dim = "dim btn-large-dim" if options[:bigthreedee]
411
- dim = "btn-rounded" if options[:rounded]
412
- dim = "btn-circle" if options[:circle]
413
-
414
- buttonOptions = {
415
- :type => options[:type] || "button",
416
- :class => "btn btn-#{style} #{size} #{blockstyle} #{outline} #{dim}",
417
- :id => options[:id]
418
- }
419
-
420
- if block
421
- closer = ""
422
-
423
- closer = "; return false;" if options[:nosubmit]
424
-
425
- action = Action.new(@page, @anchors, &block)
426
- buttonOptions[:onclick] = "#{action.name}(this)"
427
- buttonOptions[:onclick] = "#{action.name}(this, #{options[:data]})#{closer}" if options[:data]
428
- @page.scripts << action.generate
429
- end
430
-
431
- type = :button
432
-
433
- buttonOptions[:"data-toggle"] = "button" if options[:toggle]
434
- type = :a if options[:toggle]
435
-
436
-
437
- method_missing type, buttonOptions do
438
- if title.is_a? Symbol
439
- icon title
440
- else
441
- icon anIcon if anIcon
442
- text " " if anIcon
443
- text title
444
- end
445
- end
446
- end
447
-
448
- def normal_button(anIcon, title={}, options={}, &block)
449
- options[:icon] = anIcon
450
- options[:title] = title
451
- _button(options, &block)
452
- end
453
-
454
- def block_button(anIcon, title={}, options={}, &block)
455
- options[:block] = true
456
- options[:icon] = anIcon
457
- options[:title] = title
458
- _button(options, &block)
459
- end
460
-
461
- def outline_button(anIcon, title={}, options={}, &block)
462
- options[:outline] = true
463
- options[:icon] = anIcon
464
- options[:title] = title
465
- _button(options, &block)
466
- end
467
-
468
- def big_button(anIcon, title={}, options={}, &block)
469
- options[:size] = :lg
470
- options[:icon] = anIcon
471
- options[:title] = title
472
- _button(options, &block)
473
- end
474
-
475
- def small_button(anIcon, title={}, options={}, &block)
476
- options[:size] = :sm
477
- options[:icon] = anIcon
478
- options[:title] = title
479
- _button(options, &block)
480
- end
481
-
482
- def tiny_button(anIcon, title={}, options={}, &block)
483
- options[:size] = :xs
484
- options[:icon] = anIcon
485
- options[:title] = title
486
- _button(options, &block)
487
- end
488
-
489
- def embossed_button(anIcon, title={}, options={}, &block)
490
- options[:threedee] = true
491
- options[:icon] = anIcon
492
- options[:title] = title
493
- _button(options, &block)
494
- end
495
-
496
- def big_embossed_button(anIcon, title={}, options={}, &block)
497
- options[:bigthreedee] = true
498
- options[:icon] = anIcon
499
- options[:title] = title
500
- _button(options, &block)
501
- end
502
-
503
- def rounded_button(anIcon, title={}, options={}, &block)
504
- options[:rounded] = true
505
- options[:icon] = anIcon
506
- options[:title] = title
507
- _button(options, &block)
508
- end
509
-
510
- def circle_button(anIcon, title={}, options={}, &block)
511
- options[:circle] = true
512
- options[:icon] = anIcon
513
- options[:title] = title
514
- _button(options, &block)
515
- end
516
-
517
- def math(string)
518
- text "$$$MATH$$$#{string}$$$ENDMATH$$$"
519
- end
520
-
521
- def table(options={}, &block)
522
-
523
-
524
- table_name = options[:id] || @page.create_anchor("table")
525
- table_style = ""
526
-
527
-
528
- if options[:style] != nil
529
- table_style = options[:style]
530
- end
531
-
532
- classname = "table"
533
-
534
- classname += " table-bordered" if options[:bordered]
535
- classname += " table-hover" if options[:hover]
536
- classname += " table-striped" if options[:striped]
537
-
538
- table_options = {
539
- class: classname,
540
- id: table_name,
541
- style: table_style
542
- }
543
-
544
- if options[:system] == :data_table
545
- @page.request_js "js/plugins/dataTables/jquery.dataTables.js"
546
- @page.request_js "js/plugins/dataTables/dataTables.bootstrap.js"
547
- @page.request_js "js/plugins/dataTables/dataTables.responsive.js"
548
- @page.request_js "js/plugins/dataTables/dataTables.tableTools.min.js"
549
-
550
- @page.request_css "css/plugins/dataTables/dataTables.bootstrap.css"
551
- @page.request_css "css/plugins/dataTables/dataTables.responsive.css"
552
- @page.request_css "css/plugins/dataTables/dataTables.tableTools.min.css"
553
-
554
- @page.scripts << <<-DATATABLE_SCRIPT
555
- $('##{table_name}').DataTable();
556
- DATATABLE_SCRIPT
557
- end
558
-
559
- if options[:system] == :foo_table
560
- table_options[:"data-filtering"] = true
561
- table_options[:"data-sorting"] = true
562
- table_options[:"data-paging"] = true
563
- table_options[:"data-show-toggle"] = true
564
- table_options[:"data-toggle-column"] = "last"
565
-
566
- table_options[:"data-paging-size"] = "#{(options[:max_items_per_page] || 8).to_i}"
567
- table_options[:class] = table_options[:class] + " toggle-arrow-tiny"
568
-
569
-
570
- @page.request_js "js/plugins/footable/footable.all.min.js"
571
-
572
- @page.request_css "css/plugins/footable/footable.core.css"
573
-
574
- @page.scripts << <<-DATATABLE_SCRIPT
575
- $('##{table_name}').footable({
576
- paging: {
577
- size: #{(options[:max_items_per_page] || 8).to_i}
578
- }
579
- });
580
- $('##{table_name}').append(this.html).trigger('footable_redraw');
581
-
582
-
583
-
584
- DATATABLE_SCRIPT
585
-
586
- @page.onload_scripts << <<-SCRIPT
587
- SCRIPT
588
- end
589
-
590
-
591
- method_missing(:table, table_options, &block)
592
- ul class: "pagination"
593
- end
594
-
595
- def table_from_source(url, options={}, &block)
596
-
597
- dyn_table = DynamicTable.new(@page, @anchors, url, options, &block)
598
-
599
- text dyn_table.generate_table
600
-
601
- @page.scripts << dyn_table.generate_script
602
-
603
- end
604
-
605
- def table_from_hashes(hashes, options={})
606
-
607
- keys = {}
608
- hashes.each do |hash|
609
- hash.each do |key,value|
610
- keys[key] = ""
611
- end
612
- end
613
-
614
- table options do
615
-
616
- thead do
617
- keys.each do |key, _|
618
- th key.to_s
619
- end
620
- end
621
-
622
- tbody do
623
-
624
- hashes.each do |hash|
625
-
626
- tr do
627
- keys.each do |key, _|
628
- td "#{hash[key]}" || "&nbsp;"
629
- end
630
- end
631
- end
632
- end
633
- end
634
- end
635
-
636
- def generate
637
- @inner_content.join
638
- end
639
- end
640
-
641
- class ModalDialog
642
-
643
- def initialize(page, anchors, id, &block)
644
- @page = page
645
- @anchors = anchors
646
- @id = id || @page.create_anchor("modal")
647
-
648
- @header_content = Elements.new(@page, @anchors)
649
- @body_content = Elements.new(@page, @anchors)
650
- @footer_content = Elements.new(@page, @anchors)
651
-
652
- instance_eval(&block) if block
653
- end
654
-
655
- def id
656
- @id
657
- end
658
-
659
- def header(&block)
660
- @header_content.instance_eval(&block)
661
- end
662
-
663
- def body(&block)
664
- @body_content.instance_eval(&block)
665
- end
666
-
667
- def footer(&block)
668
- @footer_content.instance_eval(&block)
669
- end
670
-
671
- def generate
672
- elem = Elements.new(@page, @anchors)
673
-
674
- id = @id
675
- header_content = @header_content
676
- body_content = @body_content
677
- footer_content = @footer_content
678
-
679
- elem.instance_eval do
680
- div class: "modal fade", id: id, tabindex: -1, role: "dialog" do
681
- div class: "modal-dialog", role: "document" do
682
- div class: "modal-content" do
683
- div class: "modal-header" do
684
- button "&times;", type: "button", class: "close", :"data-dismiss" => "modal", :"aria-label" => "Close"
685
- text header_content.generate
686
- end
687
- div class: "modal-body" do
688
- text body_content.generate
689
- end
690
- div class: "modal-footer" do
691
- text footer_content.generate
692
- end
693
- end
694
- end
695
- end
696
- end
697
-
698
- elem.generate
699
-
700
- end
701
- end
702
-
703
- class DynamicTableCell < Elements
704
-
705
- attr_accessor :transform_script
706
-
707
- def data_button(anIcon, title={}, options={}, &block)
708
- options[:icon] = anIcon
709
- options[:title] = title
710
- options[:data] = "$(this).closest('td').data('object')"
711
- _button(options, &block)
712
- end
713
-
714
- def transform(script)
715
- @transform_script = script
716
- end
717
-
718
- end
719
-
720
- class JavaScriptObject
721
- def initialize(&block)
722
- @object = {}
723
- instance_eval(&block) if block
724
- end
725
-
726
- def string(name, string)
727
- @object[name] = {type: :string, value: string}
728
- end
729
-
730
- def variable(name, var_name)
731
- @object[name] = {type: :var, value: var_name}
732
- end
733
-
734
- def generate
735
- result = @object.map {
736
- |key,value|
737
-
738
- value_expression = value[:value]
739
-
740
- if value[:type] == :string
741
- value_expression = "\"#{value[:value]}\""
742
- end
743
-
744
- "#{key}: #{value_expression}"
745
-
746
- }.join ","
747
-
748
- "{#{result}}"
749
- end
750
-
751
- end
752
-
753
- class DynamicTable
754
-
755
- def initialize(page, anchors, url, options={}, &block)
756
- @page = page
757
- @anchors = anchors
758
- @url = url
759
- @options = options
760
- @columns = nil
761
- @query_object = nil
762
-
763
- self.instance_eval(&block) if block
764
-
765
- @options[:id] ||= @page.create_anchor "dyn_table"
766
- @table_name = @options[:id]
767
- @head_name = "#{@table_name}_head"
768
- @body_name = "#{@table_name}_body"
769
-
770
-
771
- end
772
-
773
- def column(name, options={}, &block)
774
- if @columns == nil
775
- @columns = []
776
- end
777
-
778
- title = options[:title] || name
779
- format = nil
780
- transform = nil
781
-
782
- if options[:icon]
783
- elem = Elements.new(@page, @anchors)
784
- elem.instance_eval do
785
- icon options[:icon]
786
- text " #{title}"
787
- end
788
- title = elem.generate
789
- end
790
-
791
- if block
792
- elem = DynamicTableCell.new(@page, @anchors)
793
- elem.instance_eval(&block)
794
- format = elem.generate
795
- if elem.transform_script
796
- func_name = @page.create_anchor "transform"
797
- @page.write_script_once <<-SCRIPT
798
- document.transform_#{func_name} = function (input)
799
- {
800
- #{elem.transform_script}
801
- }
802
- SCRIPT
803
-
804
- transform = func_name
805
- end
806
- end
807
-
808
- @columns << {name: name, title: title, format: format, transform: transform}
809
-
810
- end
811
-
812
- def generate_table
813
-
814
- table_name = @table_name
815
- head_name = @head_name
816
- body_name = @body_name
817
- options = @options
818
-
819
- columns = @columns || [ {title: "Key"}, {title: "Value"} ]
820
-
821
- elem = Elements.new(@page, @anchors)
822
- elem.instance_eval do
823
-
824
- table options do
825
- thead id: head_name do
826
- columns.each do |column, _|
827
- if column.is_a? Hash
828
- th column[:title].to_s
829
- else
830
- th column.to_s
831
- end
832
- end
833
- end
834
-
835
- tbody id: body_name do
836
- end
837
- end
838
- end
839
-
840
- elem.generate
841
- end
842
-
843
- def query(&block)
844
- @query_object = JavaScriptObject.new(&block)
845
- end
846
-
847
- def generate_script
848
-
849
- query_object_declaration = '{}'
850
- query_string = ""
851
-
852
- if @query_object
853
- query_object_declaration = @query_object.generate
854
- query_string = "+ \"?\" + $.param(query_object)"
855
- end
856
-
857
- member_expr = ""
858
- if @options[:member]
859
- member_expr = ".#{@options[:member]}"
860
- end
861
-
862
- <<-DATATABLE_SCRIPT
863
-
864
- function refresh_table_#{@table_name}()
865
- {
866
- var query_object = #{query_object_declaration};
867
-
868
- $.get( "#{@url}" #{query_string}, function( returned_data )
869
- {
870
- var data = returned_data#{member_expr};
871
- var data_object = {};
872
- if (data !== null && typeof data === 'object')
873
- {
874
- data_object = data;
875
- }
876
- else
877
- {
878
- data_object = JSON.parse(data);
879
- }
880
-
881
- var head = $("##{@head_name}")
882
- var body = $("##{@body_name}")
883
-
884
- if($.isPlainObject(data_object))
885
- {
886
- for (var key in data_object)
887
- {
888
- var row = $('<tr>');
889
- row.append($('<td>').text(key));
890
- row.append($('<td>').text(data_object[key]));
891
- body.append(row);
892
- }
893
- }
894
-
895
- if ($.isArray(data_object))
896
- {
897
-
898
- var columnData = JSON.parse(#{@columns.to_json.inspect});
899
- var columns = {};
900
- var columnTitles = [];
901
- head.empty();
902
- if (#{@columns == nil})
903
- {
904
- // Set up columns
905
- for (var index in data_object)
906
- {
907
- for (var key in data_object[index])
908
- {
909
- columns[key] = Object.keys(columns).length;
910
- }
911
- }
912
- for (var key in columns)
913
- {
914
- columnTitles.push(key);
915
- }
916
- }
917
- else
918
- {
919
- for (var key in columnData)
920
- {
921
- columns[columnData[key]["name"]] = Object.keys(columns).length;
922
- columnTitles.push(columnData[key]["title"]);
923
- }
924
- }
925
-
926
- var row = $('<tr>');
927
- for (var key in columnTitles)
928
- {
929
- var columnTitle = $('<th>').html(columnTitles[key]);
930
- row.append(columnTitle);
931
- }
932
- head.append(row);
933
-
934
- for (var index in data_object)
935
- {
936
- var row = $('<tr>');
937
- for (var columnIndex = 0; columnIndex < Object.keys(columns).length; columnIndex++) {
938
- var cell_data = data_object[index][ Object.keys(columns)[columnIndex] ];
939
-
940
- if (columnData && columnData[columnIndex]["format"])
941
- {
942
- var format = columnData[columnIndex]["format"];
943
- var matches = format.match(/###.+?###/g)
944
-
945
- var result = format;
946
- for (var matchIndex in matches)
947
- {
948
- var member_name = matches[matchIndex].match(/[^#]+/)[0];
949
- result = result.replaceAll(matches[matchIndex], data_object[index][member_name]);
950
- }
951
-
952
- if (columnData && columnData[columnIndex]["transform"])
953
- {
954
- result = document["transform_" + columnData[columnIndex]["transform"]](result);
955
- }
956
- row.append($('<td>').html( result ).data("object", data_object[index]) );
957
- }
958
- else
959
- {
960
- if (columnData && columnData[columnIndex]["transform"])
961
- {
962
- cell_data = document["transform_" + columnData[columnIndex]["transform"]](cell_data);
963
- }
964
- row.append($('<td>').text( cell_data ).data("object", data_object[index]) );
965
- }
966
- }
967
- body.append(row);
968
- }
969
- }
970
-
971
- });
972
- }
973
-
974
- refresh_table_#{@table_name}();
975
-
976
- DATATABLE_SCRIPT
977
- end
978
- end
979
-
980
- class Action
981
- def initialize(page, anchors, &block)
982
- @page = page
983
- @anchors = anchors
984
-
985
- actionsArray = @anchors["action"]
986
-
987
- if !@anchors["action"]
988
- @anchors["action"] = []
989
- end
990
-
991
- actionsArray = @anchors["action"]
992
-
993
- @actionName = "action#{actionsArray.length}"
994
- actionsArray << @actionName
995
-
996
- @code = ""
997
-
998
- self.instance_eval(&block)
999
- end
1000
-
1001
- def script(code)
1002
- @code = code
1003
- end
1004
-
1005
- def generate
1006
- #puts @code
1007
- <<-FUNCTION
1008
- function #{@actionName}(caller, data) {
1009
- #{@code}
1010
- }
1011
- FUNCTION
1012
- end
1013
-
1014
- def name
1015
- @actionName
1016
- end
1017
- end
1018
-
1019
- class Code
1020
- def initialize(page, anchors, lang)
1021
- @page = page
1022
- @anchors = anchors
1023
- @content = ""
1024
- @options = {}
1025
-
1026
- codeArray = @anchors["code"]
1027
-
1028
- if !@anchors["code"]
1029
- @anchors["code"] = []
1030
- end
1031
-
1032
- codeArray = @anchors["code"]
1033
-
1034
- @codeName = "code#{codeArray.length}"
1035
- codeArray << @codeName
1036
-
1037
- @page.request_css "css/plugins/codemirror/codemirror.css"
1038
- @page.request_js "js/plugins/codemirror/codemirror.js"
1039
-
1040
- language lang
1041
-
1042
- end
1043
-
1044
- def language(lang)
1045
- # TODO improve langmap
1046
- langmap = {
1047
- javascript: {mime: "text/javascript", file: "javascript/javascript"}
1048
- }
1049
-
1050
- if langmap[lang]
1051
- @options[:mode] = langmap[lang][:mime]
1052
- @page.request_js "js/plugins/codemirror/mode/#{langmap[lang][:file]}.js"
1053
- else
1054
- @options[:mode] = "text/x-#{lang}"
1055
- @page.request_js "js/plugins/codemirror/mode/#{lang}/#{lang}.js"
1056
- end
1057
-
1058
- end
1059
-
1060
- def content(text)
1061
- @content = text
1062
- end
1063
-
1064
- def theme(name)
1065
- @options[:theme] = name
1066
-
1067
- @page.request_css "css/plugins/codemirror/#{name}.css"
1068
- end
1069
-
1070
- def generate_script
1071
-
1072
- @options[:lineNumbers] ||= true
1073
- @options[:matchBrackets] ||= true
1074
- @options[:styleActiveLine] ||= true
1075
- @options[:mode] ||= "javascript"
1076
- @options[:readOnly] ||= true
1077
-
1078
- <<-CODESCRIPT
1079
- $(document).ready(function()
1080
- {
1081
- CodeMirror.fromTextArea(document.getElementById("#{@codeName}"),
1082
- JSON.parse('#{@options.to_json}')
1083
- );
1084
- });
1085
- CODESCRIPT
1086
- end
1087
-
1088
- def generate
1089
-
1090
- content = @content
1091
- codeName = @codeName
1092
-
1093
- elem = Elements.new(@page, @anchors)
1094
-
1095
- elem.instance_eval do
1096
- textarea id: codeName do
1097
- text content
1098
- end
1099
- end
1100
-
1101
- elem.generate
1102
- end
1103
- end
1104
-
1105
- class TextfieldJavascript
1106
-
1107
- def initialize(id)
1108
- @id = id
1109
- end
1110
-
1111
- def onchange(script)
1112
- @change_script = script
1113
- end
1114
-
1115
- def validate(script)
1116
- @validate_script = script
1117
- end
1118
-
1119
- def generate(&block)
1120
- if block
1121
- instance_eval(&block)
1122
- <<-SCRIPT
1123
-
1124
- if (!document.validators)
1125
- {
1126
- document.validators = {};
1127
- }
1128
-
1129
- document.validators["##{@id}"] = function()
1130
- {
1131
- var valid = function(data) {
1132
- #{@validate_script};
1133
- return true;
1134
- }($("##{@id}").val());
1135
-
1136
- var object = $("##{@id}");
1137
- #{@change_script};
1138
-
1139
- if (valid)
1140
- {
1141
- object.removeClass("required");
1142
- object.removeClass("error");
1143
- object.removeAttr("aria-invalid");
1144
- }
1145
- else
1146
- {
1147
- object.addClass("required");
1148
- object.addClass("error");
1149
- object.attr("aria-required", "true");
1150
- object.attr("aria-invalid", "true");
1151
- }
1152
- }
1153
-
1154
- $("##{@id}").keyup(function() { document.validators["##{@id}"](); })
1155
- $("##{@id}").blur(function() { document.validators["##{@id}"](); })
1156
- $("##{@id}").focusout(function() { document.validators["##{@id}"](); })
1157
-
1158
- SCRIPT
1159
- end
1160
- end
1161
- end
1162
-
1163
- class FormElements < Elements
1164
-
1165
- attr_accessor :options, :scripts
1166
-
1167
- def initialize(page, anchors, formName, options={})
1168
- super(page, anchors)
1169
- @formName = formName
1170
- @options = options
1171
- @scripts = []
1172
- end
1173
-
1174
- def passwordfield(name, textfield_label=nil, options={}, &block)
1175
-
1176
- if textfield_label.is_a? Hash
1177
- options = textfield_label
1178
- textfield_label = nil
1179
- end
1180
-
1181
- options[:type] = "password"
1182
- textfield(name, textfield_label, options, &block)
1183
- end
1184
-
1185
- def textfield(name, textfield_label=nil, options={}, &block)
1186
-
1187
- if textfield_label.is_a? Hash
1188
- options = textfield_label
1189
- textfield_label = nil
1190
- end
1191
-
1192
- textfield_name = options[:id] || @page.create_anchor("textfield")
1193
- options[:type] ||= "text"
1194
- options[:placeholder] ||= ""
1195
- options[:name] = name
1196
-
1197
- input_options = {}
1198
- input_options[:type] = options[:type]
1199
- input_options[:placeholder] = options[:placeholder]
1200
- input_options[:id] = textfield_name
1201
- input_options[:name] = options[:name]
1202
- input_options[:rows] = options[:rows]
1203
- input_options[:class] = "form-control"
1204
- input_options[:value] = options[:value]
1205
- input_options[:style] = options[:style]
1206
-
1207
- input_options[:autocomplete] = options[:autocomplete] || "on"
1208
- input_options[:autocorrect] = options[:autocorrect] || "on"
1209
- input_options[:autocapitalize] = options[:autocapitalize] || "off"
1210
-
1211
- if options[:mask]
1212
- @page.request_css "css/plugins/jasny/jasny-bootstrap.min.css"
1213
- @page.request_js "js/plugins/jasny/jasny-bootstrap.min.js"
1214
-
1215
- input_options[:"data-mask"] = options[:mask]
1216
- end
1217
-
1218
- div :class => "form-group #{options[:extra_class]}", id: "#{input_options[:id]}-group" do
1219
- label textfield_label if textfield_label
1220
-
1221
- div_class = " "
1222
- if options[:front_text] || options[:back_text]
1223
- div_class = "input-group m-b"
1224
- end
1225
-
1226
- div :"class" => div_class do
1227
- span "#{options[:front_text]}", class: "input-group-addon" if options[:front_text]
1228
- if input_options[:rows] and input_options[:rows] > 1
1229
- textarea input_options do
1230
- end
1231
- else
1232
- input input_options
1233
- end
1234
- span "#{options[:back_text]}", class: "input-group-addon" if options[:back_text]
1235
- end
1236
- end
1237
-
1238
- textjs = TextfieldJavascript.new(input_options[:id])
1239
-
1240
- @page.on_page_load textjs.generate(&block) if block
1241
-
1242
- @scripts << <<-SCRIPT
1243
- object["#{name}"] = $('##{textfield_name}').val();
1244
- SCRIPT
1245
- end
1246
-
1247
- def hiddenfield(name, value, options={})
1248
- hiddenfield_name = options[:id] || @page.create_anchor("hiddenfield")
1249
-
1250
- input_options = {}
1251
- input_options[:type] = "hidden"
1252
- input_options[:value] = value
1253
- input_options[:id] = hiddenfield_name
1254
- input_options[:name] = name
1255
-
1256
- input input_options
1257
-
1258
- @scripts << <<-SCRIPT
1259
- object["#{name}"] = $('##{hiddenfield_name}').val();
1260
- SCRIPT
1261
-
1262
- end
1263
-
1264
- def dropdown(name, dropdown_label, choice_array, options={})
1265
- select_name = options[:id] || @page.create_anchor("select")
1266
-
1267
- options[:class] = "form-control"
1268
- options[:name] = name
1269
- options[:id] = select_name
1270
- options[:placeholder] ||= " "
1271
-
1272
- form_options = options.clone
1273
-
1274
- if options[:multiple]
1275
-
1276
- if options[:multiple_style] == :chosen
1277
- @page.request_css "css/plugins/chosen/chosen.css"
1278
- @page.request_js "js/plugins/chosen/chosen.jquery.js"
1279
-
1280
- @page.write_script_once <<-SCRIPT
1281
- var config = {
1282
- '.chosen-select' : {placeholder_text_multiple: "#{options[:placeholder]}"},
1283
- '.chosen-select-deselect' : {allow_single_deselect:true},
1284
- '.chosen-select-no-single' : {disable_search_threshold:10},
1285
- '.chosen-select-no-results': {no_results_text:'Oops, nothing found!'},
1286
- '.chosen-select-width' : {width:"95%"}
1287
- }
1288
- for (var selector in config) {
1289
- $(selector).chosen(config[selector]);
1290
- }
1291
- SCRIPT
1292
-
1293
- form_options[:class] = "chosen-select"
1294
- form_options[:style] = "width: 100%"
1295
- end
1296
-
1297
- @scripts << <<-SCRIPT
1298
- var selections = [];
1299
- $("##{select_name} option:selected").each(function(i, selected){
1300
- selections[i] = $(selected).text();
1301
- });
1302
- object["#{name}"] = selections;
1303
- SCRIPT
1304
-
1305
- else
1306
- @scripts << <<-SCRIPT
1307
- object["#{name}"] = $( "##{select_name} option:selected" ).text();
1308
- SCRIPT
1309
- end
1310
-
1311
-
1312
- div :class => "form-group" do
1313
- label dropdown_label, :class => "control-label"
1314
-
1315
- div :class => "input-group", style: "width: 100%" do
1316
-
1317
- method_missing :select, form_options do
1318
-
1319
- choice_array.each do |choice|
1320
- if "#{options[:value]}" == "#{choice}"
1321
- option choice, selected: true
1322
- else
1323
- option choice
1324
- end
1325
- end
1326
- end
1327
- end
1328
- end
1329
-
1330
-
1331
- end
1332
-
1333
- def knob(name, options={})
1334
-
1335
- knob_name = @page.create_anchor "knob"
1336
-
1337
- @page.request_js "js/plugins/jsKnob/jquery.knob.js"
1338
- @page.write_script_once <<-SCRIPT
1339
- $(".dial").knob();
1340
- SCRIPT
1341
-
1342
- knob_options = {}
1343
-
1344
- knob_options[:id] = knob_name
1345
- knob_options[:type] = "text"
1346
- knob_options[:value] = options[:value] || "0"
1347
- knob_options[:class] = "dial"
1348
-
1349
- options.each do |key,value|
1350
- knob_options["data-#{key}".to_sym] = value
1351
- end
1352
-
1353
- knob_options[:"data-fgColor"] = "#1AB394"
1354
- knob_options[:"data-width"] = "85"
1355
- knob_options[:"data-height"] = "85"
1356
-
1357
- input knob_options
1358
-
1359
- @scripts << <<-SCRIPT
1360
- object["#{name}"] = $('##{knob_name}').val();
1361
- SCRIPT
1362
- end
1363
-
1364
- def radio(name, choice_array, options={})
1365
-
1366
- radio_name = @page.create_anchor "radio"
1367
-
1368
- choice_array = choice_array.map do |choice|
1369
- if choice.is_a? Hash
1370
- {value: choice[:value], label: choice[:label]}
1371
- else
1372
- {value: choice, label: choice}
1373
- end
1374
- end
1375
-
1376
- active = choice_array[0][:value]
1377
- if options[:value] and choice_array.index { |x| x[:value] == options[:value] } != nil
1378
- active = options[:value]
1379
- end
1380
-
1381
- div_options = {}
1382
- curobject = self
1383
- if options[:form] == :button
1384
- div_options[:"data-toggle"] = "buttons"
1385
- end
1386
- div div_options do
1387
- choice_array.each do |choice|
1388
-
1389
- value = choice[:value]
1390
- label = choice[:label]
1391
-
1392
- the_options = Hash.new(options)
1393
-
1394
- if active == value
1395
- the_options[:checked] = ""
1396
- end
1397
-
1398
- if options[:form] == :button
1399
- the_options[:type] = "radio"
1400
- the_options[:value] = value
1401
- the_options[:name] = name
1402
- the_options[:form] = :button
1403
- text curobject.boolean_element(label, the_options)
1404
- else
1405
- the_options[:type] = "radio"
1406
- the_options[:value] = value
1407
- the_options[:name] = name
1408
- text curobject.boolean_element(label, the_options)
1409
- end
1410
- end
1411
- end
1412
-
1413
-
1414
- @scripts << <<-SCRIPT
1415
- object["#{name}"] = $('input[name=#{name}]:checked', '##{@formName}').val()
1416
- SCRIPT
1417
- end
1418
-
1419
- def checkbox(name, checkbox_label, options={})
1420
- checkbox_name = options[:id] || @page.create_anchor("checkbox")
1421
- options[:type] = "checkbox"
1422
- options[:name] = name
1423
- options[:id] = checkbox_name
1424
- text boolean_element(checkbox_label, options)
1425
- @scripts << <<-SCRIPT
1426
- object["#{name}"] = $('##{checkbox_name}').is(":checked");
1427
- SCRIPT
1428
- end
1429
-
1430
-
1431
- def submit(anIcon, title={}, options={}, &block)
1432
- options[:icon] = anIcon
1433
- options[:title] = title
1434
- options[:type] = "submit"
1435
- options[:data] = "get_#{@formName}_object()"
1436
- options[:nosubmit] = true if block
1437
- _button(options, &block)
1438
- end
1439
-
1440
- def boolean_element(checkbox_label, options={})
1441
-
1442
- @page.request_css "css/plugins/iCheck/custom.css"
1443
- @page.request_js "js/plugins/iCheck/icheck.min.js"
1444
-
1445
- @page.write_script_once <<-SCRIPT
1446
- $(document).ready(function () {
1447
- $('.i-checks').iCheck({
1448
- checkboxClass: 'icheckbox_square-green',
1449
- radioClass: 'iradio_square-green',
1450
- });
1451
- });
1452
- SCRIPT
1453
-
1454
- label_options = {}
1455
- elem = Elements.new(@page, @anchors)
1456
- elem.instance_eval do
1457
-
1458
- if options[:form] == :button
1459
- options.delete(:form)
1460
- label class: "btn btn-primary btn-block btn-outline" do
1461
- input options
1462
- text "#{checkbox_label}"
1463
- end
1464
- else
1465
- div class: "i-checks" do
1466
- label label_options do
1467
- input options do
1468
- text " #{checkbox_label}"
1469
- end
1470
- end
1471
- end
1472
- end
1473
-
1474
- end
1475
-
1476
- elem.generate
1477
- end
1478
- end
1479
-
1480
- class Form
1481
- def initialize(page, anchors, options={}, &block)
1482
-
1483
- @formName = options[:id] || page.create_anchor("form")
1484
-
1485
- @form_element = FormElements.new(page, anchors, @formName, options)
1486
-
1487
- @form_element.instance_eval(&block)
1488
- end
1489
-
1490
- def generate_script
1491
- <<-SCRIPT
1492
- function get_#{@formName}_object()
1493
- {
1494
- var object = {}
1495
- #{@form_element.scripts.join "\n"}
1496
- return object;
1497
- }
1498
- SCRIPT
1499
- end
1500
-
1501
- def generate
1502
- inner = @form_element.generate
1503
- formName = @formName
1504
- options = @form_element.options
1505
-
1506
- elem = Elements.new(@page, @anchors)
1507
- elem.instance_eval do
1508
-
1509
- form_opts = {
1510
- id: formName,
1511
- role: "form"
1512
- }
1513
-
1514
- form_opts[:action] = options[:action] if options[:action]
1515
- form_opts[:method] = options[:method] if options[:method]
1516
- form_opts[:class] = options[:class] if options[:class]
1517
-
1518
- method_missing :form, form_opts do
1519
- text inner
1520
- end
1521
- end
1522
-
1523
- elem.generate
1524
- end
1525
- end
1526
-
1527
- class Panel < Elements
1528
- def initialize(page, anchors, options={})
1529
- super(page, anchors)
1530
- @title = nil
1531
- @footer = nil
1532
- @type = :ibox
1533
- @body = true
1534
- @extra = nil
1535
- @min_height = nil
1536
- @page = page
1537
- @options = options
1538
- end
1539
-
1540
- def generate
1541
- inner = super
1542
-
1543
- types =
1544
- {
1545
- :ibox => { outer: "ibox float-e-margins",header: "ibox-title", body: "ibox-content" , footer: "ibox-footer"},
1546
- :panel => { outer: "panel panel-default", header: "panel-heading", body: "panel-body" , footer: "panel-footer"},
1547
- :primary => { outer: "panel panel-primary", header: "panel-heading", body: "panel-body" , footer: "panel-footer"},
1548
- :success => { outer: "panel panel-success", header: "panel-heading", body: "panel-body" , footer: "panel-footer"},
1549
- :info => { outer: "panel panel-info", header: "panel-heading", body: "panel-body" , footer: "panel-footer"},
1550
- :warning => { outer: "panel panel-warning", header: "panel-heading", body: "panel-body" , footer: "panel-footer"},
1551
- :danger => { outer: "panel panel-danger", header: "panel-heading", body: "panel-body" , footer: "panel-footer"},
1552
- :blank => { outer: "panel blank-panel", header: "panel-heading", body: "panel-body" , footer: "panel-footer"}
1553
- }
1554
-
1555
- title = @title
1556
- footer = @footer
1557
- hasBody = @body
1558
- extra = @extra
1559
- options = @options
1560
- classNames = types[@type]
1561
- min_height = @min_height
1562
-
1563
- elem = Elements.new(@page, @anchors)
1564
-
1565
- outer_class = classNames[:outer]
1566
-
1567
- if options[:collapsed]
1568
- outer_class = "ibox collapsed"
1569
- end
1570
-
1571
- elem.instance_eval do
1572
- div class: outer_class do
1573
- if title
1574
- div class: classNames[:header] do
1575
- h5 title
1576
-
1577
- div class: "ibox-tools" do
1578
- if options[:collapsible] or options[:collapsed]
1579
- a class: "collapse-link" do
1580
- icon :"chevron-up"
1581
- end
1582
- end
1583
- if options[:expandable]
1584
- a class: "fullscreen-link" do
1585
- icon :expand
1586
- end
1587
- end
1588
- if options[:closable]
1589
- a class: "close-link" do
1590
- icon :times
1591
- end
1592
- end
1593
- end
1594
- end
1595
- end
1596
- if hasBody
1597
- div class: classNames[:body], style: "min-height: #{min_height}px" do
1598
- text inner
1599
- end
1600
- end
1601
- if extra
1602
- text extra
1603
- end
1604
- if footer
1605
- div class: classNames[:footer] do
1606
- text footer
1607
- end
1608
- end
1609
-
1610
- end
1611
- end
1612
-
1613
- elem.generate
1614
- end
1615
-
1616
- def min_height(val)
1617
- @min_height = val
1618
- end
1619
-
1620
- def type(aType)
1621
- @type = aType
1622
- end
1623
-
1624
- def body(hasBody)
1625
- @body = hasBody
1626
- end
1627
-
1628
- def title(title=nil, &block)
1629
- @title = title
1630
- if block
1631
- elem = Elements.new(@page, @anchors)
1632
- elem.instance_eval(&block)
1633
- @title = elem.generate
1634
- end
1635
- end
1636
-
1637
- def extra(&block)
1638
- if block
1639
- elem = Elements.new(@page, @anchors)
1640
- elem.instance_eval(&block)
1641
- @extra = elem.generate
1642
- end
1643
- end
1644
-
1645
- def footer(footer=nil, &block)
1646
- @footer = footer
1647
- if block
1648
- elem = Elements.new(@page, @anchors)
1649
- elem.instance_eval(&block)
1650
- @footer = elem.generate
1651
- end
1652
- end
1653
-
1654
- end
1655
-
1656
- class Accordion
1657
- def initialize(page, anchors)
1658
- @anchors = anchors
1659
- @tabs = {}
1660
- @paneltype = :panel
1661
- @is_collapsed = false
1662
- @page = page
1663
-
1664
- if !@anchors["accordia"]
1665
- @anchors["accordia"] = []
1666
- end
1667
-
1668
- accArray = @anchors["accordia"]
1669
-
1670
- @accordion_name = "accordion#{accArray.length}"
1671
- accArray << @accordion_name
1672
- end
1673
-
1674
- def collapsed(isCollapsed)
1675
- @is_collapsed = isCollapsed
1676
- end
1677
-
1678
- def type(type)
1679
- @paneltype = type
1680
- end
1681
-
1682
- def tab(title, options={}, &block)
1683
-
1684
- if !@anchors["tabs"]
1685
- @anchors["tabs"] = []
1686
- end
1687
-
1688
- tabArray = @anchors["tabs"]
1689
-
1690
- elem = Elements.new(@page, @anchors)
1691
- elem.instance_eval(&block)
1692
-
1693
- tabname = "tab#{tabArray.length}"
1694
- tabArray << tabname
1695
-
1696
- @tabs[tabname] =
1697
- {
1698
- title: title,
1699
- elem: elem
1700
- }
1701
-
1702
- if options[:mixpanel_event_name]
1703
- @tabs[tabname][:mixpanel_event_name] = options[:mixpanel_event_name]
1704
- end
1705
-
1706
- if options[:mixpanel_event_props]
1707
- @tabs[tabname][:mixpanel_event_props] = options[:mixpanel_event_props]
1708
- end
1709
-
1710
- end
1711
-
1712
- def generate
1713
- tabbar = Elements.new(@page, @anchors)
1714
-
1715
- tabs = @tabs
1716
- paneltype = @paneltype
1717
- accordion_name = @accordion_name
1718
- is_collapsed = @is_collapsed
1719
-
1720
- tabbar.instance_eval do
1721
-
1722
- div :class => "panel-group", id: accordion_name do
1723
-
1724
- cls = "panel-collapse collapse in"
1725
- cls = "panel-collapse collapse" if is_collapsed
1726
- tabs.each do |anchor, value|
1727
-
1728
- ibox do
1729
- type paneltype
1730
- body false
1731
- title do
1732
- div :class => "panel-title" do
1733
- options = {
1734
- :"data-toggle" => "collapse",
1735
- :"data-parent" => "##{accordion_name}",
1736
- href: "##{anchor}"
1737
- }
1738
-
1739
- if value[:mixpanel_event_name]
1740
- props = {}
1741
- if value[:mixpanel_event_props].is_a? Hash
1742
- props = value[:mixpanel_event_props]
1743
- end
1744
- options[:onclick] = "mixpanel.track('#{value[:mixpanel_event_name]}', #{props.to_json.gsub('"',"'")})"
1745
- end
1746
-
1747
- a options do
1748
- if value[:title].is_a? Symbol
1749
- icon value[:title]
1750
- else
1751
- text value[:title]
1752
- end
1753
- end
1754
- end
1755
- end
1756
-
1757
- extra do
1758
- div id: anchor, :class => cls do
1759
- div :class => "panel-body" do
1760
- text value[:elem].generate
1761
- end
1762
- end
1763
- end
1764
- end
1765
-
1766
- cls = "panel-collapse collapse"
1767
- end
1768
-
1769
- end
1770
-
1771
- end
1772
-
1773
- tabbar.generate
1774
- end
1775
-
1776
- end
1777
-
1778
- class Tabs
1779
- def initialize(page, anchors)
1780
- @anchors = anchors
1781
- @tabs = {}
1782
- @page = page
1783
- @orientation = :normal # :left, :right
1784
- end
1785
-
1786
- def tab(title, &block)
1787
-
1788
- if !@anchors["tabs"]
1789
- @anchors["tabs"] = []
1790
- end
1791
-
1792
- tabArray = @anchors["tabs"]
1793
-
1794
- elem = Elements.new(@page, @anchors)
1795
- elem.instance_eval(&block)
1796
-
1797
- tabname = "tab#{tabArray.length}"
1798
- tabArray << tabname
1799
-
1800
- @tabs[tabname] =
1801
- {
1802
- title: title,
1803
- elem: elem
1804
- }
1805
- end
1806
-
1807
- def orientation(direction)
1808
- @orientation = direction
1809
- end
1810
-
1811
- def generate
1812
-
1813
- tabbar = Elements.new(@page, @anchors)
1814
- tabs = @tabs
1815
- orientation = @orientation
1816
-
1817
- tabbar.instance_eval do
1818
-
1819
- div :class => "tabs-container" do
1820
-
1821
- div :class => "tabs-#{orientation}" do
1822
-
1823
- ul :class => "nav nav-tabs" do
1824
- cls = "active"
1825
- tabs.each do |anchor, value|
1826
- li :class => cls do
1827
- a :"data-toggle" => "tab", href: "##{anchor}" do
1828
- if value[:title].is_a? Symbol
1829
- icon value[:title]
1830
- else
1831
- text value[:title]
1832
- end
1833
- end
1834
- end
1835
-
1836
- cls = ""
1837
- end
1838
- end
1839
-
1840
- div :class => "tab-content" do
1841
-
1842
- cls = "tab-pane active"
1843
- tabs.each do |anchor, value|
1844
- div id: "#{anchor}", :class => cls do
1845
- div :class => "panel-body" do
1846
- text value[:elem].generate
1847
- end
1848
- end
1849
- cls = "tab-pane"
1850
- end
1851
- end
1852
- end
1853
-
1854
- end
1855
- end
1856
-
1857
- tabbar.generate
1858
- end
1859
- end
1860
-
1861
- class Page
1862
-
1863
- attr_accessor :scripts, :onload_scripts
1864
-
1865
- def initialize(title, global_settings, options, &block)
1866
- @title = title
1867
- @content = ""
1868
- @body_class = nil
1869
- @anchors = {}
1870
- @global_settings = global_settings
1871
- @options = options
1872
- @scripts = []
1873
- @top_content = ""
1874
-
1875
- @scripts_once = {}
1876
- @onload_scripts = []
1877
-
1878
- @requested_scripts = {}
1879
- @requested_css = {}
1880
-
1881
- @background = Elements.new(self, @anchors)
1882
-
1883
- @block = Proc.new &block
1884
- end
1885
-
1886
- def create_anchor(name)
1887
-
1888
- if !@anchors[name]
1889
- @anchors[name] = []
1890
- end
1891
-
1892
- anchor_array = @anchors[name]
1893
-
1894
- anchor_name = "#{name}#{anchor_array.length}"
1895
- anchor_array << anchor_name
1896
-
1897
- anchor_name
1898
- end
1899
-
1900
- def root
1901
- return @global_settings[:root]
1902
- end
1903
-
1904
- def request_js(path)
1905
- @requested_scripts[path] = true
1906
- end
1907
-
1908
- def request_css(path)
1909
- @requested_css[path] = true
1910
- end
1911
-
1912
- def on_page_load(script)
1913
- @onload_scripts << script
1914
- end
1915
-
1916
- def write_script_once(script)
1917
- @scripts_once[script] = true
1918
- end
1919
-
1920
- def background(&block)
1921
- @background.instance_eval(&block)
1922
- end
1923
-
1924
- def top(&block)
1925
- elem = Elements.new(self, @anchors)
1926
- elem.instance_eval(&block)
1927
-
1928
- @top_content = elem.generate
1929
- end
1930
-
1931
- def generate(back_folders, options={})
1932
-
1933
- if @options[:cache_file]
1934
- expired = @options[:cache_expired]
1935
- cache_exist = File.exist?("cache/cachedpage#{@options[:cache_file]}")
1936
-
1937
- if cache_exist and !expired
1938
- puts "Weaver Hit cache for file: #{@options[:cache_file]}"
1939
- puts "- expired: #{expired}"
1940
- puts "- cache_exist: #{cache_exist}"
1941
- return File.read("cache/cachedpage#{@options[:cache_file]}");
1942
- end
1943
- puts "Weaver Miss cache for file: #{@options[:cache_file]}"
1944
- puts "- expired: #{expired}"
1945
- puts "- cache_exist: #{cache_exist}"
1946
- end
1947
-
1948
- scripts = @scripts.join("\n")
1949
-
1950
- mod = "../" * back_folders
1951
-
1952
- style = <<-ENDSTYLE
1953
- <link href="#{mod}css/style.css" rel="stylesheet">
1954
- ENDSTYLE
1955
-
1956
- if options[:style] == :empty
1957
- style = ""
1958
- end
1959
-
1960
- body_tag = "<body>"
1961
-
1962
- body_tag = "<body class='#{@body_class}'>" if @body_class
1963
-
1964
- loading_bar = ""
1965
- loading_bar = "<script src='#{mod}js/plugins/pace/pace.min.js'></script>" if @loading_bar_visible
1966
-
1967
- extra_scripts = @requested_scripts.map {|key,value| <<-SCRIPT_DECL
1968
- <script src="#{mod}#{key}"></script>
1969
- SCRIPT_DECL
1970
- }.join "\n"
1971
-
1972
- extra_css = @requested_css.map {|key,value| <<-STYLESHEET_DECL
1973
- <link href="#{mod}#{key}" rel="stylesheet">
1974
- STYLESHEET_DECL
1975
- }.join "\n"
1976
-
1977
- extra_one_time_scripts = @scripts_once.map {|key,value| <<-SCRIPT_DECL
1978
- #{key}
1979
- SCRIPT_DECL
1980
- }.join "\n"
1981
-
1982
- onload_scripts = @onload_scripts.map {|value| <<-SCRIPT_DECL
1983
- #{value}
1984
- SCRIPT_DECL
1985
- }.join "\n"
1986
-
1987
- extra_stuff = ""
1988
-
1989
- if @global_settings[:mixpanel_token]
1990
- extra_stuff += '<!-- start Mixpanel --><script type="text/javascript">(function(e,a){if(!a.__SV){var b=window;try{var c,l,i,j=b.location,g=j.hash;c=function(a,b){return(l=a.match(RegExp(b+"=([^&]*)")))?l[1]:null};g&&c(g,"state")&&(i=JSON.parse(decodeURIComponent(c(g,"state"))),"mpeditor"===i.action&&(b.sessionStorage.setItem("_mpcehash",g),history.replaceState(i.desiredHash||"",e.title,j.pathname+j.search)))}catch(m){}var k,h;window.mixpanel=a;a._i=[];a.init=function(b,c,f){function e(b,a){var c=a.split(".");2==c.length&&(b=b[c[0]],a=c[1]);b[a]=function(){b.push([a].concat(Array.prototype.slice.call(arguments,
1991
- 0)))}}var d=a;"undefined"!==typeof f?d=a[f]=[]:f="mixpanel";d.people=d.people||[];d.toString=function(b){var a="mixpanel";"mixpanel"!==f&&(a+="."+f);b||(a+=" (stub)");return a};d.people.toString=function(){return d.toString(1)+".people (stub)"};k="disable time_event track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config reset opt_in_tracking opt_out_tracking has_opted_in_tracking has_opted_out_tracking clear_opt_in_out_tracking people.set people.set_once people.unset people.increment people.append people.union people.track_charge people.clear_charges people.delete_user".split(" ");
1992
- for(h=0;h<k.length;h++)e(d,k[h]);a._i.push([b,c,f])};a.__SV=1.2;b=e.createElement("script");b.type="text/javascript";b.async=!0;b.src="undefined"!==typeof MIXPANEL_CUSTOM_LIB_URL?MIXPANEL_CUSTOM_LIB_URL:"file:"===e.location.protocol&&"//cdn4.mxpnl.com/libs/mixpanel-2-latest.min.js".match(/^\/\//)?"https://cdn4.mxpnl.com/libs/mixpanel-2-latest.min.js":"//cdn4.mxpnl.com/libs/mixpanel-2-latest.min.js";c=e.getElementsByTagName("script")[0];c.parentNode.insertBefore(b,c)}})(document,window.mixpanel||[]);
1993
- mixpanel.init("'+@global_settings[:mixpanel_token]+'");</script><!-- end Mixpanel -->'
1994
- end
1995
-
1996
- if @global_settings[:google_tracking_code]
1997
- extra_stuff += <<-GOOGLE
1998
- <!-- Global site tag (gtag.js) - Google Analytics -->
1999
- <script async src="https://www.googletagmanager.com/gtag/js?id=#{@global_settings[:google_tracking_code]}"></script>
2000
- <script>
2001
- window.dataLayer = window.dataLayer || [];
2002
- function gtag(){dataLayer.push(arguments);}
2003
- gtag('js', new Date());
2004
-
2005
- gtag('config', '#{@global_settings[:google_tracking_code]}');
2006
- </script>
2007
- GOOGLE
2008
- end
2009
-
2010
-
2011
- result =<<-SKELETON
2012
- <!DOCTYPE html>
2013
- <html>
2014
- <!-- Generated using weaver: https://github.com/davidsiaw/weaver -->
2015
- <head>
2016
-
2017
- <meta charset="utf-8">
2018
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
2019
-
2020
- <title>#{@title}</title>
2021
-
2022
- <link href="#{mod}css/bootstrap.min.css" rel="stylesheet">
2023
- <link href="#{mod}font-awesome/css/font-awesome.css" rel="stylesheet">
2024
- <link href="#{mod}css/plugins/iCheck/custom.css" rel="stylesheet">
2025
-
2026
- #{style}
2027
-
2028
- <link href="#{mod}css/animate.css" rel="stylesheet">
2029
-
2030
- #{extra_css}
2031
-
2032
- #{extra_stuff}
2033
-
2034
- </head>
2035
-
2036
- #{body_tag}
2037
-
2038
- <div id="background" style="z-index: -999; position:absolute; left:0px; right:0px; width:100%; height:100%">
2039
- #{@background.generate}
2040
- </div>
2041
-
2042
- <div id="content" style="z-index: 0">
2043
- #{@top_content}
2044
- #{@content}
2045
- </div>
2046
-
2047
- <!-- Mainly scripts -->
2048
- <script src="#{mod}js/jquery-3.1.1.min.js"></script>
2049
- <script src="#{mod}js/jquery-ui-1.10.4.min.js"></script>
2050
- <script src="#{mod}js/bootstrap.min.js"></script>
2051
- <script src="#{mod}js/plugins/metisMenu/jquery.metisMenu.js"></script>
2052
- <script src="#{mod}js/plugins/slimscroll/jquery.slimscroll.min.js"></script>
2053
- <script type="text/x-mathjax-config">
2054
- MathJax.Hub.Config({
2055
- asciimath2jax: {
2056
- delimiters: [['$$$MATH$$$','$$$ENDMATH$$$']]
2057
- }
2058
- });
2059
- </script>
2060
- <script src="#{mod}js/MathJax/MathJax.js?config=AM_HTMLorMML-full" async></script>
2061
-
2062
- #{extra_scripts}
2063
-
2064
-
2065
- <!-- Custom and plugin javascript -->
2066
- <script src="#{mod}js/weaver.js"></script>
2067
- #{loading_bar}
2068
-
2069
- <script>
2070
- #{scripts}
2071
- #{extra_one_time_scripts}
2072
-
2073
- $( document ).ready(function() {
2074
-
2075
- #{onload_scripts}
2076
-
2077
- });
2078
- </script>
2079
-
2080
-
2081
-
2082
- </body>
2083
-
2084
- </html>
2085
-
2086
- SKELETON
2087
-
2088
- if @options[:cache_file]
2089
- FileUtils.mkdir_p "cache"
2090
- File.write("cache/cachedpage#{@options[:cache_file]}", result);
2091
- end
2092
-
2093
- return result
2094
-
2095
- end
2096
- end
2097
-
2098
- class Row < Elements
2099
- attr_accessor :extra_classes, :style
2100
-
2101
- def initialize(page, anchors, options)
2102
- @columns = []
2103
- @free = 12
2104
- @extra_classes = options[:class] || ""
2105
- @style = options[:style]
2106
- @anchors = anchors
2107
- @page = page
2108
- end
2109
-
2110
- def col(occupies, options={}, &block)
2111
- raise "Not enough columns!" if @free < occupies
2112
- elem = Elements.new(@page, @anchors)
2113
- elem.instance_eval(&block)
2114
-
2115
- @columns << { occupy: occupies, elem: elem, options: options }
2116
- @free -= occupies
2117
- end
2118
-
2119
- def generate
2120
-
2121
- @columns.map { |col|
2122
-
2123
- xs = col[:options][:xs] || col[:occupy]
2124
- sm = col[:options][:sm] || col[:occupy]
2125
- md = col[:options][:md] || col[:occupy]
2126
- lg = col[:options][:lg] || col[:occupy]
2127
-
2128
- hidden = ""
2129
-
2130
- xs_style = "col-xs-#{xs}" unless col[:options][:xs] == 0
2131
- sm_style = "col-sm-#{sm}" unless col[:options][:sm] == 0
2132
- md_style = "col-md-#{md}" unless col[:options][:md] == 0
2133
- lg_style = "col-lg-#{lg}" unless col[:options][:lg] == 0
2134
-
2135
- hidden += "hidden-xs " if col[:options][:xs] == 0
2136
- hidden += "hidden-sm " if col[:options][:sm] == 0
2137
- hidden += "hidden-md " if col[:options][:md] == 0
2138
- hidden += "hidden-lg " if col[:options][:lg] == 0
2139
-
2140
- <<-ENDCOLUMN
2141
- <div class="#{xs_style} #{sm_style} #{md_style} #{lg_style} #{hidden}">
2142
- #{col[:elem].generate}
2143
- </div>
2144
- ENDCOLUMN
2145
- }.join
2146
- end
2147
- end
2148
-
2149
- class Menu
2150
- attr_accessor :items
2151
- def initialize()
2152
- @items = []
2153
- end
2154
-
2155
- def nav(name, icon=:question, url=nil, options={}, &block)
2156
- if url and !block
2157
- @items << { name: name, link: url, icon: icon, options: options }
2158
- elsif block
2159
- menu = Menu.new
2160
- menu.instance_eval(&block)
2161
- @items << { name: name, menu: menu, icon: icon, options: options }
2162
- else
2163
- @items << { name: name, link: "#", icon: icon, options: options }
2164
- end
2165
- end
2166
- end
2167
-
2168
- class StructuredPage < Page
2169
-
2170
- def initialize(title, global_settings, options, &block)
2171
- @rows = []
2172
- super
2173
- end
2174
-
2175
- def header(&block)
2176
- row(class: "wrapper border-bottom white-bg page-heading", &block)
2177
- end
2178
-
2179
- def row(options={}, &block)
2180
- r = Row.new(self, @anchors, options)
2181
- r.instance_eval(&block)
2182
- @rows << r
2183
- end
2184
-
2185
-
2186
- end
2187
-
2188
- class NavPage < StructuredPage
2189
- def initialize(title, global_settings, options, &block)
2190
- super
2191
- @menu = Menu.new
2192
- end
2193
-
2194
- def menu(&block)
2195
- @menu.instance_eval(&block)
2196
- end
2197
-
2198
- def brand(text, link="/")
2199
- @brand = text
2200
- @brand_link = link
2201
- end
2202
-
2203
- end
2204
-
2205
- class SideNavPage < NavPage
2206
- def initialize(title, global_settings, options, &block)
2207
- super
2208
- end
2209
-
2210
- def generate(level)
2211
- instance_eval &@block
2212
- rows = @rows.map { |row|
2213
- <<-ENDROW
2214
- <div class="row #{row.extra_classes}" style="#{row.style}">
2215
- #{row.generate}
2216
- </div>
2217
- ENDROW
2218
- }.join
2219
-
2220
- menu = @menu
2221
-
2222
- navigation = Elements.new(self, @anchors)
2223
- navigation.instance_eval do
2224
-
2225
- menu.items.each do |item|
2226
- li item[:options] do
2227
- if item.has_key? :menu
2228
-
2229
- hyperlink "/#" do
2230
- icon item[:icon]
2231
- span :class => "nav-label" do
2232
- text item[:name]
2233
- end
2234
- span :class => "fa arrow" do
2235
- text ""
2236
- end
2237
- end
2238
-
2239
- open = ""
2240
- open = "collapse in" if item[:options][:open]
2241
- ul :class => "nav nav-second-level #{open}" do
2242
- item[:menu].items.each do |inneritem|
2243
- li inneritem[:options] do
2244
- if inneritem.has_key?(:menu)
2245
- raise "Second level menu not supported"
2246
- else
2247
- hyperlink "#{inneritem[:link]}" do
2248
- icon inneritem[:icon]
2249
- span :class => "nav-label" do
2250
- text inneritem[:name]
2251
- end
2252
- end
2253
- end
2254
- end
2255
- end
2256
- end
2257
- elsif
2258
- hyperlink "#{item[:link]}" do
2259
- icon item[:icon]
2260
- span :class => "nav-label" do
2261
- text item[:name]
2262
- end
2263
- end
2264
- end
2265
- end
2266
- end
2267
-
2268
- end
2269
-
2270
- brand_content = ""
2271
-
2272
- if @brand
2273
- brand_content = <<-BRAND_CONTENT
2274
-
2275
- <li>
2276
- <a href="#{root}"><i class="fa fa-home"></i> <span class="nav-label">#{@brand}</span> <span class="label label-primary pull-right"></span></a>
2277
- </li>
2278
- BRAND_CONTENT
2279
- end
2280
-
2281
- @loading_bar_visible = true
2282
- @content =
2283
- <<-ENDBODY
2284
- <div id="wrapper">
2285
-
2286
- <nav class="navbar-default navbar-static-side" role="navigation">
2287
- <div class="sidebar-collapse">
2288
- <ul class="nav" id="side-menu">
2289
-
2290
- #{brand_content}
2291
- #{navigation.generate}
2292
-
2293
- </ul>
2294
- </div>
2295
- </nav>
2296
- <div id="page-wrapper" class="gray-bg">
2297
- <div class="row border-bottom">
2298
- <nav class="navbar navbar-static-top " role="navigation" style="margin-bottom: 0">
2299
- <div class="navbar-header">
2300
- <a class="navbar-minimalize minimalize-styl-2 btn btn-primary " href="#"><i class="fa fa-bars"></i> </a>
2301
- </div>
2302
- <ul class="nav navbar-top-links navbar-right">
2303
- <!-- NAV RIGHT -->
2304
- </ul>
2305
- </nav>
2306
- </div>
2307
- #{rows}
2308
- </div>
2309
- </div>
2310
- ENDBODY
2311
-
2312
- super
2313
- end
2314
- end
2315
-
2316
- class TopNavPage < NavPage
2317
- def initialize(title, global_settings, options, &block)
2318
- super
2319
- end
2320
-
2321
- def generate(level)
2322
- instance_eval &@block
2323
- rows = @rows.map { |row|
2324
- <<-ENDROW
2325
- <div class="row #{row.extra_classes}" style="#{row.style}">
2326
- #{row.generate}
2327
- </div>
2328
- ENDROW
2329
- }.join
2330
-
2331
- @body_class = "top-navigation"
2332
- @loading_bar_visible = true
2333
-
2334
- menu = @menu
2335
-
2336
- navigation = Elements.new(self, @anchors)
2337
- navigation.instance_eval do
2338
-
2339
- menu.items.each do |item|
2340
- li item[:options] do
2341
- if item.has_key? :menu
2342
-
2343
- li :class => "dropdown" do
2344
- a :"aria-expanded" => "false",
2345
- role: "button",
2346
- href: "#",
2347
- :class => "dropdown-toggle",
2348
- :"data-toggle" => "dropdown" do
2349
-
2350
- icon item[:icon]
2351
- text item[:name]
2352
- span :class => "caret" do
2353
- text ""
2354
- end
2355
-
2356
- end
2357
- ul role: "menu", :class => "dropdown-menu" do
2358
- item[:menu].items.each do |inneritem|
2359
- li inneritem[:options] do
2360
- if inneritem.has_key?(:menu)
2361
- raise "Second level menu not supported"
2362
- else
2363
- hyperlink inneritem[:link], inneritem[:name]
2364
- end
2365
- end
2366
- end
2367
- end
2368
- end
2369
- elsif
2370
- hyperlink "#{item[:link]}" do
2371
- span :class => "nav-label" do
2372
- icon item[:icon]
2373
- text item[:name]
2374
- end
2375
- end
2376
- end
2377
- end if item[:options][:position] != :right
2378
- end
2379
-
2380
- end
2381
-
2382
- navigation_right = Elements.new(self, @anchors)
2383
- navigation_right.instance_eval do
2384
-
2385
- menu.items.each do |item|
2386
- li item[:options] do
2387
- if item.has_key? :menu
2388
-
2389
- li :class => "dropdown" do
2390
- a :"aria-expanded" => "false",
2391
- role: "button",
2392
- href: "#",
2393
- :class => "dropdown-toggle",
2394
- :"data-toggle" => "dropdown" do
2395
-
2396
- icon item[:icon]
2397
- text item[:name]
2398
- span :class => "caret" do
2399
- text ""
2400
- end
2401
-
2402
- end
2403
- ul role: "menu", :class => "dropdown-menu" do
2404
- item[:menu].items.each do |inneritem|
2405
- li inneritem[:options] do
2406
- if inneritem.has_key?(:menu)
2407
- raise "Second level menu not supported"
2408
- else
2409
- hyperlink inneritem[:link], inneritem[:name]
2410
- end
2411
- end
2412
- end
2413
- end
2414
- end
2415
- elsif
2416
- hyperlink "#{item[:link]}" do
2417
- span :class => "nav-label" do
2418
- icon item[:icon]
2419
- text item[:name]
2420
- end
2421
- end
2422
- end
2423
- end if item[:options][:position] == :right
2424
- end
2425
-
2426
- end
2427
-
2428
-
2429
- brand_content = ""
2430
-
2431
- if @brand
2432
- brand_content = <<-BRAND_CONTENT
2433
-
2434
- <div class="navbar-header">
2435
-
2436
- <a href="#{root}" class="navbar-brand">#{@brand}</a>
2437
- </div>
2438
- BRAND_CONTENT
2439
- end
2440
-
2441
- @content =
2442
- <<-ENDBODY
2443
- <div id="wrapper">
2444
-
2445
- <div id="page-wrapper" class="gray-bg">
2446
- <div class="row border-bottom white-bg">
2447
-
2448
- <nav class="navbar navbar-static-top" role="navigation">
2449
- <button aria-controls="navbar" aria-expanded="false" data-target="#navbar" data-toggle="collapse" class="navbar-toggle collapsed" type="button">
2450
- <i class="fa fa-reorder"></i>
2451
- </button>
2452
- #{brand_content}
2453
-
2454
- <div class="navbar-collapse collapse" id="navbar">
2455
- <ul class="nav navbar-nav">
2456
- #{navigation.generate}
2457
- </ul>
2458
- <ul class="nav navbar-top-links navbar-right">
2459
- #{navigation_right.generate}
2460
- </ul>
2461
- </div>
2462
-
2463
-
2464
-
2465
- </nav>
2466
- </div>
2467
-
2468
-
2469
- <div class="wrapper-content">
2470
- <div class="container">
2471
- #{rows}
2472
- </div>
2473
- </div>
2474
- </div>
2475
- </div>
2476
- ENDBODY
2477
-
2478
- super
2479
- end
2480
- end
2481
-
2482
- class NonNavPage < StructuredPage
2483
- def initialize(title, global_settings, options, &block)
2484
- super
2485
- end
2486
-
2487
- def generate(level)
2488
- instance_eval &@block
2489
- rows = @rows.map { |row|
2490
- <<-ENDROW
2491
- <div class="row #{row.extra_classes}">
2492
- #{row.generate}
2493
- </div>
2494
- ENDROW
2495
- }.join
2496
-
2497
- @body_class = "gray-bg"
2498
-
2499
- @content = <<-CONTENT
2500
- <div id="wrapper">
2501
- <div class="wrapper-content">
2502
- <div class="container">
2503
- #{rows}
2504
- </div>
2505
- </div>
2506
- </div>
2507
- CONTENT
2508
- super
2509
- end
2510
- end
2511
-
2512
- class RawPage < Page
2513
- def initialize(title, global_settings, options, &block)
2514
- super
2515
- end
2516
-
2517
- def generate(back_folders, options={})
2518
-
2519
- elem = Elements.new(self, {})
2520
- elem.instance_eval(&@block)
2521
-
2522
- elem.generate
2523
- end
2524
-
2525
- end
2526
-
2527
- class EmptyPage < Page
2528
- def initialize(title, global_settings, options, &block)
2529
- super
2530
- end
2531
-
2532
- def generate(level)
2533
- elem = Elements.new(self, {})
2534
- elem.instance_eval(&@block)
2535
- @body_class = "gray-bg"
2536
- @content = <<-CONTENT
2537
- <div id="wrapper">
2538
- <div class="wrapper-content">
2539
- <div class="container">
2540
- #{elem.generate}
2541
- </div>
2542
- </div>
2543
- </div>
2544
- CONTENT
2545
- super
2546
- end
2547
- end
2548
-
2549
-
2550
- class CenterPage < Page
2551
- def initialize(title, global_settings, options, &block)
2552
- super
2553
- end
2554
-
2555
- def generate(level)
2556
-
2557
- elem = Elements.new(self, {})
2558
- elem.instance_eval(&@block)
2559
-
2560
- @body_class = "gray-bg"
2561
- @content = <<-CONTENT
2562
- <div class="middle-box text-center animated fadeInDown">
2563
- <div>
2564
- #{elem.generate}
2565
- </div>
2566
- </div>
2567
- CONTENT
2568
- super
2569
- end
2570
- end
2571
-
2572
- class Weave
2573
- attr_accessor :pages
2574
- def initialize(file, options={})
2575
- @pages = {}
2576
- @file = file
2577
- @global_settings = options
2578
-
2579
- @global_settings[:root] = @global_settings[:root] || "/"
2580
- @global_settings[:root] = "#{@global_settings[:root]}/" unless @global_settings[:root].end_with? "/"
2581
- instance_eval(File.read(file), file)
2582
- end
2583
-
2584
- def set_global(key, value)
2585
- @global_settings[key] = value
2586
- end
2587
-
2588
- def center_page(path, title=nil, options={}, &block)
2589
-
2590
- if title == nil
2591
- title = path
2592
- path = ""
2593
- end
2594
-
2595
- p = CenterPage.new(title, @global_settings, options, &block)
2596
- @pages[path] = p
2597
- end
2598
-
2599
- def sidenav_page(path, title=nil, options={}, &block)
2600
-
2601
- if title == nil
2602
- title = path
2603
- path = ""
2604
- end
2605
-
2606
- p = SideNavPage.new(title, @global_settings, options, &block)
2607
- @pages[path] = p
2608
- end
2609
-
2610
- def topnav_page(path, title=nil, options={}, &block)
2611
-
2612
- if title == nil
2613
- title = path
2614
- path = ""
2615
- end
2616
-
2617
- p = TopNavPage.new(title, @global_settings, options, &block)
2618
- @pages[path] = p
2619
- end
2620
-
2621
- def nonnav_page(path, title=nil, options={}, &block)
2622
-
2623
- if title == nil
2624
- title = path
2625
- path = ""
2626
- end
2627
-
2628
- p = NonNavPage.new(title, @global_settings, options, &block)
2629
- @pages[path] = p
2630
- end
2631
-
2632
-
2633
- def empty_page(path, title=nil, options={}, &block)
2634
-
2635
- if title == nil
2636
- title = path
2637
- path = ""
2638
- end
2639
-
2640
- p = EmptyPage.new(title, @global_settings, options, &block)
2641
- @pages[path] = p
2642
- end
2643
-
2644
- def raw_page(path="", options={}, &block)
2645
-
2646
- # raw pages dont even have a title
2647
-
2648
- p = RawPage.new("", @global_settings, options, &block)
2649
- @pages[path] = p
2650
- end
2651
-
2652
- def include(file)
2653
- dir = File.dirname(@file)
2654
- filename = File.join([dir, file])
2655
- File.read(filename)
2656
- load filename
2657
- end
2658
- end
2659
- end
7
+ require 'weaver/weave'
8
+
9
+ require 'weaver/page_types/page'
10
+ require 'weaver/page_types/center_page'
11
+ require 'weaver/page_types/empty_page'
12
+ require 'weaver/page_types/raw_page'
13
+ require 'weaver/page_types/nonnav_page'
14
+ require 'weaver/page_types/sidenav_page'
15
+ require 'weaver/page_types/topnav_page'
16
+
17
+ require 'weaver/elements'
18
+
19
+ require 'weaver/element_types/accordion'
20
+ require 'weaver/element_types/action'
21
+ require 'weaver/element_types/code'
22
+ require 'weaver/element_types/dynamic_table'
23
+ require 'weaver/element_types/form'
24
+ require 'weaver/element_types/javascript_object'
25
+ require 'weaver/element_types/modal_dialog'
26
+ require 'weaver/element_types/panel'
27
+ require 'weaver/element_types/row'
28
+ require 'weaver/element_types/tabs'
29
+ require 'weaver/element_types/textfield_javascript'