render_async 2.1.4 → 2.1.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,38 +5,32 @@
5
5
  <%= placeholder %>
6
6
  </<%= html_element_name %>>
7
7
 
8
- <% content_for :render_async do %>
8
+ <% content_for content_for_name do %>
9
9
  <%= javascript_tag html_options do %>
10
+ <% locals = { container_id: container_id,
11
+ replace_container: replace_container,
12
+ path: path,
13
+ method: method,
14
+ data: data,
15
+ event_name: event_name,
16
+ toggle: toggle,
17
+ headers: headers,
18
+ error_message: error_message,
19
+ error_event_name: error_event_name,
20
+ retry_count: retry_count,
21
+ retry_delay: retry_delay,
22
+ interval: interval,
23
+ turbolinks: RenderAsync.configuration.turbolinks,
24
+ turbo: RenderAsync.configuration.turbo} %>
25
+
10
26
  <% if RenderAsync.configuration.jquery %>
11
27
  <%= render partial: 'render_async/request_jquery',
12
28
  formats: [:js],
13
- locals: { container_id: container_id,
14
- path: path,
15
- method: method,
16
- data: data,
17
- event_name: event_name,
18
- toggle: toggle,
19
- headers: headers,
20
- error_message: error_message,
21
- error_event_name: error_event_name,
22
- retry_count: retry_count,
23
- interval: interval,
24
- turbolinks: RenderAsync.configuration.turbolinks } %>
29
+ locals: locals %>
25
30
  <% else %>
26
31
  <%= render partial: 'render_async/request_vanilla',
27
32
  formats: [:js],
28
- locals: { container_id: container_id,
29
- path: path,
30
- method: method,
31
- data: data,
32
- event_name: event_name,
33
- toggle: toggle,
34
- headers: headers,
35
- error_message: error_message,
36
- error_event_name: error_event_name,
37
- retry_count: retry_count,
38
- interval: interval,
39
- turbolinks: RenderAsync.configuration.turbolinks } %>
33
+ locals: locals %>
40
34
  <% end %>
41
35
  <% end %>
42
36
  <% end %>
@@ -5,8 +5,39 @@ if (window.jQuery) {
5
5
  return;
6
6
  }
7
7
  <% end %>
8
+ <% if turbo %>
9
+ if (document.documentElement.hasAttribute("data-turbo-preview")) {
10
+ return;
11
+ }
12
+ <% end %>
13
+ function createEvent(name, container) {
14
+ var event = undefined;
15
+ if (typeof(Event) === 'function') {
16
+ event = new Event(name);
17
+ } else {
18
+ event = document.createEvent('Event');
19
+ event.initEvent(name, true, true);
20
+ }
21
+ event.container = container
22
+ return event;
23
+ }
24
+
25
+ function _runAfterDocumentLoaded(callback) {
26
+ if (document.readyState === 'complete' || document.readyState === 'interactive') {
27
+ // Handle a case where nested partials get loaded after the document loads
28
+ callback();
29
+ } else {
30
+ <% if turbolinks %>
31
+ $(document).one('turbolinks:load', callback);
32
+ <% elsif turbo %>
33
+ $(document).one('turbo:load', callback);
34
+ <% else %>
35
+ $(document).ready(callback);
36
+ <% end %>
37
+ }
38
+ }
8
39
 
