weaver 0.8.0 → 0.8.1
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 +5 -5
- data/Rakefile +1 -1
- data/bin/console +3 -3
- data/exe/weaver +112 -122
- data/lib/weaver.rb +24 -2654
- data/lib/weaver/element_types/accordion.rb +122 -0
- data/lib/weaver/element_types/action.rb +38 -0
- data/lib/weaver/element_types/code.rb +81 -0
- data/lib/weaver/element_types/dynamic_table.rb +324 -0
- data/lib/weaver/element_types/dynamic_table_cell.rb +16 -0
- data/lib/weaver/element_types/form.rb +47 -0
- data/lib/weaver/element_types/form_elements.rb +297 -0
- data/lib/weaver/element_types/javascript_object.rb +28 -0
- data/lib/weaver/element_types/modal_dialog.rb +68 -0
- data/lib/weaver/element_types/panel.rb +124 -0
- data/lib/weaver/element_types/row.rb +117 -0
- data/lib/weaver/element_types/tabs.rb +75 -0
- data/lib/weaver/element_types/textfield_javascript.rb +58 -0
- data/lib/weaver/elements.rb +406 -0
- data/lib/weaver/page_types/center_page.rb +25 -0
- data/lib/weaver/page_types/empty_page.rb +26 -0
- data/lib/weaver/page_types/nav_page.rb +39 -0
- data/lib/weaver/page_types/nonnav_page.rb +35 -0
- data/lib/weaver/page_types/page.rb +234 -0
- data/lib/weaver/page_types/raw_page.rb +17 -0
- data/lib/weaver/page_types/sidenav_page.rb +119 -0
- data/lib/weaver/page_types/structured_page.rb +19 -0
- data/lib/weaver/page_types/topnav_page.rb +167 -0
- data/lib/weaver/version.rb +1 -1
- data/lib/weaver/weave.rb +44 -0
- data/weaver.gemspec +27 -24
- metadata +37 -13
@@ -0,0 +1,124 @@
|
|
1
|
+
module Weaver
|
2
|
+
class Panel < Elements
|
3
|
+
def initialize(page, anchors, options = {})
|
4
|
+
super(page, anchors)
|
5
|
+
@title = nil
|
6
|
+
@footer = nil
|
7
|
+
@type = :ibox
|
8
|
+
@body = true
|
9
|
+
@extra = nil
|
10
|
+
@min_height = nil
|
11
|
+
@page = page
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
|
15
|
+
def generate
|
16
|
+
inner = super
|
17
|
+
|
18
|
+
types =
|
19
|
+
{
|
20
|
+
ibox: { outer: 'ibox float-e-margins', header: 'ibox-title', body: 'ibox-content', footer: 'ibox-footer' },
|
21
|
+
panel: { outer: 'panel panel-default', header: 'panel-heading', body: 'panel-body', footer: 'panel-footer' },
|
22
|
+
primary: { outer: 'panel panel-primary', header: 'panel-heading', body: 'panel-body', footer: 'panel-footer' },
|
23
|
+
success: { outer: 'panel panel-success', header: 'panel-heading', body: 'panel-body', footer: 'panel-footer' },
|
24
|
+
info: { outer: 'panel panel-info', header: 'panel-heading', body: 'panel-body', footer: 'panel-footer' },
|
25
|
+
warning: { outer: 'panel panel-warning', header: 'panel-heading', body: 'panel-body', footer: 'panel-footer' },
|
26
|
+
danger: { outer: 'panel panel-danger', header: 'panel-heading', body: 'panel-body', footer: 'panel-footer' },
|
27
|
+
blank: { outer: 'panel blank-panel', header: 'panel-heading', body: 'panel-body', footer: 'panel-footer' }
|
28
|
+
}
|
29
|
+
|
30
|
+
title = @title
|
31
|
+
footer = @footer
|
32
|
+
hasBody = @body
|
33
|
+
extra = @extra
|
34
|
+
options = @options
|
35
|
+
classNames = types[@type]
|
36
|
+
min_height = @min_height
|
37
|
+
|
38
|
+
elem = Elements.new(@page, @anchors)
|
39
|
+
|
40
|
+
outer_class = classNames[:outer]
|
41
|
+
|
42
|
+
outer_class = 'ibox collapsed' if options[:collapsed]
|
43
|
+
|
44
|
+
elem.instance_eval do
|
45
|
+
div class: outer_class do
|
46
|
+
if title
|
47
|
+
div class: classNames[:header] do
|
48
|
+
h5 title
|
49
|
+
|
50
|
+
div class: 'ibox-tools' do
|
51
|
+
if options[:collapsible] || options[:collapsed]
|
52
|
+
a class: 'collapse-link' do
|
53
|
+
icon :"chevron-up"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
if options[:expandable]
|
57
|
+
a class: 'fullscreen-link' do
|
58
|
+
icon :expand
|
59
|
+
end
|
60
|
+
end
|
61
|
+
if options[:closable]
|
62
|
+
a class: 'close-link' do
|
63
|
+
icon :times
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
if hasBody
|
70
|
+
div class: classNames[:body], style: "min-height: #{min_height}px" do
|
71
|
+
text inner
|
72
|
+
end
|
73
|
+
end
|
74
|
+
text extra if extra
|
75
|
+
if footer
|
76
|
+
div class: classNames[:footer] do
|
77
|
+
text footer
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
elem.generate
|
84
|
+
end
|
85
|
+
|
86
|
+
def min_height(val)
|
87
|
+
@min_height = val
|
88
|
+
end
|
89
|
+
|
90
|
+
def type(aType)
|
91
|
+
@type = aType
|
92
|
+
end
|
93
|
+
|
94
|
+
def body(hasBody)
|
95
|
+
@body = hasBody
|
96
|
+
end
|
97
|
+
|
98
|
+
def title(title = nil, &block)
|
99
|
+
@title = title
|
100
|
+
if block
|
101
|
+
elem = Elements.new(@page, @anchors)
|
102
|
+
elem.instance_eval(&block)
|
103
|
+
@title = elem.generate
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def extra(&block)
|
108
|
+
if block
|
109
|
+
elem = Elements.new(@page, @anchors)
|
110
|
+
elem.instance_eval(&block)
|
111
|
+
@extra = elem.generate
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def footer(footer = nil, &block)
|
116
|
+
@footer = footer
|
117
|
+
if block
|
118
|
+
elem = Elements.new(@page, @anchors)
|
119
|
+
elem.instance_eval(&block)
|
120
|
+
@footer = elem.generate
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module Weaver
|
2
|
+
# Row element
|
3
|
+
class Row < Elements
|
4
|
+
attr_accessor :extra_classes, :style
|
5
|
+
|
6
|
+
def initialize(page, anchors, options)
|
7
|
+
@columns = []
|
8
|
+
@free = 12
|
9
|
+
@extra_classes = options[:class] || ''
|
10
|
+
@style = options[:style]
|
11
|
+
@anchors = anchors
|
12
|
+
@page = page
|
13
|
+
end
|
14
|
+
|
15
|
+
def col(occupies, options = {}, &block)
|
16
|
+
raise 'Not enough columns!' if @free < occupies
|
17
|
+
|
18
|
+
@columns << Column.new(occupies, @page, @anchors, options, &block)
|
19
|
+
@free -= occupies
|
20
|
+
end
|
21
|
+
|
22
|
+
def generate
|
23
|
+
@columns.map(&:generate).join
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Column element
|
28
|
+
class Column
|
29
|
+
attr_reader :width, :options, :elem
|
30
|
+
|
31
|
+
def initialize(width, page, anchors, options = {}, &block)
|
32
|
+
@width = width
|
33
|
+
@options = options
|
34
|
+
@elem = Elements.new(page, anchors)
|
35
|
+
@elem.instance_eval(&block)
|
36
|
+
end
|
37
|
+
|
38
|
+
def colsize(size)
|
39
|
+
options[size] || width
|
40
|
+
end
|
41
|
+
|
42
|
+
def style(size)
|
43
|
+
return "hidden-#{size} " if colsize(size).zero?
|
44
|
+
|
45
|
+
"col-#{size}-#{colsize(size)}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def generate
|
49
|
+
styles = %i[xs sm md lg].map { |size| style(size) }.join(' ')
|
50
|
+
|
51
|
+
<<-ENDCOLUMN
|
52
|
+
<div class="#{styles}">
|
53
|
+
#{elem.generate}
|
54
|
+
</div>
|
55
|
+
ENDCOLUMN
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Add row and column elements
|
60
|
+
class Elements
|
61
|
+
def row(options = {}, &block)
|
62
|
+
options[:class] = 'row'
|
63
|
+
div options do
|
64
|
+
instance_eval(&block)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def twothirds(&block)
|
69
|
+
opts =
|
70
|
+
{
|
71
|
+
xs: 12,
|
72
|
+
sm: 12,
|
73
|
+
md: 8,
|
74
|
+
lg: 8
|
75
|
+
}
|
76
|
+
col(4, opts, &block)
|
77
|
+
end
|
78
|
+
|
79
|
+
def half(&block)
|
80
|
+
opts =
|
81
|
+
{
|
82
|
+
xs: 12,
|
83
|
+
sm: 12,
|
84
|
+
md: 12,
|
85
|
+
lg: 6
|
86
|
+
}
|
87
|
+
col(4, opts, &block)
|
88
|
+
end
|
89
|
+
|
90
|
+
def third(&block)
|
91
|
+
opts =
|
92
|
+
{
|
93
|
+
xs: 12,
|
94
|
+
sm: 12,
|
95
|
+
md: 4,
|
96
|
+
lg: 4
|
97
|
+
}
|
98
|
+
col(4, opts, &block)
|
99
|
+
end
|
100
|
+
|
101
|
+
def quarter(&block)
|
102
|
+
opts =
|
103
|
+
{
|
104
|
+
xs: 12,
|
105
|
+
sm: 12,
|
106
|
+
md: 6,
|
107
|
+
lg: 3
|
108
|
+
}
|
109
|
+
col(3, opts, &block)
|
110
|
+
end
|
111
|
+
|
112
|
+
def col(occupies, options = {}, &block)
|
113
|
+
column = Column.new(occupies, @page, @anchors, options, &block)
|
114
|
+
text column.generate
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Weaver
|
2
|
+
class Tabs
|
3
|
+
def initialize(page, anchors)
|
4
|
+
@anchors = anchors
|
5
|
+
@tabs = {}
|
6
|
+
@page = page
|
7
|
+
@orientation = :normal # :left, :right
|
8
|
+
end
|
9
|
+
|
10
|
+
def tab(title, &block)
|
11
|
+
@anchors['tabs'] = [] unless @anchors['tabs']
|
12
|
+
|
13
|
+
tabArray = @anchors['tabs']
|
14
|
+
|
15
|
+
elem = Elements.new(@page, @anchors)
|
16
|
+
elem.instance_eval(&block)
|
17
|
+
|
18
|
+
tabname = "tab#{tabArray.length}"
|
19
|
+
tabArray << tabname
|
20
|
+
|
21
|
+
@tabs[tabname] =
|
22
|
+
{
|
23
|
+
title: title,
|
24
|
+
elem: elem
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def orientation(direction)
|
29
|
+
@orientation = direction
|
30
|
+
end
|
31
|
+
|
32
|
+
def generate
|
33
|
+
tabbar = Elements.new(@page, @anchors)
|
34
|
+
tabs = @tabs
|
35
|
+
orientation = @orientation
|
36
|
+
|
37
|
+
tabbar.instance_eval do
|
38
|
+
div class: 'tabs-container' do
|
39
|
+
div class: "tabs-#{orientation}" do
|
40
|
+
ul class: 'nav nav-tabs' do
|
41
|
+
cls = 'active'
|
42
|
+
tabs.each do |anchor, value|
|
43
|
+
li class: cls do
|
44
|
+
a "data-toggle": 'tab', href: "##{anchor}" do
|
45
|
+
if value[:title].is_a? Symbol
|
46
|
+
icon value[:title]
|
47
|
+
else
|
48
|
+
text value[:title]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
cls = ''
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
div class: 'tab-content' do
|
58
|
+
cls = 'tab-pane active'
|
59
|
+
tabs.each do |anchor, value|
|
60
|
+
div id: anchor.to_s, class: cls do
|
61
|
+
div class: 'panel-body' do
|
62
|
+
text value[:elem].generate
|
63
|
+
end
|
64
|
+
end
|
65
|
+
cls = 'tab-pane'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
tabbar.generate
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Weaver
|
2
|
+
class TextfieldJavascript
|
3
|
+
def initialize(id)
|
4
|
+
@id = id
|
5
|
+
end
|
6
|
+
|
7
|
+
def onchange(script)
|
8
|
+
@change_script = script
|
9
|
+
end
|
10
|
+
|
11
|
+
def validate(script)
|
12
|
+
@validate_script = script
|
13
|
+
end
|
14
|
+
|
15
|
+
def generate(&block)
|
16
|
+
if block
|
17
|
+
instance_eval(&block)
|
18
|
+
<<-SCRIPT
|
19
|
+
|
20
|
+
if (!document.validators)
|
21
|
+
{
|
22
|
+
document.validators = {};
|
23
|
+
}
|
24
|
+
|
25
|
+
document.validators["##{@id}"] = function()
|
26
|
+
{
|
27
|
+
var valid = function(data) {
|
28
|
+
#{@validate_script};
|
29
|
+
return true;
|
30
|
+
}($("##{@id}").val());
|
31
|
+
|
32
|
+
var object = $("##{@id}");
|
33
|
+
#{@change_script};
|
34
|
+
|
35
|
+
if (valid)
|
36
|
+
{
|
37
|
+
object.removeClass("required");
|
38
|
+
object.removeClass("error");
|
39
|
+
object.removeAttr("aria-invalid");
|
40
|
+
}
|
41
|
+
else
|
42
|
+
{
|
43
|
+
object.addClass("required");
|
44
|
+
object.addClass("error");
|
45
|
+
object.attr("aria-required", "true");
|
46
|
+
object.attr("aria-invalid", "true");
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
$("##{@id}").keyup(function() { document.validators["##{@id}"](); })
|
51
|
+
$("##{@id}").blur(function() { document.validators["##{@id}"](); })
|
52
|
+
$("##{@id}").focusout(function() { document.validators["##{@id}"](); })
|
53
|
+
|
54
|
+
SCRIPT
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,406 @@
|
|
1
|
+
module Weaver
|
2
|
+
# Base element class for all HTML elements
|
3
|
+
class Elements
|
4
|
+
def initialize(page, anchors)
|
5
|
+
@inner_content = []
|
6
|
+
@anchors = anchors
|
7
|
+
@page = page
|
8
|
+
end
|
9
|
+
|
10
|
+
def method_missing(name, *args, &block)
|
11
|
+
tag = "<#{name} />"
|
12
|
+
|
13
|
+
inner = args.shift if args[0].is_a? String
|
14
|
+
if block
|
15
|
+
elem = Elements.new(@page, @anchors)
|
16
|
+
elem.instance_eval(&block)
|
17
|
+
inner = elem.generate
|
18
|
+
end
|
19
|
+
|
20
|
+
if !inner
|
21
|
+
|
22
|
+
options = args[0] || []
|
23
|
+
opts = options.map { |key, value| "#{key}=\"#{value}\"" }.join ' '
|
24
|
+
|
25
|
+
tag = "<#{name} #{opts} />"
|
26
|
+
elsif args.empty?
|
27
|
+
tag = "<#{name}>#{inner}</#{name}>"
|
28
|
+
elsif (args.length == 1) && args[0].is_a?(Hash)
|
29
|
+
options = args[0]
|
30
|
+
opts = options.map { |key, value| "#{key}=\"#{value}\"" }.join ' '
|
31
|
+
tag = "<#{name} #{opts}>#{inner}</#{name}>"
|
32
|
+
end
|
33
|
+
|
34
|
+
@inner_content << tag
|
35
|
+
tag
|
36
|
+
end
|
37
|
+
|
38
|
+
def root
|
39
|
+
@page.root
|
40
|
+
end
|
41
|
+
|
42
|
+
def request_js(path)
|
43
|
+
@page.request_js(path)
|
44
|
+
end
|
45
|
+
|
46
|
+
def request_css(path)
|
47
|
+
@page.request_css(path)
|
48
|
+
end
|
49
|
+
|
50
|
+
def on_page_load(script)
|
51
|
+
@page.on_page_load(script)
|
52
|
+
end
|
53
|
+
|
54
|
+
def write_script_once(script)
|
55
|
+
@page.write_script_once(script)
|
56
|
+
end
|
57
|
+
|
58
|
+
def background(&block)
|
59
|
+
@page.background(block)
|
60
|
+
end
|
61
|
+
|
62
|
+
def on_page_load(script)
|
63
|
+
@page.on_page_load(script)
|
64
|
+
end
|
65
|
+
|
66
|
+
def icon(type)
|
67
|
+
iconname = type.to_s.tr('_', '-')
|
68
|
+
if type.is_a? Symbol
|
69
|
+
i class: "fa fa-#{iconname}" do
|
70
|
+
end
|
71
|
+
else
|
72
|
+
i class: 'fa' do
|
73
|
+
text type
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def wform(options = {}, &block)
|
79
|
+
theform = Form.new(@page, @anchors, options, &block)
|
80
|
+
@inner_content << theform.generate
|
81
|
+
@page.scripts << theform.generate_script
|
82
|
+
end
|
83
|
+
|
84
|
+
def ibox(options = {}, &block)
|
85
|
+
panel = Panel.new(@page, @anchors, options)
|
86
|
+
panel.instance_eval(&block)
|
87
|
+
@inner_content << panel.generate
|
88
|
+
end
|
89
|
+
|
90
|
+
def center(content = nil, options = {}, &block)
|
91
|
+
options[:style] = '' unless options[:style]
|
92
|
+
|
93
|
+
options[:style] += '; text-align: center;'
|
94
|
+
if !content
|
95
|
+
div options, &block
|
96
|
+
else
|
97
|
+
div content, options, &block
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def panel(title, &block)
|
102
|
+
div class: 'panel panel-default' do
|
103
|
+
div class: 'panel-heading' do
|
104
|
+
h5 title
|
105
|
+
end
|
106
|
+
div class: 'panel-body', &block
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def tabs(&block)
|
111
|
+
tabs = Tabs.new(@page, @anchors)
|
112
|
+
tabs.instance_eval(&block)
|
113
|
+
|
114
|
+
@inner_content << tabs.generate
|
115
|
+
end
|
116
|
+
|
117
|
+
def syntax(lang = :javascript, &block)
|
118
|
+
code = Code.new(@page, @anchors, lang)
|
119
|
+
code.instance_eval(&block)
|
120
|
+
|
121
|
+
@inner_content << code.generate
|
122
|
+
|
123
|
+
@page.scripts << code.generate_script
|
124
|
+
end
|
125
|
+
|
126
|
+
def image(name, options = {})
|
127
|
+
style = (options[:style]).to_s
|
128
|
+
if options[:rounded_corners] == true
|
129
|
+
style += ' border-radius: 8px'
|
130
|
+
elsif options[:rounded_corners] == :top
|
131
|
+
style += ' border-radius: 8px 8px 0px 0px'
|
132
|
+
else
|
133
|
+
style += " border-radius: #{options[:rounded_corners]}px" if options[:rounded_corners]
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
img_options = {
|
138
|
+
class: "img-responsive #{options[:class]}",
|
139
|
+
src: "#{@page.root}images/#{name}",
|
140
|
+
style: style
|
141
|
+
}
|
142
|
+
img_options[:id] = options[:id] if options[:id]
|
143
|
+
|
144
|
+
img img_options
|
145
|
+
end
|
146
|
+
|
147
|
+
def crossfade_image(image_normal, image_hover)
|
148
|
+
div class: 'crossfade' do
|
149
|
+
image image_hover, class: 'bottom'
|
150
|
+
image image_normal, class: 'top'
|
151
|
+
end
|
152
|
+
image image_hover
|
153
|
+
@page.request_css 'css/crossfade_style.css'
|
154
|
+
end
|
155
|
+
|
156
|
+
def gallery(images, thumbnails = images, options = {})
|
157
|
+
@page.request_css 'css/plugins/blueimp/css/blueimp-gallery.min.css'
|
158
|
+
|
159
|
+
div class: 'lightBoxGallery' do
|
160
|
+
(0...images.length).to_a.each do |index|
|
161
|
+
title = options[:titles][index] if options[:titles]
|
162
|
+
|
163
|
+
a href: (images[index]).to_s, title: title.to_s, "data-gallery": '' do
|
164
|
+
img src: (thumbnails[index]).to_s, style: 'margin: 5px;'
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
div id: 'blueimp-gallery', class: 'blueimp-gallery' do
|
169
|
+
div class: 'slides' do end
|
170
|
+
h3 class: 'title' do end
|
171
|
+
a class: 'prev' do end
|
172
|
+
a class: 'next' do end
|
173
|
+
a class: 'close' do end
|
174
|
+
a class: 'play-pause' do end
|
175
|
+
ol class: 'indicator' do end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
@page.request_js 'js/plugins/blueimp/jquery.blueimp-gallery.min.js'
|
180
|
+
end
|
181
|
+
|
182
|
+
def breadcrumb(patharray)
|
183
|
+
ol class: 'breadcrumb' do
|
184
|
+
patharray.each do |path|
|
185
|
+
li path
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def p(*args, &block)
|
191
|
+
method_missing(:p, *args, &block)
|
192
|
+
end
|
193
|
+
|
194
|
+
def text(theText)
|
195
|
+
@inner_content << theText
|
196
|
+
end
|
197
|
+
|
198
|
+
def badge(label, options = {})
|
199
|
+
options[:type] ||= 'plain'
|
200
|
+
|
201
|
+
kind = 'label'
|
202
|
+
kind = 'badge' if options[:rounded]
|
203
|
+
tag_options = options.clone
|
204
|
+
tag_options[:class] = "#{kind} #{kind}-#{options[:type]}"
|
205
|
+
|
206
|
+
span tag_options do
|
207
|
+
text label
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def hyperlink(url, title = nil, &block)
|
212
|
+
title ||= url
|
213
|
+
|
214
|
+
if url.start_with? '/'
|
215
|
+
url.sub!(%r{^/}, @page.root)
|
216
|
+
if block
|
217
|
+
a href: url, &block
|
218
|
+
else
|
219
|
+
a title, href: url
|
220
|
+
end
|
221
|
+
else
|
222
|
+
|
223
|
+
if block
|
224
|
+
a href: url, target: '_blank' do
|
225
|
+
span do
|
226
|
+
span &block
|
227
|
+
icon :external_link
|
228
|
+
end
|
229
|
+
end
|
230
|
+
else
|
231
|
+
a href: url, target: '_blank' do
|
232
|
+
span do
|
233
|
+
text title
|
234
|
+
text ' '
|
235
|
+
icon :external_link
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def widget(options = {}, &block)
|
243
|
+
# gray-bg
|
244
|
+
# white-bg
|
245
|
+
# navy-bg
|
246
|
+
# blue-bg
|
247
|
+
# lazur-bg
|
248
|
+
# yellow-bg
|
249
|
+
# red-bg
|
250
|
+
# black-bg
|
251
|
+
|
252
|
+
color = "#{options[:color]}-bg" || 'navy-bg'
|
253
|
+
|
254
|
+
div class: "widget style1 #{color}", &block
|
255
|
+
end
|
256
|
+
|
257
|
+
def jumbotron(options = {}, &block)
|
258
|
+
additional_style = ''
|
259
|
+
|
260
|
+
if options[:background]
|
261
|
+
additional_style += " background-image: url('#{@page.root}images/#{options[:background]}'); background-position: center center; background-size: cover;"
|
262
|
+
end
|
263
|
+
|
264
|
+
additional_style += " height: #{options[:height]}px;" if options[:height]
|
265
|
+
|
266
|
+
if options[:min_height]
|
267
|
+
additional_style += " min-height: #{options[:min_height]}px;"
|
268
|
+
end
|
269
|
+
|
270
|
+
if options[:max_height]
|
271
|
+
additional_style += " max-height: #{options[:max_height]}px;"
|
272
|
+
end
|
273
|
+
|
274
|
+
div class: 'jumbotron', style: additional_style, &block
|
275
|
+
end
|
276
|
+
|
277
|
+
def _button(options = {}, &block)
|
278
|
+
anIcon = options[:icon]
|
279
|
+
title = options[:title]
|
280
|
+
|
281
|
+
if title.is_a? Hash
|
282
|
+
options.merge! title
|
283
|
+
title = anIcon
|
284
|
+
anIcon = nil
|
285
|
+
end
|
286
|
+
|
287
|
+
style = options[:style] || :primary
|
288
|
+
size = "btn-#{options[:size]}" if options[:size]
|
289
|
+
blockstyle = 'btn-block' if options[:block]
|
290
|
+
outline = 'btn-outline' if options[:outline]
|
291
|
+
dim = 'dim' if options[:threedee]
|
292
|
+
dim = 'dim btn-large-dim' if options[:bigthreedee]
|
293
|
+
dim = 'btn-rounded' if options[:rounded]
|
294
|
+
dim = 'btn-circle' if options[:circle]
|
295
|
+
|
296
|
+
buttonOptions = {
|
297
|
+
type: options[:type] || 'button',
|
298
|
+
class: "btn btn-#{style} #{size} #{blockstyle} #{outline} #{dim}",
|
299
|
+
id: options[:id]
|
300
|
+
}
|
301
|
+
|
302
|
+
if block
|
303
|
+
closer = ''
|
304
|
+
|
305
|
+
closer = '; return false;' if options[:nosubmit]
|
306
|
+
|
307
|
+
action = Action.new(@page, @anchors, &block)
|
308
|
+
buttonOptions[:onclick] = "#{action.name}(this)"
|
309
|
+
buttonOptions[:onclick] = "#{action.name}(this, #{options[:data]})#{closer}" if options[:data]
|
310
|
+
@page.scripts << action.generate
|
311
|
+
end
|
312
|
+
|
313
|
+
type = :button
|
314
|
+
|
315
|
+
buttonOptions[:"data-toggle"] = 'button' if options[:toggle]
|
316
|
+
type = :a if options[:toggle]
|
317
|
+
|
318
|
+
method_missing type, buttonOptions do
|
319
|
+
if title.is_a? Symbol
|
320
|
+
icon title
|
321
|
+
else
|
322
|
+
icon anIcon if anIcon
|
323
|
+
text ' ' if anIcon
|
324
|
+
text title
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
def normal_button(anIcon, title = {}, options = {}, &block)
|
330
|
+
options[:icon] = anIcon
|
331
|
+
options[:title] = title
|
332
|
+
_button(options, &block)
|
333
|
+
end
|
334
|
+
|
335
|
+
def block_button(anIcon, title = {}, options = {}, &block)
|
336
|
+
options[:block] = true
|
337
|
+
options[:icon] = anIcon
|
338
|
+
options[:title] = title
|
339
|
+
_button(options, &block)
|
340
|
+
end
|
341
|
+
|
342
|
+
def outline_button(anIcon, title = {}, options = {}, &block)
|
343
|
+
options[:outline] = true
|
344
|
+
options[:icon] = anIcon
|
345
|
+
options[:title] = title
|
346
|
+
_button(options, &block)
|
347
|
+
end
|
348
|
+
|
349
|
+
def big_button(anIcon, title = {}, options = {}, &block)
|
350
|
+
options[:size] = :lg
|
351
|
+
options[:icon] = anIcon
|
352
|
+
options[:title] = title
|
353
|
+
_button(options, &block)
|
354
|
+
end
|
355
|
+
|
356
|
+
def small_button(anIcon, title = {}, options = {}, &block)
|
357
|
+
options[:size] = :sm
|
358
|
+
options[:icon] = anIcon
|
359
|
+
options[:title] = title
|
360
|
+
_button(options, &block)
|
361
|
+
end
|
362
|
+
|
363
|
+
def tiny_button(anIcon, title = {}, options = {}, &block)
|
364
|
+
options[:size] = :xs
|
365
|
+
options[:icon] = anIcon
|
366
|
+
options[:title] = title
|
367
|
+
_button(options, &block)
|
368
|
+
end
|
369
|
+
|
370
|
+
def embossed_button(anIcon, title = {}, options = {}, &block)
|
371
|
+
options[:threedee] = true
|
372
|
+
options[:icon] = anIcon
|
373
|
+
options[:title] = title
|
374
|
+
_button(options, &block)
|
375
|
+
end
|
376
|
+
|
377
|
+
def big_embossed_button(anIcon, title = {}, options = {}, &block)
|
378
|
+
options[:bigthreedee] = true
|
379
|
+
options[:icon] = anIcon
|
380
|
+
options[:title] = title
|
381
|
+
_button(options, &block)
|
382
|
+
end
|
383
|
+
|
384
|
+
def rounded_button(anIcon, title = {}, options = {}, &block)
|
385
|
+
options[:rounded] = true
|
386
|
+
options[:icon] = anIcon
|
387
|
+
options[:title] = title
|
388
|
+
_button(options, &block)
|
389
|
+
end
|
390
|
+
|
391
|
+
def circle_button(anIcon, title = {}, options = {}, &block)
|
392
|
+
options[:circle] = true
|
393
|
+
options[:icon] = anIcon
|
394
|
+
options[:title] = title
|
395
|
+
_button(options, &block)
|
396
|
+
end
|
397
|
+
|
398
|
+
def math(string)
|
399
|
+
text "$$$MATH$$$#{string}$$$ENDMATH$$$"
|
400
|
+
end
|
401
|
+
|
402
|
+
def generate
|
403
|
+
@inner_content.join
|
404
|
+
end
|
405
|
+
end
|
406
|
+
end
|