PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 3.3.1
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v3.3.1
4.7.0 4.6.1 4.6.0 4.5.5 4.5.4 4.5.3 4.5.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.5 3.2.6 3.2.7 3.2.9 3.3.0 3.3.1 3.3.2 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.7.0 3.7.1 All 111 releases
wp-optimize / js / heartbeat.js

heartbeat.js in WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance 3.3.1, at js/heartbeat.js

189 lines 5.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 var WP_Optimize_Heartbeat_Agents = {};
2
3 /**
4 * Attach to WordPress heartbeat API. Has a fallback method if core API is disabled
5 *
6 * @returns {object} WP_Optimize_Heartbeat exports
7 */
8 var WP_Optimize_Heartbeat = function () {
9 var $ = jQuery;
10 var agent_idle_ttl_in_seconds = 60; // retry after 60 seconds without a response
11 var wpo_fallback;
12
13 /**
14 * Generate a unique ID to be used as agents IDs
15 *
16 * @returns {string}
17 */
18 var guid = function() {
19 var s4 = function() {
20 return Math.floor((1 + Math.random()) * 0x10000)
21 .toString(16)
22 .substring(1);
23 }
24 //return id of format 'aaaaaaaa'-'aaaa'-'aaaa'-'aaaa'-'aaaaaaaaaaaa'
25 return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
26 }
27
28 /**
29 * Configure the heartbeat events, if heartbeat API is missing, setup fallback
30 *
31 * @returns {void}
32 */
33 function setup() {
34 $(document).on('heartbeat-send', function(event, data) {
35 for(var uid in WP_Optimize_Heartbeat_Agents) {
36 if (!WP_Optimize_Heartbeat_Agents[uid].sent) {
37 data[uid] = WP_Optimize_Heartbeat_Agents[uid].command;
38
39 WP_Optimize_Heartbeat_Agents[uid].sent = true;
40 }
41
42 // Retry after idle time is passed (no response in X seconds)
43 var seconds = ((new Date()).getTime() - WP_Optimize_Heartbeat_Agents[uid].sent_time.getTime()) / 1000;
44 if (seconds > agent_idle_ttl_in_seconds) {
45 WP_Optimize_Heartbeat_Agents[uid].sent = false;
46 }
47 }
48 });
49
50 $(document).on('heartbeat-tick', function(event, data) {
51 if ('object' == typeof(data.callbacks)) {
52 for(var uid in data.callbacks) {
53 if (is_wpo_heartbeat(uid)) {
54 var response = JSON.parse(data.callbacks[uid]);
55
56 if ('undefined' != typeof(response.result) && false == response.result) {
57 wp_optimize.notices.show_notice(response.error_code, response.error_message);
58 } else {
59 WP_Optimize_Heartbeat_Agents[uid].callback(response);
60 }
61
62 delete WP_Optimize_Heartbeat_Agents[uid];
63 }
64 }
65 }
66 });
67
68 if (is_heartbeat_api_disabled()) {
69 wpo_fallback = WP_Optimize_Heartbeat_Fallback();
70 }
71 }
72
73 /**
74 * Check if heartbeat action is a WP-Optimize action or something else that we should ignore
75 *
76 * @param {string} uid The UID of the agent
77 * @returns {bool}
78 */
79 function is_wpo_heartbeat(uid) {
80 return 0 === uid.indexOf('wpo-heartbeat-');
81 }
82
83 /**
84 * Check if native heartbeat API is available
85 *
86 * @returns {bool}
87 */
88 function is_heartbeat_api_disabled() {
89 return 'undefined' == typeof(wp.heartbeat);
90 }
91
92 /**
93 * Filter function to check if an agent is already scheduled
94 *
95 * @param {object} agent1 First comparison agent, usually already scheduled agents
96 * @param {object} agent2 Second comparison agent, usually the one you are trying to check if it already exists
97 * @returns {bool}
98 */
99 function do_agents_match(agent1, agent2) {
100 var command_matches = agent1.command === agent2.command;
101 var command_not_sent_yet = false === agent1.sent;
102
103 return command_matches && command_not_sent_yet;
104 }
105
106 /**
107 * Add a heartbeat agent that will be sent to backend and has a callback to receive the response
108 *
109 * @param {object} data Expected an object like {command: string}
110 * @returns {string|null}
111 */
112 function add_agent(data) {
113 var already_scheduled = Object.values(WP_Optimize_Heartbeat_Agents).some(function(agent) { return do_agents_match(agent, data); });
114 if (already_scheduled) {
115 return null;
116 }
117
118 var agent_id = 'wpo-heartbeat-' + guid();
119 data.sent = false;
120 data.sent_time = new Date();
121 WP_Optimize_Heartbeat_Agents[agent_id] = data;
122 return agent_id;
123 }
124
125 /**
126 * Remove agent from list
127 *
128 * @param {string} agent_id The id of the agent to be removed
129 * @returns {void}
130 */
131 function cancel_agent(agent_id) {
132 delete WP_Optimize_Heartbeat_Agents[agent_id];
133 }
134
135 return {
136 setup: setup,
137 add_agent: add_agent,
138 cancel_agent: cancel_agent
139 };
140 }
141
142 /**
143 * Fallback for the heartbeat api
144 *
145 * @returns {object} WP_Optimize_Heartbeat_Fallback exports
146 */
147 var WP_Optimize_Heartbeat_Fallback = function() {
148 var timeout_handler;
149
150 var payload = {
151 "data":{},
152 "interval":wpo_heartbeat_ajax.interval,
153 "_nonce":wpo_heartbeat_ajax.nonce,
154 "action":"heartbeat",
155 "screen_id":window.pagenow,
156 "has_focus":false
157 };
158
159 /**
160 * Actually trigger the standard AJAX call to run a heartbeat event
161 *
162 * @param {int} interval How many seconds until next heartbeat
163 * @returns {void}
164 */
165 function do_heartbeat(interval) {
166 var this_payload = Object.assign({}, payload);
167 var data = {};
168
169 jQuery(document).trigger('heartbeat-send', data);
170
171 this_payload.data = data;
172
173 jQuery.ajax({
174 type : "post",
175 dataType : "json",
176 url : wpo_heartbeat_ajax.ajaxurl,
177 data : this_payload,
178 success: function(response) {
179 if('undefined' != typeof(response.callbacks)) {
180 jQuery(document).trigger('heartbeat-tick', response);
181 }
182 }
183 });
184
185 timeout_handler = setTimeout(do_heartbeat, interval * 1000, interval);
186 }
187
188 timeout_handler = setTimeout(do_heartbeat, payload.interval * 1000, payload.interval);
189 }