9
- var _makeRequest = function(currentRetryCount) {
40
+ function _makeRequest(currentRetryCount) {
10
41
  var headers = <%= headers.to_json.html_safe %>;
11
42
  var csrfTokenElement = document.querySelector('meta[name="csrf-token"]')
12
43
  if (csrfTokenElement)
@@ -18,21 +49,19 @@ if (window.jQuery) {
18
49
  data: "<%= escape_javascript(data.to_s.html_safe) %>",
19
50
  headers: headers
20
51
  }).done(function(response) {
21
- <% if interval %>
22
- $("#<%= container_id %>").empty();
23
- $("#<%= container_id %>").append(response);
52
+ var container = $("#<%= container_id %>");
53
+ <% if !interval && replace_container %>
54
+ container.replaceWith(response);
24
55
  <% else %>
25
- $("#<%= container_id %>").replaceWith(response);
56
+ container.empty();
57
+ container.append(response);
26
58
  <% end %>
27
59
 
60
+ var loadEvent = createEvent('render_async_load', container);
61
+ document.dispatchEvent(loadEvent);
62
+
28
63
  <% if event_name.present? %>
29
- var event = undefined;
30
- if (typeof(Event) === 'function') {
31
- event = new Event("<%= event_name %>");
32
- } else {
33
- event = document.createEvent('Event');
34
- event.initEvent('<%= event_name %>', true, true);
35
- }
64
+ var event = createEvent("<%= event_name %>", container)
36
65
  document.dispatchEvent(event);
37
66
  <% end %>
38
67
  }).fail(function(response) {
@@ -43,64 +72,114 @@ if (window.jQuery) {
43
72
 
44
73
  if (skipErrorMessage) return;
45
74
 
46
- $("#<%= container_id %>").replaceWith("<%= error_message.try(:html_safe) %>");
75
+ var container = $("#<%= container_id %>");
76
+ container.replaceWith("<%= error_message.try(:html_safe) %>");
47
77
 
48
- <% if error_event_name.present? %>
49
- var event = undefined;
50
- if (typeof(Event) === 'function') {
51
- event = new Event("<%= error_event_name %>");
52
- } else {
53
- event = document.createEvent('Event');
54
- event.initEvent('<%= error_event_name %>', true, true);
55
- }
56
- document.dispatchEvent(event);
57
- <% end %>
78
+ var errorEvent = createEvent(
79
+ "<%= error_event_name || 'render_async_error' %>",
80
+ container
81
+ )
82
+ errorEvent.retryCount = currentRetryCount
83
+
84
+ document.dispatchEvent(errorEvent);
58
85
  });
59
86
  };
60
87
 
61
88
  <% if retry_count > 0 %>
62
- var retry = function(currentRetryCount) {
89
+ var _retryMakeRequest = _makeRequest
90
+
91
+ <% if retry_delay %>
92
+ _retryMakeRequest = function(currentRetryCount) {
93
+ setTimeout(function() {
94
+ _makeRequest(currentRetryCount)
95
+ }, <%= retry_delay %>)
96
+ }
97
+ <% end %>
98
+
99
+ function retry(currentRetryCount) {
63
100
  if (typeof(currentRetryCount) === 'number') {
64
101
  if (currentRetryCount >= <%= retry_count %>)
65
102
  return false;
66
103
 
67
- _makeRequest(currentRetryCount + 1);
104
+ _retryMakeRequest(currentRetryCount + 1);
68
105
  return true;
69
106
  }
70
107
 
71
- _makeRequest(1);
108
+ _retryMakeRequest(1);
72
109
  return true;
73
110
  }
74
111
  <% end %>
75
112
 
76
113
  var _renderAsyncFunction = _makeRequest;
77
114
 
78
- <% if interval %>
79
115
  var _interval;
116
+ <% if interval %>
80
117
  var _renderAsyncFunction = function() {
118
+ // If interval is already set, return
119
+ if (typeof(_interval) === 'number') return
120
+
81
121
  _makeRequest();
82
122
  _interval = setInterval(_makeRequest, <%= interval %>);
83
123
  }
84
- <% end %>
85
124
 
86
- <% if toggle %>
87
- $(document).<%= toggle[:once] ? 'one' : 'on' %>('<%= toggle[:event] || 'click' %>', '<%= toggle[:selector] %>', function(event) {
88
- event.preventDefault();
89
- if (typeof(_interval) === 'number') {
90
- clearInterval(_interval);
125
+ var _clearRenderAsyncInterval = function() {
126
+ if (typeof(_interval) === 'number'){
127
+ clearInterval(_interval)
91
128
  _interval = undefined;
92
- } else {
93
- _renderAsyncFunction();
94
129
  }
95
- });
130
+ }
131
+
132
+ function _setUpControlEvents() {
133
+ var container = $("#<%= container_id %>");
134
+
135
+ // Register a stop polling event on the container
136
+ $(container).on('async-stop', _clearRenderAsyncInterval)
137
+
138
+ // Register a start polling event on the container
139
+ $(container).on('async-start', _renderAsyncFunction)
140
+ }
141
+
142
+ _runAfterDocumentLoaded(_setUpControlEvents)
143
+
144
+ <% if turbolinks %>
145
+ $(document).one('turbolinks:visit', _clearRenderAsyncInterval);
146
+ <% end %>
147
+ <% if turbo %>
148
+ $(document).one('turbo:visit', _clearRenderAsyncInterval);
96
149
  <% end %>
150
+ <% end %>
151
+
152
+ <% if !replace_container %>
153
+ function _setUpRefreshEvent() {
154
+ var container = $("#<%= container_id %>");
155
+
156
+ $(container).on('refresh', _renderAsyncFunction)
157
+ }
158
+
159
+ _runAfterDocumentLoaded(_setUpRefreshEvent)
160
+ <% end %>
161
+
162
+ <% if toggle %>
163
+ function _setUpToggle() {
164
+ $(document).<%= toggle[:once] ? 'one' : 'on' %>('<%= toggle[:event] || 'click' %>', '<%= toggle[:selector] %>', function(event) {
165
+ if (typeof(_interval) === 'number') {
166
+ clearInterval(_interval);
167
+ _interval = undefined;
168
+ } else {
169
+ _renderAsyncFunction();
170
+ }
171
+ });
172
+
173
+ <% if toggle[:start] %>
174
+ _renderAsyncFunction()
175
+ <% end %>
176
+ }
97
177
 
98
- <% if turbolinks && !toggle %>
99
- $(document).one('turbolinks:load', _renderAsyncFunction);
178
+ _runAfterDocumentLoaded(_setUpToggle);
100
179
  <% elsif !toggle %>
101
- $(document).ready(_renderAsyncFunction);
180
+ _runAfterDocumentLoaded(_renderAsyncFunction)
102
181
  <% end %>
103
182
  }(jQuery));
104
183
  } else {
105
- console.warn("Looks like you've enabled jQuery for render_async, but jQuery is not defined");
184
+ console.warn("Looks like you've enabled jQuery for render_async, but jQuery is not defined on the window object");
106
185
  };
