angular_sprinkles 0.0.4 → 0.0.5

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.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +9 -8
  3. data/Gemfile.lock +41 -13
  4. data/LICENSE.txt +1 -1
  5. data/README.md +4 -38
  6. data/Rakefile +20 -37
  7. data/VERSION +1 -1
  8. data/angular_sprinkles.gemspec +104 -41
  9. data/app/assets/javascripts/angular_sprinkles.js.erb +1 -22
  10. data/lib/angular_sprinkles/constructor.rb +12 -0
  11. data/lib/angular_sprinkles/constructor_collection.rb +20 -0
  12. data/lib/angular_sprinkles/content_cache.rb +15 -0
  13. data/lib/angular_sprinkles/content_yielder.rb +19 -0
  14. data/lib/angular_sprinkles/context.rb +13 -0
  15. data/lib/angular_sprinkles/controller.rb +38 -65
  16. data/lib/angular_sprinkles/counter.rb +12 -0
  17. data/lib/angular_sprinkles/directive/attributes.rb +16 -0
  18. data/lib/angular_sprinkles/directive/input.rb +19 -0
  19. data/lib/angular_sprinkles/directive/name.rb +19 -0
  20. data/lib/angular_sprinkles/directive/options.rb +13 -0
  21. data/lib/angular_sprinkles/helpers/directive_helper.rb +7 -20
  22. data/lib/angular_sprinkles/helpers/service_helper.rb +14 -0
  23. data/lib/angular_sprinkles/helpers.rb +2 -7
  24. data/lib/angular_sprinkles/java_script.rb +55 -0
  25. data/lib/angular_sprinkles/key_generator.rb +14 -0
  26. data/lib/angular_sprinkles/model_decorator.rb +16 -0
  27. data/lib/angular_sprinkles/object_key_wrapper.rb +12 -0
  28. data/lib/angular_sprinkles.rb +20 -14
  29. data/spec/angular_sprinkles/constructor_collection_spec.rb +22 -0
  30. data/spec/angular_sprinkles/constructor_spec.rb +12 -0
  31. data/spec/angular_sprinkles/content_cache_spec.rb +15 -0
  32. data/spec/angular_sprinkles/content_yielder_spec.rb +45 -0
  33. data/spec/angular_sprinkles/context_spec.rb +22 -0
  34. data/spec/angular_sprinkles/counter_spec.rb +15 -0
  35. data/spec/angular_sprinkles/directive/attributes_spec.rb +24 -0
  36. data/spec/angular_sprinkles/directive/input_spec.rb +11 -0
  37. data/spec/angular_sprinkles/directive/name_spec.rb +11 -0
  38. data/spec/angular_sprinkles/directive/options_spec.rb +11 -0
  39. data/spec/angular_sprinkles/key_generator_spec.rb +17 -0
  40. data/spec/angular_sprinkles/model_decorator_spec.rb +24 -0
  41. data/spec/angular_sprinkles/object_key_wrapper_spec.rb +17 -0
  42. data/spec/controllers/test_controller_spec.rb +20 -0
  43. data/spec/dummy/.rspec +3 -0
  44. data/spec/dummy/README.rdoc +28 -0
  45. data/spec/dummy/Rakefile +6 -0
  46. data/spec/dummy/app/assets/images/.keep +0 -0
  47. data/spec/dummy/app/assets/javascripts/application.js +30 -0
  48. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  49. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  50. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  51. data/spec/dummy/app/controllers/test_controller.rb +5 -0
  52. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  53. data/spec/dummy/app/mailers/.keep +0 -0
  54. data/spec/dummy/app/models/.keep +0 -0
  55. data/spec/dummy/app/models/concerns/.keep +0 -0
  56. data/spec/dummy/app/models/test_model.rb +2 -0
  57. data/spec/dummy/app/views/layouts/application.html.erb +15 -0
  58. data/spec/dummy/app/views/test/new.html.erb +9 -0
  59. data/spec/dummy/bin/bundle +3 -0
  60. data/spec/dummy/bin/rails +4 -0
  61. data/spec/dummy/bin/rake +4 -0
  62. data/spec/dummy/config/application.rb +29 -0
  63. data/spec/dummy/config/boot.rb +5 -0
  64. data/spec/dummy/config/database.yml +25 -0
  65. data/spec/dummy/config/environment.rb +5 -0
  66. data/spec/dummy/config/environments/development.rb +37 -0
  67. data/spec/dummy/config/environments/production.rb +82 -0
  68. data/spec/dummy/config/environments/test.rb +39 -0
  69. data/spec/dummy/config/initializers/assets.rb +8 -0
  70. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  71. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  72. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  73. data/spec/dummy/config/initializers/inflections.rb +16 -0
  74. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  75. data/spec/dummy/config/initializers/session_store.rb +3 -0
  76. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  77. data/spec/dummy/config/locales/en.yml +23 -0
  78. data/spec/dummy/config/routes.rb +57 -0
  79. data/spec/dummy/config/secrets.yml +22 -0
  80. data/spec/dummy/config.ru +4 -0
  81. data/spec/dummy/db/migrate/20140908021353_create_test_models.rb +9 -0
  82. data/spec/dummy/db/schema.rb +22 -0
  83. data/spec/dummy/lib/assets/.keep +0 -0
  84. data/spec/dummy/log/.keep +0 -0
  85. data/spec/dummy/public/404.html +67 -0
  86. data/spec/dummy/public/422.html +67 -0
  87. data/spec/dummy/public/500.html +66 -0
  88. data/spec/dummy/public/favicon.ico +0 -0
  89. data/spec/features/javascript_spec.rb +26 -0
  90. data/spec/rails_helper.rb +21 -0
  91. data/spec/spec_helper.rb +82 -21
  92. metadata +103 -29
  93. data/.document +0 -5
  94. data/.rspec +0 -1
  95. data/lib/angular_sprinkles/data/bind.rb +0 -18
  96. data/lib/angular_sprinkles/decorators/bind_decorator.rb +0 -61
  97. data/lib/angular_sprinkles/decorators.rb +0 -6
  98. data/lib/angular_sprinkles/helpers/bind_helper.rb +0 -56
  99. data/lib/angular_sprinkles/helpers/bind_service_helper.rb +0 -27
  100. data/lib/angular_sprinkles/mixins/cache.rb +0 -11
  101. data/lib/angular_sprinkles/mixins/js_transformable.rb +0 -27
  102. data/lib/angular_sprinkles/variable_cache.rb +0 -19
  103. data/spec/controller_spec.rb +0 -74
  104. data/spec/data/bind_spec.rb +0 -11
  105. data/spec/decorators/bind_decorator_spec.rb +0 -56
  106. data/spec/helpers/bind_helper_spec.rb +0 -94
  107. data/spec/helpers/directive_helper_spec.rb +0 -66
  108. data/spec/mixins/js_transformable_spec.rb +0 -45
  109. data/spec/variable_cache_spec.rb +0 -57
