breezy 0.1.1 → 0.1.3

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: bdb89b96ab7b57f15c03452a4b837750946635ac
4
- data.tar.gz: c87b2f313de0c13f1ba6373850e9b07fe5e1a82d
3
+ metadata.gz: 8ce62034c621228792d356fbfaa25033f2636132
4
+ data.tar.gz: 6f29e954b0b7402138e5e2c0f63736f1880c3638
5
5
  SHA512:
6
- metadata.gz: d1eb1c5bf8d46964e6b79819f8d67e94616f8810b782c69cdccd0508359b43b00ff1ed03ba0e5f301e4a02b91b8a02431821375dc73afb54a913e0b954e99e6d
7
- data.tar.gz: a3d62b3e1c163bbe520ad74d7082a0681481a57146b0d6d72baf2da245eb3ed50f4ebab69a4e3f65481710ba38501b9de820d6172ed33df497d2ac6cf08ac24f
6
+ metadata.gz: a1d54e6480b866bdd8d6bd36d1b31106a78c25c892e6101f7e1aff6a9ec8c703ef40b36555fae584806e1728302e1c01df9dba518a6b39e9eaca988763af0428
7
+ data.tar.gz: 9bb3e30225f2df6796e35e3e221ddf0509ea334ae98452a79115a27326e2d72d0b7ca7aa8ab72b50389c27e91343e9df2c7735faee27976ecf538d769dfd91c1
data/README.md CHANGED
@@ -45,12 +45,12 @@ Use the included BreezyTemplates to create your content.
45
45
 
46
46
  json.heading @greeting
47
47
 
48
- # `defer: true` will no-op the following block on a direct
48
+ # `defer: :auto` will no-op the following block on a direct
49
49
  # visit, use null as a standin value, and append additional
50
50
  # javascript in the response to fetch only this content node
51
51
  # (no-oping other sibiling blocks) and graft it in the right
52
52
  # place on the client side.
53
- json.dashboard(defer: true) do
53
+ json.dashboard(defer: :auto) do
54
54
  sleep 10
55
55
  json.num_of_views 100
56
56
  end
@@ -274,16 +274,28 @@ would become
274
274
  ```
275
275
 
276
276
  ### Deferment
277
- You can defer rendering of expensive content using the `defer: true` option available in blocks. Behind the scenes BreezyTemplates will no-op the block entirely, replace the value with a `null` as a standin, and append a `Breezy.visit(/somepath?_breezy_filter=keypath.to.node)` to the response. When the client recieves the payload, `breezy:load` will be fired, then the appended `Breezy.visit` will be called to fetch and graft the missing node before firing `breezy:load` a second time.
277
+ You can defer rendering of expensive content using the `defer: :auto` option available in blocks. Behind the scenes BreezyTemplates will no-op the block entirely, replace the value with a `null` as a standin, and append a `Breezy.visit(/somepath?_breezy_filter=keypath.to.node)` to the response. When the client recieves the payload, `breezy:load` will be fired, then the appended `Breezy.visit` will be called to fetch and graft the missing node before firing `breezy:load` a second time.
278
278
 
279
279
  Usage:
280
280
  ```ruby
281
- json.dashboard(defer: true) do
281
+ json.dashboard(defer: :auto) do
282
282
  sleep 10
283
283
  json.some_fancy_metric 42
284
284
  end
