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