emerson 0.0.11 → 0.1.0.pre.1
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.
- data/README.md +0 -12
- data/emerson.gemspec +2 -0
- data/lib/emerson.rb +3 -1
- data/lib/emerson/rails/engine.rb +3 -1
- data/lib/emerson/responder.rb +167 -0
- data/lib/emerson/response.rb +11 -0
- data/lib/emerson/scope.rb +91 -0
- data/lib/emerson/version.rb +1 -1
- data/vendor/assets/javascripts/emerson.js +1 -2
- data/vendor/assets/javascripts/emerson/base.js +1 -1
- data/vendor/assets/javascripts/emerson/sink.js +5 -39
- metadata +29 -8
data/README.md
CHANGED
@@ -2,8 +2,6 @@
|
|
2
2
|
|
3
3
|
transcendent views. (WIP)
|
4
4
|
|
5
|
-
See <http://coreyti.github.com/emerson-js/>
|
6
|
-
|
7
5
|
## Installation
|
8
6
|
|
9
7
|
Add this line to your application's Gemfile:
|
@@ -29,13 +27,3 @@ TODO: Write usage instructions here
|
|
29
27
|
3. Commit your changes (`git commit -am 'Added some feature'`)
|
30
28
|
4. Push to the branch (`git push origin my-new-feature`)
|
31
29
|
5. Create new Pull Request
|
32
|
-
|
33
|
-
## Credits
|
34
|
-
|
35
|
-
* Contributions (roughly chronologically)
|
36
|
-
* [Corey Innis](http://github.com/coreyti):<br/>
|
37
|
-
Author/maintainer
|
38
|
-
* [Rachel Heaton](https://github.com/rheaton):<br/>
|
39
|
-
Feedback and bugfixes
|
40
|
-
* [Doug Rohrer](https://github.com/JeetKunDoug):<br/>
|
41
|
-
Feedback and bugfixes
|
data/emerson.gemspec
CHANGED
data/lib/emerson.rb
CHANGED
data/lib/emerson/rails/engine.rb
CHANGED
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'action_controller/base'
|
2
|
+
|
3
|
+
module Emerson
|
4
|
+
class Responder < ActionController::Responder
|
5
|
+
# class << self
|
6
|
+
# def base_decorator=(value)
|
7
|
+
# @@base_decorator = value
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# def base_decorator
|
11
|
+
# # NOTE: requires definition of BaseDecorator
|
12
|
+
# @@base_decorator ||= BaseDecorator
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
|
16
|
+
delegate :render_to_string, :to => :controller
|
17
|
+
|
18
|
+
def initialize(*)
|
19
|
+
super
|
20
|
+
# NOTE: don't love the @resource ivar...
|
21
|
+
# may be able to remove in favor of layouts
|
22
|
+
controller.instance_variable_set(:"@resource", decorate(resource))
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_html
|
26
|
+
render(render_args)
|
27
|
+
rescue ActionView::MissingTemplate
|
28
|
+
debug(:missing_template)
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_json
|
33
|
+
# JSON rendering:
|
34
|
+
# 1. try xxx.json.erb
|
35
|
+
# 2. fail over to xxx.html.erb
|
36
|
+
controller.formats = [:json, :html]
|
37
|
+
|
38
|
+
render({
|
39
|
+
:json => {
|
40
|
+
:data => locals,
|
41
|
+
:view => render_to_string(render_args(:layout => false)).gsub(/\n/, '').presence,
|
42
|
+
}
|
43
|
+
# TODO: consider adding (with proper logic)...
|
44
|
+
# :location => location,
|
45
|
+
# :status => status
|
46
|
+
})
|
47
|
+
rescue ActionView::MissingTemplate
|
48
|
+
debug(:missing_template)
|
49
|
+
to_format
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def action
|
55
|
+
@_action ||= (@action || controller.action_name).intern
|
56
|
+
end
|
57
|
+
|
58
|
+
def decorated_resources
|
59
|
+
# NOTE: would like to use controller.current_scope, but i claimed that for the symbol
|
60
|
+
scope = controller.instance_variable_get(:"@scope")
|
61
|
+
results = ([scope] + resources).compact
|
62
|
+
decorate(results)
|
63
|
+
end
|
64
|
+
|
65
|
+
def locals
|
66
|
+
@_locals ||= begin
|
67
|
+
base = (options[:locals] || {})
|
68
|
+
base.each do |k, v|
|
69
|
+
base[k] = decorate(v)
|
70
|
+
end
|
71
|
+
|
72
|
+
decorated_resources.inject(base) do |memo, object|
|
73
|
+
memo[key_for(object)] = object
|
74
|
+
memo
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def render_args(overrides = {})
|
80
|
+
# TODO: spec me!
|
81
|
+
@_render_args ||= begin
|
82
|
+
if options[:layout] == :scoped
|
83
|
+
options.delete(:layout)
|
84
|
+
options[:layout] = controller.current_scope.to_s if controller.current_scope.present?
|
85
|
+
end
|
86
|
+
|
87
|
+
options.merge({
|
88
|
+
:template => template,
|
89
|
+
:locals => locals
|
90
|
+
}).merge(overrides) # TODO: options first?
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def template
|
95
|
+
@_template ||= begin
|
96
|
+
if options[:location].present?
|
97
|
+
nil
|
98
|
+
elsif (path = options[:path])
|
99
|
+
# TODO: spec me!
|
100
|
+
if path == :scoped
|
101
|
+
options[:path] = template_built(controller.current_scope)
|
102
|
+
end
|
103
|
+
|
104
|
+
options[:path]
|
105
|
+
else
|
106
|
+
template_built
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def template_built(prefix = nil)
|
112
|
+
@_template_default ||= [prefix, template_base, template_method].compact.join('/')
|
113
|
+
end
|
114
|
+
|
115
|
+
def template_base
|
116
|
+
@_template_base ||= controller.controller_path
|
117
|
+
end
|
118
|
+
|
119
|
+
def template_method
|
120
|
+
@_template_method ||= if get?
|
121
|
+
action
|
122
|
+
elsif delete?
|
123
|
+
:index
|
124
|
+
elsif has_errors?
|
125
|
+
default_action
|
126
|
+
else
|
127
|
+
:show
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def decorate(object)
|
132
|
+
# ActiveDecorator::Decorator.instance.decorate(object)
|
133
|
+
object
|
134
|
+
end
|
135
|
+
|
136
|
+
def key_for(object)
|
137
|
+
if object == resource
|
138
|
+
key_for_primary
|
139
|
+
else
|
140
|
+
key_for_related(object)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# The primary resource is keyed per the request.
|
145
|
+
def key_for_primary
|
146
|
+
@_key_for_primary ||= if options[:as]
|
147
|
+
options[:as]
|
148
|
+
else
|
149
|
+
controller_name = controller.controller_name
|
150
|
+
(resource.respond_to?(:each) ? controller_name : controller_name.singularize).intern
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def key_for_related(object)
|
155
|
+
# for now, assume :model_name
|
156
|
+
object.class.model_name.element.intern
|
157
|
+
end
|
158
|
+
|
159
|
+
def debug(type)
|
160
|
+
# TODO: check Emerson.debug?
|
161
|
+
case type
|
162
|
+
when :missing_template
|
163
|
+
controller.logger.warn("Emerson::Responder failed to locate template: #{render_args[:template].inspect}")
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'action_controller/base'
|
2
|
+
|
3
|
+
module Emerson
|
4
|
+
module Scope
|
5
|
+
def self.included(base)
|
6
|
+
base.class_eval do
|
7
|
+
extend ClassMethods
|
8
|
+
# TODO: consider...
|
9
|
+
# helper_method :current_scope
|
10
|
+
class_attribute :scope_configuration
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def scope(*args)
|
16
|
+
options = args.extract_options!
|
17
|
+
resources = args.shift
|
18
|
+
|
19
|
+
unless options.key?(:by)
|
20
|
+
raise ArgumentError.new(".scopes requires a :by option")
|
21
|
+
end
|
22
|
+
|
23
|
+
unless resources.present?
|
24
|
+
raise ArgumentError.new(".scopes requires a (plural) resources type")
|
25
|
+
end
|
26
|
+
|
27
|
+
self.scope_configuration ||= [resources, []]
|
28
|
+
self.scope_configuration[1] += [options[:by]].flatten
|
29
|
+
self.scope_configuration[1].uniq!
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def scoped(explicit = nil)
|
34
|
+
@_scoped ||= begin
|
35
|
+
if scope_configuration.present?
|
36
|
+
target = scope_configuration.first
|
37
|
+
|
38
|
+
if explicit.present?
|
39
|
+
@scope = explicit
|
40
|
+
@scope.send(target)
|
41
|
+
elsif scope = scope_from_params
|
42
|
+
@scope = scope
|
43
|
+
@scope.send(target)
|
44
|
+
else
|
45
|
+
@scope = nil # be explicit
|
46
|
+
class_for(singular(target)).scoped
|
47
|
+
end
|
48
|
+
else
|
49
|
+
@scope = nil # be explicit
|
50
|
+
default_scope
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def current_scope
|
56
|
+
@_current_scope ||= begin
|
57
|
+
if @scope.present?
|
58
|
+
@scope.class.model_name.plural.intern
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
protected
|
64
|
+
|
65
|
+
def scope_from_params
|
66
|
+
param = nil
|
67
|
+
type = self.scope_configuration.last.find { |scope| (param = params["#{scope}_id"]) && param }
|
68
|
+
|
69
|
+
return nil unless type
|
70
|
+
|
71
|
+
class_for(type).find(param)
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def class_for(type)
|
77
|
+
type.to_s.classify.constantize
|
78
|
+
rescue
|
79
|
+
nil
|
80
|
+
end
|
81
|
+
|
82
|
+
def default_scope
|
83
|
+
klass = class_for(singular(self.class.name.sub(/Controller$/, '')))
|
84
|
+
klass.scoped
|
85
|
+
end
|
86
|
+
|
87
|
+
def singular(plural)
|
88
|
+
plural.to_s.singularize
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/lib/emerson/version.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
|
-
// Emerson.js 0.0.
|
1
|
+
// Emerson.js 0.0.10
|
2
2
|
//
|
3
3
|
// (c) 2012 Corey Innis
|
4
4
|
// Emerson may be freely distributed under the MIT license.
|
5
5
|
// For all details and documentation:
|
6
6
|
// http://coolerator.net
|
7
7
|
|
8
|
-
// = require underscore.js
|
9
8
|
// = require emerson/base.js
|
10
9
|
// = require emerson/util.js
|
11
10
|
// = require emerson/http.js
|
@@ -21,7 +21,7 @@
|
|
21
21
|
}
|
22
22
|
|
23
23
|
// Current version of the library. Keep in sync with `package.json`.
|
24
|
-
Emerson.VERSION = '0.0.
|
24
|
+
Emerson.VERSION = '0.0.10';
|
25
25
|
|
26
26
|
// Reference the base lib (one of jQuery, Zepto or Ender) as $.
|
27
27
|
var $ = Emerson.base = (root.jQuery || root.Zepto || root.ender);
|
@@ -1,8 +1,5 @@
|
|
1
1
|
// Emerson Sink
|
2
2
|
//
|
3
|
-
// "sink - a body or process that acts to absorb or remove energy or a
|
4
|
-
// particular component from a system."
|
5
|
-
//
|
6
3
|
// Adds...
|
7
4
|
|
8
5
|
(function(ns) {
|
@@ -110,21 +107,17 @@
|
|
110
107
|
|
111
108
|
// ### process
|
112
109
|
// ...
|
113
|
-
// TODO: DRY-up the update code.
|
114
110
|
function process(element, matches) {
|
115
111
|
var parts, strategy, clone;
|
116
112
|
|
117
113
|
if(matches.length > 1) {
|
118
|
-
matches.each(function(
|
119
|
-
current = $(this);
|
114
|
+
matches.each(function() {
|
120
115
|
clone = prepare(element.clone(true));
|
121
|
-
parts =
|
116
|
+
parts = $(this).data('sink').split(':');
|
122
117
|
strategy = parts[1] || 'replace';
|
123
118
|
|
124
|
-
|
125
|
-
strategies[strategy]
|
126
|
-
.call(clone, current)
|
127
|
-
.each(forceCalculateStyle)
|
119
|
+
$(this).trigger('sink:before');
|
120
|
+
strategies[strategy].call(clone, $(this))
|
128
121
|
.trigger('sink:after');
|
129
122
|
|
130
123
|
clone.trigger('sink:after');
|
@@ -135,35 +128,8 @@
|
|
135
128
|
strategy = parts[1] || 'replace';
|
136
129
|
|
137
130
|
matches.trigger('sink:before');
|
138
|
-
strategies[strategy]
|
139
|
-
.call(prepare(element), matches)
|
140
|
-
.each(forceCalculateStyle)
|
131
|
+
strategies[strategy].call(prepare(element), matches)
|
141
132
|
.trigger('sink:after');
|
142
133
|
}
|
143
134
|
}
|
144
|
-
|
145
|
-
// ### forceCalculateStyle
|
146
|
-
//
|
147
|
-
// forceCalculateStyle.call(node)
|
148
|
-
//
|
149
|
-
// Given a DOM node, force style calculation. e.g., this might be useful for
|
150
|
-
// establishing a render baseline to enable CSS animations. Note that the
|
151
|
-
// particular property accessed is arbitrary.
|
152
|
-
//
|
153
|
-
// TODO: Add spec coverage (needs pre-/post-render and some CSS transition).
|
154
|
-
//
|
155
|
-
// Credits:
|
156
|
-
//
|
157
|
-
// * Doug Rohrer & Rachel Heaton for the bug fix:
|
158
|
-
// <https://github.com/coreyti/emerson/pull/9>
|
159
|
-
function forceCalculateStyle() {
|
160
|
-
if(this.jquery) {
|
161
|
-
window.getComputedStyle(this[0]).opacity;
|
162
|
-
}
|
163
|
-
else {
|
164
|
-
window.getComputedStyle(this).opacity;
|
165
|
-
}
|
166
|
-
|
167
|
-
return this;
|
168
|
-
}
|
169
135
|
})(Emerson);
|
metadata
CHANGED
@@ -1,16 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: emerson
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.0.pre.1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Corey Innis
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
dependencies:
|
12
|
+
date: 2012-10-17 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.2.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.2.0
|
14
30
|
description: transcendent views
|
15
31
|
email:
|
16
32
|
- corey@coolerator.net
|
@@ -31,6 +47,9 @@ files:
|
|
31
47
|
- lib/emerson.rb
|
32
48
|
- lib/emerson/rails.rb
|
33
49
|
- lib/emerson/rails/engine.rb
|
50
|
+
- lib/emerson/responder.rb
|
51
|
+
- lib/emerson/response.rb
|
52
|
+
- lib/emerson/scope.rb
|
34
53
|
- lib/emerson/version.rb
|
35
54
|
- vendor/assets/javascripts/emerson.js
|
36
55
|
- vendor/assets/javascripts/emerson/base.js
|
@@ -51,17 +70,19 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
51
70
|
- - ! '>='
|
52
71
|
- !ruby/object:Gem::Version
|
53
72
|
version: '0'
|
73
|
+
segments:
|
74
|
+
- 0
|
75
|
+
hash: 4474276250162900765
|
54
76
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
77
|
none: false
|
56
78
|
requirements:
|
57
|
-
- - ! '
|
79
|
+
- - ! '>'
|
58
80
|
- !ruby/object:Gem::Version
|
59
|
-
version:
|
81
|
+
version: 1.3.1
|
60
82
|
requirements: []
|
61
83
|
rubyforge_project:
|
62
|
-
rubygems_version: 1.8.
|
84
|
+
rubygems_version: 1.8.24
|
63
85
|
signing_key:
|
64
86
|
specification_version: 3
|
65
87
|
summary: emerson believes in the inherent good in...
|
66
88
|
test_files: []
|
67
|
-
has_rdoc:
|