pakyow-presenter 0.9.1 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/pakyow-presenter/CHANGELOG.md +94 -0
- data/pakyow-presenter/{MIT-LICENSE → LICENSE} +2 -2
- data/pakyow-presenter/README.md +36 -0
- data/pakyow-presenter/lib/pakyow-presenter.rb +1 -4
- data/pakyow-presenter/lib/presenter/attributes.rb +10 -1
- data/pakyow-presenter/lib/presenter/base.rb +2 -1
- data/pakyow-presenter/lib/presenter/binder.rb +20 -6
- data/pakyow-presenter/lib/presenter/binder_set.rb +21 -17
- data/pakyow-presenter/lib/presenter/config/presenter.rb +2 -2
- data/pakyow-presenter/lib/presenter/ext/app.rb +32 -1
- data/pakyow-presenter/lib/presenter/helpers.rb +6 -6
- data/pakyow-presenter/lib/presenter/page.rb +4 -4
- data/pakyow-presenter/lib/presenter/presenter.rb +32 -10
- data/pakyow-presenter/lib/presenter/string_doc.rb +78 -11
- data/pakyow-presenter/lib/presenter/string_doc_parser.rb +16 -7
- data/pakyow-presenter/lib/presenter/view.rb +55 -17
- data/pakyow-presenter/lib/presenter/view_collection.rb +74 -7
- data/pakyow-presenter/lib/presenter/view_composer.rb +52 -8
- data/pakyow-presenter/lib/presenter/view_context.rb +19 -1
- data/pakyow-presenter/lib/presenter/view_store.rb +202 -163
- data/pakyow-presenter/lib/presenter/view_store_loader.rb +43 -0
- data/pakyow-presenter/lib/presenter/view_version.rb +97 -0
- data/pakyow-presenter/lib/views/errors/404.html +5 -0
- data/pakyow-presenter/{README → lib/views/errors/500.html} +0 -0
- metadata +36 -21
- data/pakyow-presenter/CHANGES +0 -57
- data/pakyow-presenter/lib/presenter/nokogiri_doc.rb +0 -321
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bf054d209c01b7b382b09b1e1a01730781d8f1df
|
4
|
+
data.tar.gz: ab58a2cfde9f832773b94b15315a84f488768ece
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0780b1e866ae3de214d7166cba28564eb0ddf64a737d6fae768bf0bd9c372597802b174fe75c6885f24994d8bfcbdb2d5d3282608c5c1389056958143d12dc62
|
7
|
+
data.tar.gz: e2ae8354a5e0f68c0052c62a3d194cb1ac5ee557661b9238f8ff9e7319c543bf7484951ca31fca7e3e2d3a71e95fe0834556f5b2f2220d5ccb853a1a927a57e4
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# 0.10.0 (to be released)
|
2
|
+
|
3
|
+
* Adds precomposition to composer
|
4
|
+
* Fixes binding action for nested resources
|
5
|
+
* Fixes variable name in remap_partials
|
6
|
+
* Setup form on `_root` rather than `action` prop
|
7
|
+
* Handles view paths that don't define an `index` view
|
8
|
+
* Adds `ViewCollection#scoped_as` convenience method
|
9
|
+
* Renames default template to `default` (instead of `pakyow`)
|
10
|
+
* Adds convenience method to check for view existence
|
11
|
+
* Support binding hashes with `String` keys
|
12
|
+
* Fixes a bug when a node is inserted after another node that also has a sibling
|
13
|
+
* Fixes binding to props nested in partial
|
14
|
+
* Now allows views for a view store to be fragmented across multiple directories
|
15
|
+
* Adds versioned scopes with auto empty handling
|
16
|
+
* Now sets scope name explicitly for `ViewCollection` built from a `View`
|
17
|
+
* Adds a helper method for checking if a attribute exists
|
18
|
+
* Adds support for components and channels (realtime ftw)
|
19
|
+
* Adds id of object to scoped node during binding
|
20
|
+
* Fixes a bug with view contexts in presenter helpers
|
21
|
+
* Ported all tests to rspec
|
22
|
+
* Fixes a bug finding scopes in a nested partial
|
23
|
+
* Fixes a bug where unused partials still being included as parts in the composer
|
24
|
+
* Fixes a `StringDoc` bug when structure is empty
|
25
|
+
* Fixes bug preventing passed binding functions from being used when no binding sets are registered for scope
|
26
|
+
* Fixes namespace collisions
|
27
|
+
* Fixes error when matching data empty collection
|
28
|
+
* Renames `inner_html` to `html`
|
29
|
+
* Now only reloads a view store if the contents have changed
|
30
|
+
* Yields `prop` node rather than full `scope` in bindings
|
31
|
+
* Handles `AttributesCollection#<<` for all use cases
|
32
|
+
* Adds `to_html` method on composer
|
33
|
+
* No longer complains about a view store missing a template directory
|
34
|
+
* Now finds view info for a path that doesn't contain a page
|
35
|
+
* Allows root nodes to be appendable in string doc
|
36
|
+
* Removes nokogiri doc
|
37
|
+
|
38
|
+
# 0.9.1 / 2014-12-06
|
39
|
+
|
40
|
+
* Fixes bug where name attribute wasn't set on form fields when binding without a value
|
41
|
+
* Fixes bug causing all partials (not just available ones) to be defined as view parts
|
42
|
+
* Fixes bug causing form action binding to break
|
43
|
+
|
44
|
+
# 0.9.0 / 2014-11-09
|
45
|
+
|
46
|
+
* Introduces StringDoc, replacing Nokogiri for view rendering with a performant alternative
|
47
|
+
* Adds the ability to set an empty first option in bindings
|
48
|
+
* Remove the annoying "no content" for container log message
|
49
|
+
* Binding context must now be explicitly passed when binding
|
50
|
+
* Yield bindable value before bindable in view binding fns
|
51
|
+
* Fixes bug causing non-html view contents to be processed twice
|
52
|
+
* Removes support for Ruby versions < 2.0.0
|
53
|
+
|
54
|
+
# 0.8.0 / 2014-03-02
|
55
|
+
|
56
|
+
* Major rewrite, including new view syntax, composer, and transformation api
|
57
|
+
|
58
|
+
# 0.7.2 / 2012-02-29
|
59
|
+
|
60
|
+
* No changes -- bumped version to be consistent
|
61
|
+
|
62
|
+
# 0.7.1 / 2012-01-08
|
63
|
+
|
64
|
+
* View caching fixes
|
65
|
+
* Changed binder to allow definition for multiple endpoints
|
66
|
+
* Changed in_context to accept context as block argument
|
67
|
+
* Changed action binder to add leading slash if needed
|
68
|
+
* Change to allow a view's content to be set to nil
|
69
|
+
* Fixed Views#find method
|
70
|
+
|
71
|
+
# 0.7.0 / 2011-11-19
|
72
|
+
|
73
|
+
* Cleaned up core/presenter interface
|
74
|
+
* Optimized view caching
|
75
|
+
* Binding occurs on the label an object is being bound to, not the object type
|
76
|
+
* Root view override in index directories no longer specify a root view for siblings
|
77
|
+
* Fixed problem binding to a checkbox who’s value attribute is not set
|
78
|
+
|
79
|
+
# 0.6.3 / 2011-09-13
|
80
|
+
|
81
|
+
* Fixes binding to bindings defined by HTML 'name' attribute
|
82
|
+
|
83
|
+
# 0.6.2 / 2011-08-20
|
84
|
+
|
85
|
+
* Fixes issue binding object to root nodes
|
86
|
+
* JRuby Support
|
87
|
+
|
88
|
+
# 0.6.1 / 2011-08-20
|
89
|
+
|
90
|
+
* Fixes gemspec problem
|
91
|
+
|
92
|
+
# 0.6.0 / 2011-08-20
|
93
|
+
|
94
|
+
* Initial gem release of 0.6.0 codebase
|
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2011 Bryan Powell
|
1
|
+
Copyright (c) 2011-2015 Bryan Powell
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
a copy of this software and associated documentation files (the
|
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
17
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
18
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
19
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# pakyow-presenter
|
2
|
+
|
3
|
+
A view-first presentation layer for Pakyow.
|
4
|
+
|
5
|
+
# Download
|
6
|
+
|
7
|
+
The latest version of Pakyow Presenter can be installed with RubyGems:
|
8
|
+
|
9
|
+
```
|
10
|
+
gem install pakyow-presenter
|
11
|
+
```
|
12
|
+
|
13
|
+
Source code can be downloaded as part of the Pakyow project on Github:
|
14
|
+
|
15
|
+
- https://github.com/pakyow/pakyow/tree/master/pakyow-presenter
|
16
|
+
|
17
|
+
# License
|
18
|
+
|
19
|
+
Pakyow Presenter is released free and open-source under the [MIT
|
20
|
+
License](http://opensource.org/licenses/MIT).
|
21
|
+
|
22
|
+
# Support
|
23
|
+
|
24
|
+
Documentation is available here:
|
25
|
+
|
26
|
+
- http://pakyow.org/docs/view-composition
|
27
|
+
- http://pakyow.org/docs/data-binding
|
28
|
+
- http://pakyow.org/docs/view-management
|
29
|
+
|
30
|
+
Found a bug? Tell us about it here:
|
31
|
+
|
32
|
+
- https://github.com/pakyow/pakyow/issues
|
33
|
+
|
34
|
+
We'd love to have you in the community:
|
35
|
+
|
36
|
+
- http://pakyow.org/get-involved
|
@@ -1,13 +1,10 @@
|
|
1
1
|
libdir = File.dirname(__FILE__)
|
2
2
|
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
3
3
|
|
4
|
-
# Gems
|
4
|
+
# Gems
|
5
5
|
require 'nokogiri'
|
6
6
|
|
7
|
-
# Base
|
8
7
|
require 'presenter/base'
|
9
|
-
include Presenter
|
10
|
-
|
11
8
|
require 'presenter/presenter'
|
12
9
|
require 'presenter/config/presenter'
|
13
10
|
require 'presenter/helpers'
|
@@ -49,6 +49,10 @@ module Pakyow
|
|
49
49
|
update_value
|
50
50
|
end
|
51
51
|
|
52
|
+
def include?(attribute)
|
53
|
+
@doc.has_attribute?(attribute)
|
54
|
+
end
|
55
|
+
|
52
56
|
# passes method call to `value`
|
53
57
|
def method_missing(method, *args)
|
54
58
|
ret = @value.send(method, *args)
|
@@ -182,7 +186,12 @@ module Pakyow
|
|
182
186
|
end
|
183
187
|
|
184
188
|
def <<(attributes)
|
185
|
-
|
189
|
+
if attributes.is_a?(Attribute) || attributes.is_a?(Attributes)
|
190
|
+
@attributes << attributes
|
191
|
+
else
|
192
|
+
method_missing(:<<, *attributes)
|
193
|
+
end
|
194
|
+
|
186
195
|
self
|
187
196
|
end
|
188
197
|
|
@@ -12,13 +12,14 @@ require 'presenter/binder_set'
|
|
12
12
|
require 'presenter/attributes'
|
13
13
|
require 'presenter/exceptions'
|
14
14
|
require 'presenter/view_composer'
|
15
|
-
require 'presenter/nokogiri_doc'
|
16
15
|
require 'presenter/string_doc'
|
17
16
|
require 'presenter/string_doc_parser'
|
18
17
|
require 'presenter/string_doc_renderer'
|
19
18
|
require 'presenter/binding_eval'
|
20
19
|
require 'presenter/doc_helpers'
|
20
|
+
require 'presenter/view_version'
|
21
21
|
require 'presenter/view_context'
|
22
|
+
require 'presenter/view_store_loader'
|
22
23
|
|
23
24
|
module Pakyow
|
24
25
|
module Presenter
|
@@ -47,18 +47,22 @@ module Pakyow
|
|
47
47
|
# @param context [Symbol] context passed through to the defined bindings
|
48
48
|
#
|
49
49
|
def value_for_scoped_prop(scope, prop, bindable, bindings, context)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
50
|
+
if @sets.empty?
|
51
|
+
binding_fn = bindings[prop]
|
52
|
+
else
|
53
|
+
binding_fn = @sets.lazy.map { |set|
|
54
|
+
set[1].match_for_prop(prop, scope, bindable, bindings)
|
55
|
+
}.find { |match|
|
56
|
+
!match.nil?
|
57
|
+
}
|
58
|
+
end
|
55
59
|
|
56
60
|
if binding_fn
|
57
61
|
binding_eval = BindingEval.new(prop, bindable, context)
|
58
62
|
binding_eval.instance_exec(binding_eval.value, bindable, context, &binding_fn)
|
59
63
|
else # default value
|
60
64
|
if bindable.is_a?(Hash)
|
61
|
-
bindable[prop]
|
65
|
+
bindable.fetch(prop) { bindable[prop.to_s] }
|
62
66
|
elsif bindable.class.method_defined?(prop)
|
63
67
|
bindable.send(prop)
|
64
68
|
end
|
@@ -84,6 +88,16 @@ module Pakyow
|
|
84
88
|
!options.nil?
|
85
89
|
}
|
86
90
|
end
|
91
|
+
|
92
|
+
def bindings_for_scope(scope, bindings = {})
|
93
|
+
return bindings if @sets.empty?
|
94
|
+
|
95
|
+
@sets.map { |set|
|
96
|
+
set[1].bindings_for_scope(scope, bindings)
|
97
|
+
}.inject({}) { |acc, bindings|
|
98
|
+
acc.merge(bindings)
|
99
|
+
}
|
100
|
+
end
|
87
101
|
end
|
88
102
|
end
|
89
103
|
end
|
@@ -67,27 +67,31 @@ module Pakyow
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def restful(route_group)
|
70
|
-
binding
|
70
|
+
binding :_root do
|
71
71
|
routes = Router.instance.group(route_group)
|
72
|
-
return_data = {}
|
73
72
|
|
74
|
-
|
75
|
-
|
76
|
-
view.
|
73
|
+
{
|
74
|
+
view: lambda { |view|
|
75
|
+
action = view.attrs.action.value
|
76
|
+
return if (action && !action.empty?)
|
77
|
+
|
78
|
+
route_params = params.dup
|
79
|
+
if view.doc.tagname == 'form'
|
80
|
+
if id = bindable[:id]
|
81
|
+
view.prepend(View.new('<input type="hidden" name="_method" value="patch">'))
|
82
|
+
route_params[:"#{route_group}_id"] = id
|
83
|
+
action = :update
|
84
|
+
else
|
85
|
+
action = :create
|
86
|
+
end
|
87
|
+
|
88
|
+
view.attrs.action = routes.path(action, route_params)
|
89
|
+
view.attrs.method = 'post'
|
90
|
+
end
|
77
91
|
}
|
78
|
-
|
79
|
-
|
80
|
-
else
|
81
|
-
action = routes.path(:create)
|
82
|
-
end
|
83
|
-
|
84
|
-
return_data[:action] = action
|
85
|
-
return_data[:method] = 'post'
|
86
|
-
return_data
|
87
|
-
}
|
92
|
+
}
|
93
|
+
end
|
88
94
|
end
|
89
|
-
|
90
|
-
#TODO options
|
91
95
|
end
|
92
96
|
end
|
93
97
|
end
|
@@ -8,7 +8,7 @@ Pakyow::Config.register(:presenter) { |config|
|
|
8
8
|
}
|
9
9
|
|
10
10
|
# the default view for each view store
|
11
|
-
config.opt :default_views, { default:
|
11
|
+
config.opt :default_views, { default: :default }
|
12
12
|
|
13
13
|
# a convenience option to lookup the default_view for a view store by name
|
14
14
|
config.opt :default_view, lambda { |store_name|
|
@@ -32,5 +32,5 @@ Pakyow::Config.register(:presenter) { |config|
|
|
32
32
|
config.opt :prop_attribute, 'data-prop'
|
33
33
|
|
34
34
|
# the document class used to parse and render views
|
35
|
-
config.opt :view_doc_class, StringDoc
|
35
|
+
config.opt :view_doc_class, Pakyow::Presenter::StringDoc
|
36
36
|
}
|
@@ -3,7 +3,7 @@ module Pakyow
|
|
3
3
|
class << self
|
4
4
|
@@bindings = {}
|
5
5
|
@@processors = {}
|
6
|
-
|
6
|
+
|
7
7
|
def bindings(set_name = :main, &block)
|
8
8
|
if set_name && block
|
9
9
|
@@bindings[set_name] = block
|
@@ -28,5 +28,36 @@ module Pakyow
|
|
28
28
|
def bindings(set_name = :main, &block)
|
29
29
|
self.class.bindings(set_name, &block)
|
30
30
|
end
|
31
|
+
|
32
|
+
def content_for_code(code)
|
33
|
+
content = File.open(
|
34
|
+
File.join(
|
35
|
+
File.expand_path(
|
36
|
+
'../../../../../', __FILE__),
|
37
|
+
'pakyow-core',
|
38
|
+
'lib',
|
39
|
+
'views',
|
40
|
+
'errors',
|
41
|
+
code.to_s + '.html'
|
42
|
+
)
|
43
|
+
).read + File.open(
|
44
|
+
File.join(
|
45
|
+
File.expand_path(
|
46
|
+
'../../../', __FILE__),
|
47
|
+
'views',
|
48
|
+
'errors',
|
49
|
+
code.to_s + '.html'
|
50
|
+
)
|
51
|
+
).read
|
52
|
+
|
53
|
+
path = String.normalize_path(request.path)
|
54
|
+
path = '/' if path.empty?
|
55
|
+
|
56
|
+
content.gsub!('{view_path}', path == '/' ? 'index.html' : "#{path}.html")
|
57
|
+
|
58
|
+
template = presenter.store.template(:default)
|
59
|
+
template.container(:default).replace(content)
|
60
|
+
template.to_html
|
61
|
+
end
|
31
62
|
end
|
32
63
|
end
|
@@ -7,26 +7,26 @@ module Pakyow
|
|
7
7
|
extend Forwardable
|
8
8
|
|
9
9
|
def_delegators :@presenter, :store, :store=, :content, :view=,
|
10
|
-
:template=, :page=, :path, :path=, :compose, :composer
|
10
|
+
:template=, :page=, :path, :path=, :compose, :composer, :precompose!
|
11
11
|
|
12
12
|
def view
|
13
|
-
ViewContext.new(@presenter.view,
|
13
|
+
Presenter::ViewContext.new(@presenter.view, self)
|
14
14
|
end
|
15
15
|
|
16
16
|
def partial(*args)
|
17
|
-
ViewContext.new(@presenter.partial(*args),
|
17
|
+
Presenter::ViewContext.new(@presenter.partial(*args), self)
|
18
18
|
end
|
19
19
|
|
20
20
|
def template
|
21
|
-
ViewContext.new(@presenter.template,
|
21
|
+
Presenter::ViewContext.new(@presenter.template, self)
|
22
22
|
end
|
23
23
|
|
24
24
|
def page
|
25
|
-
ViewContext.new(@presenter.page,
|
25
|
+
Presenter::ViewContext.new(@presenter.page, self)
|
26
26
|
end
|
27
27
|
|
28
28
|
def container(*args)
|
29
|
-
ViewContext.new(@presenter.container(*args),
|
29
|
+
Presenter::ViewContext.new(@presenter.container(*args), self)
|
30
30
|
end
|
31
31
|
|
32
32
|
def presenter
|
@@ -4,21 +4,21 @@ module Pakyow
|
|
4
4
|
MATTER_MATCHER = /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
5
5
|
|
6
6
|
class << self
|
7
|
-
def load(path)
|
7
|
+
def load(path, view_store_name = :default)
|
8
8
|
format = String.split_at_last_dot(path)[-1]
|
9
9
|
name = File.basename(path, '.*').to_sym
|
10
10
|
contents = FileTest.file?(path) ? File.read(path) : nil
|
11
11
|
|
12
|
-
return Page.new(name, contents, path, format)
|
12
|
+
return Page.new(name, contents, path, format, view_store_name)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
attr_reader :path, :contents
|
17
17
|
|
18
|
-
def initialize(name, contents, path, format = :html)
|
18
|
+
def initialize(name, contents, path, format = :html, view_store_name = :default)
|
19
19
|
@name, @contents, @path, @format = name, contents, path, format
|
20
20
|
|
21
|
-
@info = { template:
|
21
|
+
@info = { template: Pakyow::App.config.presenter.default_view(view_store_name) }
|
22
22
|
@containers = {}
|
23
23
|
|
24
24
|
unless @contents.nil?
|
@@ -24,6 +24,7 @@ module Pakyow
|
|
24
24
|
|
25
25
|
Pakyow::App.before(:init) {
|
26
26
|
@presenter = Presenter.new
|
27
|
+
ViewStoreLoader.instance.reset
|
27
28
|
}
|
28
29
|
|
29
30
|
Pakyow::App.after(:match) {
|
@@ -104,6 +105,18 @@ module Pakyow
|
|
104
105
|
@composer || @view || raise(MissingView)
|
105
106
|
end
|
106
107
|
|
108
|
+
def view?(path)
|
109
|
+
if composer_for_path(path)
|
110
|
+
true
|
111
|
+
else
|
112
|
+
false
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def precompose!
|
117
|
+
self.view = @composer.view
|
118
|
+
end
|
119
|
+
|
107
120
|
def view=(view)
|
108
121
|
@view = view
|
109
122
|
|
@@ -168,23 +181,21 @@ module Pakyow
|
|
168
181
|
end
|
169
182
|
|
170
183
|
def setup_for_path(path, explicit = false)
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
return
|
176
|
-
rescue MissingView
|
177
|
-
end
|
184
|
+
if composer = composer_for_path(path)
|
185
|
+
@composer = composer
|
186
|
+
@path = path
|
187
|
+
return
|
178
188
|
end
|
179
189
|
|
180
190
|
e = MissingView.new("No view at path '#{path}'")
|
181
|
-
explicit ? raise(e) : Pakyow.logger.
|
191
|
+
explicit ? raise(e) : Pakyow.logger.info(e.message)
|
182
192
|
end
|
183
193
|
|
184
194
|
def load_views
|
185
|
-
@view_stores
|
195
|
+
@view_stores ||= {}
|
186
196
|
|
187
|
-
Pakyow::Config.presenter.view_stores.each_pair {|name, path|
|
197
|
+
Pakyow::Config.presenter.view_stores.each_pair { |name, path|
|
198
|
+
next unless ViewStoreLoader.instance.modified?(name, path)
|
188
199
|
@view_stores[name] = ViewStore.new(path, name)
|
189
200
|
}
|
190
201
|
end
|
@@ -200,6 +211,17 @@ module Pakyow
|
|
200
211
|
def load_processors
|
201
212
|
@processor_store = Pakyow::App.processors
|
202
213
|
end
|
214
|
+
|
215
|
+
def composer_for_path(path)
|
216
|
+
@view_stores.each do |name, store|
|
217
|
+
begin
|
218
|
+
return store.composer(path)
|
219
|
+
rescue MissingView
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
return nil
|
224
|
+
end
|
203
225
|
end
|
204
226
|
end
|
205
227
|
end
|
@@ -24,13 +24,12 @@ module Pakyow
|
|
24
24
|
def initialize_copy(original_doc)
|
25
25
|
super
|
26
26
|
|
27
|
-
original_structure = original_doc.instance_variable_get(:@structure)
|
28
|
-
|
27
|
+
if original_structure = original_doc.instance_variable_get(:@structure)
|
28
|
+
@structure = Utils::Dup.deep(original_structure)
|
29
|
+
end
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
node_index = original_structure.index(original_node)
|
33
|
-
@node = @structure[node_index]
|
31
|
+
if original_doc.node?
|
32
|
+
@node = @structure[original_doc.node_index]
|
34
33
|
end
|
35
34
|
end
|
36
35
|
|
@@ -68,6 +67,8 @@ module Pakyow
|
|
68
67
|
|
69
68
|
def remove
|
70
69
|
@structure.delete_if { |n| n.equal?(node) }
|
70
|
+
@node = ['', {}, [['', {}, []]]]
|
71
|
+
@removed = true
|
71
72
|
end
|
72
73
|
|
73
74
|
def clear
|
@@ -116,7 +117,7 @@ module Pakyow
|
|
116
117
|
doc = StringDoc.ensure(doc)
|
117
118
|
|
118
119
|
if doc.node?
|
119
|
-
@structure.
|
120
|
+
@structure.insert(node_index + 1, doc.node)
|
120
121
|
else
|
121
122
|
@structure.concat(doc.structure)
|
122
123
|
end
|
@@ -134,7 +135,7 @@ module Pakyow
|
|
134
135
|
|
135
136
|
def replace(doc)
|
136
137
|
doc = StringDoc.ensure(doc)
|
137
|
-
index =
|
138
|
+
index = node_index || 0
|
138
139
|
|
139
140
|
if doc.node?
|
140
141
|
@structure.insert(index + 1, node)
|
@@ -158,6 +159,14 @@ module Pakyow
|
|
158
159
|
containers.fetch(name, {})[:doc]
|
159
160
|
end
|
160
161
|
|
162
|
+
def component(name)
|
163
|
+
components.select { |c| c[:component] == name }
|
164
|
+
end
|
165
|
+
|
166
|
+
def channel(name)
|
167
|
+
find_channel(scopes, name)
|
168
|
+
end
|
169
|
+
|
161
170
|
def containers
|
162
171
|
find_containers(@node ? [@node] : @structure)
|
163
172
|
end
|
@@ -170,6 +179,10 @@ module Pakyow
|
|
170
179
|
find_scopes(@node ? [@node] : @structure)
|
171
180
|
end
|
172
181
|
|
182
|
+
def components
|
183
|
+
find_components(@node ? [@node] : @structure)
|
184
|
+
end
|
185
|
+
|
173
186
|
def to_html
|
174
187
|
StringDocRenderer.render(@node ? [@node] : @structure)
|
175
188
|
end
|
@@ -186,8 +199,15 @@ module Pakyow
|
|
186
199
|
return @node || @structure[0]
|
187
200
|
end
|
188
201
|
|
202
|
+
def node_index
|
203
|
+
return nil unless node?
|
204
|
+
@structure.index { |n| n.equal?(@node) }
|
205
|
+
end
|
206
|
+
|
189
207
|
def node?
|
190
|
-
|
208
|
+
return false if @node.nil?
|
209
|
+
return false if @removed
|
210
|
+
return true
|
191
211
|
end
|
192
212
|
|
193
213
|
def tagname
|
@@ -200,6 +220,10 @@ module Pakyow
|
|
200
220
|
})
|
201
221
|
end
|
202
222
|
|
223
|
+
def exists?
|
224
|
+
@structure.include?(node)
|
225
|
+
end
|
226
|
+
|
203
227
|
private
|
204
228
|
|
205
229
|
def title_search
|
@@ -217,8 +241,16 @@ module Pakyow
|
|
217
241
|
node[1]
|
218
242
|
end
|
219
243
|
|
244
|
+
def has_attribute?(name)
|
245
|
+
attributes.key?(name)
|
246
|
+
end
|
247
|
+
|
220
248
|
def children
|
221
|
-
|
249
|
+
if @structure.empty?
|
250
|
+
@structure
|
251
|
+
else
|
252
|
+
node[2][0][2]
|
253
|
+
end
|
222
254
|
end
|
223
255
|
|
224
256
|
def find_containers(structure, primary_structure = @structure, containers = {})
|
@@ -245,12 +277,18 @@ module Pakyow
|
|
245
277
|
def find_scopes(structure, primary_structure = @structure, scopes = [])
|
246
278
|
ret_scopes = structure.inject(scopes) { |s, e|
|
247
279
|
if e[1].has_key?(:'data-scope')
|
248
|
-
|
280
|
+
scope = {
|
249
281
|
doc: StringDoc.from_structure(primary_structure, node: e),
|
250
282
|
scope: e[1][:'data-scope'].to_sym,
|
251
283
|
props: find_node_props(e).concat(find_props(e[2])),
|
252
284
|
nested: find_scopes(e[2]),
|
253
285
|
}
|
286
|
+
|
287
|
+
if version = e[1][:'data-version']
|
288
|
+
scope[:version] = version.to_sym
|
289
|
+
end
|
290
|
+
|
291
|
+
s << scope
|
254
292
|
end
|
255
293
|
# only find scopes if `e` is the root node or we're not decending into a nested scope
|
256
294
|
find_scopes(e[2], e[2], s) if e == node || !e[1].has_key?(:'data-scope')
|
@@ -282,6 +320,35 @@ module Pakyow
|
|
282
320
|
|
283
321
|
props
|
284
322
|
end
|
323
|
+
|
324
|
+
def find_channel(scopes, name)
|
325
|
+
scopes.each do |scope|
|
326
|
+
if scope[:doc].get_attribute(:'data-channel') == name
|
327
|
+
return scope[:doc]
|
328
|
+
end
|
329
|
+
|
330
|
+
if doc = find_channel(scope[:nested], name)
|
331
|
+
return doc
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
nil
|
336
|
+
end
|
337
|
+
|
338
|
+
def find_components(structure, primary_structure = @structure, components = [])
|
339
|
+
ret_components = structure.inject(components) { |s, e|
|
340
|
+
if e[1].has_key?(:'data-ui')
|
341
|
+
s << {
|
342
|
+
doc: StringDoc.from_structure(primary_structure, node: e),
|
343
|
+
component: e[1][:'data-ui'].to_sym,
|
344
|
+
}
|
345
|
+
end
|
346
|
+
find_components(e[2], e[2], s)
|
347
|
+
s
|
348
|
+
} || []
|
349
|
+
|
350
|
+
ret_components
|
351
|
+
end
|
285
352
|
end
|
286
353
|
end
|
287
354
|
end
|