pakyow-presenter 0.11.3 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/{pakyow-presenter/CHANGELOG.md → CHANGELOG.md} +0 -5
- data/LICENSE +4 -0
- data/{pakyow-presenter/README.md → README.md} +1 -2
- data/lib/pakyow/generators/presenter/presenter_generator.rb +28 -0
- data/lib/pakyow/generators/presenter/templates/presenter.rb.tt +2 -0
- data/lib/pakyow/plugin/helpers/rendering.rb +19 -0
- data/lib/pakyow/presenter/actions/auto_render.rb +15 -0
- data/lib/pakyow/presenter/attributes/attribute.rb +22 -0
- data/lib/pakyow/presenter/attributes/boolean.rb +24 -0
- data/lib/pakyow/presenter/attributes/hash.rb +89 -0
- data/lib/pakyow/presenter/attributes/set.rb +61 -0
- data/lib/pakyow/presenter/attributes/string.rb +38 -0
- data/lib/pakyow/presenter/attributes.rb +126 -0
- data/lib/pakyow/presenter/behavior/config.rb +29 -0
- data/lib/pakyow/presenter/behavior/error_rendering.rb +124 -0
- data/lib/pakyow/presenter/behavior/exposures.rb +29 -0
- data/lib/pakyow/presenter/behavior/implicit_rendering.rb +21 -0
- data/lib/pakyow/presenter/behavior/initializing.rb +37 -0
- data/lib/pakyow/presenter/behavior/modes.rb +117 -0
- data/lib/pakyow/presenter/behavior/versions.rb +71 -0
- data/lib/pakyow/presenter/behavior/watching.rb +21 -0
- data/lib/pakyow/presenter/binder.rb +115 -0
- data/lib/pakyow/presenter/binding_parts.rb +64 -0
- data/lib/pakyow/presenter/component.rb +74 -0
- data/lib/pakyow/presenter/composers/component.rb +78 -0
- data/lib/pakyow/presenter/composers/view.rb +73 -0
- data/lib/pakyow/presenter/errors.rb +63 -0
- data/lib/pakyow/presenter/framework.rb +203 -0
- data/lib/pakyow/presenter/front_matter_parser.rb +42 -0
- data/lib/pakyow/presenter/helpers/rendering.rb +18 -0
- data/lib/pakyow/presenter/presentable.rb +28 -0
- data/lib/pakyow/presenter/presentable_error.rb +19 -0
- data/lib/pakyow/presenter/presenter.rb +766 -0
- data/lib/pakyow/presenter/presenters/endpoint.rb +158 -0
- data/lib/pakyow/presenter/presenters/form.rb +522 -0
- data/lib/pakyow/presenter/processor.rb +61 -0
- data/lib/pakyow/presenter/renderable.rb +28 -0
- data/lib/pakyow/presenter/renderer.rb +269 -0
- data/lib/pakyow/presenter/rendering/actions/cleanup_prototype_nodes.rb +21 -0
- data/lib/pakyow/presenter/rendering/actions/cleanup_unbound_bindings.rb +35 -0
- data/lib/pakyow/presenter/rendering/actions/create_template_nodes.rb +27 -0
- data/lib/pakyow/presenter/rendering/actions/insert_prototype_bar.rb +101 -0
- data/lib/pakyow/presenter/rendering/actions/install_authenticity.rb +42 -0
- data/lib/pakyow/presenter/rendering/actions/place_in_mode.rb +56 -0
- data/lib/pakyow/presenter/rendering/actions/render_components.rb +279 -0
- data/lib/pakyow/presenter/rendering/actions/set_page_title.rb +35 -0
- data/lib/pakyow/presenter/rendering/actions/setup_endpoints.rb +62 -0
- data/lib/pakyow/presenter/rendering/actions/setup_forms.rb +174 -0
- data/lib/pakyow/presenter/significant_nodes.rb +309 -0
- data/lib/pakyow/presenter/templates.rb +229 -0
- data/lib/pakyow/presenter/versioned_view.rb +209 -0
- data/lib/pakyow/presenter/view.rb +586 -0
- data/lib/pakyow/presenter/views/form.rb +58 -0
- data/lib/pakyow/presenter/views/layout.rb +32 -0
- data/lib/pakyow/presenter/views/page.rb +72 -0
- data/lib/pakyow/presenter/views/partial.rb +28 -0
- data/lib/pakyow/presenter.rb +33 -0
- data/lib/pakyow/views/errors/layouts/development_error.html +102 -0
- data/lib/pakyow/views/errors/layouts/production_error.html +27 -0
- data/lib/pakyow/views/errors/pages/404.html +12 -0
- data/lib/pakyow/views/errors/pages/500.html +12 -0
- data/lib/pakyow/views/errors/pages/development/500.html +39 -0
- data/lib/string_doc/attributes.rb +109 -0
- data/lib/string_doc/meta_attributes.rb +48 -0
- data/lib/string_doc/meta_node.rb +328 -0
- data/lib/string_doc/node.rb +377 -0
- data/lib/string_doc.rb +642 -0
- metadata +95 -75
- data/pakyow-presenter/LICENSE +0 -20
- data/pakyow-presenter/lib/pakyow/presenter/attributes.rb +0 -228
- data/pakyow-presenter/lib/pakyow/presenter/base.rb +0 -38
- data/pakyow-presenter/lib/pakyow/presenter/binder.rb +0 -116
- data/pakyow-presenter/lib/pakyow/presenter/binder_set.rb +0 -94
- data/pakyow-presenter/lib/pakyow/presenter/binding_eval.rb +0 -37
- data/pakyow-presenter/lib/pakyow/presenter/config/presenter.rb +0 -42
- data/pakyow-presenter/lib/pakyow/presenter/container.rb +0 -6
- data/pakyow-presenter/lib/pakyow/presenter/doc_helpers.rb +0 -17
- data/pakyow-presenter/lib/pakyow/presenter/exceptions.rb +0 -11
- data/pakyow-presenter/lib/pakyow/presenter/ext/app.rb +0 -33
- data/pakyow-presenter/lib/pakyow/presenter/ext/call_context.rb +0 -28
- data/pakyow-presenter/lib/pakyow/presenter/helpers.rb +0 -46
- data/pakyow-presenter/lib/pakyow/presenter/page.rb +0 -110
- data/pakyow-presenter/lib/pakyow/presenter/partial.rb +0 -6
- data/pakyow-presenter/lib/pakyow/presenter/presenter.rb +0 -232
- data/pakyow-presenter/lib/pakyow/presenter/string_doc.rb +0 -380
- data/pakyow-presenter/lib/pakyow/presenter/string_doc_parser.rb +0 -144
- data/pakyow-presenter/lib/pakyow/presenter/string_doc_renderer.rb +0 -18
- data/pakyow-presenter/lib/pakyow/presenter/template.rb +0 -51
- data/pakyow-presenter/lib/pakyow/presenter/view.rb +0 -541
- data/pakyow-presenter/lib/pakyow/presenter/view_collection.rb +0 -330
- data/pakyow-presenter/lib/pakyow/presenter/view_composer.rb +0 -237
- data/pakyow-presenter/lib/pakyow/presenter/view_context.rb +0 -111
- data/pakyow-presenter/lib/pakyow/presenter/view_store.rb +0 -262
- data/pakyow-presenter/lib/pakyow/presenter/view_store_loader.rb +0 -43
- data/pakyow-presenter/lib/pakyow/presenter/view_version.rb +0 -113
- data/pakyow-presenter/lib/pakyow/presenter.rb +0 -8
- data/pakyow-presenter/lib/pakyow/views/errors/404.erb +0 -26
- data/pakyow-presenter/lib/pakyow/views/errors/500.erb +0 -23
- data/pakyow-presenter/lib/pakyow-presenter.rb +0 -1
@@ -1,380 +0,0 @@
|
|
1
|
-
module Pakyow
|
2
|
-
module Presenter
|
3
|
-
class StringDoc
|
4
|
-
attr_reader :structure
|
5
|
-
|
6
|
-
TITLE_REGEX = /<title>(.*?)<\/title>/m
|
7
|
-
|
8
|
-
def initialize(html)
|
9
|
-
@structure = StringDocParser.new(html).structure
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.from_structure(structure, node: nil)
|
13
|
-
instance = allocate
|
14
|
-
instance.instance_variable_set(:@structure, structure)
|
15
|
-
instance.instance_variable_set(:@node, node)
|
16
|
-
return instance
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.ensure(object)
|
20
|
-
return object if object.is_a?(StringDoc)
|
21
|
-
StringDoc.new(object)
|
22
|
-
end
|
23
|
-
|
24
|
-
def initialize_copy(original_doc)
|
25
|
-
super
|
26
|
-
|
27
|
-
if original_structure = original_doc.instance_variable_get(:@structure)
|
28
|
-
@structure = Utils::Dup.deep(original_structure)
|
29
|
-
end
|
30
|
-
|
31
|
-
if original_doc.node?
|
32
|
-
@node = @structure[original_doc.node_index]
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# Creates a StringDoc instance with the same structure, but a duped node.
|
37
|
-
#
|
38
|
-
def soft_copy
|
39
|
-
StringDoc.from_structure(@structure, node: @node ? Utils::Dup.deep(@node) : nil)
|
40
|
-
end
|
41
|
-
|
42
|
-
def title
|
43
|
-
title_search do |n, match|
|
44
|
-
return match[1]
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def title=(title)
|
49
|
-
title_search do |n, match|
|
50
|
-
n.gsub!(TITLE_REGEX, "<title>#{title}</title>")
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def attribute?(name)
|
55
|
-
attributes.key?(name.to_sym)
|
56
|
-
end
|
57
|
-
|
58
|
-
def set_attribute(name, value)
|
59
|
-
return if attributes.nil?
|
60
|
-
attributes[name.to_sym] = value
|
61
|
-
end
|
62
|
-
alias :update_attribute :set_attribute
|
63
|
-
|
64
|
-
def get_attribute(name)
|
65
|
-
attributes[name.to_sym]
|
66
|
-
end
|
67
|
-
|
68
|
-
def remove_attribute(name)
|
69
|
-
attributes.delete(name.to_sym)
|
70
|
-
end
|
71
|
-
|
72
|
-
def has_attribute?(name)
|
73
|
-
attributes.key?(name)
|
74
|
-
end
|
75
|
-
|
76
|
-
def remove
|
77
|
-
@structure.delete_if { |n| n.equal?(node) }
|
78
|
-
|
79
|
-
if @node.nil?
|
80
|
-
@node = ['', {}, [['', {}, []]]]
|
81
|
-
else
|
82
|
-
@node[0] = ''
|
83
|
-
@node[1] = {}
|
84
|
-
@node[2][0][0] = ''
|
85
|
-
@node[2][0][1] = {}
|
86
|
-
@node[2][0][2] = []
|
87
|
-
@node[2].slice!(1..-1)
|
88
|
-
end
|
89
|
-
|
90
|
-
@removed = true
|
91
|
-
end
|
92
|
-
|
93
|
-
def clear
|
94
|
-
children.clear
|
95
|
-
end
|
96
|
-
|
97
|
-
def text
|
98
|
-
html.gsub(/<[^>]*>/, '')
|
99
|
-
end
|
100
|
-
|
101
|
-
def text=(text)
|
102
|
-
clear
|
103
|
-
children << [text, {}, []]
|
104
|
-
end
|
105
|
-
|
106
|
-
def html
|
107
|
-
StringDocRenderer.render(children)
|
108
|
-
end
|
109
|
-
|
110
|
-
def html=(html)
|
111
|
-
clear
|
112
|
-
children << [html, {}, []]
|
113
|
-
end
|
114
|
-
|
115
|
-
def append(doc)
|
116
|
-
doc = StringDoc.ensure(doc)
|
117
|
-
|
118
|
-
if doc.node?
|
119
|
-
children.push(doc.node)
|
120
|
-
else
|
121
|
-
children.concat(doc.structure)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
def prepend(doc)
|
126
|
-
doc = StringDoc.ensure(doc)
|
127
|
-
|
128
|
-
if doc.node?
|
129
|
-
children.unshift(doc.node)
|
130
|
-
else
|
131
|
-
children.unshift(*doc.structure)
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
def after(doc)
|
136
|
-
doc = StringDoc.ensure(doc)
|
137
|
-
|
138
|
-
if doc.node?
|
139
|
-
@structure.insert(node_index + 1, doc.node)
|
140
|
-
else
|
141
|
-
@structure.concat(doc.structure)
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
def before(doc)
|
146
|
-
doc = StringDoc.ensure(doc)
|
147
|
-
|
148
|
-
if doc.node?
|
149
|
-
@structure.unshift(doc.node)
|
150
|
-
else
|
151
|
-
@structure.unshift(*doc.structure)
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
def replace(doc)
|
156
|
-
doc = StringDoc.ensure(doc)
|
157
|
-
index = node_index || 0
|
158
|
-
|
159
|
-
if doc.node?
|
160
|
-
@structure.insert(index + 1, node)
|
161
|
-
else
|
162
|
-
@structure.insert(index + 1, *doc.structure)
|
163
|
-
end
|
164
|
-
|
165
|
-
@structure.delete_at(index)
|
166
|
-
end
|
167
|
-
|
168
|
-
def scope(scope_name)
|
169
|
-
scopes.select { |b| b[:scope] == scope_name }
|
170
|
-
end
|
171
|
-
|
172
|
-
def prop(scope_name, prop_name)
|
173
|
-
return [] unless scope = scopes.select { |s| s[:scope] == scope_name }[0]
|
174
|
-
scope[:props].select { |p| p[:prop] == prop_name }
|
175
|
-
end
|
176
|
-
|
177
|
-
def container(name)
|
178
|
-
containers.fetch(name, {})[:doc]
|
179
|
-
end
|
180
|
-
|
181
|
-
def component(name)
|
182
|
-
components.select { |c| c[:component] == name }
|
183
|
-
end
|
184
|
-
|
185
|
-
def channel(name)
|
186
|
-
find_channel(scopes, name)
|
187
|
-
end
|
188
|
-
|
189
|
-
def containers
|
190
|
-
find_containers(@node ? [@node] : @structure)
|
191
|
-
end
|
192
|
-
|
193
|
-
def partials
|
194
|
-
find_partials(@node ? [@node] : @structure)
|
195
|
-
end
|
196
|
-
|
197
|
-
def scopes
|
198
|
-
find_scopes(@node ? [@node] : @structure)
|
199
|
-
end
|
200
|
-
|
201
|
-
def components
|
202
|
-
find_components(@node ? [@node] : @structure)
|
203
|
-
end
|
204
|
-
|
205
|
-
def to_html
|
206
|
-
StringDocRenderer.render((@node && !@removed) ? [@node] : @structure)
|
207
|
-
StringDocRenderer.render(@node ? [@node] : @structure)
|
208
|
-
end
|
209
|
-
alias :to_s :to_html
|
210
|
-
|
211
|
-
def ==(o)
|
212
|
-
#TODO do this without rendering?
|
213
|
-
# (at least in the case of comparing StringDoc to StringDoc)
|
214
|
-
to_s == o.to_s
|
215
|
-
end
|
216
|
-
|
217
|
-
def node
|
218
|
-
return @structure if @structure.empty? && !@removed
|
219
|
-
return @node || @structure[0]
|
220
|
-
end
|
221
|
-
|
222
|
-
def node_index
|
223
|
-
return nil unless node?
|
224
|
-
@structure.index { |n| n.equal?(@node) }
|
225
|
-
end
|
226
|
-
|
227
|
-
def node?
|
228
|
-
return false if @node.nil?
|
229
|
-
return false if @removed
|
230
|
-
return true
|
231
|
-
end
|
232
|
-
|
233
|
-
def tagname
|
234
|
-
node[0].gsub(/[^a-zA-Z]/, '')
|
235
|
-
end
|
236
|
-
|
237
|
-
def option(value: nil)
|
238
|
-
StringDoc.from_structure(node[2][0][2].select { |option|
|
239
|
-
option[1][:value] == value.to_s
|
240
|
-
})
|
241
|
-
end
|
242
|
-
|
243
|
-
def exists?
|
244
|
-
@structure.include?(node)
|
245
|
-
end
|
246
|
-
|
247
|
-
private
|
248
|
-
|
249
|
-
def title_search
|
250
|
-
@structure.flatten.each do |n|
|
251
|
-
next unless n.is_a?(String)
|
252
|
-
if match = n.match(TITLE_REGEX)
|
253
|
-
yield n, match
|
254
|
-
end
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
# Returns the structure representing the attributes for the node
|
259
|
-
#
|
260
|
-
def attributes
|
261
|
-
node[1]
|
262
|
-
end
|
263
|
-
|
264
|
-
def children
|
265
|
-
if @structure.empty? && !@removed
|
266
|
-
@structure
|
267
|
-
else
|
268
|
-
node[2][0][2]
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
|
-
def find_containers(structure, primary_structure = @structure, containers = {})
|
273
|
-
return {} if structure.empty?
|
274
|
-
structure.inject(containers) { |s, e|
|
275
|
-
if e[1].has_key?(:container)
|
276
|
-
s[e[1][:container]] = { doc: StringDoc.from_structure(primary_structure, node: e) }
|
277
|
-
end
|
278
|
-
find_containers(e[2], e[2], s)
|
279
|
-
s
|
280
|
-
} || {}
|
281
|
-
end
|
282
|
-
|
283
|
-
def find_partials(structure, primary_structure = @structure, partials = {})
|
284
|
-
structure.inject(partials) { |s, e|
|
285
|
-
if e[1].has_key?(:partial)
|
286
|
-
(s[e[1][:partial]] ||= []) << StringDoc.from_structure(primary_structure, node: e)
|
287
|
-
end
|
288
|
-
find_partials(e[2], e[2], s)
|
289
|
-
s
|
290
|
-
} || {}
|
291
|
-
end
|
292
|
-
|
293
|
-
def find_scopes(structure, primary_structure = @structure, scopes = [])
|
294
|
-
ret_scopes = structure.inject(scopes) { |s, e|
|
295
|
-
if e[1].has_key?(:'data-scope')
|
296
|
-
scope = {
|
297
|
-
doc: StringDoc.from_structure(primary_structure, node: e),
|
298
|
-
scope: e[1][:'data-scope'].to_sym,
|
299
|
-
props: find_node_props(e).concat(find_props(e[2])),
|
300
|
-
nested: find_scopes(e[2]),
|
301
|
-
}
|
302
|
-
|
303
|
-
if version = e[1][:'data-version']
|
304
|
-
scope[:version] = version.to_sym
|
305
|
-
end
|
306
|
-
|
307
|
-
s << scope
|
308
|
-
end
|
309
|
-
# only find scopes if `e` is the root node or we're not decending into a nested scope
|
310
|
-
find_scopes(e[2], e[2], s) if e == node || !e[1].has_key?(:'data-scope')
|
311
|
-
s
|
312
|
-
} || []
|
313
|
-
|
314
|
-
ret_scopes
|
315
|
-
end
|
316
|
-
|
317
|
-
def find_props(structure, primary_structure = @structure, props = [])
|
318
|
-
structure.each do |e|
|
319
|
-
find_node_props(e, primary_structure, props)
|
320
|
-
end
|
321
|
-
|
322
|
-
props || []
|
323
|
-
end
|
324
|
-
|
325
|
-
def find_node_props(node, primary_structure = @structure, props = [])
|
326
|
-
if node[1].has_key?(:'data-prop')
|
327
|
-
prop = {
|
328
|
-
doc: StringDoc.from_structure(primary_structure, node: node),
|
329
|
-
prop: node[1][:'data-prop'].to_sym,
|
330
|
-
parts: {},
|
331
|
-
}
|
332
|
-
|
333
|
-
if node[1].has_key?(:'data-parts')
|
334
|
-
prop[:parts][:include] = node[1][:'data-parts'].split(/\s+/).map(&:to_sym)
|
335
|
-
end
|
336
|
-
|
337
|
-
if node[1].has_key?(:'data-parts-exclude')
|
338
|
-
prop[:parts][:exclude] = node[1][:'data-parts-exclude'].split(/\s+/).map(&:to_sym)
|
339
|
-
end
|
340
|
-
props << prop
|
341
|
-
end
|
342
|
-
|
343
|
-
unless node[1].has_key?(:'data-scope')
|
344
|
-
find_props(node[2], node[2], props)
|
345
|
-
end
|
346
|
-
|
347
|
-
props
|
348
|
-
end
|
349
|
-
|
350
|
-
def find_channel(scopes, name)
|
351
|
-
scopes.each do |scope|
|
352
|
-
if scope[:doc].get_attribute(:'data-channel') == name
|
353
|
-
return scope[:doc]
|
354
|
-
end
|
355
|
-
|
356
|
-
if doc = find_channel(scope[:nested], name)
|
357
|
-
return doc
|
358
|
-
end
|
359
|
-
end
|
360
|
-
|
361
|
-
nil
|
362
|
-
end
|
363
|
-
|
364
|
-
def find_components(structure, primary_structure = @structure, components = [])
|
365
|
-
ret_components = structure.inject(components) { |s, e|
|
366
|
-
if e[1].has_key?(:'data-ui')
|
367
|
-
s << {
|
368
|
-
doc: StringDoc.from_structure(primary_structure, node: e),
|
369
|
-
component: e[1][:'data-ui'].to_sym,
|
370
|
-
}
|
371
|
-
end
|
372
|
-
find_components(e[2], e[2], s)
|
373
|
-
s
|
374
|
-
} || []
|
375
|
-
|
376
|
-
ret_components
|
377
|
-
end
|
378
|
-
end
|
379
|
-
end
|
380
|
-
end
|
@@ -1,144 +0,0 @@
|
|
1
|
-
module Pakyow
|
2
|
-
module Presenter
|
3
|
-
class StringDocParser
|
4
|
-
PARTIAL_REGEX = /<!--\s*@include\s*([a-zA-Z0-9\-_]*)\s*-->/
|
5
|
-
CONTAINER_REGEX = /@container( ([a-zA-Z0-9\-_]*))*/
|
6
|
-
SIGNIFICANT = [:scope?, :prop?, :container?, :partial?, :option?, :component?]
|
7
|
-
|
8
|
-
def initialize(html)
|
9
|
-
@html = html
|
10
|
-
structure
|
11
|
-
end
|
12
|
-
|
13
|
-
def structure
|
14
|
-
@structure ||= parse(doc_from_string(@html))
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
# Parses HTML and returns a nested structure representing the document.
|
20
|
-
#
|
21
|
-
def parse(doc)
|
22
|
-
structure = []
|
23
|
-
|
24
|
-
unless doc.is_a?(Oga::XML::Element) || !doc.respond_to?(:doctype) || doc.doctype.nil?
|
25
|
-
structure << ['<!DOCTYPE html>', {}, []]
|
26
|
-
end
|
27
|
-
|
28
|
-
breadth_first(doc) do |node, queue|
|
29
|
-
if node == doc
|
30
|
-
queue.concat(node.children.to_a)
|
31
|
-
next
|
32
|
-
end
|
33
|
-
|
34
|
-
children = node.children.reject {|n| n.is_a?(Oga::XML::Text)}
|
35
|
-
|
36
|
-
if node.is_a?(Oga::XML::Element)
|
37
|
-
attributes = node.attributes
|
38
|
-
else
|
39
|
-
attributes = []
|
40
|
-
end
|
41
|
-
|
42
|
-
if !structure.empty? && children.empty? && !significant?(node)
|
43
|
-
structure << [node.to_xml, {}, []]
|
44
|
-
else
|
45
|
-
if significant?(node)
|
46
|
-
if container?(node)
|
47
|
-
match = node.text.strip.match(CONTAINER_REGEX)
|
48
|
-
name = (match[2] || :default).to_sym
|
49
|
-
structure << [node.to_xml, { container: name }, []]
|
50
|
-
elsif partial?(node)
|
51
|
-
next unless match = node.to_xml.strip.match(PARTIAL_REGEX)
|
52
|
-
name = match[1].to_sym
|
53
|
-
structure << [node.to_xml, { partial: name }, []]
|
54
|
-
else
|
55
|
-
attr_structure = attributes.inject({}) do |attrs, attr|
|
56
|
-
attrs[attr.name.to_sym] = attr.value
|
57
|
-
attrs
|
58
|
-
end
|
59
|
-
|
60
|
-
closing = [['>', {}, parse(node)]]
|
61
|
-
closing << ["</#{node.name}>", {}, []] unless self_closing?(node.name)
|
62
|
-
structure << ["<#{node.name} ", attr_structure, closing]
|
63
|
-
end
|
64
|
-
else
|
65
|
-
if node.is_a?(Oga::XML::Text) || node.is_a?(Oga::XML::Comment)
|
66
|
-
structure << [node.to_xml, {}, []]
|
67
|
-
else
|
68
|
-
attr_s = attributes.inject('') { |s, a| s << " #{a.name}=\"#{a.value}\""; s }
|
69
|
-
closing = [['>', {}, parse(node)]]
|
70
|
-
closing << ['</' + node.name + '>', {}, []] unless self_closing?(node.name)
|
71
|
-
structure << ['<' + node.name + attr_s, {}, closing]
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
return structure
|
78
|
-
end
|
79
|
-
|
80
|
-
def significant?(node)
|
81
|
-
SIGNIFICANT.each do |method|
|
82
|
-
return true if send(method, node)
|
83
|
-
end
|
84
|
-
|
85
|
-
false
|
86
|
-
end
|
87
|
-
|
88
|
-
def scope?(node)
|
89
|
-
return false unless node.is_a?(Oga::XML::Element)
|
90
|
-
return false unless node.attribute('data-scope')
|
91
|
-
return true
|
92
|
-
end
|
93
|
-
|
94
|
-
def prop?(node)
|
95
|
-
return false unless node.is_a?(Oga::XML::Element)
|
96
|
-
return false unless node.attribute('data-prop')
|
97
|
-
return true
|
98
|
-
end
|
99
|
-
|
100
|
-
def container?(node)
|
101
|
-
return false unless node.is_a?(Oga::XML::Comment)
|
102
|
-
return false unless node.text.strip.match(CONTAINER_REGEX)
|
103
|
-
return true
|
104
|
-
end
|
105
|
-
|
106
|
-
def partial?(node)
|
107
|
-
return false unless node.is_a?(Oga::XML::Comment)
|
108
|
-
return false unless node.to_xml.strip.match(PARTIAL_REGEX)
|
109
|
-
return true
|
110
|
-
end
|
111
|
-
|
112
|
-
def option?(node)
|
113
|
-
return false unless node.is_a?(Oga::XML::Element)
|
114
|
-
node.name == 'option'
|
115
|
-
end
|
116
|
-
|
117
|
-
def component?(node)
|
118
|
-
return false unless node.is_a?(Oga::XML::Element)
|
119
|
-
return false unless node.attribute('data-ui')
|
120
|
-
return true
|
121
|
-
end
|
122
|
-
|
123
|
-
def breadth_first(doc)
|
124
|
-
queue = [doc]
|
125
|
-
until queue.empty?
|
126
|
-
catch(:reject) do
|
127
|
-
node = queue.shift
|
128
|
-
yield node, queue
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
def doc_from_string(string)
|
134
|
-
Oga.parse_html(string)
|
135
|
-
end
|
136
|
-
|
137
|
-
SELF_CLOSING = %w[area base basefont br hr input img link meta]
|
138
|
-
def self_closing?(tag)
|
139
|
-
SELF_CLOSING.include? tag
|
140
|
-
end
|
141
|
-
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
module Pakyow
|
2
|
-
module Presenter
|
3
|
-
class StringDocRenderer
|
4
|
-
def self.render(structure)
|
5
|
-
structure.flatten.reject(&:empty?).map { |s|
|
6
|
-
s.is_a?(Hash) ? attrify(s) : s
|
7
|
-
}.join
|
8
|
-
end
|
9
|
-
|
10
|
-
IGNORED_ATTRS = %i[container partial]
|
11
|
-
def self.attrify(attrs)
|
12
|
-
attrs.delete_if { |a| a.nil? || IGNORED_ATTRS.include?(a) }.map { |attr|
|
13
|
-
attr[0].to_s + '="' + attr[1].to_s + '"'
|
14
|
-
}.join(' ')
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
module Pakyow
|
2
|
-
module Presenter
|
3
|
-
class Template < View
|
4
|
-
attr_accessor :name, :doc
|
5
|
-
|
6
|
-
class << self
|
7
|
-
def load(path)
|
8
|
-
format = String.split_at_last_dot(path)[-1]
|
9
|
-
contents = File.read(path)
|
10
|
-
name = File.basename(path, '.*').to_sym
|
11
|
-
|
12
|
-
self.new(name, contents, format: format)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def initialize(name, contents = '', format: :html)
|
17
|
-
@name = name
|
18
|
-
super(contents, format: format)
|
19
|
-
end
|
20
|
-
|
21
|
-
def initialize_copy(original_template)
|
22
|
-
super
|
23
|
-
|
24
|
-
# copy doc
|
25
|
-
@doc = original_template.doc.dup
|
26
|
-
end
|
27
|
-
|
28
|
-
def container(name = :default)
|
29
|
-
View.from_doc(@doc.container(name.to_sym))
|
30
|
-
end
|
31
|
-
|
32
|
-
def build(page)
|
33
|
-
@doc.containers.each do |container|
|
34
|
-
name = container[0]
|
35
|
-
|
36
|
-
begin
|
37
|
-
container[1][:doc].replace(page.content(name))
|
38
|
-
rescue MissingContainer
|
39
|
-
# This hasn't proven to be useful in dev (or prd for that matter)
|
40
|
-
# so decided to remove it. It'll save us from filling console / log
|
41
|
-
# with information that will most likely just be ignored.
|
42
|
-
#
|
43
|
-
# Pakyow.logger.info "No content for '#{name}' in page '#{page.path}'"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
View.from_doc(doc)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|