@@ -4,8 +4,40 @@
4
4
  return;
5
5
  }
6
6
  <% end %>
7
+ <% if turbo %>
8
+ if (document.documentElement.hasAttribute("data-turbo-preview")) {
9
+ return;
10
+ }
11
+ <% end %>
12
+ function createEvent(name, container) {
13
+ var event = undefined;
14
+ if (typeof(Event) === 'function') {
15
+ event = new Event(name);
16
+ } else {
17
+ event = document.createEvent('Event');
18
+ event.initEvent(name, true, true);
19
+ }
20
+ event.container = container
21
+ return event;
22
+ }
23
+
24
+ function _runAfterDocumentLoaded(callback) {
25
+ <% if turbolinks %>
26
+ document.addEventListener("turbolinks:load", function(e) {
27
+ e.target.removeEventListener(e.type, arguments.callee);
28
+ callback();
29
+ });
30
+ <% elsif turbo %>
31
+ document.addEventListener("turbo:load", function(e) {
32
+ e.target.removeEventListener(e.type, arguments.callee);
33
+ callback();
34
+ });
35
+ <% else %>
36
+ document.addEventListener("DOMContentLoaded", callback);
37
+ <% end %>
38
+ }
7
39
 
8
- var _makeRequest = function(currentRetryCount) {
40
+ function _makeRequest(currentRetryCount) {
9
41
  var request = new XMLHttpRequest();
10
42
  var asyncRequest = true;
11
43
  var SUCCESS = 200;
@@ -22,24 +54,23 @@
22
54
  request.setRequestHeader(key, headers[key]);
23
55
  });
24
56
 
57
+ request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
58
+
25
59
  request.onreadystatechange = function() {
26
60
  if (request.readyState === 4) {
27
61
  if (request.status >= SUCCESS && request.status < ERROR) {
28
62
  var container = document.getElementById('<%= container_id %>');
29
- <% if interval %>
30
- container.innerHTML = request.response;
31
- <% else %>
63
+ <% if !interval && replace_container %>
32
64
  container.outerHTML = request.response;
65
+ <% else %>
66
+ container.innerHTML = request.response;
33
67
  <% end %>
34
68
 
69
+ var loadEvent = createEvent('render_async_load', container);
70
+ document.dispatchEvent(loadEvent);
71
+
35
72
  <% if event_name.present? %>
36
- var event = undefined;
37
- if (typeof(Event) === 'function') {
38
- event = new Event("<%= event_name %>");
39
- } else {
40
- event = document.createEvent('Event');
41
- event.initEvent('<%= event_name %>', true, true);
42
- }
73
+ var event = createEvent('<%= event_name %>', container);
43
74
  document.dispatchEvent(event);
44
75
  <% end %>
45
76
  } else {
@@ -51,18 +82,15 @@
51
82
  if (skipErrorMessage) return;
52
83
 
53
84
  var container = document.getElementById('<%= container_id %>');
54
- container.outerHTML = "<%= error_message.try(:html_safe) %>";
55
-
56
- <% if error_event_name.present? %>
57
- var event = undefined;
58
- if (typeof(Event) === 'function') {
59
- event = new Event("<%= error_event_name %>");
60
- } else {
61
- event = document.createEvent('Event');
62
- event.initEvent('<%= error_event_name %>', true, true);
63
- }
64
- document.dispatchEvent(event);
65
- <% end %>
85
+ container.outerHTML = '<%= error_message.try(:html_safe) %>';
86
+
87
+ var errorEvent = createEvent(
88
+ "<%= error_event_name || 'render_async_error' %>",
89
+ container
90
+ );
91
+ errorEvent.retryCount = currentRetryCount
92
+
93
+ document.dispatchEvent(errorEvent);
66
94
  }
67
95
  }
68
96
  };
@@ -72,56 +100,104 @@
72
100
  };
73
101
 
74
102
  <% if retry_count > 0 %>