@@ -1,23 +1,2 @@
1
1
  //= require angular
2
-
3
- (function (window, document, angular) {
4
-
5
- window.sprinkles = angular.module('<%= AngularSprinkles::APP_NAME %>', []);
6
-
7
- window.onload = function () {
8
- var queue,
9
- app = angular.module('<%= AngularSprinkles::APP_NAME %>'),
10
- doc = document.documentElement,
11
- ctrlName = (doc.attributes['ng-controller'] || doc.attributes['data-ng-controller']) || 'Ctrl';
12
-
13
- ctrlName = ctrlName.split(' as ')[0];
14
-
15
- <%= AngularSprinkles::CONTROLLER_FN %> = <%= AngularSprinkles::CONTROLLER_FN %> || function(){};
16
-
17
- app.controller(ctrlName, <%= AngularSprinkles::CONTROLLER_FN %>);
18
- doc.setAttribute('data-ng-controller', ctrlName + ' as <%= AngularSprinkles::CONTROLLER_NAME %>');
19
-
20
- angular.bootstrap(doc, [app.name]);
21
- };
22
-
23
- }(window, document, window.angular));
2
+ <%= AngularSprinkles::JavaScript::PLUGIN %>
@@ -0,0 +1,12 @@
1
+ module AngularSprinkles
2
+ class Constructor
3
+ def initialize(args)
4
+ @json_wrapper = args.fetch(:json_wrapper)
5
+ @collection = args.fetch(:collection)
6
+ end
7
+
8
+ def to_json
9
+ @json_wrapper.call(@collection)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,20 @@
1
+ module AngularSprinkles
2
+ class ConstructorCollection
3
+ def initialize(args)
4
+ @json_wrapper = args.fetch(:json_wrapper)
5
+ @object_wrapper = args.fetch(:object_wrapper)
6
+ @collection = []
7
+ end
8
+
9
+ def push(object, key)
10
+ bundle = @object_wrapper.new(object, key, @json_wrapper)
11
+
12
+ @collection.push(bundle)
13
+ end
14
+
15
+ def to_json
16
+ @collection.map!(&:to_json).join("\n")
17
+ end
18
+ alias :to_s :to_json
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ module AngularSprinkles
2
+ class ContentCache
3
+ def initialize
4
+ @store = {}
5
+ end
6
+
7
+ def set(content)
8
+ @store[content.to_s] = true
9
+ end
10
+
11
+ def set?(content)
12
+ @store.has_key?(content.to_s)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ module AngularSprinkles
2
+ class ContentYielder
3
+ def initialize(args)
4
+ @context = args.fetch(:context)
5
+ @yield_to = args.fetch(:yield_to)
6
+ @cache = args.fetch(:cache)
7
+ end
8
+
9
+ def call(content)
10
+ return '' if @cache.set?(content)
11
+
12
+ @cache.set(content)
13
+
14
+ @context.content_tag(:script, content.to_json.html_safe).tap do |script_tag|
15
+ @context.content_for(@yield_to, script_tag)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ module AngularSprinkles
2
+ class Context
3
+ attr_reader :key_generator, :constructor, :constructor_collection
4
+ attr_accessor :content_yielder
5
+
6
+ def initialize(args)
7
+ @key_generator = args.fetch(:key_generator)
8
+ @constructor = args.fetch(:constructor)
9
+ @constructor_collection = args.fetch(:constructor_collection)
10
+ @content_yielder = args.fetch(:content_yielder, nil)
11
+ end
12
+ end
13
+ end
@@ -1,79 +1,52 @@
1
- require 'active_record'
2
- require 'angular_sprinkles/mixins/js_transformable'
3
- require 'angular_sprinkles/mixins/cache'
4
- require 'angular_sprinkles/decorators/bind_decorator'
5
-
6
1
  module AngularSprinkles
