render_async 2.1.4 → 2.1.9
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 +4 -4
- data/.all-contributorsrc +47 -0
- data/.github/CONTRIBUTING.md +40 -0
- data/.github/FUNDING.yml +3 -0
- data/.gitignore +1 -0
- data/.gitmodules +4 -0
- data/CHANGELOG.md +43 -1
- data/README.md +360 -76
- data/app/views/render_async/_render_async.html.erb +19 -25
- data/app/views/render_async/_request_jquery.js.erb +119 -40
- data/app/views/render_async/_request_vanilla.js.erb +125 -49
- 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 +36 -8
- metadata +8 -7
@@ -5,38 +5,32 @@
|
|
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_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:
|
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:
|
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
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
52
|
+
var container = $("#<%= container_id %>");
|
53
|
+
<% if !interval && replace_container %>
|
54
|
+
container.replaceWith(response);
|
24
55
|
<% else %>
|
25
|
-
|
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 =
|
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 %>")
|
75
|
+
var container = $("#<%= container_id %>");
|
76
|
+
container.replaceWith("<%= error_message.try(:html_safe) %>");
|
47
77
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
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
|
-
|
104
|
+
_retryMakeRequest(currentRetryCount + 1);
|
68
105
|
return true;
|
69
106
|
}
|
70
107
|
|
71
|
-
|
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
|
-
|
87
|
-
|
88
|
-
|
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
|
-
|
99
|
-
$(document).one('turbolinks:load', _renderAsyncFunction);
|
178
|
+
_runAfterDocumentLoaded(_setUpToggle);
|
100
179
|
<% elsif !toggle %>
|
101
|
-
|
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
|
-
|
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 =
|
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 =
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
-
|
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
|
-
|
117
|
+
_retryMakeRequest(currentRetryCount + 1);
|
81
118
|
return true;
|
82
119
|
}
|
83
120
|
|
84
|
-
|
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
|
-
|
100
|
-
|
101
|
-
|
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
|
-
|
110
|
-
|
111
|
-
|
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
|
-
|
115
|
-
|
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
|
120
|
-
|
121
|
-
|
122
|
-
|
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
|
-
|
201
|
+
_runAfterDocumentLoaded(_renderAsyncFunction);
|
126
202
|
<% end %>
|
127
203
|
})();
|