lux-fw 0.1.17 → 0.1.35
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 +4 -4
- data/.version +1 -1
- data/bin/cli/am +38 -29
- data/bin/cli/assets +8 -4
- data/bin/cli/exceptions +6 -6
- data/bin/cli/generate +0 -0
- data/bin/cli/get +0 -0
- data/bin/cli/nginx +11 -5
- data/bin/cli/routes +0 -0
- data/bin/cli/systemd +36 -0
- data/bin/forever +0 -0
- data/bin/job_que +0 -0
- data/bin/lux +1 -0
- data/lib/common/base32.rb +0 -0
- data/lib/common/class_attributes.rb +13 -4
- data/lib/common/crypt.rb +6 -10
- data/lib/common/dynamic_class.rb +23 -0
- data/lib/common/generic_model.rb +0 -0
- data/lib/common/hash_with_indifferent_access.rb +352 -0
- data/lib/common/method_attr.rb +69 -0
- data/lib/lux/api/api.rb +26 -27
- data/lib/lux/api/lib/application_api.rb +26 -7
- data/lib/lux/api/lib/doc_builder.rb +18 -17
- data/lib/lux/api/lib/dsl.rb +23 -41
- data/lib/lux/api/lib/error.rb +3 -0
- data/lib/lux/api/lib/model_api.rb +22 -20
- data/lib/lux/api/lib/rescue.rb +5 -15
- data/lib/lux/api/lib/response.rb +46 -0
- data/lib/lux/cache/cache.rb +13 -6
- data/lib/lux/cell/cell.rb +3 -14
- data/lib/lux/config/config.rb +4 -3
- data/lib/lux/controller/controller.rb +3 -3
- data/lib/lux/controller/lib/nav.rb +6 -2
- data/lib/lux/error/error.rb +15 -14
- data/lib/lux/helper/helper.rb +5 -5
- data/lib/lux/helper/lib/html_tag.rb +67 -0
- data/lib/lux/html/lib/input_types.rb +26 -16
- data/lib/lux/lib/lux.rb +51 -0
- data/lib/lux/lux.rb +5 -52
- data/lib/lux/page/lib/response.rb +178 -0
- data/lib/lux/page/page.rb +72 -51
- data/lib/lux/rescue_from/rescue_from.rb +8 -6
- data/lib/lux/template/template.rb +1 -0
- data/lib/lux-fw.rb +2 -0
- data/lib/overload/array.rb +4 -0
- data/lib/overload/date.rb +2 -0
- data/lib/overload/hash.rb +19 -10
- data/lib/overload/it.rb +29 -0
- data/lib/overload/object.rb +3 -19
- data/lib/overload/r.rb +53 -0
- data/lib/overload/string.rb +5 -6
- data/lib/overload/string_inflections.rb +4 -3
- data/lib/plugins/assets/assets_plug.rb +9 -4
- data/lib/plugins/assets/helper_module_adapter.rb +4 -2
- data/lib/plugins/db_helpers/link_plugin.rb +2 -2
- data/lib/plugins/db_logger/init.rb +1 -1
- data/lib/vendor/mini_assets/lib/asset/css.rb +19 -0
- data/lib/vendor/mini_assets/lib/asset/js.rb +17 -0
- data/lib/vendor/mini_assets/lib/asset.rb +71 -0
- data/lib/vendor/mini_assets/lib/base/javascript.rb +13 -0
- data/lib/vendor/mini_assets/lib/base/stylesheet.rb +5 -0
- data/lib/vendor/mini_assets/lib/base.rb +69 -0
- data/lib/vendor/mini_assets/lib/manifest.rb +18 -0
- data/lib/vendor/mini_assets/lib/opts.rb +16 -0
- data/lib/vendor/mini_assets/mini_assets.rb +74 -0
- metadata +23 -10
- data/lib/common/class_method_params.rb +0 -94
- data/lib/overload/hash_wia.rb +0 -282
- data/lib/overload/inflections.rb +0 -199
- data/lib/vendor/mini_assets/mini_asset/base.rb +0 -167
- data/lib/vendor/mini_assets/mini_asset/css.rb +0 -38
- data/lib/vendor/mini_assets/mini_asset/js.rb +0 -38
- data/lib/vendor/mini_assets/mini_asset.rb +0 -31
data/lib/lux/api/lib/dsl.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
class Lux::Api
|
2
|
-
|
3
2
|
# name 'Show user data'
|
4
3
|
# param :email, type: :email, req: false
|
5
4
|
# param :pass
|
@@ -8,56 +7,41 @@ class Lux::Api
|
|
8
7
|
# @user.slice(:id, :name, :avatar, :email)
|
9
8
|
# end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
def param(field, type=String, opts={})
|
24
|
-
opts = type.is_a?(Hash) ? type : opts.merge(type: type)
|
25
|
-
opts[:name] = field
|
26
|
-
opts[:req] = opts[:req].class.name == 'FalseClass' ? false : true
|
27
|
-
opts[:type] ||= String
|
28
|
-
|
29
|
-
ClassMethodParams.add_param self, :param, opts
|
30
|
-
end
|
10
|
+
# helper for standard definition of parametars
|
11
|
+
# param :o_id
|
12
|
+
# param :o_id, Integer
|
13
|
+
# param :o_id, Integer, req: false
|
14
|
+
# param :o_id, req: false
|
15
|
+
method_attr :param do |field, type=String, opts={}|
|
16
|
+
opts = type.is_a?(Hash) ? type : opts.merge(type: type)
|
17
|
+
opts[:name] = field
|
18
|
+
opts[:req] = true if opts[:req].nil?
|
19
|
+
opts[:type] ||= String
|
20
|
+
opts
|
21
|
+
end
|
31
22
|
|
32
|
-
|
33
|
-
|
34
|
-
ClassMethodParams.add_param self, :name, name
|
35
|
-
end
|
23
|
+
# helper for standard definition of name
|
24
|
+
method_attr :name
|
36
25
|
|
37
|
-
|
38
|
-
|
39
|
-
ClassMethodParams.add_param self, :description, name
|
40
|
-
end
|
41
|
-
end
|
26
|
+
# helper for standard definition of description
|
27
|
+
method_attr :data
|
42
28
|
|
43
29
|
###
|
44
30
|
|
45
31
|
def check_params_and_mock_instance_variables action
|
46
|
-
|
47
|
-
|
48
|
-
if opts && opts[:param]
|
49
|
-
local = opts[:param].inject({}) { |h, el| o=el.dup; h[o.delete(:name)] = o; h }
|
32
|
+
@method_attr = self.class.method_attr[action] || {}
|
50
33
|
|
51
|
-
|
34
|
+
# params check if framework default
|
35
|
+
if @method_attr[:param]
|
36
|
+
local = @method_attr[:param].inject({}) { |h, el| o=el.dup; h[o.delete(:name)] = o; h }
|
37
|
+
rules = Typero.new local
|
52
38
|
errors = rules.validate(@params)
|
53
39
|
|
54
40
|
if errors.keys.length > 0
|
55
41
|
raise ArgumentError.new(errors.values.to_sentence) unless Lux.page
|
56
42
|
|
57
|
-
Lux.page.status
|
58
|
-
|
59
|
-
@response[:errors] = errors
|
60
|
-
return false
|
43
|
+
Lux.page.status 400
|
44
|
+
return response.error errors.values.to_sentence
|
61
45
|
end
|
62
46
|
|
63
47
|
# define local prefixed @_ variables
|
@@ -66,8 +50,6 @@ class Lux::Api
|
|
66
50
|
eval "@_#{key.downcase.gsub(/[^\w]/,'_')} = value" if key.length < 15 && value.present? && key =~ /^[\w]+$/
|
67
51
|
end
|
68
52
|
end
|
69
|
-
|
70
|
-
true
|
71
53
|
end
|
72
54
|
|
73
55
|
end
|
@@ -56,12 +56,12 @@ class ModelApi < ApplicationApi
|
|
56
56
|
return if report_errros_if_any @object
|
57
57
|
|
58
58
|
if @object.id
|
59
|
-
|
59
|
+
message '%s created' % @class_name.capitalize
|
60
60
|
else
|
61
61
|
error 'object not created, error unknown'
|
62
62
|
end
|
63
63
|
|
64
|
-
|
64
|
+
response.meta :path, @object.path if @object.respond_to?(:path)
|
65
65
|
|
66
66
|
@object.attributes
|
67
67
|
end
|
@@ -76,8 +76,8 @@ class ModelApi < ApplicationApi
|
|
76
76
|
can? :update, @object
|
77
77
|
@object.save if @object.valid?
|
78
78
|
report_errros_if_any @object
|
79
|
-
|
80
|
-
|
79
|
+
response.message '%s updated' % @class_name
|
80
|
+
response.meta :path, @object.path if @object.respond_to?(:path)
|
81
81
|
@object.attributes
|
82
82
|
end
|
83
83
|
|
@@ -88,15 +88,19 @@ class ModelApi < ApplicationApi
|
|
88
88
|
|
89
89
|
if @object.respond_to?(:is_active)
|
90
90
|
@object.update is_active: false
|
91
|
-
|
91
|
+
|
92
|
+
message 'Object deleted (exists in trashcan)'
|
92
93
|
elsif @object.respond_to?(:active)
|
93
94
|
@object.update active: false
|
94
|
-
|
95
|
+
|
96
|
+
message 'Object deleted (exists in trashcan)'
|
95
97
|
else
|
96
98
|
@object.destroy
|
97
|
-
|
99
|
+
message '%s deleted' % @object.class.name
|
98
100
|
end
|
101
|
+
|
99
102
|
report_errros_if_any @object
|
103
|
+
|
100
104
|
@object.attributes
|
101
105
|
end
|
102
106
|
|
@@ -112,26 +116,24 @@ class ModelApi < ApplicationApi
|
|
112
116
|
error "No is_active, can't undelete"
|
113
117
|
end
|
114
118
|
|
115
|
-
|
119
|
+
response.message = 'Object raised from the dead.'
|
116
120
|
end
|
117
121
|
|
118
|
-
def report_errros_if_any
|
119
|
-
@response[:object] = obj.class.to_s.tableize.singularize
|
120
|
-
@response[:objects] = obj.class.to_s.tableize
|
121
|
-
|
122
|
+
def report_errros_if_any obj
|
122
123
|
if obj.errors.count > 0
|
123
|
-
|
124
|
-
@response[:errors] = {}
|
125
|
-
for k,v in obj.errors
|
124
|
+
for k, v in obj.errors
|
126
125
|
desc = v.join(', ')
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
126
|
+
|
127
|
+
response.error k, desc
|
128
|
+
response.error desc
|
129
|
+
# desc = "#{k} #{desc}" if desc.starts_with?('is ')
|
131
130
|
end
|
132
|
-
|
131
|
+
|
132
|
+
Lux.page.status 400
|
133
|
+
|
133
134
|
return true
|
134
135
|
end
|
136
|
+
|
135
137
|
false
|
136
138
|
end
|
137
139
|
|
data/lib/lux/api/lib/rescue.rb
CHANGED
@@ -1,18 +1,8 @@
|
|
1
|
-
Lux::Api.
|
1
|
+
Lux::Api.rescue_from(:default) do |msg|
|
2
|
+
response.error msg
|
2
3
|
|
3
|
-
|
4
|
-
Lux.
|
5
|
-
|
6
|
-
data = { error:msg }
|
7
|
-
|
8
|
-
if Lux.dev? && $!.class != StandardError
|
9
|
-
data[:backtrace] = $!.backtrace.reject{ |el| el.index('/gems/') }.map{ |el| el.sub(Lux.root.to_s, '') }
|
10
|
-
ap data[:backtrace]
|
11
|
-
end
|
12
|
-
|
13
|
-
ApplicationApi.new.decorate_response!(data)
|
14
|
-
|
15
|
-
Lux.page.body data
|
4
|
+
if Lux.dev? && $!.class != Lux::Api::Error
|
5
|
+
data[:backtrace] = $!.backtrace.reject{ |el| el.index('/gems/') }.map{ |el| el.sub(Lux.root.to_s, '') }
|
6
|
+
ap data[:backtrace]
|
16
7
|
end
|
17
|
-
|
18
8
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
class Lux::Api::Response
|
2
|
+
attr_accessor :data
|
3
|
+
attr_accessor :message
|
4
|
+
|
5
|
+
def meta key, value
|
6
|
+
@meta ||= {}
|
7
|
+
@meta[key.to_s] = value
|
8
|
+
end
|
9
|
+
|
10
|
+
def error key, data=nil
|
11
|
+
if data
|
12
|
+
@error_hash ||= {}
|
13
|
+
@error_hash[key.to_s] = data
|
14
|
+
data
|
15
|
+
else
|
16
|
+
@errors ||= []
|
17
|
+
@errors.push key unless @errors.include?(key)
|
18
|
+
key
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def message what
|
23
|
+
@message = what
|
24
|
+
end
|
25
|
+
|
26
|
+
def errors?
|
27
|
+
(@error_hash || @errors) ? true : false
|
28
|
+
end
|
29
|
+
|
30
|
+
def render
|
31
|
+
output = {}
|
32
|
+
|
33
|
+
output[:data] = @data if @data.present?
|
34
|
+
output[:meta] = @meta if @meta.present?
|
35
|
+
output[:message] = @message if @message.present?
|
36
|
+
|
37
|
+
if errors?
|
38
|
+
output[:error] ||= {}
|
39
|
+
output[:error][:messages] = @errors if @errors
|
40
|
+
output[:error][:hash] = @error_hash if @error_hash
|
41
|
+
end
|
42
|
+
|
43
|
+
output
|
44
|
+
end
|
45
|
+
alias :to_hash :render
|
46
|
+
end
|
data/lib/lux/cache/cache.rb
CHANGED
@@ -35,14 +35,21 @@ module Lux::Cache
|
|
35
35
|
@@server.delete(key)
|
36
36
|
end
|
37
37
|
|
38
|
-
def fetch key,
|
39
|
-
|
40
|
-
|
38
|
+
def fetch key, opts={}
|
39
|
+
opts = { ttl: opts } unless opts.is_a?(Hash)
|
40
|
+
opts = opts.to_opts!(:ttl, :log, :force)
|
41
|
+
|
42
|
+
opts.ttl = opts.ttl.to_i if opts.ttl
|
43
|
+
opts.log ||= true if opts.log.nil?
|
44
|
+
opts.force ||= true if opts.force.nil?
|
45
|
+
|
46
|
+
@@server.delete key if Lux.page && opts.force && Lux.page.no_cache?
|
47
|
+
|
48
|
+
Lux.log " Cache.fetch.get #{key} (ttl: #{opts.ttl.or(:nil)})".green if opts.log
|
41
49
|
|
42
|
-
|
43
|
-
data = @@server.fetch key, ttl do
|
50
|
+
data = @@server.fetch key, opts.ttl do
|
44
51
|
data = yield
|
45
|
-
Lux.log " Cache.fetch.SET #{key} len:#{data.to_s.length}" if log
|
52
|
+
Lux.log " Cache.fetch.SET #{key} len:#{data.to_s.length}" if opts.log
|
46
53
|
data
|
47
54
|
end
|
48
55
|
|
data/lib/lux/cell/cell.rb
CHANGED
@@ -61,6 +61,8 @@ class Lux::Cell
|
|
61
61
|
|
62
62
|
### INSTANCE METHODS
|
63
63
|
|
64
|
+
attr_reader :cell_action
|
65
|
+
|
64
66
|
def initialize
|
65
67
|
# before and after should be exected only once
|
66
68
|
@executed_filters = {}
|
@@ -91,7 +93,7 @@ class Lux::Cell
|
|
91
93
|
|
92
94
|
method_name = method_name.to_s.gsub('-', '_').gsub(/[^\w]/, '')
|
93
95
|
|
94
|
-
Lux.log " #{self.class.to_s}(:#{method_name})".
|
96
|
+
Lux.log " #{self.class.to_s}(:#{method_name})".light_blue
|
95
97
|
Lux.page.files_in_use.push "app/cells/#{self.class.to_s.underscore}.rb"
|
96
98
|
|
97
99
|
@cell_action = method_name
|
@@ -137,19 +139,6 @@ class Lux::Cell
|
|
137
139
|
|
138
140
|
opts[:template] = name if name
|
139
141
|
|
140
|
-
# etag and cache string are same things, one is client based, other one is server based
|
141
|
-
if opts[:cache]
|
142
|
-
opts[:cache] = Lux.cache.generate_key(opts[:cache] )
|
143
|
-
opts[:etag] ||= opts[:cache]
|
144
|
-
end
|
145
|
-
|
146
|
-
return if opts[:etag] && Lux.page.etag(opts[:etag])
|
147
|
-
|
148
|
-
if opts[:cache]
|
149
|
-
data = Lux.cache.get(opts[:cache])
|
150
|
-
return Lux.page.body(data) if data
|
151
|
-
end
|
152
|
-
|
153
142
|
render_resolve_body(opts)
|
154
143
|
Lux.cache.set(opts[:cache], Lux.page.body) if opts[:cache]
|
155
144
|
end
|
data/lib/lux/config/config.rb
CHANGED
@@ -74,11 +74,12 @@ module Lux::Config
|
|
74
74
|
speed = ((Time.now - load_start)*1000).round.to_s.sub(/(\d)(\d{3})$/,'\1s \2')+'ms'
|
75
75
|
ram = `ps -o rss -p #{$$}`.chomp.split("\n").last.to_i / 1000
|
76
76
|
opts = []
|
77
|
-
opts.push Lux.verbose? ? 'verbose'.yellow : '
|
78
|
-
opts.push Lux.config(:auto_code_reload) ? 'code-reload'.yellow : 'no-code-reload'.green
|
77
|
+
opts.push Lux.verbose? ? 'verbose'.yellow : 'no-verbose'.green
|
78
|
+
opts.push Lux.config(:auto_code_reload) ? 'auto-code-reload'.yellow : 'no-code-reload'.green
|
79
79
|
|
80
|
-
"* #{'Lux'.
|
80
|
+
"* #{'Lux'.white} loaded #{Lux.env('RACK_ENV').green} (#{opts.join(', ')}) mode in #{speed.to_s.white}, uses #{ram.to_s.white} MB RAM with total of #{Gem.loaded_specs.keys.length.to_s.white} gems in spec"
|
81
81
|
end
|
82
|
+
|
82
83
|
end
|
83
84
|
|
84
85
|
class Object
|
@@ -66,7 +66,7 @@ class Lux::Controller
|
|
66
66
|
|
67
67
|
def rescued_main
|
68
68
|
if respond_to?(:main)
|
69
|
-
@@rescue_from_ivar.call { main }
|
69
|
+
@@rescue_from_ivar.call(self) { main }
|
70
70
|
else
|
71
71
|
Lux.error %[No instance method "main" in Lux::Controller defiend]
|
72
72
|
end
|
@@ -81,7 +81,7 @@ class Lux::Controller
|
|
81
81
|
when nil
|
82
82
|
'/'.ljust(20).green
|
83
83
|
else
|
84
|
-
@route.to_s.ljust(20).
|
84
|
+
@route.to_s.ljust(20).light_blue
|
85
85
|
end
|
86
86
|
|
87
87
|
route_target = case @route_target
|
@@ -169,7 +169,7 @@ class Lux::Controller
|
|
169
169
|
|
170
170
|
object, action = object if object.is_a? Array
|
171
171
|
|
172
|
-
Lux.log ' %s %s # %s' % [object.to_s.
|
172
|
+
Lux.log ' %s %s # %s' % [object.to_s.light_blue, nav.path, @route_object]
|
173
173
|
|
174
174
|
if action
|
175
175
|
object.action action
|
@@ -7,7 +7,7 @@ class Lux::Controller::Nav
|
|
7
7
|
# acepts path as a string
|
8
8
|
def initialize request
|
9
9
|
@path = request.path.split('/').slice(1, 100) || []
|
10
|
-
|
10
|
+
shift_to_root if @path.first
|
11
11
|
|
12
12
|
@subdomain = request.host.split('.')
|
13
13
|
@domain = @subdomain.pop(2).join('.')
|
@@ -22,7 +22,7 @@ class Lux::Controller::Nav
|
|
22
22
|
|
23
23
|
def shift_to_root
|
24
24
|
@root.tap do
|
25
|
-
@root = @path.shift
|
25
|
+
@root = @path.shift.to_s.gsub('-', '_')
|
26
26
|
build_full
|
27
27
|
end
|
28
28
|
end
|
@@ -48,6 +48,10 @@ class Lux::Controller::Nav
|
|
48
48
|
@path.first
|
49
49
|
end
|
50
50
|
|
51
|
+
def first= data
|
52
|
+
@path[0] = data
|
53
|
+
end
|
54
|
+
|
51
55
|
def second
|
52
56
|
@path[1]
|
53
57
|
end
|
data/lib/lux/error/error.rb
CHANGED
@@ -16,14 +16,13 @@ NotFoundError ||= Class.new(StandardError)
|
|
16
16
|
RateLimitError ||= Class.new(StandardError)
|
17
17
|
|
18
18
|
module Lux::Error
|
19
|
-
OUT_OF_PROCESS_ERROR_PATH = Lux.root.join('tmp/request-error.txt')
|
20
|
-
|
21
19
|
extend self
|
22
20
|
|
23
21
|
def try(name)
|
24
22
|
begin
|
25
23
|
yield
|
26
24
|
rescue
|
25
|
+
Lux.page.status 500
|
27
26
|
log($!)
|
28
27
|
inline('%s (%s)' % [name, $!.class])
|
29
28
|
end
|
@@ -41,9 +40,20 @@ module Lux::Error
|
|
41
40
|
|
42
41
|
def inline(name=nil, o=nil)
|
43
42
|
o ||= $!
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
|
44
|
+
dmp = [[], []]
|
45
|
+
|
46
|
+
o.backtrace.each do |line|
|
47
|
+
line = line.sub(Lux.root.to_s, '.')
|
48
|
+
dmp[line.include?('/app/') ? 0 : 1].push line
|
49
|
+
end
|
50
|
+
|
51
|
+
dmp[0] = dmp[0].map { |_| _ = _.split(':', 3); '<b>%s</b> - %s - %s' % _ }
|
52
|
+
|
53
|
+
name ||= 'Undefined name'
|
54
|
+
msg = $!.to_s.gsub('","',%[",\n "]).gsub('<','<')
|
55
|
+
|
56
|
+
%[<pre style="color:red; background:#eee; padding:10px; font-family:'Lucida Console'; line-height:15pt; font-size:11pt;"><b style="font-size:110%;">#{name}</b>\n\n<b>#{msg}</b>\n\n#{dmp[0].join("\n")}\n\n#{dmp[1].join("\n")}</pre>]
|
47
57
|
end
|
48
58
|
|
49
59
|
def log(exception)
|
@@ -63,13 +73,4 @@ module Lux::Error
|
|
63
73
|
|
64
74
|
File.write("#{folder}/#{key}.txt", data)
|
65
75
|
end
|
66
|
-
|
67
|
-
|
68
|
-
# if some other process as asset complation raises error
|
69
|
-
# use this method to show errors
|
70
|
-
def log_out_of_process_error(data)
|
71
|
-
return unless Lux.config(:show_server_errors)
|
72
|
-
File.write OUT_OF_PROCESS_ERROR_PATH, data
|
73
|
-
end
|
74
|
-
|
75
76
|
end
|
data/lib/lux/helper/helper.rb
CHANGED
@@ -99,11 +99,11 @@ class Lux::Helper
|
|
99
99
|
end
|
100
100
|
|
101
101
|
# tag :div, { 'class'=>'iform' } do
|
102
|
-
def tag name, opts={}, data=nil
|
103
|
-
|
104
|
-
|
105
|
-
opts
|
102
|
+
def tag name=nil, opts={}, data=nil
|
103
|
+
return Lux::Helper::HtmlTag unless name
|
104
|
+
|
105
|
+
data = yield(opts) if block_given?
|
106
|
+
Lux::Helper::HtmlTag.tag name, opts, data
|
106
107
|
end
|
107
108
|
|
108
109
|
end
|
109
|
-
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# tag.ul do |n|
|
2
|
+
# 1.upto(3) do |num|
|
3
|
+
# n.li do |n|
|
4
|
+
# n.i '.arrow'
|
5
|
+
# n.span num
|
6
|
+
# end
|
7
|
+
# end
|
8
|
+
# end
|
9
|
+
|
10
|
+
class Lux::Helper::HtmlTag
|
11
|
+
class << self
|
12
|
+
# tag.div -> tag.tag :div
|
13
|
+
def method_missing tag_name, *args, &block
|
14
|
+
tag tag_name, args[0], args[1], &block
|
15
|
+
end
|
16
|
+
|
17
|
+
# tag :div, { 'class'=>'iform' } do
|
18
|
+
def tag name=nil, opts={}, data=nil
|
19
|
+
# covert tag.a '.foo.bar' to class names
|
20
|
+
if opts.class == String && opts[0,1] == '.'
|
21
|
+
opts = { class: opts.sub('.', '').gsub('.', ' ') }
|
22
|
+
end
|
23
|
+
|
24
|
+
# fix data and opts unless opts is Hash
|
25
|
+
data, opts = opts, {} unless opts.class == Hash
|
26
|
+
|
27
|
+
if block_given?
|
28
|
+
inline = new
|
29
|
+
data = yield(inline, opts)
|
30
|
+
|
31
|
+
# if data is pushed to passed node, use that data
|
32
|
+
data = inline.data if inline.data.first
|
33
|
+
end
|
34
|
+
|
35
|
+
data = data.join('') if data.is_a?(Array)
|
36
|
+
|
37
|
+
build opts, name, data
|
38
|
+
end
|
39
|
+
|
40
|
+
# build html node
|
41
|
+
def build attrs, node=nil, text=nil
|
42
|
+
opts = ''
|
43
|
+
attrs.each do |k,v|
|
44
|
+
opts += ' '+k.to_s.gsub(/_/,'-')+'="'+v.to_s.gsub(/"/,'"')+'"' if v.present?
|
45
|
+
end
|
46
|
+
|
47
|
+
return opts unless node
|
48
|
+
|
49
|
+
text = yield opts if block_given?
|
50
|
+
text ||= '' unless ['input', 'img', 'meta', 'link', 'hr', 'br'].include?(node.to_s)
|
51
|
+
text ? %{<#{node}#{opts}>#{text}</#{node}>} : %{<#{node}#{opts} />}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
###
|
56
|
+
|
57
|
+
attr_reader :data
|
58
|
+
|
59
|
+
def initialize
|
60
|
+
@data = []
|
61
|
+
end
|
62
|
+
|
63
|
+
# forward to class
|
64
|
+
def method_missing tag_name, *args, &block
|
65
|
+
@data.push self.class.tag(tag_name, args[0], args[1], &block)
|
66
|
+
end
|
67
|
+
end
|
@@ -62,12 +62,15 @@ class Lux::Html::Input
|
|
62
62
|
def as_select
|
63
63
|
body = []
|
64
64
|
collection = @opts.delete(:collection)
|
65
|
+
|
65
66
|
if nullval = @opts.delete(:null)
|
66
67
|
body.push %[<option value="">#{nullval}</option>] if nullval
|
67
68
|
end
|
69
|
+
|
68
70
|
for el in prepare_collection(collection)
|
69
71
|
body.push(%[<option value="#{el[0]}"#{@opts[:value].to_s == el[0].to_s ? ' selected=""' : nil}>#{el[1]}</option>])
|
70
72
|
end
|
73
|
+
|
71
74
|
body = body.join("\n")
|
72
75
|
@opts.tag(:select, body)
|
73
76
|
end
|
@@ -94,25 +97,32 @@ class Lux::Html::Input
|
|
94
97
|
end
|
95
98
|
|
96
99
|
def as_date
|
97
|
-
@opts[:type]
|
98
|
-
@opts[:style]
|
99
|
-
|
100
|
-
@opts[:
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
ret + %[<script>new Pikaday({ field: document.getElementById('#{@opts [:id]}'), format: "YYYY-MM-DD" }); </script>]
|
100
|
+
@opts[:type] = :date
|
101
|
+
@opts[:style] = 'width: 160px; display: inline;'
|
102
|
+
|
103
|
+
value = @opts[:value] || nil
|
104
|
+
desc = value ? '—' + Time.ago(value) : ''
|
105
|
+
|
106
|
+
[@opts.tag(:input), desc].join(' ')
|
105
107
|
end
|
106
108
|
|
107
109
|
def as_datetime
|
108
|
-
@opts[:
|
109
|
-
@opts[:
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
110
|
+
value = @opts[:value]
|
111
|
+
id = @opts[:id]
|
112
|
+
|
113
|
+
value_day = value ? value.strftime('%Y-%m-%d') : ''
|
114
|
+
value_time = value ? value.strftime('%H:%M') : ''
|
115
|
+
value_all = value ? value.strftime('%H:%M') : ''
|
116
|
+
|
117
|
+
base = { class: 'form-control', onchange: "datetime_set('#{id}');", style: 'width: 160px; display: inline;' }
|
118
|
+
|
119
|
+
input_day = base.merge({ type: :date, id: '%s_day' % id, value: value_day }).tag :input
|
120
|
+
input_time = base.merge({ style: 'width: 110px; display: inline;', type: :time, id: '%s_time' % id, value: value_time }).tag :input
|
121
|
+
input_all = base.merge({ style: 'width: 150px; display: inline;', type: :text, id: id, name: @opts[:name], onfocus: 'blur();' }).tag :input
|
122
|
+
script = %[<script>window.datetime_set = function(id) { $('#'+id).val($('#'+id+'_day').val()+' '+$('#'+id+'_time').val()); }; datetime_set('#{id}');</script>]
|
123
|
+
desc = value ? '—' + Time.ago(value) : ''
|
124
|
+
|
125
|
+
[input_day, input_time, input_all, script, desc].join(' ')
|
116
126
|
end
|
117
127
|
|
118
128
|
def as_datebuttons
|
data/lib/lux/lib/lux.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# handy :)
|
2
|
+
# renders full pages and exposes page object (req, res) in yiled
|
3
|
+
# for easy and powerful testing
|
4
|
+
# Hash :qs, Hash :post, String :method, Hash :cookies, Hash :session
|
5
|
+
# https://github.com/rack/rack/blob/master/test/spec_request.rb
|
6
|
+
def Lux(path, in_opts={}, &block)
|
7
|
+
allowed_opts = [:qs, :post, :method, :session, :cookies]
|
8
|
+
in_opts.keys.each { |k| die "#{k} is not allowed as opts param. allowed are #{allowed_opts}" unless allowed_opts.index(k) }
|
9
|
+
|
10
|
+
opts = {}
|
11
|
+
|
12
|
+
if in_opts[:post]
|
13
|
+
opts[:query_string] = in_opts[:post]
|
14
|
+
opts[:request_method] = :post
|
15
|
+
else
|
16
|
+
opts[:query_string] = in_opts[:qs] || {}
|
17
|
+
opts[:request_method] ||= in_opts[:method] || :get
|
18
|
+
end
|
19
|
+
opts[:request_method] = opts[:request_method].to_s.upcase
|
20
|
+
opts[:query_string] = opts[:query_string].to_query if opts[:query_string].class.to_s == 'Hash'
|
21
|
+
|
22
|
+
if path[0,4] == 'http'
|
23
|
+
parsed = URI.parse(path)
|
24
|
+
opts[:server_name] = parsed.host
|
25
|
+
opts[:server_port] = parsed.port
|
26
|
+
path = '/'+path.split('/', 4).last
|
27
|
+
end
|
28
|
+
|
29
|
+
env = Rack::MockRequest.env_for(path)
|
30
|
+
env[:input] = opts[:post] if opts[:post]
|
31
|
+
for k,v in opts
|
32
|
+
env[k.to_s.upcase] = v
|
33
|
+
end
|
34
|
+
|
35
|
+
page = nil
|
36
|
+
time_ms = Lux.speed { page = Lux::Page.prepare(env) }
|
37
|
+
page.session = in_opts[:session] if in_opts[:session]
|
38
|
+
|
39
|
+
return page.instance_exec &block if block_given?
|
40
|
+
|
41
|
+
response = page.render
|
42
|
+
body = response[2].join('')
|
43
|
+
body = JSON.parse body if response[1]['content-type'].index('/json')
|
44
|
+
|
45
|
+
{
|
46
|
+
time: time_ms,
|
47
|
+
status: response[0],
|
48
|
+
headers: response[1],
|
49
|
+
body: body
|
50
|
+
}.h
|
51
|
+
end
|