You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flagon.apache.org by po...@apache.org on 2019/08/09 18:49:00 UTC
[incubator-flagon-useralejs] 01/01: [FLAGON-440] created
sendOnRefresh function to call via attachEventListeners so data isn't lost
for events that trigger refreshes
This is an automated email from the ASF dual-hosted git repository.
poorejc pushed a commit to branch FLAGON-434
in repository https://gitbox.apache.org/repos/asf/incubator-flagon-useralejs.git
commit 397a22b46b52b0c732fae8bf1e8652fab863530d
Author: poorejc <po...@apache.org>
AuthorDate: Fri Aug 9 14:48:39 2019 -0400
[FLAGON-440] created sendOnRefresh function to call via attachEventListeners so data isn't lost for events that trigger refreshes
---
build/UserAleWebExtension/content.js | 238 ++++++++++++++++++++---------------
build/userale-2.0.2.js | 238 ++++++++++++++++++++---------------
build/userale-2.0.2.min.js | 2 +-
example/index_form.html | 81 ++++++++++++
src/attachHandlers.js | 20 ++-
src/sendLogs.js | 18 +++
6 files changed, 385 insertions(+), 212 deletions(-)
diff --git a/build/UserAleWebExtension/content.js b/build/UserAleWebExtension/content.js
index ab02b35..9efa490 100644
--- a/build/UserAleWebExtension/content.js
+++ b/build/UserAleWebExtension/content.js
@@ -468,11 +468,133 @@ function selectorizePath(path) {
* limitations under the License.
*/
+var sendIntervalId = null;
+
+/**
+ * Initializes the log queue processors.
+ * @param {Array} logs Array of logs to append to.
+ * @param {Object} config Configuration object to use when logging.
+ */
+function initSender(logs, config) {
+ if (sendIntervalId !== null) {
+ clearInterval(sendIntervalId);
+ }
+
+ sendIntervalId = sendOnInterval(logs, config);
+ sendOnClose(logs, config);
+}
+
+/**
+ * Checks the provided log array on an interval, flushing the logs
+ * if the queue has reached the threshold specified by the provided config.
+ * @param {Array} logs Array of logs to read from.
+ * @param {Object} config Configuration object to be read from.
+ * @return {Number} The newly created interval id.
+ */
+function sendOnInterval(logs, config) {
+ return setInterval(function() {
+ if (!config.on) {
+ return;
+ }
+
+ if (logs.length >= config.logCountThreshold) {
+ sendLogs(logs.slice(0), config.url, 0); // Send a copy
+ logs.splice(0); // Clear array reference (no reassignment)
+ }
+ }, config.transmitInterval);
+}
+
+/**
+ * Provides a simplified send function that can be called before events that would
+ * refresh page can resolve so that log queue ('logs) can be shipped immediately. This
+ * is different than sendOnClose because browser security practices prevent you from
+ * listening the process responsible for window navigation actions, in action (e.g., refresh;
+ * you can only detect, after the fact, the process responsible for the current window state.
+ * @param {Array} logs Array of logs to read from.
+ * @param {Object} config Configuration object to be read from.
+ */
+function sendOnRefresh(logs, config) {
+ if (!config.on) {
+ return;
+ }
+ if (logs.length > 0) {
+ sendLogs(logs, config.url, 1);
+ }
+}
+
+/**
+ * Attempts to flush the remaining logs when the window is closed.
+ * @param {Array} logs Array of logs to be flushed.
+ * @param {Object} config Configuration object to be read from.
+ */
+function sendOnClose(logs, config) {
+ if (!config.on) {
+ return;
+ }
+
+ if (navigator.sendBeacon) {
+ window.addEventListener('unload', function() {
+ navigator.sendBeacon(config.url, JSON.stringify(logs));
+ });
+ } else {
+ window.addEventListener('beforeunload', function() {
+ if (logs.length > 0) {
+ sendLogs(logs, config.url, 1);
+ }
+ });
+ }
+}
+
+/**
+ * Sends the provided array of logs to the specified url,
+ * retrying the request up to the specified number of retries.
+ * @param {Array} logs Array of logs to send.
+ * @param {string} url URL to send the POST request to.
+ * @param {Number} retries Maximum number of attempts to send the logs.
+ */
+function sendLogs(logs, url, retries) {
+ var req = new XMLHttpRequest();
+
+ var data = JSON.stringify(logs);
+
+ req.open('POST', url);
+ req.setRequestHeader('Content-type', 'application/json;charset=UTF-8');
+
+ req.onreadystatechange = function() {
+ if (req.readyState === 4 && req.status !== 200) {
+ if (retries > 0) {
+ sendLogs(logs, url, retries--);
+ }
+ }
+ };
+
+ req.send(data);
+}
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
var events;
var bufferBools;
var bufferedEvents;
//@todo: Investigate drag events and their behavior
var intervalEvents = ['click', 'focus', 'blur', 'input', 'change', 'mouseover', 'submit'];
+var refreshEvents;
var windowEvents = ['load', 'blur', 'focus'];
/**
@@ -512,8 +634,7 @@ function defineDetails(config) {
'drag' : null,
'drop' : null,
'keydown' : config.logDetails ? function(e) { return { 'key' : e.keyCode, 'ctrl' : e.ctrlKey, 'alt' : e.altKey, 'shift' : e.shiftKey, 'meta' : e.metaKey }; } : null,
- 'mouseover' : null,
- 'submit' : null
+ 'mouseover' : null
};
bufferBools = {};
@@ -522,6 +643,10 @@ function defineDetails(config) {
'scroll' : function() { return { 'x' : window.scrollX, 'y' : window.scrollY }; },
'resize' : function() { return { 'width' : window.outerWidth, 'height' : window.outerHeight }; }
};
+
+ refreshEvents = {
+ 'submit' : null
+ };
}
/**
@@ -556,6 +681,13 @@ function attachHandlers(config) {
}, true);
});
+ Object.keys(refreshEvents).forEach(function(ev) {
+ document.addEventListener(ev, function(e) {
+ packageLog(e, events[ev]);
+ sendOnRefresh(logs,config);
+ }, true);
+ });
+
windowEvents.forEach(function(ev) {
window.addEventListener(ev, function(e) {
packageLog(e, function() { return { 'window' : true }; });
@@ -582,108 +714,6 @@ function attachHandlers(config) {
* limitations under the License.
*/
-var sendIntervalId = null;
-
-/**
- * Initializes the log queue processors.
- * @param {Array} logs Array of logs to append to.
- * @param {Object} config Configuration object to use when logging.
- */
-function initSender(logs, config) {
- if (sendIntervalId !== null) {
- clearInterval(sendIntervalId);
- }
-
- sendIntervalId = sendOnInterval(logs, config);
- sendOnClose(logs, config);
-}
-
-/**
- * Checks the provided log array on an interval, flushing the logs
- * if the queue has reached the threshold specified by the provided config.
- * @param {Array} logs Array of logs to read from.
- * @param {Object} config Configuration object to be read from.
- * @return {Number} The newly created interval id.
- */
-function sendOnInterval(logs, config) {
- return setInterval(function() {
- if (!config.on) {
- return;
- }
-
- if (logs.length >= config.logCountThreshold) {
- sendLogs(logs.slice(0), config.url, 0); // Send a copy
- logs.splice(0); // Clear array reference (no reassignment)
- }
- }, config.transmitInterval);
-}
-
-/**
- * Attempts to flush the remaining logs when the window is closed.
- * @param {Array} logs Array of logs to be flushed.
- * @param {Object} config Configuration object to be read from.
- */
-function sendOnClose(logs, config) {
- if (!config.on) {
- return;
- }
-
- if (navigator.sendBeacon) {
- window.addEventListener('unload', function() {
- navigator.sendBeacon(config.url, JSON.stringify(logs));
- });
- } else {
- window.addEventListener('beforeunload', function() {
- if (logs.length > 0) {
- sendLogs(logs, config.url, 1);
- }
- });
- }
-}
-
-/**
- * Sends the provided array of logs to the specified url,
- * retrying the request up to the specified number of retries.
- * @param {Array} logs Array of logs to send.
- * @param {string} url URL to send the POST request to.
- * @param {Number} retries Maximum number of attempts to send the logs.
- */
-function sendLogs(logs, url, retries) {
- var req = new XMLHttpRequest();
-
- var data = JSON.stringify(logs);
-
- req.open('POST', url);
- req.setRequestHeader('Content-type', 'application/json;charset=UTF-8');
-
- req.onreadystatechange = function() {
- if (req.readyState === 4 && req.status !== 200) {
- if (retries > 0) {
- sendLogs(logs, url, retries--);
- }
- }
- };
-
- req.send(data);
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
var config$1 = {};
var logs$1 = [];
var started = false;
diff --git a/build/userale-2.0.2.js b/build/userale-2.0.2.js
index 28bf257..f0ba930 100644
--- a/build/userale-2.0.2.js
+++ b/build/userale-2.0.2.js
@@ -447,11 +447,133 @@ var userale = (function (exports) {
* limitations under the License.
*/
+ var sendIntervalId = null;
+
+ /**
+ * Initializes the log queue processors.
+ * @param {Array} logs Array of logs to append to.
+ * @param {Object} config Configuration object to use when logging.
+ */
+ function initSender(logs, config) {
+ if (sendIntervalId !== null) {
+ clearInterval(sendIntervalId);
+ }
+
+ sendIntervalId = sendOnInterval(logs, config);
+ sendOnClose(logs, config);
+ }
+
+ /**
+ * Checks the provided log array on an interval, flushing the logs
+ * if the queue has reached the threshold specified by the provided config.
+ * @param {Array} logs Array of logs to read from.
+ * @param {Object} config Configuration object to be read from.
+ * @return {Number} The newly created interval id.
+ */
+ function sendOnInterval(logs, config) {
+ return setInterval(function() {
+ if (!config.on) {
+ return;
+ }
+
+ if (logs.length >= config.logCountThreshold) {
+ sendLogs(logs.slice(0), config.url, 0); // Send a copy
+ logs.splice(0); // Clear array reference (no reassignment)
+ }
+ }, config.transmitInterval);
+ }
+
+ /**
+ * Provides a simplified send function that can be called before events that would
+ * refresh page can resolve so that log queue ('logs) can be shipped immediately. This
+ * is different than sendOnClose because browser security practices prevent you from
+ * listening the process responsible for window navigation actions, in action (e.g., refresh;
+ * you can only detect, after the fact, the process responsible for the current window state.
+ * @param {Array} logs Array of logs to read from.
+ * @param {Object} config Configuration object to be read from.
+ */
+ function sendOnRefresh(logs, config) {
+ if (!config.on) {
+ return;
+ }
+ if (logs.length > 0) {
+ sendLogs(logs, config.url, 1);
+ }
+ }
+
+ /**
+ * Attempts to flush the remaining logs when the window is closed.
+ * @param {Array} logs Array of logs to be flushed.
+ * @param {Object} config Configuration object to be read from.
+ */
+ function sendOnClose(logs, config) {
+ if (!config.on) {
+ return;
+ }
+
+ if (navigator.sendBeacon) {
+ window.addEventListener('unload', function() {
+ navigator.sendBeacon(config.url, JSON.stringify(logs));
+ });
+ } else {
+ window.addEventListener('beforeunload', function() {
+ if (logs.length > 0) {
+ sendLogs(logs, config.url, 1);
+ }
+ });
+ }
+ }
+
+ /**
+ * Sends the provided array of logs to the specified url,
+ * retrying the request up to the specified number of retries.
+ * @param {Array} logs Array of logs to send.
+ * @param {string} url URL to send the POST request to.
+ * @param {Number} retries Maximum number of attempts to send the logs.
+ */
+ function sendLogs(logs, url, retries) {
+ var req = new XMLHttpRequest();
+
+ var data = JSON.stringify(logs);
+
+ req.open('POST', url);
+ req.setRequestHeader('Content-type', 'application/json;charset=UTF-8');
+
+ req.onreadystatechange = function() {
+ if (req.readyState === 4 && req.status !== 200) {
+ if (retries > 0) {
+ sendLogs(logs, url, retries--);
+ }
+ }
+ };
+
+ req.send(data);
+ }
+
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
var events;
var bufferBools;
var bufferedEvents;
//@todo: Investigate drag events and their behavior
var intervalEvents = ['click', 'focus', 'blur', 'input', 'change', 'mouseover', 'submit'];
+ var refreshEvents;
var windowEvents = ['load', 'blur', 'focus'];
/**
@@ -491,8 +613,7 @@ var userale = (function (exports) {
'drag' : null,
'drop' : null,
'keydown' : config.logDetails ? function(e) { return { 'key' : e.keyCode, 'ctrl' : e.ctrlKey, 'alt' : e.altKey, 'shift' : e.shiftKey, 'meta' : e.metaKey }; } : null,
- 'mouseover' : null,
- 'submit' : null
+ 'mouseover' : null
};
bufferBools = {};
@@ -501,6 +622,10 @@ var userale = (function (exports) {
'scroll' : function() { return { 'x' : window.scrollX, 'y' : window.scrollY }; },
'resize' : function() { return { 'width' : window.outerWidth, 'height' : window.outerHeight }; }
};
+
+ refreshEvents = {
+ 'submit' : null
+ };
}
/**
@@ -535,6 +660,13 @@ var userale = (function (exports) {
}, true);
});
+ Object.keys(refreshEvents).forEach(function(ev) {
+ document.addEventListener(ev, function(e) {
+ packageLog(e, events[ev]);
+ sendOnRefresh(logs,config);
+ }, true);
+ });
+
windowEvents.forEach(function(ev) {
window.addEventListener(ev, function(e) {
packageLog(e, function() { return { 'window' : true }; });
@@ -561,108 +693,6 @@ var userale = (function (exports) {
* limitations under the License.
*/
- var sendIntervalId = null;
-
- /**
- * Initializes the log queue processors.
- * @param {Array} logs Array of logs to append to.
- * @param {Object} config Configuration object to use when logging.
- */
- function initSender(logs, config) {
- if (sendIntervalId !== null) {
- clearInterval(sendIntervalId);
- }
-
- sendIntervalId = sendOnInterval(logs, config);
- sendOnClose(logs, config);
- }
-
- /**
- * Checks the provided log array on an interval, flushing the logs
- * if the queue has reached the threshold specified by the provided config.
- * @param {Array} logs Array of logs to read from.
- * @param {Object} config Configuration object to be read from.
- * @return {Number} The newly created interval id.
- */
- function sendOnInterval(logs, config) {
- return setInterval(function() {
- if (!config.on) {
- return;
- }
-
- if (logs.length >= config.logCountThreshold) {
- sendLogs(logs.slice(0), config.url, 0); // Send a copy
- logs.splice(0); // Clear array reference (no reassignment)
- }
- }, config.transmitInterval);
- }
-
- /**
- * Attempts to flush the remaining logs when the window is closed.
- * @param {Array} logs Array of logs to be flushed.
- * @param {Object} config Configuration object to be read from.
- */
- function sendOnClose(logs, config) {
- if (!config.on) {
- return;
- }
-
- if (navigator.sendBeacon) {
- window.addEventListener('unload', function() {
- navigator.sendBeacon(config.url, JSON.stringify(logs));
- });
- } else {
- window.addEventListener('beforeunload', function() {
- if (logs.length > 0) {
- sendLogs(logs, config.url, 1);
- }
- });
- }
- }
-
- /**
- * Sends the provided array of logs to the specified url,
- * retrying the request up to the specified number of retries.
- * @param {Array} logs Array of logs to send.
- * @param {string} url URL to send the POST request to.
- * @param {Number} retries Maximum number of attempts to send the logs.
- */
- function sendLogs(logs, url, retries) {
- var req = new XMLHttpRequest();
-
- var data = JSON.stringify(logs);
-
- req.open('POST', url);
- req.setRequestHeader('Content-type', 'application/json;charset=UTF-8');
-
- req.onreadystatechange = function() {
- if (req.readyState === 4 && req.status !== 200) {
- if (retries > 0) {
- sendLogs(logs, url, retries--);
- }
- }
- };
-
- req.send(data);
- }
-
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
var config$1 = {};
var logs$1 = [];
exports.started = false;
diff --git a/build/userale-2.0.2.min.js b/build/userale-2.0.2.min.js
index 85b781b..0a3b0c8 100644
--- a/build/userale-2.0.2.min.js
+++ b/build/userale-2.0.2.min.js
@@ -15,4 +15,4 @@
* limitations under the License.
* @preserved
*/
-var userale=function(n){"use strict";var a,i,u,l,s,c,d,f,t="2.0.2";function e(n,o){Object.keys(o).forEach(function(t){if("userFromParams"===t){var e=function(t){var e=new RegExp("[?&]"+t+"(=([^&#]*)|&|#|$)"),n=window.location.href.match(e);return n&&n[2]?decodeURIComponent(n[2].replace(/\+/g," ")):null}(o[t]);e&&(n.userId=e)}n[t]=o[t]})}var o,r,m,p=null,g=null;function v(t,e){if(!i.on)return!1;var n=null;e&&(n=e(t));var o=function(t){return{milli:Math.floor(t),micro:Number((t%1).toFixed( [...]
\ No newline at end of file
+var userale=function(n){"use strict";var a,i,u,l,s,c,d,f,t="2.0.2";function e(n,o){Object.keys(o).forEach(function(t){if("userFromParams"===t){var e=function(t){var e=new RegExp("[?&]"+t+"(=([^&#]*)|&|#|$)"),n=window.location.href.match(e);return n&&n[2]?decodeURIComponent(n[2].replace(/\+/g," ")):null}(o[t]);e&&(n.userId=e)}n[t]=o[t]})}var m=null,p=null;function o(t,e){if(!i.on)return!1;var n=null;e&&(n=e(t));var o=function(t){return{milli:Math.floor(t),micro:Number((t%1).toFixed(3))}}( [...]
\ No newline at end of file
diff --git a/example/index_form.html b/example/index_form.html
new file mode 100644
index 0000000..7095e3d
--- /dev/null
+++ b/example/index_form.html
@@ -0,0 +1,81 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<html>
+<head>
+ <title>UserAleJS - Example Page</title>
+ <script
+ src="file:///Users/jpoore/Documents/Apache_Flagon/test/incubator-flagon-useralejs/build/userale-2.0.2.min.js"
+ data-url="http://localhost:8000/"
+ data-user="example-user"
+ data-log-details="true"
+ data-version="2.0.2"
+ data-tool="Apache UserALE.js Example"
+ ></script>
+ <script type="text/javascript">
+ window.userale.filter(function (log) {
+ var type_array = ['mouseup', 'mousedown', 'dblclick', 'blur']
+ var logType_array = ['interval']
+ return !type_array.includes(log.type) && !logType_array.includes(log.logType);
+ });
+ </script>
+</head>
+<body>
+ <br>
+ <br>
+ <br>
+ <div class="container">
+ <button id="test_button">Click me!</button>
+ </div>
+<!--Play around with this mapping function to transform your logs!
+ <script type="text/javascript">
+ window.userale.map(function (log) {
+ var targetsForLabels = ["button#test_button"];
+ if (targetsForLabels.includes(log.target)) {
+ return Object.assign({}, log, { CustomLabel: "Click me!" });
+ } else {
+ return log;
+ }
+ });
+ </script>
+-->
+ <br>
+ <br>
+ <br>
+ <form id="test_text_input">
+ <label>Test field: <input type="text"></label>
+ <br><br>
+ <button type="submit">Submit form</button>
+ </form>
+ <br>
+ <br>
+ <br>
+ <select name="cars">
+ <option value="volvo">Volvo</option>
+ <option value="saab">Saab</option>
+ <option value="fiat">Fiat</option>
+ <option value="audi">Audi</option>
+ </select>
+ <br>
+ <br>
+ <br>
+ <form id="test_radio_input">
+ <input type="radio" name="gender" value="male" checked> Male<br>
+ <input type="radio" name="gender" value="female"> Female<br>
+ <input type="radio" name="gender" value="other"> Other
+ </form>
+</body>
+</html>
diff --git a/src/attachHandlers.js b/src/attachHandlers.js
index f025a4e..43b8aba 100644
--- a/src/attachHandlers.js
+++ b/src/attachHandlers.js
@@ -15,14 +15,18 @@
* limitations under the License.
*/
+import { logs } from './packageLogs';
import { packageLog } from './packageLogs.js';
-import { packageIntervalLog } from './packageLogs';
+import { packageIntervalLog} from './packageLogs';
+import { sendOnRefresh } from "./sendLogs";
+
var events;
var bufferBools;
var bufferedEvents;
//@todo: Investigate drag events and their behavior
var intervalEvents = ['click', 'focus', 'blur', 'input', 'change', 'mouseover', 'submit'];
+var refreshEvents;
var windowEvents = ['load', 'blur', 'focus'];
/**
@@ -62,8 +66,7 @@ export function defineDetails(config) {
'drag' : null,
'drop' : null,
'keydown' : config.logDetails ? function(e) { return { 'key' : e.keyCode, 'ctrl' : e.ctrlKey, 'alt' : e.altKey, 'shift' : e.shiftKey, 'meta' : e.metaKey }; } : null,
- 'mouseover' : null,
- 'submit' : null
+ 'mouseover' : null
};
bufferBools = {};
@@ -72,6 +75,10 @@ export function defineDetails(config) {
'scroll' : function() { return { 'x' : window.scrollX, 'y' : window.scrollY }; },
'resize' : function() { return { 'width' : window.outerWidth, 'height' : window.outerHeight }; }
};
+
+ refreshEvents = {
+ 'submit' : null
+ };
}
/**
@@ -106,6 +113,13 @@ export function attachHandlers(config) {
}, true);
});
+ Object.keys(refreshEvents).forEach(function(ev) {
+ document.addEventListener(ev, function(e) {
+ packageLog(e, events[ev]);
+ sendOnRefresh(logs,config);
+ }, true);
+ });
+
windowEvents.forEach(function(ev) {
window.addEventListener(ev, function(e) {
packageLog(e, function() { return { 'window' : true }; });
diff --git a/src/sendLogs.js b/src/sendLogs.js
index 8f1bc86..b057a3e 100644
--- a/src/sendLogs.js
+++ b/src/sendLogs.js
@@ -52,6 +52,24 @@ export function sendOnInterval(logs, config) {
}
/**
+ * Provides a simplified send function that can be called before events that would
+ * refresh page can resolve so that log queue ('logs) can be shipped immediately. This
+ * is different than sendOnClose because browser security practices prevent you from
+ * listening the process responsible for window navigation actions, in action (e.g., refresh;
+ * you can only detect, after the fact, the process responsible for the current window state.
+ * @param {Array} logs Array of logs to read from.
+ * @param {Object} config Configuration object to be read from.
+ */
+export function sendOnRefresh(logs, config) {
+ if (!config.on) {
+ return;
+ }
+ if (logs.length > 0) {
+ sendLogs(logs, config.url, 1);
+ }
+}
+
+/**
* Attempts to flush the remaining logs when the window is closed.
* @param {Array} logs Array of logs to be flushed.
* @param {Object} config Configuration object to be read from.