dominate 0.5.2 → 0.6.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/dominate.gemspec +1 -0
- data/lib/dominate/dom.rb +5 -1
- data/lib/dominate/html.rb +8 -3
- data/lib/dominate/instance.rb +4 -4
- data/lib/dominate/version.rb +1 -1
- data/lib/dominate/widget/event.rb +17 -0
- data/lib/dominate/widget/helper.rb +58 -0
- data/lib/dominate/widget/middleware.rb +49 -0
- data/lib/dominate/widget.rb +152 -0
- data/lib/dominate.rb +6 -1
- data/test/dummy/widgets/other_widget.rb +11 -0
- data/test/dummy/widgets/some_widget/display.slim +3 -0
- data/test/dummy/widgets/some_widget/test.slim +2 -0
- data/test/dummy/widgets/some_widget.rb +17 -0
- data/test/helper.rb +2 -0
- data/test/{dominate_test.rb → template_test.rb} +7 -3
- data/test/widget_test.rb +50 -0
- metadata +32 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 002723ab44811ed63d9c1288531e1ac92eb3a0f5
|
4
|
+
data.tar.gz: 6c7eaaad47a20ba8274b9beb91ee0945e111b315
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9f9c264fa9524b3474f45f4dee0460bc6ec316602908af12cc76d9ff1a7fcd0d7ae4eb7dbc8b3cfe674b1e54841ba288261408b9a51f6ac86d3b42ed66adea5
|
7
|
+
data.tar.gz: e30b012604baebe274ff73e3a885a7be5d39f05bc063303dce4409d69da38803bf18d27fc355a5454f3b0425fc89678325b6bef8b5fb4d0a87176fce0cadb252
|
data/dominate.gemspec
CHANGED
data/lib/dominate/dom.rb
CHANGED
data/lib/dominate/html.rb
CHANGED
@@ -21,15 +21,20 @@ module Dominate
|
|
21
21
|
html = false
|
22
22
|
|
23
23
|
VIEW_TYPES.each do |type|
|
24
|
-
|
24
|
+
f = "#{path}.#{type}"
|
25
25
|
|
26
|
-
if File.file?
|
27
|
-
template = Tilt.new
|
26
|
+
if File.file? f
|
27
|
+
template = Tilt.new f
|
28
28
|
html = template.render Instance.new(instance, config)
|
29
29
|
break
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
+
unless html
|
34
|
+
raise Dominate::NoFileFound,
|
35
|
+
"Could't find file: #{path} with any of these extensions: #{VIEW_TYPES.join(', ')}."
|
36
|
+
end
|
37
|
+
|
33
38
|
html
|
34
39
|
end
|
35
40
|
end
|
data/lib/dominate/instance.rb
CHANGED
@@ -13,11 +13,11 @@ module Dominate
|
|
13
13
|
|
14
14
|
def method_missing method, *args, &block
|
15
15
|
if @__config__.respond_to? method
|
16
|
-
@__config__.send method
|
17
|
-
elsif @__instance__.respond_to? method
|
18
|
-
@__instance__.send method
|
16
|
+
@__config__.send method, *args, &block
|
17
|
+
elsif @__instance__.respond_to? method, *args, &block
|
18
|
+
@__instance__.send method, *args, &block
|
19
19
|
else
|
20
|
-
|
20
|
+
@__instance__.send 'method_missing', method, *args, &block
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
data/lib/dominate/version.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "observer"
|
2
|
+
|
3
|
+
module Dominate
|
4
|
+
class Widget
|
5
|
+
class Event < Struct.new(:res, :req)
|
6
|
+
include Observable
|
7
|
+
|
8
|
+
def trigger widget_name, widget_event, data = {}
|
9
|
+
# THIS IS WHAT WILL MAKE SURE EVENTS ARE TRIGGERED
|
10
|
+
changed
|
11
|
+
##################################################
|
12
|
+
|
13
|
+
notify_observers widget_name, widget_event, data.to_deep_ostruct
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Dominate
|
2
|
+
class Widget
|
3
|
+
module Helper
|
4
|
+
class << self
|
5
|
+
def setup app
|
6
|
+
initialize
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
# Load the widgets
|
11
|
+
Dir.glob("#{Dominate.config.widget_path}/**/*.rb").each do |w|
|
12
|
+
require w
|
13
|
+
end
|
14
|
+
|
15
|
+
if defined?(Slim) && defined?(Slim::Engine)
|
16
|
+
Slim::Engine.set_default_options \
|
17
|
+
disable_escape: true,
|
18
|
+
use_html_safe: false,
|
19
|
+
disable_capture: false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def render_widget *args
|
25
|
+
Widget.load_all(self, req, res)
|
26
|
+
|
27
|
+
if args.first.kind_of? Hash
|
28
|
+
opts = args.first
|
29
|
+
name = req.env[:widget_name]
|
30
|
+
else
|
31
|
+
name = args.first
|
32
|
+
opts = args.length > 1 ? args.last : {}
|
33
|
+
end
|
34
|
+
|
35
|
+
# set the current state (the method that will get called on render_widget)
|
36
|
+
state = opts[:state] || 'display'
|
37
|
+
|
38
|
+
widget = req.env[:loaded_widgets][name]
|
39
|
+
|
40
|
+
# begin
|
41
|
+
if widget.method(state).parameters.length > 0
|
42
|
+
resp = widget.send state, opts.to_deep_ostruct
|
43
|
+
else
|
44
|
+
resp = widget.send state
|
45
|
+
end
|
46
|
+
|
47
|
+
if resp.is_a? Dominate::Dom
|
48
|
+
resp.html
|
49
|
+
else
|
50
|
+
resp
|
51
|
+
end
|
52
|
+
# rescue NoMethodError
|
53
|
+
# raise "Please add ##{state} to #{widget.class}."
|
54
|
+
# end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Dominate
|
2
|
+
class Widget
|
3
|
+
class Middleware
|
4
|
+
|
5
|
+
def initialize(app)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
@env = env
|
11
|
+
|
12
|
+
if widget_path
|
13
|
+
widget_name, widget_event, event = Widget.load_all @app, req, res
|
14
|
+
|
15
|
+
event.trigger widget_name, widget_event, req.params
|
16
|
+
# res.write "$('head > meta[name=csrf-token]').attr('content', '#{csrf_token}');"
|
17
|
+
res.write '$(document).trigger("page:change");'
|
18
|
+
res.finish
|
19
|
+
else
|
20
|
+
res
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def res
|
27
|
+
@res ||= begin
|
28
|
+
if not widget_path
|
29
|
+
@app.call(req.env)
|
30
|
+
else
|
31
|
+
Cuba::Response.new
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def req
|
37
|
+
@req ||= Rack::Request.new(@env)
|
38
|
+
end
|
39
|
+
|
40
|
+
def widget_path
|
41
|
+
path[Regexp.new("^#{Dominate.config.widget_url}($|\\?.*)")]
|
42
|
+
end
|
43
|
+
|
44
|
+
def path
|
45
|
+
@env['PATH_INFO']
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
module Dominate
|
2
|
+
class Widget
|
3
|
+
JS_ESCAPE = { '\\' => '\\\\', '</' => '<\/', "\r\n" => '\n', "\n" => '\n', "\r" => '\n', '"' => '\\"', "'" => "\\'" }
|
4
|
+
PARTIAL_REGEX = Regexp.new '([a-zA-Z_]+)$'
|
5
|
+
|
6
|
+
autoload :Event, "dominate/widget/event"
|
7
|
+
autoload :Middleware, "dominate/widget/middleware"
|
8
|
+
autoload :Helper, "dominate/widget/helper"
|
9
|
+
|
10
|
+
attr_accessor :app, :res, :req, :name, :event, :widget_state
|
11
|
+
|
12
|
+
def initialize app, res, req, name, event
|
13
|
+
@app = app
|
14
|
+
@res = res
|
15
|
+
@req = req
|
16
|
+
@name = name.to_s
|
17
|
+
@event = event
|
18
|
+
@widget_state = false
|
19
|
+
|
20
|
+
event.add_observer self, :trigger_event
|
21
|
+
end
|
22
|
+
|
23
|
+
def method_missing method, *args, &block
|
24
|
+
if app.respond_to? method
|
25
|
+
self.instance_variables.each do |name|
|
26
|
+
app.instance_variable_set name, self.instance_variable_get(name)
|
27
|
+
end
|
28
|
+
|
29
|
+
app.send method, *args, &block
|
30
|
+
else
|
31
|
+
super
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def trigger widget_event, data = {}
|
36
|
+
widget_name = data.delete(:for)
|
37
|
+
|
38
|
+
req.env[:loaded_widgets].each do |n, w|
|
39
|
+
w.trigger_event (widget_name || req.params['widget_name']), widget_event,
|
40
|
+
data.to_deep_ostruct
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def trigger_event widget_name, widget_event, data = {}
|
45
|
+
if class_events = self.class.events
|
46
|
+
class_events.each do |class_event, opts|
|
47
|
+
if class_event.to_s == widget_event.to_s && (
|
48
|
+
widget_name.to_s == name or
|
49
|
+
opts[:for].to_s == widget_name.to_s
|
50
|
+
)
|
51
|
+
if not opts[:with]
|
52
|
+
e = widget_event
|
53
|
+
else
|
54
|
+
e = opts[:with]
|
55
|
+
end
|
56
|
+
|
57
|
+
# begin
|
58
|
+
if method(e) and method(e).parameters.length > 0
|
59
|
+
resp = send(e, data)
|
60
|
+
else
|
61
|
+
resp = send(e)
|
62
|
+
end
|
63
|
+
|
64
|
+
if resp.is_a? Dominate::Dom
|
65
|
+
res.write resp.html
|
66
|
+
else
|
67
|
+
resp
|
68
|
+
end
|
69
|
+
# rescue NoMethodError
|
70
|
+
# raise "Please add ##{e} to your #{self.class}."
|
71
|
+
# end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def render *args
|
78
|
+
if args.first.kind_of? Hash
|
79
|
+
locals = args.first
|
80
|
+
# if it's a partial we add an underscore infront of it
|
81
|
+
state = view = locals[:state] ||
|
82
|
+
"#{locals[:partial]}".gsub(PARTIAL_REGEX, '_\1')
|
83
|
+
else
|
84
|
+
state = view = args.first
|
85
|
+
locals = args.length > 1 ? args.last : {}
|
86
|
+
end
|
87
|
+
|
88
|
+
# set the state and view if it's blank
|
89
|
+
if view.blank?
|
90
|
+
state = view = caller[0][/`.*'/][1..-2]
|
91
|
+
# override state if widget_state set
|
92
|
+
elsif !locals[:state] && widget_state
|
93
|
+
state = widget_state
|
94
|
+
end
|
95
|
+
|
96
|
+
req.env[:widget_name] = name
|
97
|
+
req.env[:widget_state] = state
|
98
|
+
|
99
|
+
view_folder = self.class.to_s.gsub(
|
100
|
+
/\w+::Widgets::/, ''
|
101
|
+
).split('::').map(&:underscore).join('/')
|
102
|
+
|
103
|
+
# set the view path to the widget path
|
104
|
+
locals[:view_path] = view_path
|
105
|
+
# we also don't want a layout
|
106
|
+
locals[:layout] = false unless locals.key? :layout
|
107
|
+
file = "#{view_folder}/#{view}"
|
108
|
+
|
109
|
+
Dominate::HTML.file(file, self, locals)
|
110
|
+
end
|
111
|
+
|
112
|
+
def view_path
|
113
|
+
Dominate.config.widget_path
|
114
|
+
end
|
115
|
+
|
116
|
+
class << self
|
117
|
+
attr_accessor :events
|
118
|
+
|
119
|
+
def load_all app, req, res
|
120
|
+
event = Event.new res, req
|
121
|
+
|
122
|
+
if widget_event = req.params["widget_event"]
|
123
|
+
widget_name = req.params["widget_name"]
|
124
|
+
end
|
125
|
+
|
126
|
+
unless req.env[:loaded_widgets]
|
127
|
+
req.env[:loaded_widgets] ||= {}
|
128
|
+
|
129
|
+
Dominate.config.widgets.each do |name, widget|
|
130
|
+
req.env[:loaded_widgets][name] = Object.const_get(widget).new(
|
131
|
+
app, res, req, name, event
|
132
|
+
)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
[widget_name, widget_event, event]
|
137
|
+
end
|
138
|
+
|
139
|
+
def respond_to event, opts = {}
|
140
|
+
@events ||= []
|
141
|
+
@events << [event.to_s, opts]
|
142
|
+
end
|
143
|
+
|
144
|
+
def responds_to *events
|
145
|
+
@events ||= []
|
146
|
+
events.each do |event|
|
147
|
+
@events << [event, {}]
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
data/lib/dominate.rb
CHANGED
@@ -11,7 +11,9 @@ module Dominate
|
|
11
11
|
autoload :HTML, "dominate/html"
|
12
12
|
autoload :Scope, "dominate/scope"
|
13
13
|
autoload :Dom, "dominate/dom"
|
14
|
+
autoload :Widget, "dominate/widget"
|
14
15
|
|
16
|
+
class NoFileFound < StandardError; end
|
15
17
|
|
16
18
|
attr_accessor :config, :reset_config
|
17
19
|
|
@@ -27,7 +29,10 @@ module Dominate
|
|
27
29
|
def reset_config!
|
28
30
|
@config = OpenStruct.new({
|
29
31
|
view_path: './views',
|
30
|
-
layout: 'app'
|
32
|
+
layout: 'app',
|
33
|
+
widget_path: './widgets',
|
34
|
+
widget_url: '/widgets',
|
35
|
+
widgets: {}
|
31
36
|
})
|
32
37
|
end
|
33
38
|
|
data/test/helper.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
require_relative 'helper'
|
2
|
-
require 'dominate'
|
3
|
-
require 'slim'
|
4
2
|
|
5
3
|
setup do
|
6
4
|
Dominate.reset_config!
|
@@ -24,7 +22,7 @@ setup do
|
|
24
22
|
})
|
25
23
|
end
|
26
24
|
|
27
|
-
scope 'dominate' do
|
25
|
+
scope 'dominate template' do
|
28
26
|
test 'html' do |a|
|
29
27
|
assert a.dom.html['test']
|
30
28
|
assert a.dom.html.scan(/<a.*>/).length == 2
|
@@ -114,4 +112,10 @@ scope 'dominate' do
|
|
114
112
|
assert dom.html['#000']
|
115
113
|
assert dom.html['added via .dom file']
|
116
114
|
end
|
115
|
+
|
116
|
+
test 'raise' do
|
117
|
+
assert_raise(Dominate::NoFileFound) do
|
118
|
+
Dominate::HTML.file 'no_file', false, name: '.dom'
|
119
|
+
end
|
120
|
+
end
|
117
121
|
end
|
data/test/widget_test.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
require 'cuba'
|
3
|
+
|
4
|
+
setup do
|
5
|
+
Dominate.reset_config!
|
6
|
+
Dominate.setup do |c|
|
7
|
+
c.widget_path = './test/dummy/widgets'
|
8
|
+
c.widget_url = '/widgets'
|
9
|
+
c.widgets = {
|
10
|
+
some_widget: 'SomeWidget',
|
11
|
+
other_widget: 'OtherWidget'
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
Cuba.reset!
|
16
|
+
Cuba.use Dominate::Widget::Middleware
|
17
|
+
Cuba.plugin Dominate::Widget::Helper
|
18
|
+
Cuba.define do
|
19
|
+
on "test" do
|
20
|
+
res.write render_widget :some_widget
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
scope 'dominate widget' do
|
26
|
+
test 'render_widget' do |a|
|
27
|
+
_, _, resp = Cuba.call({
|
28
|
+
'PATH_INFO' => '/test',
|
29
|
+
'SCRIPT_NAME' => '/test',
|
30
|
+
'REQUEST_METHOD' => 'GET',
|
31
|
+
'rack.input' => {}
|
32
|
+
})
|
33
|
+
|
34
|
+
assert resp.join.scan('Hello, World!').length == 2
|
35
|
+
end
|
36
|
+
|
37
|
+
test 'event' do
|
38
|
+
_, _, resp = Cuba.call({
|
39
|
+
'PATH_INFO' => '/widgets',
|
40
|
+
'REQUEST_METHOD' => 'GET',
|
41
|
+
'rack.input' => {},
|
42
|
+
'QUERY_STRING' => 'widget_name=some_widget&widget_event=test'
|
43
|
+
})
|
44
|
+
body = resp.join
|
45
|
+
|
46
|
+
assert body['Hello, World!']
|
47
|
+
assert body['moo']
|
48
|
+
assert body['cow']
|
49
|
+
end
|
50
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dominate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- cj
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-06-
|
11
|
+
date: 2014-06-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -136,6 +136,20 @@ dependencies:
|
|
136
136
|
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: cuba
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
139
153
|
description: Allows you to manipulate the dom without touching it.
|
140
154
|
email:
|
141
155
|
- cjlazell@gmail.com
|
@@ -156,14 +170,23 @@ files:
|
|
156
170
|
- lib/dominate/instance.rb
|
157
171
|
- lib/dominate/scope.rb
|
158
172
|
- lib/dominate/version.rb
|
159
|
-
-
|
173
|
+
- lib/dominate/widget.rb
|
174
|
+
- lib/dominate/widget/event.rb
|
175
|
+
- lib/dominate/widget/helper.rb
|
176
|
+
- lib/dominate/widget/middleware.rb
|
160
177
|
- test/dummy/app.slim
|
161
178
|
- test/dummy/flat.dom
|
162
179
|
- test/dummy/flat.slim
|
163
180
|
- test/dummy/footer.slim
|
164
181
|
- test/dummy/header.html
|
165
182
|
- test/dummy/index.html
|
183
|
+
- test/dummy/widgets/other_widget.rb
|
184
|
+
- test/dummy/widgets/some_widget.rb
|
185
|
+
- test/dummy/widgets/some_widget/display.slim
|
186
|
+
- test/dummy/widgets/some_widget/test.slim
|
166
187
|
- test/helper.rb
|
188
|
+
- test/template_test.rb
|
189
|
+
- test/widget_test.rb
|
167
190
|
homepage: ''
|
168
191
|
licenses:
|
169
192
|
- MIT
|
@@ -189,11 +212,16 @@ signing_key:
|
|
189
212
|
specification_version: 4
|
190
213
|
summary: Templating Engine.
|
191
214
|
test_files:
|
192
|
-
- test/dominate_test.rb
|
193
215
|
- test/dummy/app.slim
|
194
216
|
- test/dummy/flat.dom
|
195
217
|
- test/dummy/flat.slim
|
196
218
|
- test/dummy/footer.slim
|
197
219
|
- test/dummy/header.html
|
198
220
|
- test/dummy/index.html
|
221
|
+
- test/dummy/widgets/other_widget.rb
|
222
|
+
- test/dummy/widgets/some_widget.rb
|
223
|
+
- test/dummy/widgets/some_widget/display.slim
|
224
|
+
- test/dummy/widgets/some_widget/test.slim
|
199
225
|
- test/helper.rb
|
226
|
+
- test/template_test.rb
|
227
|
+
- test/widget_test.rb
|