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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eb406d2542020af78ec7fa5410828484f54663ae
4
- data.tar.gz: e1931bd044daecb7c27bd0f48a573eaa1503c86b
3
+ metadata.gz: 002723ab44811ed63d9c1288531e1ac92eb3a0f5
4
+ data.tar.gz: 6c7eaaad47a20ba8274b9beb91ee0945e111b315
5
5
  SHA512:
6
- metadata.gz: 3560002bf681a6f8e3dd19fccd84c04df20c9939669334066475fbb45e118698ffff7e74999db60fd63e6848d44ae61abb08176fe3d2313a033d3267143eafb6
7
- data.tar.gz: 3961637f04483f8990e2320e333cc2eb7f7c4936e0914399821ee365bfa843b7bdaa335d85176d4f451cf15b6e82a940f45ea3ae65d2968de5603a154bc5641f
6
+ metadata.gz: f9f9c264fa9524b3474f45f4dee0460bc6ec316602908af12cc76d9ff1a7fcd0d7ae4eb7dbc8b3cfe674b1e54841ba288261408b9a51f6ac86d3b42ed66adea5
7
+ data.tar.gz: e30b012604baebe274ff73e3a885a7be5d39f05bc063303dce4409d69da38803bf18d27fc355a5454f3b0425fc89678325b6bef8b5fb4d0a87176fce0cadb252
data/dominate.gemspec CHANGED
@@ -28,4 +28,5 @@ Gem::Specification.new do |spec|
28
28
  spec.add_development_dependency "pry"
29
29
  spec.add_development_dependency "awesome_print"
30
30
  spec.add_development_dependency "slim"
31
+ spec.add_development_dependency "cuba"
31
32
  end
data/lib/dominate/dom.rb CHANGED
@@ -73,7 +73,11 @@ module Dominate
73
73
  private
74
74
 
75
75
  def set_doc html
76
- @doc = Nokogiri::HTML.parse html
76
+ if html.match(/<html.*>/)
77
+ @doc = Nokogiri::HTML::Document.parse html
78
+ else
79
+ @doc = Nokogiri::HTML.fragment html
80
+ end
77
81
  end
78
82
 
79
83
  def reset_html
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
- file = "#{path}.#{type}"
24
+ f = "#{path}.#{type}"
25
25
 
26
- if File.file? file
27
- template = Tilt.new file
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
@@ -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
- super
20
+ @__instance__.send 'method_missing', method, *args, &block
21
21
  end
22
22
  end
23
23
  end
@@ -1,3 +1,3 @@
1
1
  module Dominate
2
- VERSION = "0.5.2"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -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
 
@@ -0,0 +1,11 @@
1
+ class OtherWidget < Dominate::Widget
2
+ respond_to :test, for: :some_widget, with: :some_widget_test
3
+
4
+ def display
5
+ render
6
+ end
7
+
8
+ def some_widget_test
9
+ res.write 'cow'
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ h1
2
+ | Hello, #{@var}
3
+ = hello
@@ -0,0 +1,2 @@
1
+ | moo
2
+ = render_widget :some_widget
@@ -0,0 +1,17 @@
1
+ class SomeWidget < Dominate::Widget
2
+ respond_to :test
3
+
4
+ def display
5
+ @var = 'World!'
6
+
7
+ render
8
+ end
9
+
10
+ def test data
11
+ render
12
+ end
13
+
14
+ def hello
15
+ "Hello, World!"
16
+ end
17
+ end
data/test/helper.rb CHANGED
@@ -1,2 +1,4 @@
1
+ require 'dominate'
2
+ require 'slim'
1
3
  require 'pry'
2
4
  require 'awesome_print'
@@ -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
@@ -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.5.2
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-03 00:00:00.000000000 Z
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
- - test/dominate_test.rb
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