285
285
  ```
286
286
 
287
+ A manual option is also available:
288
+
289
+ ```ruby
290
+ json.dashboard(defer: :manual) do
291
+ sleep 10
292
+ json.some_fancy_metric 42
293
+ end
294
+ ```
295
+ If `:manual` is used, Breezy will no-op the block and not append `Breezy.visit` to the payload. Its up to you to use [node filtering](#filtering_nodes) to fetch the node seperately. A common usecase would be tab content that does not load until you click the tab.
296
+
297
+
298
+
287
299
  #### Working with arrays
288
300
  If you want to defer elements in an array, you should add a key as an option on `array!` to help breezy generate a more specific keypath, otherwise it'll just use the index.
289
301
 
@@ -291,7 +303,7 @@ If you want to defer elements in an array, you should add a key as an option on
291
303
  data = [{id: 1, name: 'foo'}, {id: 2, name: 'bar'}]
292
304
 
293
305
  json.array! data, key: :id do
294
- json.greeting defer: true do
306
+ json.greeting defer: :auto do
295
307
  json.greet 'hi'
296
308
  end
297
309
  end
@@ -1,3 +1,3 @@
1
1
  module Breezy
2
- VERSION = '0.1.1'
2
+ VERSION = '0.1.3'
3
3
  end
@@ -0,0 +1,48 @@
1
+ module BreezyTemplate
2
+ module DefermentExtension
3
+ ACTIVE_MODES = [:auto, :manual].freeze
4
+
5
+ def set!(key, value = BLANK, *args)
6
+ options = args.first || {}
7
+ options = _normalize_options(options)
8
+ if ::Kernel.block_given? && _deferment_enabled?(options)
9
+ if _deferment_auto?(options)
10
+ @js.push(_breezy_visit_current(@path))
11
+ end
12
+ return _set_value key, nil
13
+ else
14
+ super
15
+ end
16
+ end
17
+
18
+ def _deferment_auto?(options)
19
+ options[:defer] == :auto
20
+ end
21
+
22
+ def _deferment_enabled?(options)
23
+ ACTIVE_MODES.include?(options[:defer]) && (@search_path.nil? || @search_path.size == 0)
24
+ end
25
+
26
+ def _set_request_url(request_path)
27
+ @request_path = request_path
28
+ end
29
+
30
+ def _deferment_options?(options)
31
+ ::Hash === options && options.key?(:defer)
32
+ end
33
+
34
+ def _mapping_element(element, options)
35
+ if _deferment_enabled? options
36
+ if options.has_key? :key
37
+ id_name = options[:key]
38
+ id_val = element[id_name]
39
+ ::Hash[id_name, id_val]
40
+ else
41
+ nil
42
+ end
43
+ else
44
+ super
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,47 @@
1
+ # This was taken from jbuilder
2
+
3
+ dependency_tracker = false
4
+
5
+ begin
6
+ require 'action_view'
7
+ require 'action_view/dependency_tracker'
8
+ dependency_tracker = ::ActionView::DependencyTracker
9
+ rescue LoadError
10
+ begin
11
+ require 'cache_digests'
12
+ dependency_tracker = ::CacheDigests::DependencyTracker
13
+ rescue LoadError
14
+ end
15
+ end
16
+
17
+ if dependency_tracker
18
+ class BreezyTemplate::Template
19
+ module DependencyTrackerMethods
20
+ # Matches:
21
+ # json.partial! partial: "comments/comment"
22
+ # json.comments @post.comments, partial: "comments/comment", as: :comment
23
+ # json.array! @posts, partial: "posts/post", as: :post
24
+ # = render partial: "account"
25
+ #
26
+ INDIRECT_RENDERS = /
27
+ (?::partial\s*=>|partial:) # partial: or :partial =>
28
+ \s* # optional whitespace
29
+ (['"])([^'"]+)\1 # quoted value
30
+ /x
31
+
32
+ def dependencies
33
+ indirect_dependencies + explicit_dependencies
34
+ end
35
+
36
+ private
37
+
38
+ def indirect_dependencies
39
+ source.scan(INDIRECT_RENDERS).map(&:second)
40
+ end
41
+ end
42
+ end
43
+
44
+ ::BreezyTemplate::DependencyTracker = Class.new(dependency_tracker::ERBTracker)
45
+ ::BreezyTemplate::DependencyTracker.send :include, ::BreezyTemplate::Template::DependencyTrackerMethods
46
+ dependency_tracker.register_tracker :breezy, ::BreezyTemplate::DependencyTracker
47
+ end
@@ -0,0 +1,30 @@
1
+ require 'action_view'
2
+ require 'action_view/digestor'
3
+
4
+ module BreezyTemplate
5
+ module PartialDigestor
6
+ if ::Rails.version >= '5.0'
7
+ def _partial_digestor(options)
8
+ name = options[:name]
9
+ finder = options[:finder]
10
+ ::ActionView::Digestor.digest(name: name, finder: finder)
11
+ end
12
+ elsif ::Rails.version >= '4.1'
13
+ def _partial_digestor(options)
14
+ name = options[:name]
15
+ finder = options[:finder]
16
+ ::ActionView::PartialDigestor.new(name: name, finder: finder).digest
17
+ end
18
+ elsif ::Rails.version >= '4.0'
19
+ def _partial_digestor(options={})
20
+ name = options[:name]
21
+ finder = options[:finder]
22
+ ::ActionView::PartialDigestor.new(name, finder.formats.last, finder).digest
23
+ end
24
+ else
25
+ def _partial_digestor(options)
26
+ options[:name]
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,43 @@
1
+ module BreezyTemplate
2
+ class Handler
3
+ cattr_accessor :default_format
4
+ self.default_format = Mime[:js]
5
+
6
+ def self.call(template)
7
+ # this juggling is required to keep line numbers right in the error
8
+ %{__already_defined = defined?(json); json||=::BreezyTemplate::Template.new(self);json._filter_by_path(breezy_filter) if defined?(breezy_filter); json._set_request_url(request.path);#{template.source}
9
+ if !(__already_defined && __already_defined != "method")
10
+ json.merge!({data: json.found! || json.empty! })
11
+ if defined?(breezy) && breezy
12
+ breezy.each do |k, v|
13
+ json.set! k, v
14
+ end
15
+ end
16
+
17
+ if protect_against_forgery?
18
+ json.csrf_token form_authenticity_token
19
+ end
20
+
21
+ if ::Breezy.configuration.track_assets.any?
22
+ json.assets do
23
+ json.array! (::Breezy.configuration.track_assets || []).map{|assets|
24
+ asset_path(assets)
25
+ }
26
+ end
27
+ end
28
+
29
+ if defined?(breezy_filter) && !!breezy_filter
30
+ json.action 'graft'
31
+ json.path breezy_filter
32
+ end
33
+
34
+ if defined?(session) && session
35
+ session.delete(:breezy_filter)
36
+ end
37
+
38
+ json.target!
39
+ end
40
+ }
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,87 @@
1
+ module BreezyTemplate
2
+ module PartialExtension
3
+ def set!(key, value = BLANK, *args)
4
+ options = args.first || {}
5
+ options = _normalize_options(options)
6
+ if args.one? && _partial_options?(options)
7
+ _set_inline_partial key, value, options
8
+ else
9
+ super
10
+ end
11
+ end
12
+
13
+ def _fragment_name_with_digest(key, options)
14
+ if options[:partial] && !options[:skip_digest]
15
+ [key, _partial_digest(options[:partial])]
16
+ else
17
+ super
18
+ end
19
+ end
20
+
21
+ def array!(collection = [], *attributes)
22
+ options = attributes.first || {}
23
+ options = _normalize_options(options)
24
+
25
+ if attributes.one? && _partial_options?(options)
26
+ _render_partial_with_options(options.merge(collection: collection))
27
+ else
28
+ super
29
+ end
30
+ end
31
+
32
+ def _partial_options?(options)
33
+ ::Hash === options && options.key?(:partial)
34
+ end
35
+
36
+ def _partial_digest(partial)
37
+ lookup_context = @context.lookup_context
38
+ name = lookup_context.find(partial, lookup_context.prefixes, true).virtual_path
39
+ _partial_digestor({name: name, finder: lookup_context})
40
+ end
41
+
42
+ def _set_inline_partial(name, object, options)
43
+ value = if object.nil?
44
+ []
45
+ elsif _is_collection?(object)
46
+ _scope{ _render_partial_with_options options.merge(collection: object) }
47
+ else
48
+ locals = {}
49
+ locals[options[:as]] = object if !_blank?(object) && options.key?(:as)
50
+ locals.merge!(options[:locals]) if options.key? :locals
51
+
52
+ _cache(*options[:cache]) {
53
+ _scope{ _render_partial options.merge(locals: locals) }
54
+ }
55
+ end
56
+
57
+ set! name, value
58
+ end
59
+
60
+ def _render_partial(options)
61
+ options[:locals].merge! json: self
62
+ @context.render options
63
+ end
64
+
65
+ def _render_partial_with_options(options)
66
+ ary_opts = options.dup
67
+ options.reverse_merge! locals: {}
68
+ options.reverse_merge! ::BreezyTemplate::Template.template_lookup_options
69
+ as = options[:as]
70
+
71
+ if options.key?(:collection)
72
+ collection = options.delete(:collection)
73
+ locals = options.delete(:locals)
74
+
75
+ ary_opts.delete(:partial)
76
+ array! collection, ary_opts do |member|
77
+ member_locals = locals.clone
78
+ member_locals.merge! collection: collection
79
+ member_locals.merge! as.to_sym => member if as
80
+ _render_partial options.merge(locals: member_locals)
81
+ end
82
+ else
83
+ _render_partial options
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,83 @@
1
+ module BreezyTemplate
2
+ module SearchExtension
3
+ def found!
4
+ found = @found
5
+ @found = nil
6
+ @search_path = []
7
+ found
8
+ end
9
+
10
+ def array!(collection = [], *attributes)
11
+ original_search_path = @search_path
12
+ super
13
+ ensure
14
+ @search_path = original_search_path
15
+ end
16
+
17
+ def _filter_by_path(search_path)
18
+ if search_path.is_a? ::String
19
+ return _filter_by_path(search_path.split('.'))
20
+ end
21
+ @search_path = search_path
22
+ end
23
+
24
+ def _prepare_collection_for_map(collection)
25
+ if @search_path && !@search_path.empty?
26
+ id_name, id_val = @search_path.first.split('=')
27
+
28
+ @search_path = @search_path[1..-1]
29
+
30
+ if (defined? ::ActiveRecord) && collection.is_a?(::ActiveRecord::Relation)
31
+ if id_val
32
+ id_val = id_val.to_i
33
+ collection = collection.where(::Hash[id_name, id_val])
34
+ else
35
+ index = id_name.to_i
36
+ collection = collection.offset(index).limit(1)
37
+ end
38
+ else
39
+ if id_val
40
+ id_val = id_val.to_i
41
+ found = collection.find do |ele|
42
+ ele[id_name] == id_val || ele[id_name.to_sym] == id_val
43
+ end
44
+ else
45
+ index = id_name.to_i
46
+ found = collection[index]
47
+ end
48
+
49
+ collection = [found]
50
+ end
51
+ else
52
+ super
53
+ end
54
+ end
55
+
56
+ def set!(key, value = BLANK, *args)
57
+ options = args.first || {}
58
+ options = _normalize_options(options)
59
+
60
+ if ::Kernel.block_given? && @search_path && !@search_path.empty?
61
+ if key.to_s == @search_path.first
62
+ original_search_path = @search_path
63
+ @search_path = original_search_path[1..-1]
64
+ if @search_path.size == 0
65
+ @found = if _cache_options?(options)
66
+ _cache(*options[:cache]) { _scope { yield self } }
67
+ else
68
+ _scope { yield self }
69
+ end
70
+ else
71
+ yield self
72
+ end
73
+
74
+ @search_path = original_search_path
75
+ end
76
+
77
+ return _blank
78
+ else
79
+ super
80
+ end
81
+ end
82
+ end
83
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: breezy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Johny Ho
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-15 00:00:00.000000000 Z
11
+ date: 2017-04-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: coffee-rails
@@ -126,6 +126,12 @@ files:
126
126
  - lib/breezy/xhr_redirect.rb
127
127
  - lib/breezy/xhr_url_for.rb
128
128
  - lib/breezy_template.rb
129
+ - lib/breezy_template/deferment_extension.rb
130
+ - lib/breezy_template/dependency_tracker.rb
131
+ - lib/breezy_template/digestor.rb
132
+ - lib/breezy_template/handler.rb
133
+ - lib/breezy_template/partial_extension.rb
134
+ - lib/breezy_template/search_extension.rb
129
135
  - test/blade_helper.rb
130
136
  - test/breezy_template_test.rb
131
137
  - test/breezy_test.rb