pakyow-ui 0.10.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.
@@ -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: []