cells 4.0.0.rc1 → 4.0.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/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>
|