render_async 2.1.0 → 2.1.11
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 +5 -5
- data/.all-contributorsrc +88 -2
- data/.github/CONTRIBUTING.md +40 -0
- data/.github/FUNDING.yml +3 -0
- data/.gitignore +1 -0
- data/.gitmodules +4 -0
- data/CHANGELOG.md +71 -0
- data/README.md +405 -70
- data/app/views/render_async/_render_async.html.erb +20 -23
- data/app/views/render_async/_request_jquery.js.erb +146 -37
- data/app/views/render_async/_request_vanilla.js.erb +152 -38
- data/bin/integration-tests +7 -0
- data/lib/render_async/configuration.rb +4 -1
- data/lib/render_async/version.rb +1 -1
- data/lib/render_async/view_helper.rb +63 -23
- metadata +8 -7
|
@@ -5,36 +5,33 @@
|
|
|
5
5
|
<%= placeholder %>
|
|
6
6
|
</<%= html_element_name %>>
|
|
7
7
|
|
|
8
|
-
<% content_for
|
|
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_count_header: retry_count_header,
|
|
22
|
+
retry_delay: retry_delay,
|
|
23
|
+
interval: interval,
|
|
24
|
+
turbolinks: RenderAsync.configuration.turbolinks,
|
|
25
|
+
turbo: RenderAsync.configuration.turbo} %>
|
|
26
|
+
|
|
10
27
|
<% if RenderAsync.configuration.jquery %>
|
|
11
28
|
<%= render partial: 'render_async/request_jquery',
|
|
12
29
|
formats: [:js],
|
|
13
|
-
locals:
|
|
14
|
-
path: path,
|
|
15
|
-
method: method,
|
|
16
|
-
data: data,
|
|
17
|
-
event_name: event_name,
|
|
18
|
-
headers: headers,
|
|
19
|
-
error_message: error_message,
|
|
20
|
-
error_event_name: error_event_name,
|
|
21
|
-
retry_count: retry_count,
|
|
22
|
-
interval: interval,
|
|
23
|
-
turbolinks: RenderAsync.configuration.turbolinks } %>
|
|
30
|
+
locals: locals %>
|
|
24
31
|
<% else %>
|
|
25
32
|
<%= render partial: 'render_async/request_vanilla',
|
|
26
33
|
formats: [:js],
|
|
27
|
-
locals:
|
|
28
|
-
path: path,
|
|
29
|
-
method: method,
|
|
30
|
-
data: data,
|
|
31
|
-
event_name: event_name,
|
|
32
|
-
headers: headers,
|
|
33
|
-
error_message: error_message,
|
|
34
|
-
error_event_name: error_event_name,
|
|
35
|
-
retry_count: retry_count,
|
|
36
|
-
interval: interval,
|
|
37
|
-
turbolinks: RenderAsync.configuration.turbolinks } %>
|
|
34
|
+
locals: locals %>
|
|
38
35
|
<% end %>
|
|
39
36
|
<% end %>
|
|
40
37
|
<% end %>
|
|
@@ -5,12 +5,49 @@ 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
|
+
}
|
|
8
24
|
|
|
9
|
-
|
|
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
|
+
}
|
|
39
|
+
|
|
40
|
+
function _makeRequest(currentRetryCount) {
|
|
10
41
|
var headers = <%= headers.to_json.html_safe %>;
|
|
11
|
-
var csrfTokenElement = document.querySelector('meta[name="csrf-token"]')
|
|
42
|
+
var csrfTokenElement = document.querySelector('meta[name="csrf-token"]');
|
|
12
43
|
if (csrfTokenElement)
|
|
13
|
-
headers['X-CSRF-Token'] = csrfTokenElement.content
|
|
44
|
+
headers['X-CSRF-Token'] = csrfTokenElement.content;
|
|
45
|
+
|
|
46
|
+
<% if retry_count_header %>
|
|
47
|
+
if (typeof(currentRetryCount) === 'number') {
|
|
48
|
+
headers['<%= retry_count_header.html_safe %>'] = currentRetryCount;
|
|
49
|
+
}
|
|
50
|
+
<% end %>
|
|
14
51
|
|
|
15
52
|
$.ajax({
|
|
16
53
|
url: '<%= path.html_safe %>',
|
|
@@ -18,21 +55,23 @@ if (window.jQuery) {
|
|
|
18
55
|
data: "<%= escape_javascript(data.to_s.html_safe) %>",
|
|
19
56
|
headers: headers
|
|
20
57
|
}).done(function(response) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
58
|
+
var container = $("#<%= container_id %>");
|
|
59
|
+
|
|
60
|
+
// If user navigated away before the request completed
|
|
61
|
+
if (!container.length) return;
|
|
62
|
+
|
|
63
|
+
<% if !interval && replace_container %>
|
|
64
|
+
container.replaceWith(response);
|
|
24
65
|
<% else %>
|
|
25
|
-
|
|
66
|
+
container.empty();
|
|
67
|
+
container.append(response);
|
|
26
68
|
<% end %>
|
|
27
69
|
|
|
70
|
+
var loadEvent = createEvent('render_async_load', container);
|
|
71
|
+
document.dispatchEvent(loadEvent);
|
|
72
|
+
|
|
28
73
|
<% if event_name.present? %>
|
|
29
|
-
var event =
|
|
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
|
-
}
|
|
74
|
+
var event = createEvent("<%= event_name %>", container)
|
|
36
75
|
document.dispatchEvent(event);
|
|
37
76
|
<% end %>
|
|
38
77
|
}).fail(function(response) {
|
|
@@ -43,48 +82,118 @@ if (window.jQuery) {
|
|
|
43
82
|
|
|
44
83
|
if (skipErrorMessage) return;
|
|
45
84
|
|
|
46
|
-
$("#<%= container_id %>")
|
|
85
|
+
var container = $("#<%= container_id %>");
|
|
86
|
+
if (!container.length) return;
|
|
47
87
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
<% end %>
|
|
88
|
+
container.replaceWith("<%= error_message.try(:html_safe) %>");
|
|
89
|
+
|
|
90
|
+
var errorEvent = createEvent(
|
|
91
|
+
"<%= error_event_name || 'render_async_error' %>",
|
|
92
|
+
container
|
|
93
|
+
)
|
|
94
|
+
errorEvent.retryCount = currentRetryCount
|
|
95
|
+
|
|
96
|
+
document.dispatchEvent(errorEvent);
|
|
58
97
|
});
|
|
59
98
|
};
|
|
60
99
|
|
|
61
100
|
<% if retry_count > 0 %>
|
|
62
|
-
var
|
|
101
|
+
var _retryMakeRequest = _makeRequest
|
|
102
|
+
|
|
103
|
+
<% if retry_delay %>
|
|
104
|
+
_retryMakeRequest = function(currentRetryCount) {
|
|
105
|
+
setTimeout(function() {
|
|
106
|
+
_makeRequest(currentRetryCount)
|
|
107
|
+
}, <%= retry_delay %>)
|
|
108
|
+
}
|
|
109
|
+
<% else %>
|
|
110
|
+
_retryMakeRequest = _makeRequest
|
|
111
|
+
<% end %>
|
|
112
|
+
|
|
113
|
+
function retry(currentRetryCount) {
|
|
63
114
|
if (typeof(currentRetryCount) === 'number') {
|
|
64
115
|
if (currentRetryCount >= <%= retry_count %>)
|
|
65
116
|
return false;
|
|
66
117
|
|
|
67
|
-
|
|
118
|
+
_retryMakeRequest(currentRetryCount + 1);
|
|
68
119
|
return true;
|
|
69
120
|
}
|
|
70
121
|
|
|
71
|
-
|
|
122
|
+
_retryMakeRequest(1);
|
|
72
123
|
return true;
|
|
73
124
|
}
|
|
74
125
|
<% end %>
|
|
75
126
|
|
|
127
|
+
var _renderAsyncFunction = _makeRequest;
|
|
128
|
+
|
|
129
|
+
var _interval;
|
|
130
|
+
<% if interval %>
|
|
131
|
+
var _renderAsyncFunction = function() {
|
|
132
|
+
// If interval is already set, return
|
|
133
|
+
if (typeof(_interval) === 'number') return
|
|
134
|
+
|
|
135
|
+
_makeRequest();
|
|
136
|
+
_interval = setInterval(_makeRequest, <%= interval %>);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
var _clearRenderAsyncInterval = function() {
|
|
140
|
+
if (typeof(_interval) === 'number'){
|
|
141
|
+
clearInterval(_interval)
|
|
142
|
+
_interval = undefined;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function _setUpControlEvents() {
|
|
147
|
+
var container = $("#<%= container_id %>");
|
|
148
|
+
|
|
149
|
+
// Register a stop polling event on the container
|
|
150
|
+
$(container).on('async-stop', _clearRenderAsyncInterval)
|
|
151
|
+
|
|
152
|
+
// Register a start polling event on the container
|
|
153
|
+
$(container).on('async-start', _renderAsyncFunction)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
_runAfterDocumentLoaded(_setUpControlEvents)
|
|
157
|
+
|
|
76
158
|
<% if turbolinks %>
|
|
77
|
-
$(document).one('turbolinks:
|
|
78
|
-
<%
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
159
|
+
$(document).one('turbolinks:visit', _clearRenderAsyncInterval);
|
|
160
|
+
<% end %>
|
|
161
|
+
<% if turbo %>
|
|
162
|
+
$(document).one('turbo:visit', _clearRenderAsyncInterval);
|
|
163
|
+
<% end %>
|
|
164
|
+
<% end %>
|
|
165
|
+
|
|
166
|
+
<% if !replace_container %>
|
|
167
|
+
function _setUpRefreshEvent() {
|
|
168
|
+
var container = $("#<%= container_id %>");
|
|
169
|
+
|
|
170
|
+
$(container).on('refresh', _renderAsyncFunction)
|
|
82
171
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
172
|
+
|
|
173
|
+
_runAfterDocumentLoaded(_setUpRefreshEvent)
|
|
174
|
+
<% end %>
|
|
175
|
+
|
|
176
|
+
<% if toggle %>
|
|
177
|
+
function _setUpToggle() {
|
|
178
|
+
$(document).<%= toggle[:once] ? 'one' : 'on' %>('<%= toggle[:event] || 'click' %>', '<%= toggle[:selector] %>', function(event) {
|
|
179
|
+
if (typeof(_interval) === 'number') {
|
|
180
|
+
clearInterval(_interval);
|
|
181
|
+
_interval = undefined;
|
|
182
|
+
} else {
|
|
183
|
+
_renderAsyncFunction();
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
<% if toggle[:start] %>
|
|
188
|
+
_renderAsyncFunction()
|
|
189
|
+
<% end %>
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
_runAfterDocumentLoaded(_setUpToggle);
|
|
193
|
+
<% elsif !toggle %>
|
|
194
|
+
_runAfterDocumentLoaded(_renderAsyncFunction)
|
|
86
195
|
<% end %>
|
|
87
196
|
}(jQuery));
|
|
88
197
|
} else {
|
|
89
|
-
console.warn("Looks like you've enabled jQuery for render_async, but jQuery is not defined");
|
|
198
|
+
console.warn("Looks like you've enabled jQuery for render_async, but jQuery is not defined on the window object");
|
|
90
199
|
};
|
|
@@ -4,8 +4,40 @@
|
|
|
4
4
|
return;
|
|
5
5
|
}
|
|
6
6
|
<% end %>
|
|
7
|
-
|
|
8
|
-
|
|
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
|
+
}
|
|
39
|
+
|
|
40
|
+
function _makeRequest(currentRetryCount) {
|
|
9
41
|
var request = new XMLHttpRequest();
|
|
10
42
|
var asyncRequest = true;
|
|
11
43
|
var SUCCESS = 200;
|
|
@@ -14,32 +46,41 @@
|
|
|
14
46
|
request.open('<%= method %>', '<%= path.html_safe %>', asyncRequest);
|
|
15
47
|
|
|
16
48
|
var headers = <%= headers.to_json.html_safe %>;
|
|
17
|
-
var csrfTokenElement = document.querySelector('meta[name="csrf-token"]')
|
|
49
|
+
var csrfTokenElement = document.querySelector('meta[name="csrf-token"]');
|
|
18
50
|
if (csrfTokenElement)
|
|
19
|
-
headers['X-CSRF-Token'] = csrfTokenElement.content
|
|
51
|
+
headers['X-CSRF-Token'] = csrfTokenElement.content;
|
|
52
|
+
|
|
53
|
+
<% if retry_count_header %>
|
|
54
|
+
if (typeof(currentRetryCount) === 'number') {
|
|
55
|
+
headers['<%= retry_count_header.html_safe %>'] = currentRetryCount;
|
|
56
|
+
}
|
|
57
|
+
<% end %>
|
|
20
58
|
|
|
21
59
|
Object.keys(headers).map(function(key) {
|
|
22
60
|
request.setRequestHeader(key, headers[key]);
|
|
23
61
|
});
|
|
24
62
|
|
|
63
|
+
request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
|
64
|
+
|
|
25
65
|
request.onreadystatechange = function() {
|
|
26
66
|
if (request.readyState === 4) {
|
|
27
67
|
if (request.status >= SUCCESS && request.status < ERROR) {
|
|
28
68
|
var container = document.getElementById('<%= container_id %>');
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
69
|
+
|
|
70
|
+
// If user navigated away before the request completed
|
|
71
|
+
if (!container) return;
|
|
72
|
+
|
|
73
|
+
<% if !interval && replace_container %>
|
|
32
74
|
container.outerHTML = request.response;
|
|
75
|
+
<% else %>
|
|
76
|
+
container.innerHTML = request.response;
|
|
33
77
|
<% end %>
|
|
34
78
|
|
|
79
|
+
var loadEvent = createEvent('render_async_load', container);
|
|
80
|
+
document.dispatchEvent(loadEvent);
|
|
81
|
+
|
|
35
82
|
<% if event_name.present? %>
|
|
36
|
-
var event =
|
|
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
|
-
}
|
|
83
|
+
var event = createEvent('<%= event_name %>', container);
|
|
43
84
|
document.dispatchEvent(event);
|
|
44
85
|
<% end %>
|
|
45
86
|
} else {
|
|
@@ -51,18 +92,17 @@
|
|
|
51
92
|
if (skipErrorMessage) return;
|
|
52
93
|
|
|
53
94
|
var container = document.getElementById('<%= container_id %>');
|
|
95
|
+
if (!container) return;
|
|
96
|
+
|
|
54
97
|
container.outerHTML = '<%= error_message.try(:html_safe) %>';
|
|
55
98
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
document.dispatchEvent(event);
|
|
65
|
-
<% end %>
|
|
99
|
+
var errorEvent = createEvent(
|
|
100
|
+
"<%= error_event_name || 'render_async_error' %>",
|
|
101
|
+
container
|
|
102
|
+
);
|
|
103
|
+
errorEvent.retryCount = currentRetryCount
|
|
104
|
+
|
|
105
|
+
document.dispatchEvent(errorEvent);
|
|
66
106
|
}
|
|
67
107
|
}
|
|
68
108
|
};
|
|
@@ -72,32 +112,106 @@
|
|
|
72
112
|
};
|
|
73
113
|
|
|
74
114
|
<% if retry_count > 0 %>
|
|
75
|
-
|
|
115
|
+
|
|
116
|
+
<% if retry_delay %>
|
|
117
|
+
var _retryMakeRequest = function(currentRetryCount) {
|
|
118
|
+
setTimeout(function() {
|
|
119
|
+
_makeRequest(currentRetryCount)
|
|
120
|
+
}, <%= retry_delay %>)
|
|
121
|
+
}
|
|
122
|
+
<% else %>
|
|
123
|
+
var _retryMakeRequest = _makeRequest
|
|
124
|
+
<% end %>
|
|
125
|
+
|
|
126
|
+
function retry(currentRetryCount) {
|
|
76
127
|
if (typeof(currentRetryCount) === 'number') {
|
|
77
128
|
if (currentRetryCount >= <%= retry_count %>)
|
|
78
129
|
return false;
|
|
79
130
|
|
|
80
|
-
|
|
131
|
+
_retryMakeRequest(currentRetryCount + 1);
|
|
81
132
|
return true;
|
|
82
133
|
}
|
|
83
134
|
|
|
84
|
-
|
|
135
|
+
_retryMakeRequest(1);
|
|
85
136
|
return true;
|
|
86
137
|
}
|
|
87
138
|
<% end %>
|
|
88
139
|
|
|
140
|
+
var _renderAsyncFunction = _makeRequest;
|
|
141
|
+
|
|
142
|
+
var _interval;
|
|
143
|
+
<% if interval %>
|
|
144
|
+
var _renderAsyncFunction = function() {
|
|
145
|
+
// If interval is already set, return
|
|
146
|
+
if (typeof(_interval) === 'number') return
|
|
147
|
+
|
|
148
|
+
_makeRequest();
|
|
149
|
+
_interval = setInterval(_makeRequest, <%= interval %>);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
var _clearRenderAsyncInterval = function() {
|
|
153
|
+
if (typeof(_interval) === 'number'){
|
|
154
|
+
clearInterval(_interval)
|
|
155
|
+
_interval = undefined;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function _setUpControlEvents() {
|
|
160
|
+
var container = document.getElementById('<%= container_id %>');
|
|
161
|
+
|
|
162
|
+
// Register a polling stop event on the container
|
|
163
|
+
container.addEventListener("async-stop", _clearRenderAsyncInterval)
|
|
164
|
+
|
|
165
|
+
// Register a start polling event on the container
|
|
166
|
+
container.addEventListener("async-start", _renderAsyncFunction)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
_runAfterDocumentLoaded(_setUpControlEvents)
|
|
170
|
+
|
|
89
171
|
<% if turbolinks %>
|
|
90
|
-
document.addEventListener("turbolinks:
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
<%
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
172
|
+
document.addEventListener("turbolinks:visit", _clearRenderAsyncInterval)
|
|
173
|
+
<% end %>
|
|
174
|
+
<% if turbo %>
|
|
175
|
+
document.addEventListener("turbo:visit", _clearRenderAsyncInterval)
|
|
176
|
+
<% end %>
|
|
177
|
+
<% end %>
|
|
178
|
+
|
|
179
|
+
<% if !replace_container %>
|
|
180
|
+
function _setUpRefreshEvent() {
|
|
181
|
+
var container = document.getElementById('<%= container_id %>');
|
|
182
|
+
|
|
183
|
+
container.addEventListener('refresh', _renderAsyncFunction)
|
|
98
184
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
185
|
+
|
|
186
|
+
_runAfterDocumentLoaded(_setUpRefreshEvent)
|
|
187
|
+
<% end %>
|
|
188
|
+
|
|
189
|
+
<% if toggle %>
|
|
190
|
+
function _setUpToggle() {
|
|
191
|
+
var selectors = document.querySelectorAll('<%= toggle[:selector] %>');
|
|
192
|
+
var handler = function(event) {
|
|
193
|
+
if (typeof(_interval) === 'number') {
|
|
194
|
+
clearInterval(_interval);
|
|
195
|
+
_interval = undefined;
|
|
196
|
+
} else {
|
|
197
|
+
_renderAsyncFunction();
|
|
198
|
+
}
|
|
199
|
+
<% if toggle[:once] %>
|
|
200
|
+
this.removeEventListener(event.type, handler);
|
|
201
|
+
<% end %>
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
<% if toggle[:start] %>
|
|
205
|
+
_renderAsyncFunction()
|
|
206
|
+
<% end %>
|
|
207
|
+
|
|
208
|
+
for (var i = 0; i < selectors.length; ++i) {
|
|
209
|
+
selectors[i].addEventListener('<%= toggle[:event] || 'click' %>', handler)
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
_runAfterDocumentLoaded(_setUpToggle);
|
|
214
|
+
<% elsif !toggle %>
|
|
215
|
+
_runAfterDocumentLoaded(_renderAsyncFunction);
|
|
102
216
|
<% end %>
|
|
103
217
|
})();
|
data/bin/integration-tests
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
module RenderAsync
|
|
2
2
|
class Configuration
|
|
3
|
-
attr_accessor :jquery, :turbolinks
|
|
3
|
+
attr_accessor :jquery, :turbolinks, :turbo, :replace_container, :nonces
|
|
4
4
|
|
|
5
5
|
def initialize
|
|
6
6
|
@jquery = false
|
|
7
7
|
@turbolinks = false
|
|
8
|
+
@turbo = false
|
|
9
|
+
@replace_container = true
|
|
10
|
+
@nonces = false
|
|
8
11
|
end
|
|
9
12
|
end
|
|
10
13
|
end
|
data/lib/render_async/version.rb
CHANGED
|
@@ -2,7 +2,6 @@ require 'securerandom'
|
|
|
2
2
|
|
|
3
3
|
module RenderAsync
|
|
4
4
|
module ViewHelper
|
|
5
|
-
|
|
6
5
|
def render_async_cache_key(path)
|
|
7
6
|
"render_async_#{path}"
|
|
8
7
|
end
|
|
@@ -18,39 +17,80 @@ module RenderAsync
|
|
|
18
17
|
end
|
|
19
18
|
|
|
20
19
|
def render_async(path, options = {}, &placeholder)
|
|
21
|
-
html_element_name = options.delete(:html_element_name) || 'div'
|
|
22
|
-
container_id = options.delete(:container_id) || generate_container_id
|
|
23
|
-
container_class = options.delete(:container_class)
|
|
24
20
|
event_name = options.delete(:event_name)
|
|
25
21
|
placeholder = capture(&placeholder) if block_given?
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
headers = options.delete(:headers) || {}
|
|
29
|
-
error_message = options.delete(:error_message)
|
|
30
|
-
error_event_name = options.delete(:error_event_name)
|
|
31
|
-
retry_count = options.delete(:retry_count) || 0
|
|
32
|
-
interval = options.delete(:interval)
|
|
33
|
-
|
|
34
|
-
render 'render_async/render_async', html_element_name: html_element_name,
|
|
35
|
-
container_id: container_id,
|
|
36
|
-
container_class: container_class,
|
|
22
|
+
|
|
23
|
+
render 'render_async/render_async', **container_element_options(options),
|
|
37
24
|
path: path,
|
|
38
|
-
html_options: options,
|
|
25
|
+
html_options: html_options(options),
|
|
39
26
|
event_name: event_name,
|
|
40
27
|
placeholder: placeholder,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
retry_count: retry_count,
|
|
47
|
-
interval: interval
|
|
28
|
+
**request_options(options),
|
|
29
|
+
**error_handling_options(options),
|
|
30
|
+
**retry_options(options),
|
|
31
|
+
**polling_options(options),
|
|
32
|
+
**content_for_options(options)
|
|
48
33
|
end
|
|
49
34
|
|
|
50
35
|
private
|
|
51
36
|
|
|
37
|
+
def container_element_options(options)
|
|
38
|
+
{ html_element_name: options[:html_element_name] || 'div',
|
|
39
|
+
container_id: options[:container_id] || generate_container_id,
|
|
40
|
+
container_class: options[:container_class],
|
|
41
|
+
replace_container: replace_container(options) }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def html_options(options)
|
|
45
|
+
set_options = options.delete(:html_options) || {}
|
|
46
|
+
|
|
47
|
+
set_options[:nonce] = configuration.nonces if set_options[:nonce].nil?
|
|
48
|
+
|
|
49
|
+
set_options
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def request_options(options)
|
|
53
|
+
{ method: options[:method] || 'GET',
|
|
54
|
+
data: options[:data],
|
|
55
|
+
headers: options[:headers] || {} }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def error_handling_options(options)
|
|
59
|
+
{ error_message: options[:error_message],
|
|
60
|
+
error_event_name: options[:error_event_name] }
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def retry_options(options)
|
|
64
|
+
{
|
|
65
|
+
retry_count: options.delete(:retry_count) || 0,
|
|
66
|
+
retry_count_header: options.delete(:retry_count_header),
|
|
67
|
+
retry_delay: options.delete(:retry_delay)
|
|
68
|
+
}
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def polling_options(options)
|
|
72
|
+
{ interval: options[:interval],
|
|
73
|
+
toggle: options[:toggle] }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def content_for_options(options)
|
|
77
|
+
{
|
|
78
|
+
content_for_name: options[:content_for_name] || :render_async
|
|
79
|
+
}
|
|
80
|
+
end
|
|
81
|
+
|
|
52
82
|
def generate_container_id
|
|
53
83
|
"render_async_#{SecureRandom.hex(5)}#{Time.now.to_i}"
|
|
54
84
|
end
|
|
85
|
+
|
|
86
|
+
def replace_container(options)
|
|
87
|
+
return options[:replace_container] unless options[:replace_container].nil?
|
|
88
|
+
|
|
89
|
+
configuration.replace_container
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def configuration
|
|
93
|
+
RenderAsync.configuration
|
|
94
|
+
end
|
|
55
95
|
end
|
|
56
96
|
end
|