dominate 0.5.2 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|