7
2
  module Controller
8
- include AngularSprinkles::Mixins::JsTransformable
9
- include AngularSprinkles::Mixins::Cache
3
+ def initialize(*args)
4
+ counter = Counter.new
5
+ key_generator = KeyGenerator.new(counter: counter)
10
6
 
11
- def bindable(object)
12
- object = object.to_a if object.is_a?(::ActiveRecord::Relation)
13
- key = object_key(object)
7
+ constructor_collection = ConstructorCollection.new({
8
+ json_wrapper: JavaScript::ConstructorThis,
9
+ object_wrapper: ObjectKeyWrapper
10
+ })
14
11
 
15
- if object.is_a?(Array)
16
- # TODO: Give me some love
17
- object.map!(&method(:bindable))
18
- constructor_keys = object.map { |o| "this.#{o.bind_key}" }
19
- sprinkles_constructor.push("this.#{key} = [#{constructor_keys.join(',')}]")
20
- else
21
- add_to_constructor(key => object)
22
- end
12
+ constructor = Constructor.new({
13
+ json_wrapper: JavaScript::ConstructorWrapper,
14
+ collection: constructor_collection
15
+ })
16
+
17
+ @_sprinkles = Context.new({
18
+ key_generator: key_generator,
19
+ constructor: constructor,
20
+ constructor_collection: constructor_collection
21
+ })
23
22
 
24
- AngularSprinkles::Decorators::Bind.new(object, key, method(:view_context))
23
+ super
25
24
  end
26
25
 
27
- def add_to_constructor(hash)
28
- raise TypeError unless hash.is_a?(Hash)
29
- hash.each do |var_name, value|
30
- _sprinkles_cache.yield_if_new(var_name) do |var|
31
- str = set_constructor_variable(var, value)
32
- sprinkles_constructor.push(str)
33
- end
34
- end
35
- sprinkles_constructor
26
+ def bindable(object)
27
+ object = object.to_a if object.is_a?(::ActiveRecord::Relation)
28
+ object.map!(&method(:bindable)) if object.is_a?(Array)
29
+ key = @_sprinkles.key_generator.call(object)
30
+ @_sprinkles.constructor_collection.push(object, key)
31
+ ModelDecorator.new({
32
+ object: object,
33
+ key: key,
34
+ json_wrapper: JavaScript::BindVariable,
35
+ object_wrapper: ObjectKeyWrapper
36
+ })
36
37
  end
