This is an automated email from the ASF dual-hosted git repository. poorejc pushed a commit to branch test in repository https://gitbox.apache.org/repos/asf/incubator-flagon-useralejs.git
commit 92ae6935272680467cf92bd898339cb195a7d63c Author: Gedd Johnson <[email protected]> AuthorDate: Tue Mar 23 16:29:59 2021 +0000 adds babel to rollup builds --- build/UserALEWebExtension/background.js | 126 +++--- build/UserALEWebExtension/content.js | 603 ++++++++++++++-------------- build/UserALEWebExtension/options.js | 106 +++-- build/userale-2.1.1.js | 675 ++++++++++++++++++-------------- build/userale-2.1.1.min.js | 2 +- package-lock.json | 34 ++ package.json | 1 + rollup.config.js | 16 +- 8 files changed, 839 insertions(+), 724 deletions(-) diff --git a/build/UserALEWebExtension/background.js b/build/UserALEWebExtension/background.js index 24fc4e3..4e15eb9 100644 --- a/build/UserALEWebExtension/background.js +++ b/build/UserALEWebExtension/background.js @@ -13,17 +13,15 @@ * 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. -*/ - -/* eslint-disable */ - -// these are default values, which can be overridden by the user on the options page -var userAleHost = 'http://localhost:8000'; -var userAleScript = 'userale-2.1.1.min.js'; -var toolUser = 'nobody'; -var toolName = 'test_app'; -var toolVersion = '2.1.1'; - +*/ + +/* eslint-disable */ +// these are default values, which can be overridden by the user on the options page +var userAleHost = 'http://localhost:8000'; +var userAleScript = 'userale-2.1.1.min.js'; +var toolUser = 'nobody'; +var toolName = 'test_app'; +var toolVersion = '2.1.1'; /* eslint-enable */ /* @@ -42,9 +40,7 @@ var toolVersion = '2.1.1'; * See the License for the specific language governing permissions and * limitations under the License. */ - var prefix = 'USERALE_'; - var CONFIG_CHANGE = prefix + 'CONFIG_CHANGE'; var ADD_LOG = prefix + 'ADD_LOG'; @@ -64,13 +60,12 @@ var ADD_LOG = prefix + 'ADD_LOG'; * See the License for the specific language governing permissions and * limitations under the License. */ - - /** * Creates a function to normalize the timestamp of the provided event. * @param {Object} e An event containing a timeStamp property. * @return {timeStampScale~tsScaler} The timestamp normalizing function. */ + function timeStampScale(e) { if (e.timeStamp && e.timeStamp > 0) { var delta = Date.now() - e.timeStamp; @@ -79,24 +74,28 @@ function timeStampScale(e) { * @param {?Number} ts A timestamp to use for normalization. * @return {Number} A normalized timestamp. */ + var tsScaler; if (delta < 0) { - tsScaler = function () { + tsScaler = function tsScaler() { return e.timeStamp / 1000; }; } else if (delta > e.timeStamp) { var navStart = performance.timing.navigationStart; - tsScaler = function (ts) { + + tsScaler = function tsScaler(ts) { return ts + navStart; }; } else { - tsScaler = function (ts) { + tsScaler = function tsScaler(ts) { return ts; }; } } else { - tsScaler = function () { return Date.now(); }; + tsScaler = function tsScaler() { + return Date.now(); + }; } return tsScaler; @@ -317,17 +316,17 @@ function createVersionParts(count) { * limitations under the License. */ detect(); - /** * Extract the millisecond and microsecond portions of a timestamp. * @param {Number} timeStamp The timestamp to split into millisecond and microsecond fields. * @return {Object} An object containing the millisecond * and microsecond portions of the timestamp. */ + function extractTimeFields(timeStamp) { return { milli: Math.floor(timeStamp), - micro: Number((timeStamp % 1).toFixed(3)), + micro: Number((timeStamp % 1).toFixed(3)) }; } @@ -347,14 +346,13 @@ function extractTimeFields(timeStamp) { * See the License for the specific language governing permissions and * 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); @@ -363,7 +361,6 @@ function initSender(logs, config) { 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. @@ -371,42 +368,43 @@ function initSender(logs, config) { * @param {Object} config Configuration object to be read from. * @return {Number} The newly created interval id. */ + function sendOnInterval(logs, config) { - return setInterval(function() { + return setInterval(function () { if (!config.on) { return; } if (logs.length >= config.logCountThreshold) { sendLogs(logs.slice(0), config, 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() { + window.addEventListener('unload', function () { navigator.sendBeacon(config.url, JSON.stringify(logs)); }); } else { - window.addEventListener('beforeunload', function() { + window.addEventListener('beforeunload', function () { if (logs.length > 0) { sendLogs(logs, config, 1); } }); } } - /** * Sends the provided array of logs to the specified url, * retrying the request up to the specified number of retries. @@ -414,22 +412,21 @@ function sendOnClose(logs, config) { * @param {string} config configuration parameters (e.g., to extract URL from & send the POST request to). * @param {Number} retries Maximum number of attempts to send the logs. */ - // @todo expose config object to sendLogs replate url with config.url + function sendLogs(logs, config, retries) { - var req = new XMLHttpRequest(); + var req = new XMLHttpRequest(); // @todo setRequestHeader for Auth - // @todo setRequestHeader for Auth var data = JSON.stringify(logs); - req.open('POST', config.url); + if (config.authHeader) { req.setRequestHeader('Authorization', config.authHeader); } req.setRequestHeader('Content-type', 'application/json;charset=UTF-8'); - req.onreadystatechange = function() { + req.onreadystatechange = function () { if (req.readyState === 4 && req.status !== 200) { if (retries > 0) { sendLogs(logs, config, retries--); @@ -456,9 +453,6 @@ function sendLogs(logs, config, retries) { * See the License for the specific language governing permissions and * limitations under the License. */ - -// inherent dependency on globals.js, loaded by the webext - // browser is defined in firefox, but not in chrome. In chrome, they use // the 'chrome' global instead. Let's map it to browser so we don't have // to have if-conditions all over the place. @@ -474,24 +468,23 @@ var config = { version: null, resolution: 500, time: timeStampScale({}), - on: true, + on: true }; var sessionId = 'session_' + Date.now(); - -var getTimestamp = ((typeof performance !== 'undefined') && (typeof performance.now !== 'undefined')) - ? function () { return performance.now() + performance.timing.navigationStart; } - : Date.now; - -browser.storage.local.set({ sessionId: sessionId }); - +var getTimestamp = typeof performance !== 'undefined' && typeof performance.now !== 'undefined' ? function () { + return performance.now() + performance.timing.navigationStart; +} : Date.now; +browser.storage.local.set({ + sessionId: sessionId +}); browser.storage.local.get({ userAleHost: userAleHost, userAleScript: userAleScript, toolUser: toolUser, toolName: toolName, - toolVersion: toolVersion, + toolVersion: toolVersion }, storeCallback); - + function storeCallback(item) { config = Object.assign({}, config, { url: item.userAleHost, @@ -513,22 +506,21 @@ function dispatchTabMessage(message) { function packageBrowserLog(type, logDetail) { var timeFields = extractTimeFields(getTimestamp()); - logs.push({ - 'target' : null, - 'path' : null, - 'clientTime' : timeFields.milli, - 'microTime' : timeFields.micro, - 'location' : null, - 'type' : 'browser.' + type, + 'target': null, + 'path': null, + 'clientTime': timeFields.milli, + 'microTime': timeFields.micro, + 'location': null, + 'type': 'browser.' + type, 'logType': 'raw', - 'userAction' : true, - 'details' : logDetail, - 'userId' : toolUser, + 'userAction': true, + 'details': logDetail, + 'userId': toolUser, 'toolVersion': null, 'toolName': null, 'useraleVersion': null, - 'sessionID': sessionId, + 'sessionID': sessionId }); } @@ -545,12 +537,14 @@ browser.runtime.onMessage.addListener(function (message) { initSender(logs, updatedConfig); dispatchTabMessage(message); })(); + break; case ADD_LOG: (function () { logs.push(message.payload); })(); + break; default: @@ -571,7 +565,7 @@ function getTabDetailById(tabId, onReady) { tabId: tab.id, title: tab.title, url: tab.url, - windowId: tab.windowId, + windowId: tab.windowId }); }); } @@ -581,7 +575,6 @@ browser.tabs.onActivated.addListener(function (e) { packageBrowserLog('tabs.onActivated', detail); }); }); - browser.tabs.onCreated.addListener(function (tab, e) { packageBrowserLog('tabs.onCreated', { active: tab.active, @@ -594,35 +587,32 @@ browser.tabs.onCreated.addListener(function (tab, e) { tabId: tab.id, title: tab.title, url: tab.url, - windowId: tab.windowId, + windowId: tab.windowId }); }); - browser.tabs.onDetached.addListener(function (tabId) { getTabDetailById(tabId, function (detail) { packageBrowserLog('tabs.onDetached', detail); }); }); - browser.tabs.onMoved.addListener(function (tabId) { getTabDetailById(tabId, function (detail) { packageBrowserLog('tabs.onMoved', detail); }); }); - browser.tabs.onRemoved.addListener(function (tabId) { - packageBrowserLog('tabs.onRemoved', { tabId: tabId }); + packageBrowserLog('tabs.onRemoved', { + tabId: tabId + }); }); - browser.tabs.onZoomChange.addListener(function (e) { getTabDetailById(e.tabId, function (detail) { packageBrowserLog('tabs.onZoomChange', Object.assign({}, { oldZoomFactor: e.oldZoomFactor, - newZoomFactor: e.newZoomFactor, + newZoomFactor: e.newZoomFactor }, detail)); }); }); - /* eslint-enable */ diff --git a/build/UserALEWebExtension/content.js b/build/UserALEWebExtension/content.js index 0c6e317..5016c4d 100644 --- a/build/UserALEWebExtension/content.js +++ b/build/UserALEWebExtension/content.js @@ -13,17 +13,15 @@ * 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. -*/ - -/* eslint-disable */ - -// these are default values, which can be overridden by the user on the options page -var userAleHost = 'http://localhost:8000'; -var userAleScript = 'userale-2.1.1.min.js'; -var toolUser = 'nobody'; -var toolName = 'test_app'; -var toolVersion = '2.1.1'; - +*/ + +/* eslint-disable */ +// these are default values, which can be overridden by the user on the options page +var userAleHost = 'http://localhost:8000'; +var userAleScript = 'userale-2.1.1.min.js'; +var toolUser = 'nobody'; +var toolName = 'test_app'; +var toolVersion = '2.1.1'; /* eslint-enable */ /* @@ -42,9 +40,7 @@ var toolVersion = '2.1.1'; * See the License for the specific language governing permissions and * limitations under the License. */ - var prefix = 'USERALE_'; - var CONFIG_CHANGE = prefix + 'CONFIG_CHANGE'; var ADD_LOG = prefix + 'ADD_LOG'; @@ -66,14 +62,13 @@ var version = "2.1.1"; * See the License for the specific language governing permissions and * limitations under the License. */ - - var sessionId = null; - +var sessionId = null; /** * Extracts the initial configuration settings from the * currently executing script tag. * @return {Object} The extracted configuration object */ + function getInitialSettings() { var settings = {}; @@ -81,12 +76,14 @@ function getInitialSettings() { sessionId = getSessionId('userAleSessionId', 'session_' + String(Date.now())); } - var script = document.currentScript || (function () { + var script = document.currentScript || function () { var scripts = document.getElementsByTagName('script'); return scripts[scripts.length - 1]; - })(); + }(); - var get = script ? script.getAttribute.bind(script) : function() { return null; }; + var get = script ? script.getAttribute.bind(script) : function () { + return null; + }; settings.autostart = get('data-autostart') === 'false' ? false : true; settings.url = get('data-url') || 'http://localhost:8000'; settings.transmitInterval = +get('data-interval') || 5000; @@ -103,14 +100,14 @@ function getInitialSettings() { settings.custIndex = get('data-index') || null; return settings; } - /** * defines sessionId, stores it in sessionStorage, checks to see if there is a sessionId in * storage when script is started. This prevents events like 'submit', which refresh page data * from refreshing the current user session * */ -function getSessionId(sessionKey, value){ + +function getSessionId(sessionKey, value) { if (window.sessionStorage.getItem(sessionKey) === null) { window.sessionStorage.setItem(sessionKey, JSON.stringify(value)); return value; @@ -118,13 +115,12 @@ function getSessionId(sessionKey, value){ return JSON.parse(window.sessionStorage.getItem(sessionKey)); } - - /** * Creates a function to normalize the timestamp of the provided event. * @param {Object} e An event containing a timeStamp property. * @return {timeStampScale~tsScaler} The timestamp normalizing function. */ + function timeStampScale(e) { if (e.timeStamp && e.timeStamp > 0) { var delta = Date.now() - e.timeStamp; @@ -133,24 +129,28 @@ function timeStampScale(e) { * @param {?Number} ts A timestamp to use for normalization. * @return {Number} A normalized timestamp. */ + var tsScaler; if (delta < 0) { - tsScaler = function () { + tsScaler = function tsScaler() { return e.timeStamp / 1000; }; } else if (delta > e.timeStamp) { var navStart = performance.timing.navigationStart; - tsScaler = function (ts) { + + tsScaler = function tsScaler(ts) { return ts + navStart; }; } else { - tsScaler = function (ts) { + tsScaler = function tsScaler(ts) { return ts; }; } } else { - tsScaler = function () { return Date.now(); }; + tsScaler = function tsScaler() { + return Date.now(); + }; } return tsScaler; @@ -180,22 +180,24 @@ function timeStampScale(e) { * @param {Object} newConfig Configuration object to merge into the current config. */ function configure(config, newConfig) { - Object.keys(newConfig).forEach(function(option) { + Object.keys(newConfig).forEach(function (option) { if (option === 'userFromParams') { var userId = getUserIdFromParams(newConfig[option]); + if (userId) { config.userId = userId; } } + config[option] = newConfig[option]; }); } - /** * Attempts to extract the userid from the query parameters of the URL. * @param {string} param The name of the query parameter containing the userid. * @return {string|null} The extracted/decoded userid, or null if none is found. */ + function getUserIdFromParams(param) { var userField = param; var regex = new RegExp('[?&]' + userField + '(=([^&#]*)|&|#|$)'); @@ -423,35 +425,31 @@ function createVersionParts(count) { * limitations under the License. */ var browser$1 = detect(); - var logs$1; -var config$1; +var config$1; // Interval Logging Globals -// Interval Logging Globals var intervalID; var intervalType; var intervalPath; var intervalTimer; var intervalCounter; var intervalLog; - var filterHandler = null; var mapHandler = null; - /** * Assigns a handler to filter logs out of the queue. * @param {Function} callback The handler to invoke when logging. */ + function setLogFilter(callback) { filterHandler = callback; } - - /** * Assigns the config and log container to be used by the logging functions. * @param {Array} newLogs Log container. * @param {Object} newConfig Configuration to use while logging. */ + function initPackager(newLogs, newConfig) { logs$1 = newLogs; config$1 = newConfig; @@ -464,50 +462,48 @@ function initPackager(newLogs, newConfig) { intervalCounter = 0; intervalLog = null; } - /** * Transforms the provided HTML event into a log and appends it to the log queue. * @param {Object} e The event to be logged. * @param {Function} detailFcn The function to extract additional log parameters from the event. * @return {boolean} Whether the event was logged. */ + function packageLog(e, detailFcn) { if (!config$1.on) { return false; } var details = null; + if (detailFcn) { details = detailFcn(e); } - var timeFields = extractTimeFields( - (e.timeStamp && e.timeStamp > 0) ? config$1.time(e.timeStamp) : Date.now() - ); - + var timeFields = extractTimeFields(e.timeStamp && e.timeStamp > 0 ? config$1.time(e.timeStamp) : Date.now()); var log = { - 'target' : getSelector(e.target), - 'path' : buildPath(e), + 'target': getSelector(e.target), + 'path': buildPath(e), 'pageUrl': window.location.href, 'pageTitle': document.title, 'pageReferrer': document.referrer, 'browser': detectBrowser(), - 'clientTime' : timeFields.milli, - 'microTime' : timeFields.micro, - 'location' : getLocation(e), - 'scrnRes' : getSreenRes(), - 'type' : e.type, + 'clientTime': timeFields.milli, + 'microTime': timeFields.micro, + 'location': getLocation(e), + 'scrnRes': getSreenRes(), + 'type': e.type, 'logType': 'raw', - 'userAction' : true, - 'details' : details, - 'userId' : config$1.userId, - 'toolVersion' : config$1.version, - 'toolName' : config$1.toolName, + 'userAction': true, + 'details': details, + 'userId': config$1.userId, + 'toolVersion': config$1.version, + 'toolName': config$1.toolName, 'useraleVersion': config$1.useraleVersion, - 'sessionID': config$1.sessionID, + 'sessionID': config$1.sessionID }; - if ((typeof filterHandler === 'function') && !filterHandler(log)) { + if (typeof filterHandler === 'function' && !filterHandler(log)) { return false; } @@ -516,10 +512,8 @@ function packageLog(e, detailFcn) { } logs$1.push(log); - return true; } - /** * Packages the provided customLog to include standard meta data and appends it to the log queue. * @param {Object} customLog The behavior to be logged. @@ -527,187 +521,199 @@ function packageLog(e, detailFcn) { * @param {boolean} userAction Indicates user behavior (true) or system behavior (false) * @return {boolean} Whether the event was logged. */ -function packageCustomLog(customLog, detailFcn, userAction) { - if (!config$1.on) { - return false; - } - var details = null; - if (detailFcn) { - details = detailFcn(); - } +function packageCustomLog(customLog, detailFcn, userAction) { + if (!config$1.on) { + return false; + } - var metaData = { - 'pageUrl': window.location.href, - 'pageTitle': document.title, - 'pageReferrer': document.referrer, - 'browser': detectBrowser(), - 'clientTime' : Date.now(), - 'scrnRes' : getSreenRes(), - 'logType': 'custom', - 'userAction' : userAction, - 'details' : details, - 'userId' : config$1.userId, - 'toolVersion' : config$1.version, - 'toolName' : config$1.toolName, - 'useraleVersion': config$1.useraleVersion, - 'sessionID': config$1.sessionID - }; + var details = null; - var log = Object.assign(metaData, customLog); + if (detailFcn) { + details = detailFcn(); + } - if ((typeof filterHandler === 'function') && !filterHandler(log)) { - return false; - } + var metaData = { + 'pageUrl': window.location.href, + 'pageTitle': document.title, + 'pageReferrer': document.referrer, + 'browser': detectBrowser(), + 'clientTime': Date.now(), + 'scrnRes': getSreenRes(), + 'logType': 'custom', + 'userAction': userAction, + 'details': details, + 'userId': config$1.userId, + 'toolVersion': config$1.version, + 'toolName': config$1.toolName, + 'useraleVersion': config$1.useraleVersion, + 'sessionID': config$1.sessionID + }; + var log = Object.assign(metaData, customLog); - if (typeof mapHandler === 'function') { - log = mapHandler(log); - } + if (typeof filterHandler === 'function' && !filterHandler(log)) { + return false; + } - logs$1.push(log); + if (typeof mapHandler === 'function') { + log = mapHandler(log); + } - return true; + logs$1.push(log); + return true; } - /** * Extract the millisecond and microsecond portions of a timestamp. * @param {Number} timeStamp The timestamp to split into millisecond and microsecond fields. * @return {Object} An object containing the millisecond * and microsecond portions of the timestamp. */ + function extractTimeFields(timeStamp) { return { milli: Math.floor(timeStamp), - micro: Number((timeStamp % 1).toFixed(3)), + micro: Number((timeStamp % 1).toFixed(3)) }; } - /** * Track intervals and gather details about it. * @param {Object} e * @return boolean */ + function packageIntervalLog(e) { - var target = getSelector(e.target); - var path = buildPath(e); - var type = e.type; - var timestamp = Math.floor((e.timeStamp && e.timeStamp > 0) ? config$1.time(e.timeStamp) : Date.now()); - - // Init - this should only happen once on initialization - if (intervalID == null) { - intervalID = target; - intervalType = type; - intervalPath = path; - intervalTimer = timestamp; - intervalCounter = 0; - } + var target = getSelector(e.target); + var path = buildPath(e); + var type = e.type; + var timestamp = Math.floor(e.timeStamp && e.timeStamp > 0 ? config$1.time(e.timeStamp) : Date.now()); // Init - this should only happen once on initialization + + if (intervalID == null) { + intervalID = target; + intervalType = type; + intervalPath = path; + intervalTimer = timestamp; + intervalCounter = 0; + } - if (intervalID !== target || intervalType !== type) { - // When to create log? On transition end - // @todo Possible for intervalLog to not be pushed in the event the interval never ends... - - intervalLog = { - 'target': intervalID, - 'path': intervalPath, - 'pageUrl': window.location.href, - 'pageTitle': document.title, - 'pageReferrer': document.referrer, - 'browser': detectBrowser(), - 'count': intervalCounter, - 'duration': timestamp - intervalTimer, // microseconds - 'startTime': intervalTimer, - 'endTime': timestamp, - 'type': intervalType, - 'logType': 'interval', - 'targetChange': intervalID !== target, - 'typeChange': intervalType !== type, - 'userAction': false, - 'userId': config$1.userId, - 'toolVersion': config$1.version, - 'toolName': config$1.toolName, - 'useraleVersion': config$1.useraleVersion, - 'sessionID': config$1.sessionID - }; + if (intervalID !== target || intervalType !== type) { + // When to create log? On transition end + // @todo Possible for intervalLog to not be pushed in the event the interval never ends... + intervalLog = { + 'target': intervalID, + 'path': intervalPath, + 'pageUrl': window.location.href, + 'pageTitle': document.title, + 'pageReferrer': document.referrer, + 'browser': detectBrowser(), + 'count': intervalCounter, + 'duration': timestamp - intervalTimer, + // microseconds + 'startTime': intervalTimer, + 'endTime': timestamp, + 'type': intervalType, + 'logType': 'interval', + 'targetChange': intervalID !== target, + 'typeChange': intervalType !== type, + 'userAction': false, + 'userId': config$1.userId, + 'toolVersion': config$1.version, + 'toolName': config$1.toolName, + 'useraleVersion': config$1.useraleVersion, + 'sessionID': config$1.sessionID + }; - if (typeof filterHandler === 'function' && !filterHandler(intervalLog)) { - return false; - } + if (typeof filterHandler === 'function' && !filterHandler(intervalLog)) { + return false; + } - if (typeof mapHandler === 'function') { - intervalLog = mapHandler(intervalLog, e); - } + if (typeof mapHandler === 'function') { + intervalLog = mapHandler(intervalLog, e); + } - logs$1.push(intervalLog); + logs$1.push(intervalLog); // Reset - // Reset - intervalID = target; - intervalType = type; - intervalPath = path; - intervalTimer = timestamp; - intervalCounter = 0; - } + intervalID = target; + intervalType = type; + intervalPath = path; + intervalTimer = timestamp; + intervalCounter = 0; + } // Interval is still occuring, just update counter - // Interval is still occuring, just update counter - if (intervalID == target && intervalType == type) { - intervalCounter = intervalCounter + 1; - } - return true; -} + if (intervalID == target && intervalType == type) { + intervalCounter = intervalCounter + 1; + } + return true; +} /** * Extracts coordinate information from the event * depending on a few browser quirks. * @param {Object} e The event to extract coordinate information from. * @return {Object} An object containing nullable x and y coordinates for the event. */ + function getLocation(e) { if (e.pageX != null) { - return { 'x' : e.pageX, 'y' : e.pageY }; + return { + 'x': e.pageX, + 'y': e.pageY + }; } else if (e.clientX != null) { - return { 'x' : document.documentElement.scrollLeft + e.clientX, 'y' : document.documentElement.scrollTop + e.clientY }; + return { + 'x': document.documentElement.scrollLeft + e.clientX, + 'y': document.documentElement.scrollTop + e.clientY + }; } else { - return { 'x' : null, 'y' : null }; + return { + 'x': null, + 'y': null + }; } } - /** * Extracts innerWidth and innerHeight to provide estimates of screen resolution * @return {Object} An object containing the innerWidth and InnerHeight */ + function getSreenRes() { - return { 'width': window.innerWidth, 'height': window.innerHeight}; + return { + 'width': window.innerWidth, + 'height': window.innerHeight + }; } - /** * Builds a string CSS selector from the provided element * @param {HTMLElement} ele The element from which the selector is built. * @return {string} The CSS selector for the element, or Unknown if it can't be determined. */ + function getSelector(ele) { if (ele.localName) { - return ele.localName + (ele.id ? ('#' + ele.id) : '') + (ele.className ? ('.' + ele.className) : ''); + return ele.localName + (ele.id ? '#' + ele.id : '') + (ele.className ? '.' + ele.className : ''); } else if (ele.nodeName) { - return ele.nodeName + (ele.id ? ('#' + ele.id) : '') + (ele.className ? ('.' + ele.className) : ''); + return ele.nodeName + (ele.id ? '#' + ele.id : '') + (ele.className ? '.' + ele.className : ''); } else if (ele && ele.document && ele.location && ele.alert && ele.setInterval) { return "Window"; } else { return "Unknown"; } } - /** * Builds an array of elements from the provided event target, to the root element. * @param {Object} e Event from which the path should be built. * @return {HTMLElement[]} Array of elements, starting at the event target, ending at the root element. */ + function buildPath(e) { var path = []; + if (e.path) { path = e.path; } else { var ele = e.target; - while(ele) { + + while (ele) { path.push(ele); ele = ele.parentElement; } @@ -715,28 +721,29 @@ function buildPath(e) { return selectorizePath(path); } - /** * Builds a CSS selector path from the provided list of elements. * @param {HTMLElement[]} path Array of HTMLElements from which the path should be built. * @return {string[]} Array of string CSS selectors. */ + function selectorizePath(path) { var i = 0; var pathEle; var pathSelectors = []; + while (pathEle = path[i]) { pathSelectors.push(getSelector(pathEle)); ++i; } + return pathSelectors; } - function detectBrowser() { - return { - 'browser': browser$1 ? browser$1.name : '', - 'version': browser$1 ? browser$1.version : '' - }; + return { + 'browser': browser$1 ? browser$1.name : '', + 'version': browser$1 ? browser$1.version : '' + }; } /* @@ -755,14 +762,13 @@ function detectBrowser() { * See the License for the specific language governing permissions and * 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); @@ -771,7 +777,6 @@ function initSender(logs, config) { 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. @@ -779,19 +784,20 @@ function initSender(logs, config) { * @param {Object} config Configuration object to be read from. * @return {Number} The newly created interval id. */ + function sendOnInterval(logs, config) { - return setInterval(function() { + return setInterval(function () { if (!config.on) { return; } if (logs.length >= config.logCountThreshold) { sendLogs(logs.slice(0), config, 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 @@ -801,38 +807,39 @@ function sendOnInterval(logs, config) { * @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, 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() { + window.addEventListener('unload', function () { navigator.sendBeacon(config.url, JSON.stringify(logs)); }); } else { - window.addEventListener('beforeunload', function() { + window.addEventListener('beforeunload', function () { if (logs.length > 0) { sendLogs(logs, config, 1); } }); } } - /** * Sends the provided array of logs to the specified url, * retrying the request up to the specified number of retries. @@ -840,22 +847,21 @@ function sendOnClose(logs, config) { * @param {string} config configuration parameters (e.g., to extract URL from & send the POST request to). * @param {Number} retries Maximum number of attempts to send the logs. */ - // @todo expose config object to sendLogs replate url with config.url + function sendLogs(logs, config, retries) { - var req = new XMLHttpRequest(); + var req = new XMLHttpRequest(); // @todo setRequestHeader for Auth - // @todo setRequestHeader for Auth var data = JSON.stringify(logs); - req.open('POST', config.url); + if (config.authHeader) { req.setRequestHeader('Authorization', config.authHeader); } req.setRequestHeader('Content-type', 'application/json;charset=UTF-8'); - req.onreadystatechange = function() { + req.onreadystatechange = function () { if (req.readyState === 4 && req.status !== 200) { if (retries > 0) { sendLogs(logs, config, retries--); @@ -883,193 +889,203 @@ function sendLogs(logs, config, retries) { * limitations under the License. */ -// @todo var>let var events; var bufferBools; -var bufferedEvents; -//@todo: Investigate drag events and their behavior +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']; - /** * Maps an event to an object containing useful information. * @param {Object} e Event to extract data from */ + function extractMouseEvent(e) { return { - 'clicks' : e.detail, - 'ctrl' : e.ctrlKey, - 'alt' : e.altKey, - 'shift' : e.shiftKey, - 'meta' : e.metaKey, -// 'text' : e.target.innerHTML + 'clicks': e.detail, + 'ctrl': e.ctrlKey, + 'alt': e.altKey, + 'shift': e.shiftKey, + 'meta': e.metaKey // 'text' : e.target.innerHTML + }; } - /** * Defines the way information is extracted from various events. * Also defines which events we will listen to. * @param {Object} config Configuration object to read from. */ + function defineDetails(config) { // Events list // Keys are event types // Values are functions that return details object if applicable events = { - 'click' : extractMouseEvent, - 'dblclick' : extractMouseEvent, - 'mousedown' : extractMouseEvent, - 'mouseup' : extractMouseEvent, - 'focus' : null, - 'blur' : null, - 'input' : config.logDetails ? function(e) { return { 'value' : e.target.value }; } : null, - 'change' : config.logDetails ? function(e) { return { 'value' : e.target.value }; } : null, - 'dragstart' : null, - 'dragend' : null, - '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 + 'click': extractMouseEvent, + 'dblclick': extractMouseEvent, + 'mousedown': extractMouseEvent, + 'mouseup': extractMouseEvent, + 'focus': null, + 'blur': null, + 'input': config.logDetails ? function (e) { + return { + 'value': e.target.value + }; + } : null, + 'change': config.logDetails ? function (e) { + return { + 'value': e.target.value + }; + } : null, + 'dragstart': null, + 'dragend': null, + '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 }; - bufferBools = {}; bufferedEvents = { - 'wheel' : function(e) { return { 'x' : e.deltaX, 'y' : e.deltaY, 'z' : e.deltaZ }; }, - 'scroll' : function() { return { 'x' : window.scrollX, 'y' : window.scrollY }; }, - 'resize' : function() { return { 'width' : window.outerWidth, 'height' : window.outerHeight }; } + 'wheel': function wheel(e) { + return { + 'x': e.deltaX, + 'y': e.deltaY, + 'z': e.deltaZ + }; + }, + 'scroll': function scroll() { + return { + 'x': window.scrollX, + 'y': window.scrollY + }; + }, + 'resize': function resize() { + return { + 'width': window.outerWidth, + 'height': window.outerHeight + }; + } }; - refreshEvents = { - 'submit' : null + 'submit': null }; } - /** * Hooks the event handlers for each event type of interest. * @param {Object} config Configuration object to use. * @return {boolean} Whether the operation succeeded */ + function attachHandlers(config) { defineDetails(config); - - Object.keys(events).forEach(function(ev) { - document.addEventListener(ev, function(e) { + Object.keys(events).forEach(function (ev) { + document.addEventListener(ev, function (e) { packageLog(e, events[ev]); }, true); }); - - intervalEvents.forEach(function(ev) { - document.addEventListener(ev, function(e) { - packageIntervalLog(e); + intervalEvents.forEach(function (ev) { + document.addEventListener(ev, function (e) { + packageIntervalLog(e); }, true); }); - - Object.keys(bufferedEvents).forEach(function(ev) { + Object.keys(bufferedEvents).forEach(function (ev) { bufferBools[ev] = true; - - window.addEventListener(ev, function(e) { + window.addEventListener(ev, function (e) { if (bufferBools[ev]) { bufferBools[ev] = false; packageLog(e, bufferedEvents[ev]); - setTimeout(function() { bufferBools[ev] = true; }, config.resolution); + setTimeout(function () { + bufferBools[ev] = true; + }, config.resolution); } }, true); }); - - Object.keys(refreshEvents).forEach(function(ev) { - document.addEventListener(ev, function(e) { + Object.keys(refreshEvents).forEach(function (ev) { + document.addEventListener(ev, function (e) { packageLog(e, events[ev]); - sendOnRefresh(logs$1,config); + sendOnRefresh(logs$1, config); }, true); }); - - windowEvents.forEach(function(ev) { - window.addEventListener(ev, function(e) { - packageLog(e, function() { return { 'window' : true }; }); + windowEvents.forEach(function (ev) { + window.addEventListener(ev, function (e) { + packageLog(e, function () { + return { + 'window': true + }; + }); }, true); }); - return true; } -/* - * 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 = {}; var logs = []; var startLoadTimestamp = Date.now(); var endLoadTimestamp; + window.onload = function () { - endLoadTimestamp = Date.now(); + endLoadTimestamp = Date.now(); }; var started = false; - -// Start up Userale config.on = false; config.useraleVersion = version; - configure(config, getInitialSettings()); initPackager(logs, config); if (config.autostart) { - setup(config); + setup(config); } - /** * Hooks the global event listener, and starts up the * logging interval. * @param {Object} config Configuration settings for the logger */ -function setup(config) { - if (!started) { - setTimeout(function () { - var state = document.readyState; - - if (state === 'interactive' || state === 'complete') { - attachHandlers(config); - initSender(logs, config); - started = config.on = true; - packageCustomLog({ - type: 'load', - logType: 'raw', - pageLoadTime: endLoadTimestamp - startLoadTimestamp - }, () => {},false); - } else { - setup(config); - } - }, 100); - } -} + +function setup(config) { + if (!started) { + setTimeout(function () { + var state = document.readyState; + + if (state === 'interactive' || state === 'complete') { + attachHandlers(config); + initSender(logs, config); + started = config.on = true; + packageCustomLog({ + type: 'load', + logType: 'raw', + pageLoadTime: endLoadTimestamp - startLoadTimestamp + }, function () {}, false); + } else { + setup(config); + } + }, 100); + } +} // Export the Userale API /** * Updates the current configuration * object with the provided values. * @param {Object} newConfig The configuration options to use. * @return {Object} Returns the updated configuration. */ + function options(newConfig) { - if (newConfig !== undefined) { - configure(config, newConfig); - } + if (newConfig !== undefined) { + configure(config, newConfig); + } - return config; + return config; } /* @@ -1088,24 +1104,21 @@ function options(newConfig) { * See the License for the specific language governing permissions and * limitations under the License. */ - -// browser is defined in firefox, but not in chrome. In chrome, they use // the 'chrome' global instead. Let's map it to browser so we don't have // to have if-conditions all over the place. -var browser = browser || chrome; - -// creates a Future for retrieval of the named keys +var browser = browser || chrome; // creates a Future for retrieval of the named keys // the value specified is the default value if one doesn't exist in the storage + browser.storage.local.get({ sessionId: null, userAleHost: userAleHost, userAleScript: userAleScript, toolUser: toolUser, toolName: toolName, - toolVersion: toolVersion, + toolVersion: toolVersion }, storeCallback); - + function storeCallback(item) { injectScript({ url: item.userAleHost, @@ -1117,15 +1130,18 @@ function storeCallback(item) { } function queueLog(log) { - browser.runtime.sendMessage({ type: ADD_LOG, payload: log }); + browser.runtime.sendMessage({ + type: ADD_LOG, + payload: log + }); } function injectScript(config) { - options(config); -// start(); not necessary given that autostart in place, and option is masked from WebExt users + options(config); // start(); not necessary given that autostart in place, and option is masked from WebExt users + setLogFilter(function (log) { queueLog(Object.assign({}, log, { - pageUrl: document.location.href, + pageUrl: document.location.href })); return false; }); @@ -1141,7 +1157,6 @@ browser.runtime.onMessage.addListener(function (message) { }); } }); - /* eslint-enable */ diff --git a/build/UserALEWebExtension/options.js b/build/UserALEWebExtension/options.js index c1fe90f..7ef243d 100644 --- a/build/UserALEWebExtension/options.js +++ b/build/UserALEWebExtension/options.js @@ -13,17 +13,15 @@ * 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. -*/ - -/* eslint-disable */ - -// these are default values, which can be overridden by the user on the options page -var userAleHost = 'http://localhost:8000'; -var userAleScript = 'userale-2.1.1.min.js'; -var toolUser = 'nobody'; -var toolName = 'test_app'; -var toolVersion = '2.1.1'; - +*/ + +/* eslint-disable */ +// these are default values, which can be overridden by the user on the options page +var userAleHost = 'http://localhost:8000'; +var userAleScript = 'userale-2.1.1.min.js'; +var toolUser = 'nobody'; +var toolName = 'test_app'; +var toolVersion = '2.1.1'; /* eslint-enable */ /* @@ -42,9 +40,7 @@ var toolVersion = '2.1.1'; * See the License for the specific language governing permissions and * limitations under the License. */ - var prefix = 'USERALE_'; - var CONFIG_CHANGE = prefix + 'CONFIG_CHANGE'; /* @@ -62,46 +58,46 @@ var CONFIG_CHANGE = prefix + 'CONFIG_CHANGE'; * 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. -*/ - -if (chrome) { - browser = chrome; -} - -// creates a Future for retrieval of the named keys -// the value specified is the default value if one doesn't exist in the storage -browser.storage.local.get({ - userAleHost: userAleHost, - userAleScript: userAleScript, - toolUser: toolUser, - toolName: toolName, - toolVersion: toolVersion, -}, storeCallback); - -function storeCallback(item) { - document.getElementById("host").value = item.userAleHost; - document.getElementById("clientScript").value = item.userAleScript; - document.getElementById("toolUser").value = item.toolUser; - document.getElementById("toolName").value = item.toolName; - document.getElementById("toolVersion").value = item.toolVersion; -} - -function saveOptions(e) { - const updatedConfig = { - userAleHost: document.getElementById("host").value, - userAleScript: document.getElementById("clientScript").value, - toolUser: document.getElementById("toolUser").value, - toolName: document.getElementById("toolName").value, - toolVersion: document.getElementById("toolVersion").value, - }; - - browser.storage.local.set(updatedConfig); - - browser.runtime.sendMessage({ type: CONFIG_CHANGE, payload: updatedConfig }); -} - -document.addEventListener("submit", function() { - saveOptions(); -}); - +*/ + +if (chrome) { + browser = chrome; +} // creates a Future for retrieval of the named keys +// the value specified is the default value if one doesn't exist in the storage + + +browser.storage.local.get({ + userAleHost: userAleHost, + userAleScript: userAleScript, + toolUser: toolUser, + toolName: toolName, + toolVersion: toolVersion +}, storeCallback); + +function storeCallback(item) { + document.getElementById("host").value = item.userAleHost; + document.getElementById("clientScript").value = item.userAleScript; + document.getElementById("toolUser").value = item.toolUser; + document.getElementById("toolName").value = item.toolName; + document.getElementById("toolVersion").value = item.toolVersion; +} + +function saveOptions(e) { + var updatedConfig = { + userAleHost: document.getElementById("host").value, + userAleScript: document.getElementById("clientScript").value, + toolUser: document.getElementById("toolUser").value, + toolName: document.getElementById("toolName").value, + toolVersion: document.getElementById("toolVersion").value + }; + browser.storage.local.set(updatedConfig); + browser.runtime.sendMessage({ + type: CONFIG_CHANGE, + payload: updatedConfig + }); +} + +document.addEventListener("submit", function () { + saveOptions(); +}); /* eslint-enable */ diff --git a/build/userale-2.1.1.js b/build/userale-2.1.1.js index ea5de7d..b0681e8 100644 --- a/build/userale-2.1.1.js +++ b/build/userale-2.1.1.js @@ -22,6 +22,22 @@ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.userale = {})); }(this, (function (exports) { 'use strict'; + function _typeof(obj) { + "@babel/helpers - typeof"; + + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function _typeof(obj) { + return typeof obj; + }; + } else { + _typeof = function _typeof(obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } + + return _typeof(obj); + } + var version$1 = "2.1.1"; /* @@ -40,14 +56,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - - var sessionId = null; - + var sessionId = null; /** * Extracts the initial configuration settings from the * currently executing script tag. * @return {Object} The extracted configuration object */ + function getInitialSettings() { var settings = {}; @@ -55,12 +70,14 @@ sessionId = getSessionId('userAleSessionId', 'session_' + String(Date.now())); } - var script = document.currentScript || (function () { + var script = document.currentScript || function () { var scripts = document.getElementsByTagName('script'); return scripts[scripts.length - 1]; - })(); + }(); - var get = script ? script.getAttribute.bind(script) : function() { return null; }; + var get = script ? script.getAttribute.bind(script) : function () { + return null; + }; settings.autostart = get('data-autostart') === 'false' ? false : true; settings.url = get('data-url') || 'http://localhost:8000'; settings.transmitInterval = +get('data-interval') || 5000; @@ -77,14 +94,14 @@ settings.custIndex = get('data-index') || null; return settings; } - /** * defines sessionId, stores it in sessionStorage, checks to see if there is a sessionId in * storage when script is started. This prevents events like 'submit', which refresh page data * from refreshing the current user session * */ - function getSessionId(sessionKey, value){ + + function getSessionId(sessionKey, value) { if (window.sessionStorage.getItem(sessionKey) === null) { window.sessionStorage.setItem(sessionKey, JSON.stringify(value)); return value; @@ -92,13 +109,12 @@ return JSON.parse(window.sessionStorage.getItem(sessionKey)); } - - /** * Creates a function to normalize the timestamp of the provided event. * @param {Object} e An event containing a timeStamp property. * @return {timeStampScale~tsScaler} The timestamp normalizing function. */ + function timeStampScale(e) { if (e.timeStamp && e.timeStamp > 0) { var delta = Date.now() - e.timeStamp; @@ -107,24 +123,28 @@ * @param {?Number} ts A timestamp to use for normalization. * @return {Number} A normalized timestamp. */ + var tsScaler; if (delta < 0) { - tsScaler = function () { + tsScaler = function tsScaler() { return e.timeStamp / 1000; }; } else if (delta > e.timeStamp) { var navStart = performance.timing.navigationStart; - tsScaler = function (ts) { + + tsScaler = function tsScaler(ts) { return ts + navStart; }; } else { - tsScaler = function (ts) { + tsScaler = function tsScaler(ts) { return ts; }; } } else { - tsScaler = function () { return Date.now(); }; + tsScaler = function tsScaler() { + return Date.now(); + }; } return tsScaler; @@ -154,22 +174,24 @@ * @param {Object} newConfig Configuration object to merge into the current config. */ function configure(config, newConfig) { - Object.keys(newConfig).forEach(function(option) { + Object.keys(newConfig).forEach(function (option) { if (option === 'userFromParams') { var userId = getUserIdFromParams(newConfig[option]); + if (userId) { config.userId = userId; } } + config[option] = newConfig[option]; }); } - /** * Attempts to extract the userid from the query parameters of the URL. * @param {string} param The name of the query parameter containing the userid. * @return {string|null} The extracted/decoded userid, or null if none is found. */ + function getUserIdFromParams(param) { var userField = param; var regex = new RegExp('[?&]' + userField + '(=([^&#]*)|&|#|$)'); @@ -397,43 +419,39 @@ * limitations under the License. */ var browser = detect(); - var logs$1; - var config$1; + var config$1; // Interval Logging Globals - // Interval Logging Globals var intervalID; var intervalType; var intervalPath; var intervalTimer; var intervalCounter; var intervalLog; - var filterHandler = null; var mapHandler = null; - /** * Assigns a handler to filter logs out of the queue. * @param {Function} callback The handler to invoke when logging. */ + function setLogFilter(callback) { filterHandler = callback; } - /** * Assigns a handler to transform logs from their default structure. * @param {Function} callback The handler to invoke when logging. */ + function setLogMapper(callback) { mapHandler = callback; } - - /** * Assigns the config and log container to be used by the logging functions. * @param {Array} newLogs Log container. * @param {Object} newConfig Configuration to use while logging. */ + function initPackager(newLogs, newConfig) { logs$1 = newLogs; config$1 = newConfig; @@ -446,50 +464,48 @@ intervalCounter = 0; intervalLog = null; } - /** * Transforms the provided HTML event into a log and appends it to the log queue. * @param {Object} e The event to be logged. * @param {Function} detailFcn The function to extract additional log parameters from the event. * @return {boolean} Whether the event was logged. */ + function packageLog(e, detailFcn) { if (!config$1.on) { return false; } var details = null; + if (detailFcn) { details = detailFcn(e); } - var timeFields = extractTimeFields( - (e.timeStamp && e.timeStamp > 0) ? config$1.time(e.timeStamp) : Date.now() - ); - + var timeFields = extractTimeFields(e.timeStamp && e.timeStamp > 0 ? config$1.time(e.timeStamp) : Date.now()); var log = { - 'target' : getSelector(e.target), - 'path' : buildPath(e), + 'target': getSelector(e.target), + 'path': buildPath(e), 'pageUrl': window.location.href, 'pageTitle': document.title, 'pageReferrer': document.referrer, 'browser': detectBrowser(), - 'clientTime' : timeFields.milli, - 'microTime' : timeFields.micro, - 'location' : getLocation(e), - 'scrnRes' : getSreenRes(), - 'type' : e.type, + 'clientTime': timeFields.milli, + 'microTime': timeFields.micro, + 'location': getLocation(e), + 'scrnRes': getSreenRes(), + 'type': e.type, 'logType': 'raw', - 'userAction' : true, - 'details' : details, - 'userId' : config$1.userId, - 'toolVersion' : config$1.version, - 'toolName' : config$1.toolName, + 'userAction': true, + 'details': details, + 'userId': config$1.userId, + 'toolVersion': config$1.version, + 'toolName': config$1.toolName, 'useraleVersion': config$1.useraleVersion, - 'sessionID': config$1.sessionID, + 'sessionID': config$1.sessionID }; - if ((typeof filterHandler === 'function') && !filterHandler(log)) { + if (typeof filterHandler === 'function' && !filterHandler(log)) { return false; } @@ -498,10 +514,8 @@ } logs$1.push(log); - return true; } - /** * Packages the provided customLog to include standard meta data and appends it to the log queue. * @param {Object} customLog The behavior to be logged. @@ -509,187 +523,199 @@ * @param {boolean} userAction Indicates user behavior (true) or system behavior (false) * @return {boolean} Whether the event was logged. */ - function packageCustomLog(customLog, detailFcn, userAction) { - if (!config$1.on) { - return false; - } - var details = null; - if (detailFcn) { - details = detailFcn(); - } + function packageCustomLog(customLog, detailFcn, userAction) { + if (!config$1.on) { + return false; + } - var metaData = { - 'pageUrl': window.location.href, - 'pageTitle': document.title, - 'pageReferrer': document.referrer, - 'browser': detectBrowser(), - 'clientTime' : Date.now(), - 'scrnRes' : getSreenRes(), - 'logType': 'custom', - 'userAction' : userAction, - 'details' : details, - 'userId' : config$1.userId, - 'toolVersion' : config$1.version, - 'toolName' : config$1.toolName, - 'useraleVersion': config$1.useraleVersion, - 'sessionID': config$1.sessionID - }; + var details = null; - var log = Object.assign(metaData, customLog); + if (detailFcn) { + details = detailFcn(); + } - if ((typeof filterHandler === 'function') && !filterHandler(log)) { - return false; - } + var metaData = { + 'pageUrl': window.location.href, + 'pageTitle': document.title, + 'pageReferrer': document.referrer, + 'browser': detectBrowser(), + 'clientTime': Date.now(), + 'scrnRes': getSreenRes(), + 'logType': 'custom', + 'userAction': userAction, + 'details': details, + 'userId': config$1.userId, + 'toolVersion': config$1.version, + 'toolName': config$1.toolName, + 'useraleVersion': config$1.useraleVersion, + 'sessionID': config$1.sessionID + }; + var log = Object.assign(metaData, customLog); - if (typeof mapHandler === 'function') { - log = mapHandler(log); - } + if (typeof filterHandler === 'function' && !filterHandler(log)) { + return false; + } - logs$1.push(log); + if (typeof mapHandler === 'function') { + log = mapHandler(log); + } - return true; + logs$1.push(log); + return true; } - /** * Extract the millisecond and microsecond portions of a timestamp. * @param {Number} timeStamp The timestamp to split into millisecond and microsecond fields. * @return {Object} An object containing the millisecond * and microsecond portions of the timestamp. */ + function extractTimeFields(timeStamp) { return { milli: Math.floor(timeStamp), - micro: Number((timeStamp % 1).toFixed(3)), + micro: Number((timeStamp % 1).toFixed(3)) }; } - /** * Track intervals and gather details about it. * @param {Object} e * @return boolean */ + function packageIntervalLog(e) { - var target = getSelector(e.target); - var path = buildPath(e); - var type = e.type; - var timestamp = Math.floor((e.timeStamp && e.timeStamp > 0) ? config$1.time(e.timeStamp) : Date.now()); - - // Init - this should only happen once on initialization - if (intervalID == null) { - intervalID = target; - intervalType = type; - intervalPath = path; - intervalTimer = timestamp; - intervalCounter = 0; - } + var target = getSelector(e.target); + var path = buildPath(e); + var type = e.type; + var timestamp = Math.floor(e.timeStamp && e.timeStamp > 0 ? config$1.time(e.timeStamp) : Date.now()); // Init - this should only happen once on initialization + + if (intervalID == null) { + intervalID = target; + intervalType = type; + intervalPath = path; + intervalTimer = timestamp; + intervalCounter = 0; + } - if (intervalID !== target || intervalType !== type) { - // When to create log? On transition end - // @todo Possible for intervalLog to not be pushed in the event the interval never ends... - - intervalLog = { - 'target': intervalID, - 'path': intervalPath, - 'pageUrl': window.location.href, - 'pageTitle': document.title, - 'pageReferrer': document.referrer, - 'browser': detectBrowser(), - 'count': intervalCounter, - 'duration': timestamp - intervalTimer, // microseconds - 'startTime': intervalTimer, - 'endTime': timestamp, - 'type': intervalType, - 'logType': 'interval', - 'targetChange': intervalID !== target, - 'typeChange': intervalType !== type, - 'userAction': false, - 'userId': config$1.userId, - 'toolVersion': config$1.version, - 'toolName': config$1.toolName, - 'useraleVersion': config$1.useraleVersion, - 'sessionID': config$1.sessionID - }; + if (intervalID !== target || intervalType !== type) { + // When to create log? On transition end + // @todo Possible for intervalLog to not be pushed in the event the interval never ends... + intervalLog = { + 'target': intervalID, + 'path': intervalPath, + 'pageUrl': window.location.href, + 'pageTitle': document.title, + 'pageReferrer': document.referrer, + 'browser': detectBrowser(), + 'count': intervalCounter, + 'duration': timestamp - intervalTimer, + // microseconds + 'startTime': intervalTimer, + 'endTime': timestamp, + 'type': intervalType, + 'logType': 'interval', + 'targetChange': intervalID !== target, + 'typeChange': intervalType !== type, + 'userAction': false, + 'userId': config$1.userId, + 'toolVersion': config$1.version, + 'toolName': config$1.toolName, + 'useraleVersion': config$1.useraleVersion, + 'sessionID': config$1.sessionID + }; - if (typeof filterHandler === 'function' && !filterHandler(intervalLog)) { - return false; - } + if (typeof filterHandler === 'function' && !filterHandler(intervalLog)) { + return false; + } - if (typeof mapHandler === 'function') { - intervalLog = mapHandler(intervalLog, e); - } + if (typeof mapHandler === 'function') { + intervalLog = mapHandler(intervalLog, e); + } - logs$1.push(intervalLog); + logs$1.push(intervalLog); // Reset - // Reset - intervalID = target; - intervalType = type; - intervalPath = path; - intervalTimer = timestamp; - intervalCounter = 0; - } + intervalID = target; + intervalType = type; + intervalPath = path; + intervalTimer = timestamp; + intervalCounter = 0; + } // Interval is still occuring, just update counter - // Interval is still occuring, just update counter - if (intervalID == target && intervalType == type) { - intervalCounter = intervalCounter + 1; - } - return true; - } + if (intervalID == target && intervalType == type) { + intervalCounter = intervalCounter + 1; + } + return true; + } /** * Extracts coordinate information from the event * depending on a few browser quirks. * @param {Object} e The event to extract coordinate information from. * @return {Object} An object containing nullable x and y coordinates for the event. */ + function getLocation(e) { if (e.pageX != null) { - return { 'x' : e.pageX, 'y' : e.pageY }; + return { + 'x': e.pageX, + 'y': e.pageY + }; } else if (e.clientX != null) { - return { 'x' : document.documentElement.scrollLeft + e.clientX, 'y' : document.documentElement.scrollTop + e.clientY }; + return { + 'x': document.documentElement.scrollLeft + e.clientX, + 'y': document.documentElement.scrollTop + e.clientY + }; } else { - return { 'x' : null, 'y' : null }; + return { + 'x': null, + 'y': null + }; } } - /** * Extracts innerWidth and innerHeight to provide estimates of screen resolution * @return {Object} An object containing the innerWidth and InnerHeight */ + function getSreenRes() { - return { 'width': window.innerWidth, 'height': window.innerHeight}; + return { + 'width': window.innerWidth, + 'height': window.innerHeight + }; } - /** * Builds a string CSS selector from the provided element * @param {HTMLElement} ele The element from which the selector is built. * @return {string} The CSS selector for the element, or Unknown if it can't be determined. */ + function getSelector(ele) { if (ele.localName) { - return ele.localName + (ele.id ? ('#' + ele.id) : '') + (ele.className ? ('.' + ele.className) : ''); + return ele.localName + (ele.id ? '#' + ele.id : '') + (ele.className ? '.' + ele.className : ''); } else if (ele.nodeName) { - return ele.nodeName + (ele.id ? ('#' + ele.id) : '') + (ele.className ? ('.' + ele.className) : ''); + return ele.nodeName + (ele.id ? '#' + ele.id : '') + (ele.className ? '.' + ele.className : ''); } else if (ele && ele.document && ele.location && ele.alert && ele.setInterval) { return "Window"; } else { return "Unknown"; } } - /** * Builds an array of elements from the provided event target, to the root element. * @param {Object} e Event from which the path should be built. * @return {HTMLElement[]} Array of elements, starting at the event target, ending at the root element. */ + function buildPath(e) { var path = []; + if (e.path) { path = e.path; } else { var ele = e.target; - while(ele) { + + while (ele) { path.push(ele); ele = ele.parentElement; } @@ -697,28 +723,29 @@ return selectorizePath(path); } - /** * Builds a CSS selector path from the provided list of elements. * @param {HTMLElement[]} path Array of HTMLElements from which the path should be built. * @return {string[]} Array of string CSS selectors. */ + function selectorizePath(path) { var i = 0; var pathEle; var pathSelectors = []; + while (pathEle = path[i]) { pathSelectors.push(getSelector(pathEle)); ++i; } + return pathSelectors; } - function detectBrowser() { - return { - 'browser': browser ? browser.name : '', - 'version': browser ? browser.version : '' - }; + return { + 'browser': browser ? browser.name : '', + 'version': browser ? browser.version : '' + }; } /* @@ -737,14 +764,13 @@ * See the License for the specific language governing permissions and * 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); @@ -753,7 +779,6 @@ 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. @@ -761,19 +786,20 @@ * @param {Object} config Configuration object to be read from. * @return {Number} The newly created interval id. */ + function sendOnInterval(logs, config) { - return setInterval(function() { + return setInterval(function () { if (!config.on) { return; } if (logs.length >= config.logCountThreshold) { sendLogs(logs.slice(0), config, 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 @@ -783,38 +809,39 @@ * @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, 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() { + window.addEventListener('unload', function () { navigator.sendBeacon(config.url, JSON.stringify(logs)); }); } else { - window.addEventListener('beforeunload', function() { + window.addEventListener('beforeunload', function () { if (logs.length > 0) { sendLogs(logs, config, 1); } }); } } - /** * Sends the provided array of logs to the specified url, * retrying the request up to the specified number of retries. @@ -822,22 +849,21 @@ * @param {string} config configuration parameters (e.g., to extract URL from & send the POST request to). * @param {Number} retries Maximum number of attempts to send the logs. */ - // @todo expose config object to sendLogs replate url with config.url + function sendLogs(logs, config, retries) { - var req = new XMLHttpRequest(); + var req = new XMLHttpRequest(); // @todo setRequestHeader for Auth - // @todo setRequestHeader for Auth var data = JSON.stringify(logs); - req.open('POST', config.url); + if (config.authHeader) { req.setRequestHeader('Authorization', config.authHeader); } req.setRequestHeader('Content-type', 'application/json;charset=UTF-8'); - req.onreadystatechange = function() { + req.onreadystatechange = function () { if (req.readyState === 4 && req.status !== 200) { if (retries > 0) { sendLogs(logs, config, retries--); @@ -865,263 +891,304 @@ * limitations under the License. */ - // @todo var>let var events; var bufferBools; - var bufferedEvents; - //@todo: Investigate drag events and their behavior + 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']; - /** * Maps an event to an object containing useful information. * @param {Object} e Event to extract data from */ + function extractMouseEvent(e) { return { - 'clicks' : e.detail, - 'ctrl' : e.ctrlKey, - 'alt' : e.altKey, - 'shift' : e.shiftKey, - 'meta' : e.metaKey, - // 'text' : e.target.innerHTML + 'clicks': e.detail, + 'ctrl': e.ctrlKey, + 'alt': e.altKey, + 'shift': e.shiftKey, + 'meta': e.metaKey // 'text' : e.target.innerHTML + }; } - /** * Defines the way information is extracted from various events. * Also defines which events we will listen to. * @param {Object} config Configuration object to read from. */ + function defineDetails(config) { // Events list // Keys are event types // Values are functions that return details object if applicable events = { - 'click' : extractMouseEvent, - 'dblclick' : extractMouseEvent, - 'mousedown' : extractMouseEvent, - 'mouseup' : extractMouseEvent, - 'focus' : null, - 'blur' : null, - 'input' : config.logDetails ? function(e) { return { 'value' : e.target.value }; } : null, - 'change' : config.logDetails ? function(e) { return { 'value' : e.target.value }; } : null, - 'dragstart' : null, - 'dragend' : null, - '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 + 'click': extractMouseEvent, + 'dblclick': extractMouseEvent, + 'mousedown': extractMouseEvent, + 'mouseup': extractMouseEvent, + 'focus': null, + 'blur': null, + 'input': config.logDetails ? function (e) { + return { + 'value': e.target.value + }; + } : null, + 'change': config.logDetails ? function (e) { + return { + 'value': e.target.value + }; + } : null, + 'dragstart': null, + 'dragend': null, + '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 }; - bufferBools = {}; bufferedEvents = { - 'wheel' : function(e) { return { 'x' : e.deltaX, 'y' : e.deltaY, 'z' : e.deltaZ }; }, - 'scroll' : function() { return { 'x' : window.scrollX, 'y' : window.scrollY }; }, - 'resize' : function() { return { 'width' : window.outerWidth, 'height' : window.outerHeight }; } + 'wheel': function wheel(e) { + return { + 'x': e.deltaX, + 'y': e.deltaY, + 'z': e.deltaZ + }; + }, + 'scroll': function scroll() { + return { + 'x': window.scrollX, + 'y': window.scrollY + }; + }, + 'resize': function resize() { + return { + 'width': window.outerWidth, + 'height': window.outerHeight + }; + } }; - refreshEvents = { - 'submit' : null + 'submit': null }; } - /** * Defines the way information is extracted from various events. * Also defines which events we will listen to. * @param {Object} options UserALE.js Configuration object to read from. * @param {string} type of html event (e.g., 'click', 'mouseover', etc.), such as passed to addEventListener methods. */ + function defineCustomDetails(options, type) { // Events list // Keys are event types // Values are functions that return details object if applicable var eventType = { - 'click' : extractMouseEvent, - 'dblclick' : extractMouseEvent, - 'mousedown' : extractMouseEvent, - 'mouseup' : extractMouseEvent, - 'focus' : null, - 'blur' : null, - 'input' : options.logDetails ? function(e) { return { 'value' : e.target.value }; } : null, - 'change' : options.logDetails ? function(e) { return { 'value' : e.target.value }; } : null, - 'dragstart' : null, - 'dragend' : null, - 'drag' : null, - 'drop' : null, - 'keydown' : options.logDetails ? function(e) { return { 'key' : e.keyCode, 'ctrl' : e.ctrlKey, 'alt' : e.altKey, 'shift' : e.shiftKey, 'meta' : e.metaKey }; } : null, - 'mouseover' : null, - 'wheel' : function(e) { return { 'x' : e.deltaX, 'y' : e.deltaY, 'z' : e.deltaZ }; }, - 'scroll' : function() { return { 'x' : window.scrollX, 'y' : window.scrollY }; }, - 'resize' : function() { return { 'width' : window.outerWidth, 'height' : window.outerHeight }; }, - 'submit' : null + 'click': extractMouseEvent, + 'dblclick': extractMouseEvent, + 'mousedown': extractMouseEvent, + 'mouseup': extractMouseEvent, + 'focus': null, + 'blur': null, + 'input': options.logDetails ? function (e) { + return { + 'value': e.target.value + }; + } : null, + 'change': options.logDetails ? function (e) { + return { + 'value': e.target.value + }; + } : null, + 'dragstart': null, + 'dragend': null, + 'drag': null, + 'drop': null, + 'keydown': options.logDetails ? function (e) { + return { + 'key': e.keyCode, + 'ctrl': e.ctrlKey, + 'alt': e.altKey, + 'shift': e.shiftKey, + 'meta': e.metaKey + }; + } : null, + 'mouseover': null, + 'wheel': function wheel(e) { + return { + 'x': e.deltaX, + 'y': e.deltaY, + 'z': e.deltaZ + }; + }, + 'scroll': function scroll() { + return { + 'x': window.scrollX, + 'y': window.scrollY + }; + }, + 'resize': function resize() { + return { + 'width': window.outerWidth, + 'height': window.outerHeight + }; + }, + 'submit': null }; return eventType[type]; } - /** * Hooks the event handlers for each event type of interest. * @param {Object} config Configuration object to use. * @return {boolean} Whether the operation succeeded */ + function attachHandlers(config) { defineDetails(config); - - Object.keys(events).forEach(function(ev) { - document.addEventListener(ev, function(e) { + Object.keys(events).forEach(function (ev) { + document.addEventListener(ev, function (e) { packageLog(e, events[ev]); }, true); }); - - intervalEvents.forEach(function(ev) { - document.addEventListener(ev, function(e) { - packageIntervalLog(e); + intervalEvents.forEach(function (ev) { + document.addEventListener(ev, function (e) { + packageIntervalLog(e); }, true); }); - - Object.keys(bufferedEvents).forEach(function(ev) { + Object.keys(bufferedEvents).forEach(function (ev) { bufferBools[ev] = true; - - window.addEventListener(ev, function(e) { + window.addEventListener(ev, function (e) { if (bufferBools[ev]) { bufferBools[ev] = false; packageLog(e, bufferedEvents[ev]); - setTimeout(function() { bufferBools[ev] = true; }, config.resolution); + setTimeout(function () { + bufferBools[ev] = true; + }, config.resolution); } }, true); }); - - Object.keys(refreshEvents).forEach(function(ev) { - document.addEventListener(ev, function(e) { + Object.keys(refreshEvents).forEach(function (ev) { + document.addEventListener(ev, function (e) { packageLog(e, events[ev]); - sendOnRefresh(logs$1,config); + sendOnRefresh(logs$1, config); }, true); }); - - windowEvents.forEach(function(ev) { - window.addEventListener(ev, function(e) { - packageLog(e, function() { return { 'window' : true }; }); + windowEvents.forEach(function (ev) { + window.addEventListener(ev, function (e) { + packageLog(e, function () { + return { + 'window': true + }; + }); }, true); }); - return true; } - /* - * 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 = {}; var logs = []; var startLoadTimestamp = Date.now(); var endLoadTimestamp; + window.onload = function () { - endLoadTimestamp = Date.now(); + endLoadTimestamp = Date.now(); }; exports.started = false; - - // Start up Userale config.on = false; config.useraleVersion = version$1; - configure(config, getInitialSettings()); initPackager(logs, config); if (config.autostart) { - setup(config); + setup(config); } - /** * Hooks the global event listener, and starts up the * logging interval. * @param {Object} config Configuration settings for the logger */ + + function setup(config) { - if (!exports.started) { - setTimeout(function () { - var state = document.readyState; - - if (state === 'interactive' || state === 'complete') { - attachHandlers(config); - initSender(logs, config); - exports.started = config.on = true; - packageCustomLog({ - type: 'load', - logType: 'raw', - pageLoadTime: endLoadTimestamp - startLoadTimestamp - }, () => {},false); - } else { - setup(config); - } - }, 100); - } - } + if (!exports.started) { + setTimeout(function () { + var state = document.readyState; + + if (state === 'interactive' || state === 'complete') { + attachHandlers(config); + initSender(logs, config); + exports.started = config.on = true; + packageCustomLog({ + type: 'load', + logType: 'raw', + pageLoadTime: endLoadTimestamp - startLoadTimestamp + }, function () {}, false); + } else { + setup(config); + } + }, 100); + } + } // Export the Userale API - // Export the Userale API var version = version$1; - /** * Used to start the logging process if the * autostart configuration option is set to false. */ + function start() { - if (!exports.started) { - setup(config); - } + if (!exports.started) { + setup(config); + } - config.on = true; + config.on = true; } - /** * Halts the logging process. Logs will no longer be sent. */ + function stop() { - config.on = false; + config.on = false; } - /** * Updates the current configuration * object with the provided values. * @param {Object} newConfig The configuration options to use. * @return {Object} Returns the updated configuration. */ + function options(newConfig) { - if (newConfig !== undefined) { - configure(config, newConfig); - } + if (newConfig !== undefined) { + configure(config, newConfig); + } - return config; + return config; } - /** * Appends a log to the log queue. * @param {Object} customLog The log to append. * @return {boolean} Whether the operation succeeded. */ + function log(customLog) { - if (customLog !== null && typeof customLog === 'object') { - logs.push(customLog); - return true; - } else { - return false; - } + if (customLog !== null && _typeof(customLog) === 'object') { + logs.push(customLog); + return true; + } else { + return false; + } } exports.buildPath = buildPath; diff --git a/build/userale-2.1.1.min.js b/build/userale-2.1.1.min.js index 8086315..93d5364 100644 --- a/build/userale-2.1.1.min.js +++ b/build/userale-2.1.1.min.js @@ -16,4 +16,4 @@ * @preserved */ -!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).userale={})}(this,(function(e){"use strict";var n="2.1.1",t=null;function o(e,n){Object.keys(n).forEach((function(t){if("userFromParams"===t){var o=(r=n[t],i=new RegExp("[?&]"+r+"(=([^&#]*)|&|#|$)"),(a=window.location.href.match(i))&&a[2]?decodeURIComponent(a[2].replace(/\+/g," ")):null);o&&(e.us [...] +!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).userale={})}(this,(function(e){"use strict";function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var t="2.1.1",o=null;fun [...] diff --git a/package-lock.json b/package-lock.json index dabeeb9..3adb892 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@babel/plugin-transform-runtime": "^7.13.9", "@babel/preset-env": "^7.13.9", "@babel/register": "^7.13.8", + "@rollup/plugin-babel": "^5.3.0", "@rollup/plugin-commonjs": "^17.1.0", "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^11.2.0", @@ -1508,6 +1509,29 @@ "node": ">= 8" } }, + "node_modules/@rollup/plugin-babel": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.0.tgz", + "integrity": "sha512-9uIC8HZOnVLrLHxayq/PTzw+uS25E14KPUBh5ktF+18Mjo5yK0ToMMx6epY0uEgkjwJw0aBW4x2horYXh8juWw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + } + } + }, "node_modules/@rollup/plugin-commonjs": { "version": "17.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-17.1.0.tgz", @@ -10109,6 +10133,16 @@ "fastq": "^1.6.0" } }, + "@rollup/plugin-babel": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.0.tgz", + "integrity": "sha512-9uIC8HZOnVLrLHxayq/PTzw+uS25E14KPUBh5ktF+18Mjo5yK0ToMMx6epY0uEgkjwJw0aBW4x2horYXh8juWw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + } + }, "@rollup/plugin-commonjs": { "version": "17.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-17.1.0.tgz", diff --git a/package.json b/package.json index 51072d2..e4c7c4e 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "@babel/plugin-transform-runtime": "^7.13.9", "@babel/preset-env": "^7.13.9", "@babel/register": "^7.13.8", + "@rollup/plugin-babel": "^5.3.0", "@rollup/plugin-commonjs": "^17.1.0", "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^11.2.0", diff --git a/rollup.config.js b/rollup.config.js index b796f72..8556fc6 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -8,6 +8,7 @@ import {version} from './package.json'; const srcWebExtensionDir = 'src/UserALEWebExtension/' const buildWebExtensionDir = 'build/UserALEWebExtension/' +const {babel: rollupBabel} = require('@rollup/plugin-babel'); const banner = 'Licensed to the Apache Software Foundation (ASF) under one or more\n' + 'contributor license agreements. See the NOTICE file distributed with\n' + @@ -40,7 +41,12 @@ export default [ plugins: [terser()] } ], - plugins: [license({banner}), json(), nodeResolve(), commonjs()] + plugins: [license({banner}), json(), nodeResolve(), commonjs({include: /node_modules/}), + rollupBabel({ + babelHelpers: "runtime", + exclude: /node_modules/, + plugins: ["@babel/plugin-transform-block-scoping"] + })] }, ...['content.js', 'background.js', 'options.js'].map(fileName => ({ input: srcWebExtensionDir + fileName, @@ -56,6 +62,12 @@ export default [ {src: srcWebExtensionDir + 'optionsPage.html', dest: buildWebExtensionDir} ], copyOnce: true - }), json(), nodeResolve(), commonjs()] + }), json(), nodeResolve(), commonjs({include: /node_modules/}), + rollupBabel({ + babelHelpers: "runtime", + exclude: /node_modules/, + plugins: ["@babel/plugin-transform-block-scoping"] + }) + ] })) ]; \ No newline at end of file
