cells 4.0.0.rc1 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +8 -5
- data/README.md +130 -408
- data/lib/cell.rb +1 -0
- data/lib/cell/concept.rb +20 -13
- data/lib/cell/escaped.rb +27 -0
- data/lib/cell/rails.rb +4 -0
- data/lib/cell/railtie.rb +3 -3
- data/lib/cell/version.rb +1 -1
- data/test/concept_test.rb +10 -3
- data/test/property_test.rb +41 -0
- data/test/rails4.2/app/cells/form_for_cell.rb +0 -4
- data/test/rails4.2/app/cells/formtastic_cell.rb +0 -4
- data/test/rails4.2/app/cells/simple_form_cell.rb +0 -4
- data/test/rails4.2/app/cells/song/with_escaped.erb +1 -0
- data/test/rails4.2/app/cells/song_cell.rb +6 -0
- data/test/rails4.2/app/controllers/songs_controller.rb +8 -0
- data/test/rails4.2/app/models/song.rb +1 -1
- data/test/rails4.2/app/views/songs/with_escaped.html.erb +1 -0
- data/test/rails4.2/config/routes.rb +3 -0
- data/test/rails4.2/test/integration/controller_test.rb +5 -1
- data/test/rails4.2/test/integration/url_helper_test.rb +11 -0
- metadata +8 -10
- data/lib/cell/engines.rb +0 -61
- data/test/rails4.2/public/404.html +0 -67
- data/test/rails4.2/public/422.html +0 -67
- data/test/rails4.2/public/500.html +0 -66
- data/test/rails4.2/public/favicon.ico +0 -0
- data/test/rails4.2/public/robots.txt +0 -5
data/lib/cell.rb
CHANGED
data/lib/cell/concept.rb
CHANGED
@@ -1,19 +1,26 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
module Cell
|
2
|
+
class Concept < Cell::ViewModel
|
3
|
+
abstract!
|
4
|
+
self.view_paths = ["app/concepts"]
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
# TODO: this should be in Helper or something. this should be the only entry point from controller/view.
|
7
|
+
class << self
|
8
|
+
def class_from_cell_name(name)
|
9
|
+
name.classify.constantize
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
12
|
+
def controller_path
|
13
|
+
@controller_path ||= util.underscore(name.sub(/::Cell/, ''))
|
14
|
+
end
|
13
15
|
end
|
14
|
-
end
|
15
16
|
|
16
|
-
|
17
|
+
alias_method :concept, :cell # Concept#concept does exactly what #cell does: delegate to class builder.
|
17
18
|
|
18
|
-
|
19
|
+
# Get nested cell in instance.
|
20
|
+
def cell(name, model=nil, options={})
|
21
|
+
ViewModel.cell(name, model, options.merge(controller: parent_controller)) # #cell calls need to be delegated to ViewModel.
|
22
|
+
end
|
23
|
+
|
24
|
+
self_contained!
|
25
|
+
end
|
19
26
|
end
|
data/lib/cell/escaped.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module Cell::ViewModel::Escaped
|
2
|
+
def self.included(includer)
|
3
|
+
includer.extend Property
|
4
|
+
end
|
5
|
+
|
6
|
+
module Property
|
7
|
+
def property(name, *args)
|
8
|
+
super.tap do # super defines #title
|
9
|
+
mod = Module.new do
|
10
|
+
define_method(name) do |options={}|
|
11
|
+
value = super() # call the original #title.
|
12
|
+
return value unless value.is_a?(String)
|
13
|
+
return value if options[:escape] == false
|
14
|
+
escape!(value)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
include mod
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end # Property
|
21
|
+
|
22
|
+
# Can be used as a helper in the cell, too.
|
23
|
+
# Feel free to override and use a different escaping implementation.
|
24
|
+
def escape!(string)
|
25
|
+
::ERB::Util.html_escape(string)
|
26
|
+
end
|
27
|
+
end
|
data/lib/cell/rails.rb
CHANGED
@@ -41,6 +41,10 @@ module Cell
|
|
41
41
|
delegates :parent_controller, :session, :params, :request, :config, :env, :url_options
|
42
42
|
end
|
43
43
|
|
44
|
+
def protect_against_forgery? # TODO: implement forgery protection with ActionController.
|
45
|
+
false
|
46
|
+
end
|
47
|
+
|
44
48
|
def call(*)
|
45
49
|
super.html_safe
|
46
50
|
end
|
data/lib/cell/railtie.rb
CHANGED
@@ -50,9 +50,9 @@ module Cell
|
|
50
50
|
# TODO: allow to turn off this.
|
51
51
|
initializer "cells.include_template_module", after: "cells.include_default_helpers" do
|
52
52
|
# yepp, this is happening. saves me a lot of coding in each extension.
|
53
|
-
ViewModel.send(:include, Cell::Erb) if Cell.const_defined?(:Erb)
|
54
|
-
ViewModel.send(:include, Cell::Haml) if Cell.const_defined?(:Haml)
|
55
|
-
ViewModel.send(:include, Cell::Slim) if Cell.const_defined?(:Slim)
|
53
|
+
ViewModel.send(:include, Cell::Erb) if Cell.const_defined?(:Erb, false)
|
54
|
+
ViewModel.send(:include, Cell::Haml) if Cell.const_defined?(:Haml, false)
|
55
|
+
ViewModel.send(:include, Cell::Slim) if Cell.const_defined?(:Slim, false)
|
56
56
|
end
|
57
57
|
# ViewModel.template_engine = app.config.app_generators.rails.fetch(:template_engine, 'erb').to_s
|
58
58
|
|
data/lib/cell/version.rb
CHANGED
data/test/concept_test.rb
CHANGED
@@ -63,12 +63,19 @@ class ConceptTest < MiniTest::Spec
|
|
63
63
|
it { Cell::Concept.cell("record/cell/song").show.must_equal "Lalala" }
|
64
64
|
end
|
65
65
|
|
66
|
-
|
66
|
+
|
67
|
+
class RecordCell < Cell::ViewModel
|
68
|
+
def description
|
69
|
+
"Record! A Tribute To Rancid, with #{@options[:tracks]} songs! [#{parent_controller}]"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#cell (in state)" do
|
67
74
|
# test with controller, but remove tests when we don't need it anymore.
|
68
|
-
it { Cell::Concept.cell("record/cell", nil, controller: Object).cell("record
|
75
|
+
it { Cell::Concept.cell("record/cell", nil, controller: Object).cell("concept_test/record", nil, tracks: 24).(:description).must_equal "Record! A Tribute To Rancid, with 24 songs! [Object]" }
|
69
76
|
it { Cell::Concept.cell("record/cell", nil, controller: Object).concept("record/cell", nil, tracks: 24).(:description).must_equal "A Tribute To Rancid, with 24 songs! [Object]" }
|
70
77
|
# concept(.., collection: ..)
|
71
|
-
it
|
78
|
+
it { Cell::Concept.cell("record/cell", nil, controller: Object).
|
72
79
|
concept("record/cell", collection: [1,2], tracks: 24, method: :description).must_equal "A Tribute To Rancid, with 24 songs! [Object]A Tribute To Rancid, with 24 songs! [Object]" }
|
73
80
|
end
|
74
81
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class PropertyTest < MiniTest::Spec
|
4
|
+
class SongCell < Cell::ViewModel
|
5
|
+
property :title
|
6
|
+
|
7
|
+
def title
|
8
|
+
super + "</b>"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
let (:song) { Struct.new(:title).new("<b>She Sells And Sand Sandwiches") }
|
13
|
+
# ::property creates automatic accessor.
|
14
|
+
it { SongCell.(song).title.must_equal "<b>She Sells And Sand Sandwiches</b>" }
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
class EscapedPropertyTest < MiniTest::Spec
|
19
|
+
class SongCell < Cell::ViewModel
|
20
|
+
include Escaped
|
21
|
+
property :title
|
22
|
+
property :artist
|
23
|
+
|
24
|
+
def title(*)
|
25
|
+
"#{super}</b>" # super + "</b>" still escapes, but this is Rails.
|
26
|
+
end
|
27
|
+
|
28
|
+
def raw_title
|
29
|
+
title(escape: false)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
let (:song) { Struct.new(:title, :artist).new("<b>She Sells And Sand Sandwiches", Object) }
|
34
|
+
|
35
|
+
# ::property escapes, everywhere.
|
36
|
+
it { SongCell.(song).title.must_equal "<b>She Sells And Sand Sandwiches</b>" }
|
37
|
+
# no escaping for non-strings.
|
38
|
+
it { SongCell.(song).artist.must_equal Object }
|
39
|
+
# no escaping when escape: false
|
40
|
+
it { SongCell.(song).raw_title.must_equal "<b>She Sells And Sand Sandwiches</b>" }
|
41
|
+
end
|
@@ -6,10 +6,6 @@ class SimpleFormCell < Cell::ViewModel
|
|
6
6
|
# include ActiveSupport::Configurable
|
7
7
|
# include ActionController::RequestForgeryProtection # FIXME: this does NOT activate any protection.
|
8
8
|
|
9
|
-
def protect_against_forgery?
|
10
|
-
false
|
11
|
-
end
|
12
|
-
|
13
9
|
def show
|
14
10
|
render
|
15
11
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<b><%= title %></b>
|
@@ -0,0 +1 @@
|
|
1
|
+
<h1>Yeah!</h1><%= cell(:song, Song.new(title: "<script>")).(:with_escaped) %>
|
@@ -3,10 +3,14 @@ require "test_helper"
|
|
3
3
|
class ControllerTest < ActionController::TestCase
|
4
4
|
tests SongsController
|
5
5
|
|
6
|
-
# TODO: test url stuff in Song#show.
|
7
6
|
it do
|
8
7
|
get :index
|
9
8
|
response.body.must_equal "happy"
|
10
9
|
end
|
11
10
|
|
11
|
+
# HTML escaping.
|
12
|
+
it do
|
13
|
+
get :with_escaped
|
14
|
+
response.body.must_equal "<h1>Yeah!</h1><b><script></b>" # only the property is escaped.
|
15
|
+
end
|
12
16
|
end
|
@@ -33,4 +33,15 @@ class UrlTest < ActionDispatch::IntegrationTest
|
|
33
33
|
# visit "/songs/1/edit"
|
34
34
|
# page.text.must_equal "http://www.example.com/songs/1"
|
35
35
|
# end
|
36
|
+
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
class AssetsHelperTest < ActionController::TestCase
|
41
|
+
tests SongsController
|
42
|
+
|
43
|
+
it do
|
44
|
+
get :with_image_tag
|
45
|
+
response.body.must_equal "<img src=\"/images/logo.png\" alt=\"Logo\" />"
|
46
|
+
end
|
36
47
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cells
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.0
|
4
|
+
version: 4.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: uber
|
@@ -126,7 +126,7 @@ files:
|
|
126
126
|
- lib/cell/caching/notification.rb
|
127
127
|
- lib/cell/concept.rb
|
128
128
|
- lib/cell/development.rb
|
129
|
-
- lib/cell/
|
129
|
+
- lib/cell/escaped.rb
|
130
130
|
- lib/cell/layout.rb
|
131
131
|
- lib/cell/partial.rb
|
132
132
|
- lib/cell/prefixes.rb
|
@@ -210,6 +210,7 @@ files:
|
|
210
210
|
- test/layout_test.rb
|
211
211
|
- test/partial_test.rb
|
212
212
|
- test/prefixes_test.rb
|
213
|
+
- test/property_test.rb
|
213
214
|
- test/public_test.rb
|
214
215
|
- test/rails4.2/.gitignore
|
215
216
|
- test/rails4.2/Gemfile
|
@@ -224,6 +225,7 @@ files:
|
|
224
225
|
- test/rails4.2/app/cells/simple_form/show.erb
|
225
226
|
- test/rails4.2/app/cells/simple_form_cell.rb
|
226
227
|
- test/rails4.2/app/cells/song/song.css
|
228
|
+
- test/rails4.2/app/cells/song/with_escaped.erb
|
227
229
|
- test/rails4.2/app/cells/song_cell.rb
|
228
230
|
- test/rails4.2/app/controllers/application_controller.rb
|
229
231
|
- test/rails4.2/app/controllers/concerns/.keep
|
@@ -238,6 +240,7 @@ files:
|
|
238
240
|
- test/rails4.2/app/views/index/index.html.erb
|
239
241
|
- test/rails4.2/app/views/layouts/application.html.erb
|
240
242
|
- test/rails4.2/app/views/songs/show.html.erb
|
243
|
+
- test/rails4.2/app/views/songs/with_escaped.html.erb
|
241
244
|
- test/rails4.2/bin/bundle
|
242
245
|
- test/rails4.2/bin/rails
|
243
246
|
- test/rails4.2/bin/rake
|
@@ -289,11 +292,6 @@ files:
|
|
289
292
|
- test/rails4.2/lib/assets/.keep
|
290
293
|
- test/rails4.2/lib/tasks/.keep
|
291
294
|
- test/rails4.2/log/.keep
|
292
|
-
- test/rails4.2/public/404.html
|
293
|
-
- test/rails4.2/public/422.html
|
294
|
-
- test/rails4.2/public/500.html
|
295
|
-
- test/rails4.2/public/favicon.ico
|
296
|
-
- test/rails4.2/public/robots.txt
|
297
295
|
- test/rails4.2/test/integration/asset_pipeline_test.rb
|
298
296
|
- test/rails4.2/test/integration/controller_test.rb
|
299
297
|
- test/rails4.2/test/integration/form_for_test.rb
|
@@ -323,9 +321,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
323
321
|
version: '0'
|
324
322
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
325
323
|
requirements:
|
326
|
-
- - "
|
324
|
+
- - ">="
|
327
325
|
- !ruby/object:Gem::Version
|
328
|
-
version:
|
326
|
+
version: '0'
|
329
327
|
requirements: []
|
330
328
|
rubyforge_project:
|
331
329
|
rubygems_version: 2.2.2
|
data/lib/cell/engines.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
module Cell
|
2
|
-
# Now <tt>Rails::Engine</tt>s can contribute to Cells view paths.
|
3
|
-
# By default, any 'app/cells' found inside any Engine is automatically included into Cells view paths.
|
4
|
-
#
|
5
|
-
# You can customize the view paths changing/appending to the <tt>'app/cell_views'</tt> path configuration:
|
6
|
-
#
|
7
|
-
# module MyAwesome
|
8
|
-
# class Engine < Rails::Engine
|
9
|
-
# # loads views from 'cell/views' and NOT from 'app/cells'
|
10
|
-
# config.paths.add 'app/cell_views', :with => 'cell/views'
|
11
|
-
#
|
12
|
-
# # appends 'lib/my_cells_view_path' to this Railtie view path contribution
|
13
|
-
# config.paths['app/cell_views'] << 'lib/my_cells_view_path'
|
14
|
-
# end
|
15
|
-
# end
|
16
|
-
#
|
17
|
-
# You can manually specify which Engines will be added to Cell view paths
|
18
|
-
#
|
19
|
-
# Cell::Base.config.view_path_engines = [MyAwesome::Engine]
|
20
|
-
#
|
21
|
-
# And even disable the automatic loading
|
22
|
-
#
|
23
|
-
# Cell::Base.config.view_path_engines = false
|
24
|
-
#
|
25
|
-
# You can programatically append a Rails::Engine to Cell view path
|
26
|
-
#
|
27
|
-
# Cells.setup do |config|
|
28
|
-
# config.append_engine_view_path!(MyEngine::Engine)
|
29
|
-
# end
|
30
|
-
#
|
31
|
-
module Engines
|
32
|
-
extend VersionStrategy # adds #registered_engines and #existent_directories_for.
|
33
|
-
|
34
|
-
# Appends all <tt>Rails::Engine</tt>s cell-views path to Cell::Base#view_paths
|
35
|
-
#
|
36
|
-
# All <tt>Rails::Engine</tt>s specified at <tt>config.view_path_engines</tt> will have its cell-views path appended to Cell::Base#view_paths
|
37
|
-
#
|
38
|
-
# Defaults <tt>config.view_path_engines</tt> to all loaded <tt>Rails::Engine</tt>s.
|
39
|
-
#
|
40
|
-
def self.append_engines_view_paths_for(config)
|
41
|
-
return if config.view_path_engines == false
|
42
|
-
|
43
|
-
engines = config.view_path_engines || registered_engines #::Rails::Application::Railties.engines
|
44
|
-
engines.each {|engine| append_engine_view_path!(engine) }
|
45
|
-
end
|
46
|
-
|
47
|
-
# Appends a <tt>Rails::Engine</tt> cell-views path to @Cell::Base@
|
48
|
-
#
|
49
|
-
# The <tt>Rails::Engine</tt> cell-views path is obtained from the <tt>paths['app/cell_views']</tt> configuration.
|
50
|
-
# All existing directories specified at cell-views path will be appended do Cell::Base#view_paths
|
51
|
-
#
|
52
|
-
# Defaults <tt>paths['app/cell_views']</tt> to 'app/cells'
|
53
|
-
#
|
54
|
-
def self.append_engine_view_path!(engine)
|
55
|
-
return unless engine.is_a?(::Rails::Engine) # In Rails 4.1, this could be a Rails::Railtie, which doesn't make sense.
|
56
|
-
|
57
|
-
engine.paths['app/cell_views'] || engine.paths.add('app/cell_views', :with => 'app/cells')
|
58
|
-
Cell::Rails.append_view_path(existent_directories_for(engine.paths["app/cell_views"]))
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
@@ -1,67 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<html>
|
3
|
-
<head>
|
4
|
-
<title>The page you were looking for doesn't exist (404)</title>
|
5
|
-
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
-
<style>
|
7
|
-
body {
|
8
|
-
background-color: #EFEFEF;
|
9
|
-
color: #2E2F30;
|
10
|
-
text-align: center;
|
11
|
-
font-family: arial, sans-serif;
|
12
|
-
margin: 0;
|
13
|
-
}
|
14
|
-
|
15
|
-
div.dialog {
|
16
|
-
width: 95%;
|
17
|
-
max-width: 33em;
|
18
|
-
margin: 4em auto 0;
|
19
|
-
}
|
20
|
-
|
21
|
-
div.dialog > div {
|
22
|
-
border: 1px solid #CCC;
|
23
|
-
border-right-color: #999;
|
24
|
-
border-left-color: #999;
|
25
|
-
border-bottom-color: #BBB;
|
26
|
-
border-top: #B00100 solid 4px;
|
27
|
-
border-top-left-radius: 9px;
|
28
|
-
border-top-right-radius: 9px;
|
29
|
-
background-color: white;
|
30
|
-
padding: 7px 12% 0;
|
31
|
-
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
-
}
|
33
|
-
|
34
|
-
h1 {
|
35
|
-
font-size: 100%;
|
36
|
-
color: #730E15;
|
37
|
-
line-height: 1.5em;
|
38
|
-
}
|
39
|
-
|
40
|
-
div.dialog > p {
|
41
|
-
margin: 0 0 1em;
|
42
|
-
padding: 1em;
|
43
|
-
background-color: #F7F7F7;
|
44
|
-
border: 1px solid #CCC;
|
45
|
-
border-right-color: #999;
|
46
|
-
border-left-color: #999;
|
47
|
-
border-bottom-color: #999;
|
48
|
-
border-bottom-left-radius: 4px;
|
49
|
-
border-bottom-right-radius: 4px;
|
50
|
-
border-top-color: #DADADA;
|
51
|
-
color: #666;
|
52
|
-
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
-
}
|
54
|
-
</style>
|
55
|
-
</head>
|
56
|
-
|
57
|
-
<body>
|
58
|
-
<!-- This file lives in public/404.html -->
|
59
|
-
<div class="dialog">
|
60
|
-
<div>
|
61
|
-
<h1>The page you were looking for doesn't exist.</h1>
|
62
|
-
<p>You may have mistyped the address or the page may have moved.</p>
|
63
|
-
</div>
|
64
|
-
<p>If you are the application owner check the logs for more information.</p>
|
65
|
-
</div>
|
66
|
-
</body>
|
67
|
-
</html>
|