weaver 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,122 @@
1
+ module Weaver
2
+ # Accordion element
3
+ class Accordion
4
+ def initialize(page, anchors)
5
+ @anchors = anchors
6
+ @tabs = {}
7
+ @paneltype = :panel
8
+ @is_collapsed = false
9
+ @page = page
10
+
11
+ @anchors['accordia'] = [] unless @anchors['accordia']
12
+
13
+ accArray = @anchors['accordia']
14
+
15
+ @accordion_name = "accordion#{accArray.length}"
16
+ accArray << @accordion_name
17
+ end
18
+
19
+ def collapsed(isCollapsed)
20
+ @is_collapsed = isCollapsed
21
+ end
22
+
23
+ def type(type)
24
+ @paneltype = type
25
+ end
26
+
27
+ def tab(title, options = {}, &block)
28
+ @anchors['tabs'] = [] unless @anchors['tabs']
29
+
30
+ tabArray = @anchors['tabs']
31
+
32
+ elem = Elements.new(@page, @anchors)
33
+ elem.instance_eval(&block)
34
+
35
+ tabname = "tab#{tabArray.length}"
36
+ tabArray << tabname
37
+
38
+ @tabs[tabname] =
39
+ {
40
+ title: title,
41
+ elem: elem
42
+ }
43
+
44
+ if options[:mixpanel_event_name]
45
+ @tabs[tabname][:mixpanel_event_name] = options[:mixpanel_event_name]
46
+ end
47
+
48
+ if options[:mixpanel_event_props]
49
+ @tabs[tabname][:mixpanel_event_props] = options[:mixpanel_event_props]
50
+ end
51
+ end
52
+
53
+ def generate
54
+ tabbar = Elements.new(@page, @anchors)
55
+
56
+ tabs = @tabs
57
+ paneltype = @paneltype
58
+ accordion_name = @accordion_name
59
+ is_collapsed = @is_collapsed
60
+
61
+ tabbar.instance_eval do
62
+ div class: 'panel-group', id: accordion_name do
63
+ cls = 'panel-collapse collapse in'
64
+ cls = 'panel-collapse collapse' if is_collapsed
65
+ tabs.each do |anchor, value|
66
+ ibox do
67
+ type paneltype
68
+ body false
69
+ title do
70
+ div class: 'panel-title' do
71
+ options = {
72
+ "data-toggle": 'collapse',
73
+ "data-parent": "##{accordion_name}",
74
+ href: "##{anchor}"
75
+ }
76
+
77
+ if value[:mixpanel_event_name]
78
+ props = {}
79
+ if value[:mixpanel_event_props].is_a? Hash
80
+ props = value[:mixpanel_event_props]
81
+ end
82
+ options[:onclick] = "mixpanel.track('#{value[:mixpanel_event_name]}', #{props.to_json.tr('"', "'")})"
83
+ end
84
+
85
+ a options do
86
+ if value[:title].is_a? Symbol
87
+ icon value[:title]
88
+ else
89
+ text value[:title]
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ extra do
96
+ div id: anchor, class: cls do
97
+ div class: 'panel-body' do
98
+ text value[:elem].generate
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ cls = 'panel-collapse collapse'
105
+ end
106
+ end
107
+ end
108
+
109
+ tabbar.generate
110
+ end
111
+ end
112
+
113
+ # Add accordion to elements
114
+ class Elements
115
+ def accordion(&block)
116
+ acc = Accordion.new(@page, @anchors)
117
+ acc.instance_eval(&block)
118
+
119
+ @inner_content << acc.generate
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,38 @@
1
+ module Weaver
2
+ class Action
3
+ def initialize(page, anchors, &block)
4
+ @page = page
5
+ @anchors = anchors
6
+
7
+ actionsArray = @anchors['action']
8
+
9
+ @anchors['action'] = [] unless @anchors['action']
10
+
11
+ actionsArray = @anchors['action']
12
+
13
+ @actionName = "action#{actionsArray.length}"
14
+ actionsArray << @actionName
15
+
16
+ @code = ''
17
+
18
+ instance_eval(&block)
19
+ end
20
+
21
+ def script(code)
22
+ @code = code
23
+ end
24
+
25
+ def generate
26
+ # puts @code
27
+ <<-FUNCTION
28
+ function #{@actionName}(caller, data) {
29
+ #{@code}
30
+ }
31
+ FUNCTION
32
+ end
33
+
34
+ def name
35
+ @actionName
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,81 @@
1
+ module Weaver
2
+ class Code
3
+ def initialize(page, anchors, lang)
4
+ @page = page
5
+ @anchors = anchors
6
+ @content = ''
7
+ @options = {}
8
+
9
+ codeArray = @anchors['code']
10
+
11
+ @anchors['code'] = [] unless @anchors['code']
12
+
13
+ codeArray = @anchors['code']
14
+
15
+ @codeName = "code#{codeArray.length}"
16
+ codeArray << @codeName
17
+
18
+ @page.request_css 'css/plugins/codemirror/codemirror.css'
19
+ @page.request_js 'js/plugins/codemirror/codemirror.js'
20
+
21
+ language lang
22
+ end
23
+
24
+ def language(lang)
25
+ # TODO: improve langmap
26
+ langmap = {
27
+ javascript: { mime: 'text/javascript', file: 'javascript/javascript' }
28
+ }
29
+
30
+ if langmap[lang]
31
+ @options[:mode] = langmap[lang][:mime]
32
+ @page.request_js "js/plugins/codemirror/mode/#{langmap[lang][:file]}.js"
33
+ else
34
+ @options[:mode] = "text/x-#{lang}"
35
+ @page.request_js "js/plugins/codemirror/mode/#{lang}/#{lang}.js"
36
+ end
37
+ end
38
+
39
+ def content(text)
40
+ @content = text
41
+ end
42
+
43
+ def theme(name)
44
+ @options[:theme] = name
45
+
46
+ @page.request_css "css/plugins/codemirror/#{name}.css"
47
+ end
48
+
49
+ def generate_script
50
+ @options[:lineNumbers] ||= true
51
+ @options[:matchBrackets] ||= true
52
+ @options[:styleActiveLine] ||= true
53
+ @options[:mode] ||= 'javascript'
54
+ @options[:readOnly] ||= true
55
+
56
+ <<-CODESCRIPT
57
+ $(document).ready(function()
58
+ {
59
+ CodeMirror.fromTextArea(document.getElementById("#{@codeName}"),
60
+ JSON.parse('#{@options.to_json}')
61
+ );
62
+ });
63
+ CODESCRIPT
64
+ end
65
+
66
+ def generate
67
+ content = @content
68
+ codeName = @codeName
69
+
70
+ elem = Elements.new(@page, @anchors)
71
+
72
+ elem.instance_eval do
73
+ textarea id: codeName do
74
+ text content
75
+ end
76
+ end
77
+
78
+ elem.generate
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,324 @@
1
+ require 'weaver/element_types/dynamic_table_cell'
2
+ module Weaver
3
+ # Tables that dynamically load data
4
+ class DynamicTable
5
+ def initialize(page, anchors, url, options = {}, &block)
6
+ @page = page
7
+ @anchors = anchors
8
+ @url = url
9
+ @options = options
10
+ @columns = nil
11
+ @query_object = nil
12
+
13
+ instance_eval(&block) if block
14
+
15
+ @options[:id] ||= @page.create_anchor 'dyn_table'
16
+ @table_name = @options[:id]
17
+ @head_name = "#{@table_name}_head"
18
+ @body_name = "#{@table_name}_body"
19
+ end
20
+
21
+ def column(name, options = {}, &block)
22
+ @columns = [] if @columns.nil?
23
+
24
+ title = options[:title] || name
25
+ format = nil
26
+ transform = nil
27
+
28
+ if options[:icon]
29
+ elem = Elements.new(@page, @anchors)
30
+ elem.instance_eval do
31
+ icon options[:icon]
32
+ text " #{title}"
33
+ end
34
+ title = elem.generate
35
+ end
36
+
37
+ if block
38
+ elem = DynamicTableCell.new(@page, @anchors)
39
+ elem.instance_eval(&block)
40
+ format = elem.generate
41
+ if elem.transform_script
42
+ func_name = @page.create_anchor 'transform'
43
+ @page.write_script_once <<-SCRIPT
44
+ document.transform_#{func_name} = function (input)
45
+ {
46
+ #{elem.transform_script}
47
+ }
48
+ SCRIPT
49
+
50
+ transform = func_name
51
+ end
52
+ end
53
+
54
+ @columns << { name: name, title: title, format: format, transform: transform }
55
+ end
56
+
57
+ def generate_table
58
+ table_name = @table_name
59
+ head_name = @head_name
60
+ body_name = @body_name
61
+ options = @options
62
+
63
+ columns = @columns || [{ title: 'Key' }, { title: 'Value' }]
64
+
65
+ elem = Elements.new(@page, @anchors)
66
+ elem.instance_eval do
67
+ table options do
68
+ thead id: head_name do
69
+ columns.each do |column, _|
70
+ if column.is_a? Hash
71
+ th column[:title].to_s
72
+ else
73
+ th column.to_s
74
+ end
75
+ end
76
+ end
77
+
78
+ tbody id: body_name do
79
+ end
80
+ end
81
+ end
82
+
83
+ elem.generate
84
+ end
85
+
86
+ def query(&block)
87
+ @query_object = JavaScriptObject.new(&block)
88
+ end
89
+
90
+ def generate_script
91
+ query_object_declaration = '{}'
92
+ query_string = ''
93
+
94
+ if @query_object
95
+ query_object_declaration = @query_object.generate
96
+ query_string = '+ "?" + $.param(query_object)'
97
+ end
98
+
99
+ member_expr = ''
100
+ member_expr = ".#{@options[:member]}" if @options[:member]
101
+
102
+ <<-DATATABLE_SCRIPT
103
+
104
+ function refresh_table_#{@table_name}()
105
+ {
106
+ var query_object = #{query_object_declaration};
107
+
108
+ $.get( "#{@url}" #{query_string}, function( returned_data )
109
+ {
110
+ var data = returned_data#{member_expr};
111
+ var data_object = {};
112
+ if (data !== null && typeof data === 'object')
113
+ {
114
+ data_object = data;
115
+ }
116
+ else
117
+ {
118
+ data_object = JSON.parse(data);
119
+ }
120
+
121
+ var head = $("##{@head_name}")
122
+ var body = $("##{@body_name}")
123
+
124
+ if($.isPlainObject(data_object))
125
+ {
126
+ for (var key in data_object)
127
+ {
128
+ var row = $('<tr>');
129
+ row.append($('<td>').text(key));
130
+ row.append($('<td>').text(data_object[key]));
131
+ body.append(row);
132
+ }
133
+ }
134
+
135
+ if ($.isArray(data_object))
136
+ {
137
+
138
+ var columnData = JSON.parse(#{@columns.to_json.inspect});
139
+ var columns = {};
140
+ var columnTitles = [];
141
+ head.empty();
142
+ if (#{@columns.nil?})
143
+ {
144
+ // Set up columns
145
+ for (var index in data_object)
146
+ {
147
+ for (var key in data_object[index])
148
+ {
149
+ columns[key] = Object.keys(columns).length;
150
+ }
151
+ }
152
+ for (var key in columns)
153
+ {
154
+ columnTitles.push(key);
155
+ }
156
+ }
157
+ else
158
+ {
159
+ for (var key in columnData)
160
+ {
161
+ columns[columnData[key]["name"]] = Object.keys(columns).length;
162
+ columnTitles.push(columnData[key]["title"]);
163
+ }
164
+ }
165
+
166
+ var row = $('<tr>');
167
+ for (var key in columnTitles)
168
+ {
169
+ var columnTitle = $('<th>').html(columnTitles[key]);
170
+ row.append(columnTitle);
171
+ }
172
+ head.append(row);
173
+
174
+ for (var index in data_object)
175
+ {
176
+ var row = $('<tr>');
177
+ for (var columnIndex = 0; columnIndex < Object.keys(columns).length; columnIndex++) {
178
+ var cell_data = data_object[index][ Object.keys(columns)[columnIndex] ];
179
+
180
+ if (columnData && columnData[columnIndex]["format"])
181
+ {
182
+ var format = columnData[columnIndex]["format"];
183
+ var matches = format.match(/###.+?###/g)
184
+
185
+ var result = format;
186
+ for (var matchIndex in matches)
187
+ {
188
+ var member_name = matches[matchIndex].match(/[^#]+/)[0];
189
+ result = result.replaceAll(matches[matchIndex], data_object[index][member_name]);
190
+ }
191
+
192
+ if (columnData && columnData[columnIndex]["transform"])
193
+ {
194
+ result = document["transform_" + columnData[columnIndex]["transform"]](result);
195
+ }
196
+ row.append($('<td>').html( result ).data("object", data_object[index]) );
197
+ }
198
+ else
199
+ {
200
+ if (columnData && columnData[columnIndex]["transform"])
201
+ {
202
+ cell_data = document["transform_" + columnData[columnIndex]["transform"]](cell_data);
203
+ }
204
+ row.append($('<td>').text( cell_data ).data("object", data_object[index]) );
205
+ }
206
+ }
207
+ body.append(row);
208
+ }
209
+ }
210
+
211
+ });
212
+ }
213
+
214
+ refresh_table_#{@table_name}();
215
+
216
+ DATATABLE_SCRIPT
217
+ end
218
+ end
219
+
220
+ # Add tables to elements
221
+ class Elements
222
+ def table(options = {}, &block)
223
+ table_name = options[:id] || @page.create_anchor('table')
224
+ table_style = ''
225
+
226
+ table_style = options[:style] unless options[:style].nil?
227
+
228
+ classname = 'table'
229
+
230
+ classname += ' table-bordered' if options[:bordered]
231
+ classname += ' table-hover' if options[:hover]
232
+ classname += ' table-striped' if options[:striped]
233
+
234
+ table_options = {
235
+ class: classname,
236
+ id: table_name,
237
+ style: table_style
238
+ }
239
+
240
+ if options[:system] == :data_table
241
+ @page.request_js 'js/plugins/dataTables/jquery.dataTables.js'
242
+ @page.request_js 'js/plugins/dataTables/dataTables.bootstrap.js'
243
+ @page.request_js 'js/plugins/dataTables/dataTables.responsive.js'
244
+ @page.request_js 'js/plugins/dataTables/dataTables.tableTools.min.js'
245
+
246
+ @page.request_css 'css/plugins/dataTables/dataTables.bootstrap.css'
247
+ @page.request_css 'css/plugins/dataTables/dataTables.responsive.css'
248
+ @page.request_css 'css/plugins/dataTables/dataTables.tableTools.min.css'
249
+
250
+ @page.scripts << <<-DATATABLE_SCRIPT
251
+ $('##{table_name}').DataTable();
252
+ DATATABLE_SCRIPT
253
+ end
254
+
255
+ if options[:system] == :foo_table
256
+ table_options[:"data-filtering"] = true
257
+ table_options[:"data-sorting"] = true
258
+ table_options[:"data-paging"] = true
259
+ table_options[:"data-show-toggle"] = true
260
+ table_options[:"data-toggle-column"] = 'last'
261
+
262
+ table_options[:"data-paging-size"] = (options[:max_items_per_page] || 8).to_i.to_s
263
+ table_options[:class] = table_options[:class] + ' toggle-arrow-tiny'
264
+
265
+ @page.request_js 'js/plugins/footable/footable.all.min.js'
266
+
267
+ @page.request_css 'css/plugins/footable/footable.core.css'
268
+
269
+ @page.scripts << <<-DATATABLE_SCRIPT
270
+ $('##{table_name}').footable({
271
+ paging: {
272
+ size: #{(options[:max_items_per_page] || 8).to_i}
273
+ }
274
+ });
275
+ $('##{table_name}').append(this.html).trigger('footable_redraw');
276
+
277
+
278
+
279
+ DATATABLE_SCRIPT
280
+
281
+ @page.onload_scripts << <<-SCRIPT
282
+ SCRIPT
283
+ end
284
+
285
+ method_missing(:table, table_options, &block)
286
+ ul class: 'pagination'
287
+ end
288
+
289
+ def table_from_source(url, options = {}, &block)
290
+ dyn_table = DynamicTable.new(@page, @anchors, url, options, &block)
291
+
292
+ text dyn_table.generate_table
293
+
294
+ @page.scripts << dyn_table.generate_script
295
+ end
296
+
297
+ def table_from_hashes(hashes, options = {})
298
+ keys = {}
299
+ hashes.each do |hash|
300
+ hash.each do |key, _value|
301
+ keys[key] = ''
302
+ end
303
+ end
304
+
305
+ table options do
306
+ thead do
307
+ keys.each do |key, _|
308
+ th key.to_s
309
+ end
310
+ end
311
+
312
+ tbody do
313
+ hashes.each do |hash|
314
+ tr do
315
+ keys.each do |key, _|
316
+ td (hash[key]).to_s || '&nbsp;'
317
+ end
318
+ end
319
+ end
320
+ end
321
+ end
322
+ end
323
+ end
324
+ end