pakyow-presenter 0.9.1 → 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.
- 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
|