37
38
 
38
39
  def view_context
39
- @_sprinkles_view_context ||= super.tap do |view|
40
- constructor = constructor_wrapper(sprinkles_constructor).gsub(/^\s+/, "")
41
- content = view.content_tag(:script, constructor.html_safe)
42
- view.content_for(:sprinkles, content)
40
+ super.tap do |context|
41
+ @_sprinkles.content_yielder = ContentYielder.new({
42
+ cache: ContentCache.new,
43
+ context: context,
44
+ yield_to: JavaScript::PREFIX
45
+ })
46
+ @_sprinkles.content_yielder.call(@_sprinkles.constructor)
43
47
  end
44
48
  end
45
-
46
- private
47
-
48
- def object_key(object)
49
- klass = object.class
50
- "#{klass}_#{inc_sprinkles_counter(klass)}"
51
- end
52
-
53
- def sprinkles_counter
54
- @_sprinkles_counter ||= {}
55
- end
56
-
57
- def inc_sprinkles_counter(klass)
58
- sprinkles_counter[klass] ||= 0
59
- sprinkles_counter[klass] += 1
60
- end
61
-
62
- def sprinkles_constructor
63
- @_sprinkles_constructor ||= []
64
- end
65
-
66
- def constructor_wrapper(assignments)
67
- <<-WRAPPER
68
- #{CONTROLLER_FN} = #{CONTROLLER_FN} || function ($injector) {
69
- #{assignments.join(";\n") + ";"}
70
-
71
- #{SERVICE_QUEUE}.forEach(function (service) {
72
- this[service] = $injector.get(service);
73
- }.bind(this));
74
- };
75
- #{SERVICE_QUEUE} = [];
76
- WRAPPER
77
- end
78
49
  end
79
50
  end
51
+
52
+ ActionController::Base.send(:include, AngularSprinkles::Controller)
@@ -0,0 +1,12 @@
1
+ module AngularSprinkles
2
+ class Counter
3
+ def initialize
4
+ @klasses = {}
5
+ end
6
+
7
+ def inc(klass)
8
+ @klasses[klass] ||= 0
9
+ @klasses[klass] += 1
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ module AngularSprinkles
2
+ module Directive
3
+ class Attributes
4
+ def initialize(args, options)
5
+ @args = args
6
+ @content = options.fetch(:content, '')
7
+ @tag = options[:tag] || :div
8
+ end
9
+
10
+ def to_content_tag
11
+ attrs = @args.map(&:attributes).inject(&:deep_merge)
12
+ [@tag, @content, attrs]
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ module AngularSprinkles
2
+ module Directive
3
+ class Input
4
+ def initialize(args)
5
+ @args = args.symbolize_keys
6
+ end
7
+
8
+ def attributes
9
+ { data: to_json_hash }
10
+ end
11
+
12
+ private
13
+
14
+ def to_json_hash
15
+ Hash[@args.map { |k, v| [k, v.to_json] }]
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module AngularSprinkles
2
+ module Directive
3
+ class Name
4
+ def initialize(*names)
5
+ @names = names.flatten
6
+ end
7
+
8
+ def attributes
9
+ { data: to_empty_hash }
10
+ end
11
+
12
+ private
13
+
14
+ def to_empty_hash
15
+ Hash[@names.product([''])]
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ module AngularSprinkles
2
+ module Directive
3
+ class Options
4
+ def initialize(args)
5
+ @args = args.symbolize_keys
6
+ end
7
+
8
+ def attributes
9
+ @args
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,29 +1,16 @@
1
- require 'action_view/helpers'
2
-
3
1
  module AngularSprinkles
4
2
  module Helpers
5
3
  module DirectiveHelper
6
- include ::ActionView::Helpers
7
-
8
4
  def directive(name, input = {}, options = {}, &block)
9
- raise TypeError unless [String, Symbol, Array].include?(name.class)
10
- raise TypeError unless input.is_a?(Hash)
11
- raise TypeError unless options.is_a?(Hash)
12
-
13
- input.symbolize_keys!
14
- options.symbolize_keys!
15
-
16
- tag_contents = block_given? ? capture(&block) : ''
17
- tag_attributes = {}
18
- tag_name = options[:tag] || :div
19
-
20
- directive_attributes = Hash[input.map { |k, v| [k, v.to_json] }]
21
- name_attributes = Hash[[name].flatten.product([''])]
5
+ content = capture(&block) if block_given?
22
6
 