75
- var retry = function(currentRetryCount) {
103
+
104
+ <% if retry_delay %>
105
+ _retryMakeRequest = function(currentRetryCount) {
106
+ setTimeout(function() {
107
+ _makeRequest(currentRetryCount)
108
+ }, <%= retry_delay %>)
109
+ }
110
+ <% end %>
111
+
112
+ function retry(currentRetryCount) {
76
113
  if (typeof(currentRetryCount) === 'number') {
77
114
  if (currentRetryCount >= <%= retry_count %>)
78
115
  return false;
79
116
 
80
- _makeRequest(currentRetryCount + 1);
117
+ _retryMakeRequest(currentRetryCount + 1);
81
118
  return true;
82
119
  }
83
120
 
84
- _makeRequest(1);
121
+ _retryMakeRequest(1);
85
122
  return true;
86
123
  }
87
124
  <% end %>
88
125
 
89
126
  var _renderAsyncFunction = _makeRequest;
90
127
 
91
- <% if interval %>
92
128
  var _interval;
129
+ <% if interval %>
93
130
  var _renderAsyncFunction = function() {
131
+ // If interval is already set, return
132
+ if (typeof(_interval) === 'number') return
133
+
94
134
  _makeRequest();
95
135
  _interval = setInterval(_makeRequest, <%= interval %>);
96
136
  }
97
- <% end %>
98
137
 
99
- <% if toggle %>
100
- var selectors = document.querySelectorAll('<%= toggle[:selector] %>');
101
- var handler = function(event) {
102
- event.preventDefault();
103
- if (typeof(_interval) === 'number') {
104
- clearInterval(_interval);
138
+ var _clearRenderAsyncInterval = function() {
139
+ if (typeof(_interval) === 'number'){
140
+ clearInterval(_interval)
105
141
  _interval = undefined;
106
- } else {
107
- _renderAsyncFunction();
108
142
  }
109
- <% if toggle[:once] %>
110
- this.removeEventListener(event.type, handler);
111
- <% end %>
112
- };
143
+ }
144
+
145
+ function _setUpControlEvents() {
146
+ var container = document.getElementById('<%= container_id %>');
147
+
148
+ // Register a polling stop event on the container
149
+ container.addEventListener("async-stop", _clearRenderAsyncInterval)
150
+
151
+ // Register a start polling event on the container
152
+ container.addEventListener("async-start", _renderAsyncFunction)
153
+ }
154
+
155
+ _runAfterDocumentLoaded(_setUpControlEvents)
156
+
157
+ <% if turbolinks %>
158
+ document.addEventListener("turbolinks:visit", _clearRenderAsyncInterval)
159
+ <% end %>
160
+ <% if turbo %>
161
+ document.addEventListener("turbo:visit", _clearRenderAsyncInterval)
162
+ <% end %>
163
+ <% end %>
113
164
 
114
- [...selectors].forEach(function(selector) {
115
- selector.addEventListener('<%= toggle[:event] || 'click' %>', handler)
116
- });
165
+ <% if !replace_container %>
166
+ function _setUpRefreshEvent() {
167
+ var container = document.getElementById('<%= container_id %>');
168
+
169
+ container.addEventListener('refresh', _renderAsyncFunction)
170
+ }
171
+
172
+ _runAfterDocumentLoaded(_setUpRefreshEvent)
117
173
  <% end %>
118
174
 
119
- <% if turbolinks && !toggle %>
120
- document.addEventListener("turbolinks:load", function (e) {
121
- e.target.removeEventListener(e.type, arguments.callee);
122
- _renderAsyncFunction();
123
- });
175
+ <% if toggle %>
176
+ function _setUpToggle() {
177
+ var selectors = document.querySelectorAll('<%= toggle[:selector] %>');
178
+ var handler = function(event) {
179
+ if (typeof(_interval) === 'number') {
180
+ clearInterval(_interval);
181
+ _interval = undefined;
182
+ } else {
183
+ _renderAsyncFunction();
184
+ }
185
+ <% if toggle[:once] %>
186
+ this.removeEventListener(event.type, handler);
187
+ <% end %>
188
+ };
189
+
190
+ <% if toggle[:start] %>
191
+ _renderAsyncFunction()
192
+ <% end %>
193
+
194
+ for (var i = 0; i < selectors.length; ++i) {
195
+ selectors[i].addEventListener('<%= toggle[:event] || 'click' %>', handler)
196
+ }
197
+ }
198
+
199
+ _runAfterDocumentLoaded(_setUpToggle);
124
200
  <% elsif !toggle %>
125
- document.addEventListener("DOMContentLoaded", _renderAsyncFunction);
201
+ _runAfterDocumentLoaded(_renderAsyncFunction);
126
202
  <% end %>
127
203
  })();