pakyow-ui 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,112 @@
1
+ module Pakyow
2
+ module UI
3
+ # Helper methods for instructable objects.
4
+ #
5
+ # @api private
6
+ module Instructable
7
+ def self.included(klass)
8
+ (@instructables ||= []) << klass
9
+ end
10
+
11
+ def self.instructable?(object)
12
+ @instructables.select { |i|
13
+ object.is_a?(i)
14
+ }.any?
15
+ end
16
+
17
+ attr_reader :instructions
18
+ attr_accessor :root
19
+
20
+ def initialize
21
+ @instructions = []
22
+ end
23
+
24
+ def instruct(method, data)
25
+ @instructions << [clean_method(method), hashify(data)]
26
+ self
27
+ end
28
+
29
+ def nested_instruct(method, data, scope = nil)
30
+ view = nested_instruct_object(method, data, scope)
31
+ view.root = self
32
+
33
+ @instructions << [clean_method(method), hashify(data), view]
34
+ view
35
+ end
36
+
37
+ # Returns an instruction set for all view transformations.
38
+ #
39
+ # e.g. a value-less transformation:
40
+ # [[:remove, nil]]
41
+ #
42
+ # e.g. a transformation with a value:
43
+ # [[:text=, 'foo']]
44
+ #
45
+ # e.g. a nested transformation
46
+ # [[:scope, :post, [[:remove, nil]]]]
47
+ def finalize
48
+ @instructions.map { |instruction|
49
+ if Instructable.instructable?(instruction[2])
50
+ instruction[2] = instruction[2].finalize
51
+ end
52
+
53
+ instruction
54
+ }
55
+ end
56
+
57
+ private
58
+
59
+ def mixin_bindings(data, bindings = {})
60
+ data.map { |bindable|
61
+ datum = bindable.to_hash
62
+ Pakyow::Presenter::Binder.instance.bindings_for_scope(scoped_as, bindings).keys.each do |key|
63
+ result = Pakyow::Presenter::Binder.instance.value_for_scoped_prop(scoped_as, key, bindable, bindings, self)
64
+
65
+ if result.is_a?(Hash)
66
+ # we don't currently support view manipulations that occur in bindings
67
+ # TODO: look into what it would take to support this
68
+ result.delete(:view)
69
+
70
+ datum[key] = {
71
+ __content: result.delete(:content),
72
+ __attrs: Hash[*result.flat_map { |k, v|
73
+ if v.respond_to?(:to_proc)
74
+ attrs = UIAttrs.new
75
+ v.call(attrs)
76
+ [k, attrs.finalize]
77
+ else
78
+ [k, v]
79
+ end
80
+ }]
81
+ }
82
+ else
83
+ datum[key] = result
84
+ end
85
+ end
86
+
87
+ datum
88
+ }
89
+ end
90
+
91
+ def hashify(data)
92
+ return hashify_datum(data) unless data.is_a?(Array)
93
+
94
+ data.map { |datum|
95
+ hashify_datum(datum)
96
+ }
97
+ end
98
+
99
+ def hashify_datum(datum)
100
+ if datum.respond_to?(:to_hash)
101
+ datum.to_hash
102
+ else
103
+ datum
104
+ end
105
+ end
106
+
107
+ def clean_method(method)
108
+ method.to_s.delete('=').to_sym
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,179 @@
1
+ require_relative 'ui_attrs'
2
+ require_relative 'ui_instructable'
3
+
4
+ module Pakyow
5
+ module UI
6
+ # Translates view transformations to instructions.
7
+ #
8
+ # @api private
9
+ class UIView
10
+ include Instructable
11
+
12
+ def initialize(scope)
13
+ super()
14
+ @scope = scope
15
+ end
16
+
17
+ def nested_instruct_object(_method, _data, scope)
18
+ UIView.new(scope || @scope)
19
+ end
20
+
21
+ def scoped_as
22
+ @scope
23
+ end
24
+
25
+ def attrs_instruct
26
+ attrs = UIAttrs.new
27
+ @instructions << [:attrs, nil, attrs]
28
+ attrs
29
+ end
30
+
31
+ ### view methods w/o args
32
+
33
+ %i(
34
+ remove
35
+ clear
36
+ ).each do |method|
37
+ define_method method do
38
+ instruct(method, nil)
39
+ end
40
+ end
41
+
42
+ ### view methods w/ args
43
+
44
+ %i(
45
+ title=
46
+ text=
47
+ html=
48
+ append
49
+ prepend
50
+ after
51
+ before
52
+ replace
53
+ ).each do |method|
54
+ define_method method do |value|
55
+ instruct(method, value.to_s)
56
+ end
57
+ end
58
+
59
+ ### misc view methods
60
+
61
+ def with(&block)
62
+ if block.arity == 0
63
+ instance_exec(&block)
64
+ else
65
+ yield(self)
66
+ end
67
+
68
+ self
69
+ end
70
+
71
+ def match(data)
72
+ instruct(:match, Array.ensure(data))
73
+ end
74
+
75
+ def scope(name)
76
+ nested_instruct(:scope, name.to_s, name)
77
+ end
78
+
79
+ def attrs
80
+ attrs_instruct
81
+ end
82
+
83
+ ### view methods that change context
84
+
85
+ %i(
86
+ prop
87
+ component
88
+ ).each do |method|
89
+ define_method method do |value|
90
+ nested_instruct(method, value.to_s)
91
+ end
92
+ end
93
+
94
+ ### view methods that continue into a new context
95
+
96
+ def for(data, &block)
97
+ nested = nested_instruct(:for, data)
98
+ Array.ensure(data).each do |datum|
99
+ sub = UIView.new(@scope)
100
+
101
+ if block.arity == 1
102
+ sub.instance_exec(datum, &block)
103
+ else
104
+ block.call(sub, datum)
105
+ end
106
+
107
+ nested.instructions << sub.finalize
108
+ end
109
+ end
110
+
111
+ def for_with_index(*args, &block)
112
+ self.for(*args, &block)
113
+ end
114
+
115
+ def repeat(data, &block)
116
+ nested = nested_instruct(:repeat, data)
117
+ Array.ensure(data).each do |datum|
118
+ sub = UIView.new(@scope)
119
+
120
+ if block.arity == 1
121
+ sub.instance_exec(datum, &block)
122
+ else
123
+ block.call(sub, datum)
124
+ end
125
+
126
+ nested.instructions << sub.finalize
127
+ end
128
+ end
129
+
130
+ def repeat_with_index(*args, &block)
131
+ repeat(*args, &block)
132
+ end
133
+
134
+ def bind(data, bindings: {}, context: nil, &block)
135
+ # TODO: handle context?
136
+
137
+ data = mixin_bindings(Array.ensure(data), bindings)
138
+ nested = nested_instruct(:bind, data)
139
+ return self unless block_given?
140
+
141
+ data.each do |datum|
142
+ sub = UIView.new(@scope)
143
+
144
+ if block.arity == 1
145
+ sub.instance_exec(datum, &block)
146
+ else
147
+ block.call(sub, datum)
148
+ end
149
+
150
+ nested.instructions << sub.finalize
151
+ end
152
+ end
153
+
154
+ def bind_with_index(*args, &block)
155
+ bind(*args, &block)
156
+ end
157
+
158
+ def apply(data, bindings: {}, context: nil, &block)
159
+ # TODO: handle context?
160
+
161
+ data = mixin_bindings(Array.ensure(data), bindings)
162
+ nested = nested_instruct(:apply, data)
163
+ return self unless block_given?
164
+
165
+ data.each do |datum|
166
+ sub = UIView.new(@scope)
167
+
168
+ if block.arity == 1
169
+ sub.instance_exec(datum, &block)
170
+ else
171
+ block.call(sub, datum)
172
+ end
173
+
174
+ nested.instructions << sub.finalize
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1 @@
1
+ require_relative 'pakyow-ui/base'
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pakyow-ui
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.10.0
5
+ platform: ruby
6
+ authors:
7
+ - Bryan Powell
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pakyow-support
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.10.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.10.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: pakyow-core
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 0.10.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 0.10.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: pakyow-presenter
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 0.10.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 0.10.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: pakyow-realtime
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.10.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 0.10.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '5.6'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '5.6'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.2'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.2'
97
+ description: Auto-Updating UIs for Pakyow
98
+ email: bryan@metabahn.com
99
+ executables: []
100
+ extensions: []
101
+ extra_rdoc_files: []
102
+ files:
103
+ - pakyow-ui/CHANGELOG.md
104
+ - pakyow-ui/LICENSE
105
+ - pakyow-ui/README.md
106
+ - pakyow-ui/lib/pakyow-ui.rb
107
+ - pakyow-ui/lib/pakyow-ui/base.rb
108
+ - pakyow-ui/lib/pakyow-ui/channel_builder.rb
109
+ - pakyow-ui/lib/pakyow-ui/config.rb
110
+ - pakyow-ui/lib/pakyow-ui/ext/app.rb
111
+ - pakyow-ui/lib/pakyow-ui/ext/app_context.rb
112
+ - pakyow-ui/lib/pakyow-ui/ext/view_context.rb
113
+ - pakyow-ui/lib/pakyow-ui/fetch_view_handler.rb
114
+ - pakyow-ui/lib/pakyow-ui/helpers.rb
115
+ - pakyow-ui/lib/pakyow-ui/mock_mutation_eval.rb
116
+ - pakyow-ui/lib/pakyow-ui/mutable.rb
117
+ - pakyow-ui/lib/pakyow-ui/mutable_data.rb
118
+ - pakyow-ui/lib/pakyow-ui/mutate_context.rb
119
+ - pakyow-ui/lib/pakyow-ui/mutation_set.rb
120
+ - pakyow-ui/lib/pakyow-ui/mutation_store.rb
121
+ - pakyow-ui/lib/pakyow-ui/mutator.rb
122
+ - pakyow-ui/lib/pakyow-ui/no_op_view.rb
123
+ - pakyow-ui/lib/pakyow-ui/registries/redis_mutation_registry.rb
124
+ - pakyow-ui/lib/pakyow-ui/registries/simple_mutation_registry.rb
125
+ - pakyow-ui/lib/pakyow-ui/ui.rb
126
+ - pakyow-ui/lib/pakyow-ui/ui_attrs.rb
127
+ - pakyow-ui/lib/pakyow-ui/ui_component.rb
128
+ - pakyow-ui/lib/pakyow-ui/ui_instructable.rb
129
+ - pakyow-ui/lib/pakyow-ui/ui_view.rb
130
+ homepage: http://pakyow.org
131
+ licenses:
132
+ - MIT
133
+ metadata: {}
134
+ post_install_message:
135
+ rdoc_options: []
136
+ require_paths:
137
+ - pakyow-ui/lib
138
+ required_ruby_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: 2.0.0
143
+ required_rubygems_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ requirements: []
149
+ rubyforge_project:
150
+ rubygems_version: 2.4.5
151
+ signing_key:
152
+ specification_version: 4
153
+ summary: Pakyow UI
154
+ test_files: []