23
- tag_attributes[:data] = [directive_attributes, name_attributes].compact.inject(&:merge)
24
- tag_attributes.merge!(options.slice(:class, :style))
7
+ attributes = Directive::Attributes.new([
8
+ Directive::Name.new(name),
9
+ Directive::Input::new(input),
10
+ Directive::Options::new(options.except(:tag))
11
+ ], { tag: options[:tag], content: content })
25
12
 
26
- content_tag(tag_name, tag_contents, tag_attributes)
13
+ content_tag(*attributes.to_content_tag)
27
14
  end
28
15
  end
29
16
  end
@@ -0,0 +1,14 @@
1
+ module AngularSprinkles
2
+ module Helpers
3
+ module ServiceHelper
4
+ def service(service, *input)
5
+ camelized = service.to_s.camelize(:lower)
6
+
7
+ register_service = ObjectKeyWrapper.new(camelized, JavaScript::RegisterService)
8
+ @_sprinkles.content_yielder.call(register_service)
9
+
10
+ ObjectKeyWrapper.new(camelized, input, JavaScript::BindService)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,11 +1,6 @@
1
- require 'angular_sprinkles/helpers/bind_helper'
2
- require 'angular_sprinkles/helpers/bind_service_helper'
3
- require 'angular_sprinkles/helpers/directive_helper'
4
-
5
1
  module AngularSprinkles
6
2
  module Helpers
7
- include Helpers::BindHelper
8
- include Helpers::BindServiceHelper
9
- include Helpers::DirectiveHelper
3
+ include ServiceHelper
4
+ include DirectiveHelper
10
5
  end
11
6
  end
@@ -0,0 +1,55 @@
1
+ module AngularSprinkles
2
+ module JavaScript
3
+ PREFIX = :sprinkles
4
+ APP_NAME = "#{PREFIX}App"
5
+ CONTROLLER_NAME = "#{PREFIX}Ctrl"
6
+ CONTROLLER_FN = "window.#{CONTROLLER_NAME}Fn"
7
+ SERVICE_QUEUE = "#{CONTROLLER_FN}.serviceQueue"
8
+
9
+ PLUGIN = <<-BlockOfJavaScript
10
+ (function (window, document, angular) {
11
+ window.sprinkles = angular.module('#{APP_NAME}', []);
12
+ window.onload = function () {
13
+ var queue,
14
+ app = angular.module('#{APP_NAME}'),
15
+ doc = document.documentElement,
16
+ ctrlName = 'Ctrl';
17
+ #{CONTROLLER_FN} = #{CONTROLLER_FN} || function(){};
18
+ app.controller(ctrlName, #{CONTROLLER_FN});
19
+ doc.setAttribute('data-ng-controller', ctrlName + ' as #{CONTROLLER_NAME}');
20
+ angular.bootstrap(doc, [app.name]);
21
+ };
22
+ }(window, document, window.angular));
23
+ BlockOfJavaScript
24
+
25
+ ConstructorWrapper = ->(string) do
26
+ <<-BlockOfJavaScript
27
+ #{CONTROLLER_FN} = #{CONTROLLER_FN} || function ($injector) {
28
+ #{string};
29
+
30
+ #{SERVICE_QUEUE}.forEach(function (service) {
31
+ this[service] = $injector.get(service);
32
+ }.bind(this));
33
+ #{SERVICE_QUEUE} = [];
34
+ };
35
+ #{SERVICE_QUEUE} = [];
36
+ BlockOfJavaScript
37
+ end
38
+
39
+ ConstructorThis = ->(object, key) do
40
+ "this.#{key} = #{object.to_json};"
41
+ end
42
+
43
+ RegisterService = -> (method) do
44
+ "#{SERVICE_QUEUE}.push('#{method}')"
45
+ end
46
+
47
+ BindService = ->(method, input) do
48
+ "#{CONTROLLER_NAME}.#{method}(#{input.join(',')})"
49
+ end
50
+
51
+ BindVariable = ->(key, attribute) do
52
+ [CONTROLLER_NAME, key, attribute].flatten.compact.join('.')
53
+ end
54
+ end
55
+ end