wrap_it 0.2.0 → 1.0.0
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/.ruby-version +1 -0
- data/.yardopts +3 -0
- data/README.md +67 -66
- data/lib/wrap_it.rb +16 -16
- data/lib/wrap_it/arguments.rb +368 -0
- data/lib/wrap_it/base.rb +56 -47
- data/lib/wrap_it/callbacks.rb +24 -5
- data/lib/wrap_it/capture_array.rb +140 -0
- data/lib/wrap_it/container.rb +69 -25
- data/lib/wrap_it/derived_attributes.rb +22 -6
- data/lib/wrap_it/enums.rb +44 -34
- data/lib/wrap_it/frameworks.rb +7 -3
- data/lib/wrap_it/helpers.rb +66 -1
- data/lib/wrap_it/html.rb +149 -0
- data/lib/wrap_it/html_class.rb +164 -183
- data/lib/wrap_it/html_data.rb +28 -15
- data/lib/wrap_it/link.rb +40 -17
- data/lib/wrap_it/sections.rb +90 -2
- data/lib/wrap_it/switches.rb +33 -29
- data/lib/wrap_it/text_container.rb +83 -10
- data/lib/wrap_it/version.rb +2 -1
- data/spec/frameworks/log/development.log +2108 -0
- data/spec/integration/base_spec.rb +2 -2
- data/spec/integration/container_spec.rb +3 -3
- data/spec/integration/examples_spec.rb +16 -15
- data/spec/integration/text_container_spec.rb +3 -3
- data/spec/lib/arguments_array_spec.rb +37 -27
- data/spec/lib/arguments_spec.rb +153 -0
- data/spec/lib/base_spec.rb +2 -25
- data/spec/lib/callbacks_spec.rb +1 -1
- data/spec/lib/container_spec.rb +1 -1
- data/spec/lib/derived_attributes_spec.rb +1 -1
- data/spec/lib/enums_spec.rb +2 -3
- data/spec/lib/html_class_spec.rb +269 -80
- data/spec/lib/html_data_spec.rb +18 -12
- data/spec/lib/html_spec.rb +124 -0
- data/spec/lib/link_spec.rb +2 -2
- data/spec/lib/sections_spec.rb +1 -1
- data/spec/lib/switches_spec.rb +3 -3
- data/spec/lib/text_container_spec.rb +2 -2
- data/spec/support/example_groups/{wrap_it_example_group.rb → wrapped_example_group.rb} +5 -5
- data/wrap_it.gemspec +2 -0
- metadata +15 -8
- data/lib/wrap_it/arguments_array.rb +0 -128
- data/lib/wrap_it/module_helpers.rb +0 -23
@@ -5,33 +5,49 @@ module WrapIt
|
|
5
5
|
# @author Alexey Ovchinnikov <alexiss@cybernetlab.ru>
|
6
6
|
#
|
7
7
|
module DerivedAttributes
|
8
|
+
# Documentation includes
|
9
|
+
# @!parse extend DerivedAttributes::ClassMethods
|
10
|
+
|
11
|
+
# module implementation
|
12
|
+
|
13
|
+
#
|
8
14
|
def self.included(base)
|
9
15
|
base.extend ClassMethods
|
10
16
|
end
|
11
17
|
|
12
18
|
#
|
13
|
-
#
|
19
|
+
# {DerivedAttributes} class methods
|
14
20
|
#
|
15
21
|
module ClassMethods
|
22
|
+
#
|
23
|
+
# retrieves first founded derived variable or nil
|
24
|
+
# @param name [Symbol] variable name (should contain `@` sign)
|
25
|
+
#
|
26
|
+
# @return [Object, nil] founded variable or nil
|
16
27
|
def get_derived(name)
|
17
28
|
return instance_variable_get(name) if instance_variable_defined?(name)
|
18
29
|
ancestors.each do |ancestor|
|
19
|
-
break if ancestor == Object
|
20
30
|
next unless ancestor.instance_variable_defined?(name)
|
31
|
+
break if ancestor == Base
|
21
32
|
return ancestor.instance_variable_get(name)
|
22
33
|
end
|
23
34
|
nil
|
24
35
|
end
|
25
36
|
|
37
|
+
#
|
38
|
+
# Collects all derived variables with specified name
|
39
|
+
# @param name [Symbol] variable name (should contain `@` sign)
|
40
|
+
# @param initial [Object] initial collection object
|
41
|
+
# @param method [Symbol] collection's method name to concatinate
|
42
|
+
# founded variable with collection
|
43
|
+
#
|
44
|
+
# @return [Object] collection of variables
|
26
45
|
def collect_derived(name, initial = [], method = :concat)
|
27
46
|
result = initial
|
28
|
-
# if instance_variable_defined?(name)
|
29
|
-
# result = result.send(method, instance_variable_get(name))
|
30
|
-
# end
|
31
47
|
ancestors.each do |ancestor|
|
32
|
-
break if ancestor == Object
|
33
48
|
next unless ancestor.instance_variable_defined?(name)
|
34
49
|
result = result.send(method, ancestor.instance_variable_get(name))
|
50
|
+
break if ancestor == Base
|
35
51
|
end
|
36
52
|
result
|
37
53
|
end
|
data/lib/wrap_it/enums.rb
CHANGED
@@ -5,47 +5,38 @@ module WrapIt
|
|
5
5
|
# @author Alexey Ovchinnikov <alexiss@cybernetlab.ru>
|
6
6
|
#
|
7
7
|
module Enums
|
8
|
+
# Documentation includes
|
9
|
+
# @!parse extend Enums::ClassMethods
|
10
|
+
|
11
|
+
# module implementation
|
12
|
+
|
8
13
|
extend DerivedAttributes
|
9
14
|
|
15
|
+
#
|
10
16
|
def self.included(base)
|
11
17
|
base == Base || fail(
|
12
18
|
TypeError,
|
13
19
|
"#{self.class.name} can be included only into WrapIt::Base"
|
14
20
|
)
|
15
|
-
base.
|
16
|
-
|
17
|
-
end
|
21
|
+
base.class_eval do
|
22
|
+
extend ClassMethods
|
18
23
|
|
19
|
-
|
24
|
+
before_initialize { @enums = {} }
|
20
25
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
names = [name] + [opts[:aliases] || []].flatten
|
27
|
-
opt_keys.select { |o| names.include? o }.each do |key|
|
28
|
-
tmp = @options.delete(key)
|
29
|
-
value ||= tmp
|
30
|
-
!value.nil? && !opts[:values].include?(value) && value = nil
|
31
|
-
end
|
32
|
-
@arguments.extract!(Symbol, and: [opts[:values]]).each do |key|
|
33
|
-
value ||= key
|
26
|
+
before_capture do
|
27
|
+
self.class.collect_derived(:@enums, {}, :merge).each do |name, e|
|
28
|
+
next unless e.key?(:default) && !@enums.key?(name)
|
29
|
+
send("#{name}=", e[:default])
|
30
|
+
end
|
34
31
|
end
|
35
|
-
send("#{name}=", value)
|
36
32
|
end
|
37
33
|
end
|
38
34
|
|
39
|
-
def enums
|
40
|
-
@enums_hash ||= self.class.collect_derived(:@enums, {}, :merge)
|
41
|
-
end
|
42
|
-
|
43
35
|
#
|
44
|
-
#
|
36
|
+
# {Enums} class methods
|
45
37
|
#
|
46
38
|
module ClassMethods
|
47
39
|
#
|
48
|
-
# @dsl
|
49
40
|
# Adds `enum`. When element created, creation arguments will be scanned
|
50
41
|
# for `Symbol`, that included contains in `values`. If it founded, enum
|
51
42
|
# takes this value. Also creation options inspected. If its contains
|
@@ -60,16 +51,26 @@ module WrapIt
|
|
60
51
|
#
|
61
52
|
# This method also adds getter and setter for this enum.
|
62
53
|
#
|
54
|
+
# @example
|
55
|
+
# class Button < WrapIt::Base
|
56
|
+
# enum :style, %i(red green black), html_class_prefix: 'btn-'
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
# btn = Button.new(template, :green)
|
60
|
+
# btn.render # => '<div class="btn-green">'
|
61
|
+
# btn = Button.new(template, style: :red)
|
62
|
+
# btn.render # => '<div class="btn-red">'
|
63
|
+
#
|
63
64
|
# @param name [String, Symbol] Enum name. Converted to `Symbol`.
|
64
|
-
# @param
|
65
|
-
# @
|
65
|
+
# @param opts [Hash] Enum options
|
66
|
+
# @option opts [String, Symbol] :html_class_prefix prefix of HTML
|
66
67
|
# class that will automatically added to element if enum changes its
|
67
68
|
# value.
|
68
|
-
# @
|
69
|
+
# @option opts [Boolean] :html_class whether this enum changes
|
69
70
|
# should affect to html class.
|
70
|
-
# @
|
71
|
+
# @option opts [Symbol, Array<Symbol>] :aliases list of enum aliases.
|
71
72
|
# Warning! Values are not converted - pass only `Symbols` here.
|
72
|
-
# @
|
73
|
+
# @option opts [String, Symbol] :default default value for enum,
|
73
74
|
# if nil or wrong value given. Converted to `Symbol`.
|
74
75
|
# @yield [value] Runs block when enum value changed, gives it to block.
|
75
76
|
# @yieldparam value [Symbol] New enum value.
|
@@ -90,25 +91,34 @@ module WrapIt
|
|
90
91
|
opts[:regexp] = /\A#{prefix}(?:#{values.join('|')})\z/
|
91
92
|
opts[:html_class_prefix] = prefix
|
92
93
|
end
|
93
|
-
define_method("#{name}") { @enums[name] }
|
94
|
+
define_method("#{name}") { @enums[name] ||= opts[:default] }
|
94
95
|
define_method("#{name}=", &Enums.setter(name, &block))
|
95
96
|
@enums ||= {}
|
97
|
+
|
98
|
+
o_params = {}
|
99
|
+
if opts.key?(:aliases)
|
100
|
+
aliases = [opts[:aliases]].flatten.compact
|
101
|
+
o_params[:if] = [name] + aliases
|
102
|
+
end
|
103
|
+
|
96
104
|
@enums[name] = opts
|
105
|
+
option(name, **o_params) { |_, v| send("#{name}=", v) }
|
106
|
+
argument(name, if: Symbol, and: values) { |_, v| send("#{name}=", v) }
|
97
107
|
end
|
98
108
|
end
|
99
109
|
|
100
110
|
private
|
101
111
|
|
102
112
|
def self.setter(name, &block)
|
103
|
-
|
104
|
-
opts = enums[name]
|
113
|
+
->(value) do
|
114
|
+
opts = self.class.collect_derived(:@enums, {}, :merge)[name]
|
105
115
|
v = value if opts[:values].include?(value)
|
106
116
|
v ||= opts[:default] if opts.key?(:default)
|
107
117
|
@enums[name] = v
|
108
118
|
block.nil? || instance_exec(v, &block)
|
109
119
|
if opts.key?(:regexp)
|
110
|
-
|
111
|
-
v.nil? ||
|
120
|
+
html_class.delete(opts[:regexp])
|
121
|
+
v.nil? || html_class << "#{opts[:html_class_prefix]}#{v}"
|
112
122
|
end
|
113
123
|
end
|
114
124
|
end
|
data/lib/wrap_it/frameworks.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
#
|
2
|
-
# Framework detection methods
|
3
|
-
#
|
4
1
|
module WrapIt
|
2
|
+
#
|
3
|
+
# Framework detection methods
|
4
|
+
#
|
5
|
+
|
6
|
+
# @private
|
5
7
|
def self.framework
|
6
8
|
return @framework unless @framework.nil?
|
7
9
|
gems = Gem.loaded_specs.keys
|
@@ -14,10 +16,12 @@ module WrapIt
|
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
19
|
+
# @private
|
17
20
|
def self.rails?
|
18
21
|
framework == :rails
|
19
22
|
end
|
20
23
|
|
24
|
+
# @private
|
21
25
|
def self.sinatra?
|
22
26
|
framework == :sinatra
|
23
27
|
end
|
data/lib/wrap_it/helpers.rb
CHANGED
@@ -1,9 +1,64 @@
|
|
1
1
|
#
|
2
|
-
#
|
2
|
+
# Registering helpers
|
3
|
+
#
|
4
|
+
# To use your classes and helpers in templates you should register your
|
5
|
+
# library. First, in your framework initialization, you should register
|
6
|
+
# your library in WrapIt. You can have separate module for it or WrapIt
|
7
|
+
# will make anonymous one. After this, your module will have `register`
|
8
|
+
# and `unregister` methods to register your classes.
|
9
|
+
#
|
10
|
+
# @example usual case - library in separate module
|
11
|
+
# # initialization time
|
12
|
+
# module Library
|
13
|
+
# module Helpers; end
|
14
|
+
# end
|
15
|
+
# WrapIt.register_module Library::Helpers, prefix: 'lib_'
|
16
|
+
#
|
17
|
+
# # controller
|
18
|
+
# class MyController < ApplicationController
|
19
|
+
# helper Library::Helpers
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# # implementation
|
23
|
+
# module Library
|
24
|
+
# module Helpers
|
25
|
+
# class Button < WrapIt::Base
|
26
|
+
# ...
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# register :super_button, Button
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# # in template:
|
34
|
+
# <%= lib_super_button 'text' %>
|
35
|
+
#
|
36
|
+
# @example anonymous module
|
37
|
+
# helpers = WrapIt.register_module prefix: 'lib_'
|
38
|
+
#
|
39
|
+
# class Button < WrapIt::Base
|
40
|
+
# ...
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# helpers.register :super_button, Button
|
44
|
+
#
|
45
|
+
# class MyController
|
46
|
+
# helper helpers
|
47
|
+
# end
|
3
48
|
#
|
4
49
|
# @author Alexey Ovchinnikov <alexiss@cybernetlab.ru>
|
5
50
|
#
|
6
51
|
module WrapIt
|
52
|
+
#
|
53
|
+
# Registers helpers module
|
54
|
+
#
|
55
|
+
# @overload register_module(mod = nil, opts = {})
|
56
|
+
# @param mod [Module] module for register. Anonymous module will be
|
57
|
+
# created if ommited.
|
58
|
+
# @param opts [Hash] options
|
59
|
+
# @option opts [String] :prefix prefix for helper methods
|
60
|
+
#
|
61
|
+
# @return [void]
|
7
62
|
def self.register_module(*args)
|
8
63
|
options = args.extract_options!
|
9
64
|
options.symbolize_keys!
|
@@ -17,6 +72,16 @@ module WrapIt
|
|
17
72
|
mod
|
18
73
|
end
|
19
74
|
|
75
|
+
# @!method register([name, ...], class_name)
|
76
|
+
# adds to template list of helpers for creating elements of specified class
|
77
|
+
# @param name [Symbol, String] name of helper. Will be prefixed with prefix
|
78
|
+
# option, specified in {WrapIt#register_module} call.
|
79
|
+
# @param class_name [String, Class] element class
|
80
|
+
|
81
|
+
# @!method unregister([name, ...])
|
82
|
+
# removes list of helpers from template
|
83
|
+
# @param name [Symbol, String] name of helper to remove from tampate
|
84
|
+
|
20
85
|
private
|
21
86
|
|
22
87
|
def self.register_block(options)
|
data/lib/wrap_it/html.rb
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
require File.join %w(wrap_it html_class)
|
2
|
+
require File.join %w(wrap_it html_data)
|
3
|
+
|
4
|
+
module WrapIt
|
5
|
+
#
|
6
|
+
# Methods for manipulationg with HTML class. For internal usage.
|
7
|
+
# You should not include this class directly - subclass from
|
8
|
+
# `WrapIt::Base` instead.
|
9
|
+
#
|
10
|
+
# @author Alexey Ovchinnikov <alexiss@cybernetlab.ru>
|
11
|
+
#
|
12
|
+
module HTML
|
13
|
+
# Documentation includes
|
14
|
+
# @!parse extend HTML::ClassMethods
|
15
|
+
|
16
|
+
# module implementation
|
17
|
+
|
18
|
+
extend DerivedAttributes
|
19
|
+
|
20
|
+
#
|
21
|
+
def self.included(base)
|
22
|
+
base == Base || fail(
|
23
|
+
TypeError,
|
24
|
+
"#{self.class.name} can be included only into WrapIt::Base"
|
25
|
+
)
|
26
|
+
base.class_eval do
|
27
|
+
extend ClassMethods
|
28
|
+
|
29
|
+
option(:class) { |_, v| self.html_class << v }
|
30
|
+
|
31
|
+
# TODO: extend hashes for html_attr and html_data
|
32
|
+
before_initialize do
|
33
|
+
html_class
|
34
|
+
@html_attr ||= {}
|
35
|
+
@html_data ||= {}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# TODO: actually we should have separate setter and merge (see Base)
|
41
|
+
#
|
42
|
+
# Sets HTML attributes hash.
|
43
|
+
#
|
44
|
+
# Actually it merges its with current
|
45
|
+
# attributes. To remove some attributes use `html_attr.delete(:attr)`.
|
46
|
+
# extracts HTML class and data from provided hash and places its to
|
47
|
+
# appropriate holder
|
48
|
+
#
|
49
|
+
# @param hash [Hash] attributes
|
50
|
+
#
|
51
|
+
# @return [Hash] resulting attributes
|
52
|
+
def html_attr=(hash)
|
53
|
+
return unless hash.is_a?(Hash)
|
54
|
+
hash.symbolize_keys!
|
55
|
+
html_class << hash.delete(:class)
|
56
|
+
html_data.merge(hash.delete(:data) || {})
|
57
|
+
(@html_attr ||= {}).merge!(hash)
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Retrieves HTML attributes hash (without HTML class and HTML data)
|
62
|
+
#
|
63
|
+
# @return [Hash] attributes
|
64
|
+
def html_attr
|
65
|
+
@html_attr ||= {}
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# Retrieves HTML data hash
|
70
|
+
#
|
71
|
+
# @return [Hash] data
|
72
|
+
def html_data
|
73
|
+
@html_data ||= {}
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# HTML class prefix getter
|
78
|
+
#
|
79
|
+
# This prefix used in enums to combine HTML classes.
|
80
|
+
#
|
81
|
+
# @return [String] HTML class prefix.
|
82
|
+
def html_class_prefix
|
83
|
+
@html_class_prefix ||= self.class.html_class_prefix
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
# Sets HTML class(es) for element
|
88
|
+
#
|
89
|
+
# @example
|
90
|
+
# element.html_class = [:a, 'b', ['c', :d, 'a']]
|
91
|
+
# element.html_class #=> ['a', 'b', 'c', 'd']
|
92
|
+
#
|
93
|
+
# @param value [Symbol, String, Array<Symbol, String>] HTML class or list
|
94
|
+
# of classes. All classes will be converted to Strings, duplicates are
|
95
|
+
# removed. Refer to {HTMLClass} description for details.
|
96
|
+
# @return [HTMLClass] resulting html class
|
97
|
+
def html_class=(value)
|
98
|
+
@html_class = HTMLClass.new(value)
|
99
|
+
end
|
100
|
+
|
101
|
+
#
|
102
|
+
# Retrieves HTML class of element
|
103
|
+
#
|
104
|
+
# See {HTMLClass} for details
|
105
|
+
#
|
106
|
+
# @return [HTMLClass] HTML class of element
|
107
|
+
def html_class
|
108
|
+
@html_class ||= HTMLClass.new
|
109
|
+
end
|
110
|
+
|
111
|
+
protected
|
112
|
+
|
113
|
+
def add_default_classes
|
114
|
+
html_class << self.class.collect_derived(
|
115
|
+
:@html_class, HTMLClass.new, :<<
|
116
|
+
)
|
117
|
+
end
|
118
|
+
|
119
|
+
#
|
120
|
+
# {HTML} class methods
|
121
|
+
#
|
122
|
+
module ClassMethods
|
123
|
+
#
|
124
|
+
# Adds default html classes, thats are automatically added when element
|
125
|
+
# created.
|
126
|
+
# @overload html_class([html_class, ...])
|
127
|
+
# @param html_class [String, Symbol, Array<String, Symbol>] HTML class.
|
128
|
+
# Converted to `String`
|
129
|
+
#
|
130
|
+
# @return [void]
|
131
|
+
def html_class(*args)
|
132
|
+
(@html_class ||= HTMLClass.new) << args
|
133
|
+
end
|
134
|
+
|
135
|
+
#
|
136
|
+
# Sets HTML class prefix. It used in switchers and enums
|
137
|
+
# @param prefix [String] HTML class prefix
|
138
|
+
#
|
139
|
+
# @return [void]
|
140
|
+
def html_class_prefix(prefix = nil)
|
141
|
+
return(get_derived(:@html_class_prefix) || '') if prefix.nil?
|
142
|
+
prefix.is_a?(Symbol) && prefix = prefix.to_s
|
143
|
+
prefix.is_a?(String) || fail(ArgumentError,
|
144
|
+
'prefix should be a String or Symbol')
|
145
|
+
@html_class_prefix = prefix
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|