This is an automated email from the ASF dual-hosted git repository. unclegedd pushed a commit to branch test in repository https://gitbox.apache.org/repos/asf/flagon-useralejs.git
commit 1cbfd0f882b07586a7ce52fb9114ec4a61eff8c1 Author: Jason Young <[email protected]> AuthorDate: Thu Mar 23 15:52:33 2023 -0700 Changed map/filter to addCallbacks Co-authored-by: Nicholas Alexander Sagun <[email protected]> --- build/UserALEWebExtension/background.js | 206 ++++++------- build/UserALEWebExtension/content.js | 523 +++++++++++++++++--------------- build/UserALEWebExtension/options.js | 30 +- build/userale-2.3.0.js | 115 ++++--- build/userale-2.3.0.min.js | 2 +- example/index.js | 30 +- src/UserALEWebExtension/content.js | 7 +- src/main.js | 3 +- src/packageLogs.js | 81 +++-- test/packageLogs_spec.js | 113 +++---- 10 files changed, 578 insertions(+), 532 deletions(-) diff --git a/build/UserALEWebExtension/background.js b/build/UserALEWebExtension/background.js index ad860f7..abd9d13 100644 --- a/build/UserALEWebExtension/background.js +++ b/build/UserALEWebExtension/background.js @@ -26,57 +26,57 @@ var toolVersion = '2.3.0'; /* eslint-enable */ -/* -* 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. +/* +* 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 prefix = 'USERALE_'; var CONFIG_CHANGE = prefix + 'CONFIG_CHANGE'; var ADD_LOG = prefix + 'ADD_LOG'; -/* - * 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. +/* + * 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. */ -/** - * 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. +/** + * 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) { var tsScaler; if (e.timeStamp && e.timeStamp > 0) { var delta = Date.now() - e.timeStamp; - /** - * Returns a timestamp depending on various browser quirks. - * @param {?Number} ts A timestamp to use for normalization. - * @return {Number} A normalized timestamp. + /** + * Returns a timestamp depending on various browser quirks. + * @param {?Number} ts A timestamp to use for normalization. + * @return {Number} A normalized timestamp. */ if (delta < 0) { @@ -307,29 +307,13 @@ function createVersionParts(count) { return output; } -/* - * 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. - */ 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. +/** + * 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 { @@ -338,29 +322,29 @@ function extractTimeFields(timeStamp) { }; } -/* - * 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. +/* + * 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 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. +/** + * 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) { @@ -370,12 +354,12 @@ function initSender(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. +/** + * 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 () { @@ -389,10 +373,10 @@ function sendOnInterval(logs, config) { }, 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. +/** + * 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) { window.addEventListener('pagehide', function () { @@ -403,12 +387,12 @@ function sendOnClose(logs, config) { }); } -/** - * 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} 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. +/** + * 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} 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 @@ -432,21 +416,21 @@ function sendLogs(logs, config, 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. +/* + * 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. */ // inherent dependency on globals.js, loaded by the webext @@ -602,6 +586,6 @@ browser.tabs.onZoomChange.addListener(function (e) { }); }); -/* - eslint-enable +/* + eslint-enable */ diff --git a/build/UserALEWebExtension/content.js b/build/UserALEWebExtension/content.js index 5720e9a..d0689d1 100644 --- a/build/UserALEWebExtension/content.js +++ b/build/UserALEWebExtension/content.js @@ -26,21 +26,21 @@ var toolVersion = '2.3.0'; /* eslint-enable */ -/* -* 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. +/* +* 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 prefix = 'USERALE_'; @@ -49,29 +49,29 @@ var ADD_LOG = prefix + 'ADD_LOG'; var version = "2.3.0"; -/* - * 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. +/* + * 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 sessionId = null; -/** - * Extracts the initial configuration settings from the - * currently executing script tag. - * @return {Object} The extracted configuration object +/** + * Extracts the initial configuration settings from the + * currently executing script tag. + * @return {Object} The extracted configuration object */ function getInitialSettings() { var settings = {}; @@ -102,11 +102,11 @@ function getInitialSettings() { 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 - * +/** + * 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) { if (window.sessionStorage.getItem(sessionKey) === null) { @@ -116,19 +116,19 @@ 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. +/** + * 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) { var tsScaler; if (e.timeStamp && e.timeStamp > 0) { var delta = Date.now() - e.timeStamp; - /** - * Returns a timestamp depending on various browser quirks. - * @param {?Number} ts A timestamp to use for normalization. - * @return {Number} A normalized timestamp. + /** + * Returns a timestamp depending on various browser quirks. + * @param {?Number} ts A timestamp to use for normalization. + * @return {Number} A normalized timestamp. */ if (delta < 0) { @@ -153,28 +153,28 @@ function timeStampScale(e) { return tsScaler; } -/* - * 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. +/* + * 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. */ -/** - * Shallow merges the first argument with the second. - * Retrieves/updates the userid if userFromParams is provided. - * @param {Object} config Current configuration object to be merged into. - * @param {Object} newConfig Configuration object to merge into the current config. +/** + * Shallow merges the first argument with the second. + * Retrieves/updates the userid if userFromParams is provided. + * @param {Object} config Current configuration object to be merged into. + * @param {Object} newConfig Configuration object to merge into the current config. */ function configure(config, newConfig) { var configAutostart = config['autostart']; @@ -193,10 +193,10 @@ function configure(config, newConfig) { } } -/** - * 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. +/** + * 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; @@ -415,22 +415,9 @@ function createVersionParts(count) { return output; } -/* - * 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. - */ +function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new T [...] +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } var browser$1 = detect(); var logs$1; var config$1; @@ -442,27 +429,41 @@ var intervalPath; var intervalTimer; var intervalCounter; var intervalLog; -var filterHandler = null; -var mapHandler = null; +var cbHandlers = {}; -/** - * Assigns a handler to filter logs out of the queue. - * @param {Function} callback The handler to invoke when logging. +/** + * Adds named callbacks to be executed when logging. + * @param {Object } newCallbacks An object containing named callback functions. */ -function setLogFilter(callback) { - filterHandler = callback; +function addCallbacks() { + for (var _len = arguments.length, newCallbacks = new Array(_len), _key = 0; _key < _len; _key++) { + newCallbacks[_key] = arguments[_key]; + } + newCallbacks.forEach(function (source) { + var descriptors = Object.keys(source).reduce(function (descriptors, key) { + descriptors[key] = Object.getOwnPropertyDescriptor(source, key); + return descriptors; + }, {}); + Object.getOwnPropertySymbols(source).forEach(function (sym) { + var descriptor = Object.getOwnPropertyDescriptor(source, sym); + if (descriptor.enumerable) { + descriptors[sym] = descriptor; + } + }); + Object.defineProperties(cbHandlers, descriptors); + }); + return cbHandlers; } -/** - * 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. +/** + * 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; - filterHandler = null; - mapHandler = null; + cbHandlers = []; intervalID = null; intervalType = null; intervalPath = null; @@ -471,11 +472,11 @@ function initPackager(newLogs, newConfig) { 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. +/** + * 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) { @@ -507,22 +508,25 @@ function packageLog(e, detailFcn) { 'useraleVersion': config$1.useraleVersion, 'sessionID': config$1.sessionID }; - if (typeof filterHandler === 'function' && !filterHandler(log)) { - return false; - } - if (typeof mapHandler === 'function') { - log = mapHandler(log, e); + for (var _i = 0, _Object$values = Object.values(cbHandlers); _i < _Object$values.length; _i++) { + var func = _Object$values[_i]; + if (typeof func === 'function') { + log = func(log, e); + if (!log) { + return false; + } + } } 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. - * @param {Function} detailFcn The function to extract additional log parameters from the event. - * @param {boolean} userAction Indicates user behavior (true) or system behavior (false) - * @return {boolean} Whether the event was logged. +/** + * Packages the provided customLog to include standard meta data and appends it to the log queue. + * @param {Object} customLog The behavior to be logged. + * @param {Function} detailFcn The function to extract additional log parameters from the event. + * @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) { @@ -549,21 +553,32 @@ function packageCustomLog(customLog, detailFcn, userAction) { 'sessionID': config$1.sessionID }; var log = Object.assign(metaData, customLog); - if (typeof filterHandler === 'function' && !filterHandler(log)) { - return false; - } - if (typeof mapHandler === 'function') { - log = mapHandler(log); + var _iterator = _createForOfIteratorHelper(cbHandlers.values()), + _step; + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var func = _step.value; + if (typeof func === 'function') { + log = func(log, null); + if (!log) { + return false; + } + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); } 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. +/** + * 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 { @@ -572,10 +587,10 @@ function extractTimeFields(timeStamp) { }; } -/** - * Track intervals and gather details about it. - * @param {Object} e - * @return boolean +/** + * Track intervals and gather details about it. + * @param {Object} e + * @return boolean */ function packageIntervalLog(e) { var target = getSelector(e.target); @@ -618,11 +633,22 @@ function packageIntervalLog(e) { 'useraleVersion': config$1.useraleVersion, 'sessionID': config$1.sessionID }; - if (typeof filterHandler === 'function' && !filterHandler(intervalLog)) { - return false; - } - if (typeof mapHandler === 'function') { - intervalLog = mapHandler(intervalLog, e); + var _iterator2 = _createForOfIteratorHelper(cbHandlers.values()), + _step2; + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var func = _step2.value; + if (typeof func === 'function') { + intervalLog = func(intervalLog, null); + if (!intervalLog) { + return false; + } + } + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); } logs$1.push(intervalLog); @@ -641,11 +667,11 @@ function packageIntervalLog(e) { 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. +/** + * 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) { @@ -666,9 +692,9 @@ function getLocation(e) { } } -/** - * Extracts innerWidth and innerHeight to provide estimates of screen resolution - * @return {Object} An object containing the innerWidth and InnerHeight +/** + * Extracts innerWidth and innerHeight to provide estimates of screen resolution + * @return {Object} An object containing the innerWidth and InnerHeight */ function getSreenRes() { return { @@ -677,10 +703,10 @@ function getSreenRes() { }; } -/** - * 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. +/** + * 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) { @@ -694,10 +720,10 @@ function getSelector(ele) { } } -/** - * 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. +/** + * 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) { if (e instanceof window.Event) { @@ -706,10 +732,10 @@ function buildPath(e) { } } -/** - * 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. +/** + * 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; @@ -728,21 +754,21 @@ function detectBrowser() { }; } -/* - * 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. +/* + * 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; @@ -752,9 +778,9 @@ var intervalEvents = ['click', 'focus', 'blur', 'input', 'change', 'mouseover', var refreshEvents; var windowEvents = ['load', 'blur', 'focus']; -/** - * Maps an event to an object containing useful information. - * @param {Object} e Event to extract data from +/** + * Maps an event to an object containing useful information. + * @param {Object} e Event to extract data from */ function extractMouseEvent(e) { return { @@ -767,10 +793,10 @@ function extractMouseEvent(e) { }; } -/** - * 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. +/** + * 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 @@ -835,10 +861,10 @@ function defineDetails(config) { }; } -/** - * Hooks the event handlers for each event type of interest. - * @param {Object} config Configuration object to use. - * @return {boolean} Whether the operation succeeded +/** + * 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); @@ -881,29 +907,29 @@ function attachHandlers(config) { 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. +/* + * 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 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. +/** + * 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) { @@ -913,12 +939,12 @@ function initSender(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. +/** + * 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 () { @@ -932,10 +958,10 @@ function sendOnInterval(logs, config) { }, 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. +/** + * 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) { window.addEventListener('pagehide', function () { @@ -946,12 +972,12 @@ function sendOnClose(logs, config) { }); } -/** - * 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} 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. +/** + * 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} 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 @@ -993,10 +1019,10 @@ if (config.autostart) { setup(config); } -/** - * Hooks the global event listener, and starts up the - * logging interval. - * @param {Object} config Configuration settings for the logger +/** + * Hooks the global event listener, and starts up the + * logging interval. + * @param {Object} config Configuration settings for the logger */ function setup(config) { if (!started) { @@ -1020,11 +1046,11 @@ function setup(config) { } } -/** - * Updates the current configuration - * object with the provided values. - * @param {Object} newConfig The configuration options to use. - * @return {Object} Returns the updated configuration. +/** + * 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) { @@ -1033,21 +1059,21 @@ function options(newConfig) { return config; } -/* - * 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. +/* + * 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. */ // browser is defined in firefox, but not in chrome. In chrome, they use @@ -1084,11 +1110,14 @@ function queueLog(log) { function injectScript(config) { 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 - })); - return false; + addCallbacks({ + "function": function _function(log) { + queueLog(Object.assign({}, log, { + pageUrl: document.location.href + })); + console.log(log); + return false; + } }); } browser.runtime.onMessage.addListener(function (message) { @@ -1102,6 +1131,6 @@ browser.runtime.onMessage.addListener(function (message) { } }); -/* - eslint-enable +/* + eslint-enable */ diff --git a/build/UserALEWebExtension/options.js b/build/UserALEWebExtension/options.js index d935e14..eed800f 100644 --- a/build/UserALEWebExtension/options.js +++ b/build/UserALEWebExtension/options.js @@ -26,21 +26,21 @@ var toolVersion = '2.3.0'; /* eslint-enable */ -/* -* 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. +/* +* 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 prefix = 'USERALE_'; diff --git a/build/userale-2.3.0.js b/build/userale-2.3.0.js index 795ff29..fd8a994 100644 --- a/build/userale-2.3.0.js +++ b/build/userale-2.3.0.js @@ -400,22 +400,9 @@ return output; } - /* - * 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. - */ + function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new [...] + function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } + function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } var browser = detect(); var logs$1; var config$1; @@ -427,23 +414,30 @@ 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; - } + var cbHandlers = {}; /** - * Assigns a handler to transform logs from their default structure. - * @param {Function} callback The handler to invoke when logging. + * Adds named callbacks to be executed when logging. + * @param {Object } newCallbacks An object containing named callback functions. */ - function setLogMapper(callback) { - mapHandler = callback; + function addCallbacks() { + for (var _len = arguments.length, newCallbacks = new Array(_len), _key = 0; _key < _len; _key++) { + newCallbacks[_key] = arguments[_key]; + } + newCallbacks.forEach(function (source) { + var descriptors = Object.keys(source).reduce(function (descriptors, key) { + descriptors[key] = Object.getOwnPropertyDescriptor(source, key); + return descriptors; + }, {}); + Object.getOwnPropertySymbols(source).forEach(function (sym) { + var descriptor = Object.getOwnPropertyDescriptor(source, sym); + if (descriptor.enumerable) { + descriptors[sym] = descriptor; + } + }); + Object.defineProperties(cbHandlers, descriptors); + }); + return cbHandlers; } /** @@ -454,8 +448,7 @@ function initPackager(newLogs, newConfig) { logs$1 = newLogs; config$1 = newConfig; - filterHandler = null; - mapHandler = null; + cbHandlers = []; intervalID = null; intervalType = null; intervalPath = null; @@ -500,11 +493,14 @@ 'useraleVersion': config$1.useraleVersion, 'sessionID': config$1.sessionID }; - if (typeof filterHandler === 'function' && !filterHandler(log)) { - return false; - } - if (typeof mapHandler === 'function') { - log = mapHandler(log, e); + for (var _i = 0, _Object$values = Object.values(cbHandlers); _i < _Object$values.length; _i++) { + var func = _Object$values[_i]; + if (typeof func === 'function') { + log = func(log, e); + if (!log) { + return false; + } + } } logs$1.push(log); return true; @@ -542,11 +538,22 @@ 'sessionID': config$1.sessionID }; var log = Object.assign(metaData, customLog); - if (typeof filterHandler === 'function' && !filterHandler(log)) { - return false; - } - if (typeof mapHandler === 'function') { - log = mapHandler(log); + var _iterator = _createForOfIteratorHelper(cbHandlers.values()), + _step; + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var func = _step.value; + if (typeof func === 'function') { + log = func(log, null); + if (!log) { + return false; + } + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); } logs$1.push(log); return true; @@ -611,11 +618,22 @@ 'useraleVersion': config$1.useraleVersion, 'sessionID': config$1.sessionID }; - if (typeof filterHandler === 'function' && !filterHandler(intervalLog)) { - return false; - } - if (typeof mapHandler === 'function') { - intervalLog = mapHandler(intervalLog, e); + var _iterator2 = _createForOfIteratorHelper(cbHandlers.values()), + _step2; + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var func = _step2.value; + if (typeof func === 'function') { + intervalLog = func(intervalLog, null); + if (!intervalLog) { + return false; + } + } + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); } logs$1.push(intervalLog); @@ -1127,12 +1145,11 @@ } } + exports.addCallbacks = addCallbacks; exports.buildPath = buildPath; exports.details = defineCustomDetails; - exports.filter = setLogFilter; exports.getSelector = getSelector; exports.log = log; - exports.map = setLogMapper; exports.options = options; exports.packageCustomLog = packageCustomLog; exports.packageLog = packageLog; diff --git a/build/userale-2.3.0.min.js b/build/userale-2.3.0.min.js index 0f1d734..82396de 100644 --- a/build/userale-2.3.0.min.js +++ b/build/userale-2.3.0.min.js @@ -16,4 +16,4 @@ * @preserved */ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).userale={})}(this,(function(e){"use strict";function t(e){return t="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},t(e)}var n="2.3.0",o=null;fu [...] +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).userale={})}(this,(function(e){"use strict";function t(e){return t="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},t(e)}var n="2.3.0",o=null;fu [...] diff --git a/example/index.js b/example/index.js index 21d5113..11af64a 100644 --- a/example/index.js +++ b/example/index.js @@ -34,10 +34,12 @@ window.userale.options({ * Note that for surgical filters, you may need to clear or reset back to a global filter callback * the same is true for the 'map' API. See examples below: */ -window.userale.filter(function (log) { - var type_array = ['mouseup', 'mouseover', 'mousedown', 'keydown', 'dblclick', 'blur', 'focus', 'input', 'wheel']; - var logType_array = ['interval']; - return !type_array.includes(log.type) && !logType_array.includes(log.logType); +window.userale.addCallbacks({ + filter(log) { + var type_array = ['mouseup', 'mouseover', 'mousedown', 'keydown', 'dblclick', 'blur', 'focus', 'input', 'wheel']; + var logType_array = ['interval']; + return !type_array.includes(log.type) && !logType_array.includes(log.logType); + } }); /**Log Mapping API @@ -45,17 +47,13 @@ window.userale.filter(function (log) { * the 'map' API allows you to add or modify new fields to your logs * this example works with the "Click Me!" button at the top of index.html */ -document.addEventListener('click', function(e){ - if (e.target.innerHTML === 'Click Me!') { - window.userale.map(function (log) { +window.userale.addCallbacks({ + map(log, e) { + if(e && e.type === 'click' && e.target.innerHTML === 'Click Me!') { return Object.assign({}, log, { logType: 'custom', customLabel: 'map & packageLog Example' }); - }); - window.userale.packageLog(e, window.userale.details(window.userale.options(),e.type)); - /**you'll want to reset the map callback function, or set a conditional (e.g., return log), else - * the callback may be applied to other events of the same class (e.g., click) */ - window.userale.map(); - } else { - return false + } + + return log; } }); @@ -108,14 +106,14 @@ document.addEventListener('change', function(e) { document.addEventListener('change', function(e){ if (e.target.value === 'packageLog') { /**You can then use the 'Mapping' API function to modify custom logs created with the packageLog function*/ - window.userale.map(function (log) { + window.userale.addCallbacks({changeMap(log) { var targetsForLabels = ['change']; if (targetsForLabels.includes(log.type)) { return Object.assign({}, log, { logType: 'custom', customLabel: 'packageLog Example' }); } else { return log; } - }); + }}); /**You can also use the details function to package additional log meta data, or add custom details*/ window.userale.packageLog(e, window.userale.details(window.userale.options(),e.type)); } else { diff --git a/src/UserALEWebExtension/content.js b/src/UserALEWebExtension/content.js index be80806..7ede7a6 100644 --- a/src/UserALEWebExtension/content.js +++ b/src/UserALEWebExtension/content.js @@ -19,7 +19,7 @@ import * as globals from './globals'; import * as MessageTypes from './messageTypes.js'; -import { filter, options, start } from '../main.js'; +import { addCallbacks, options, start } from '../main.js'; // 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 @@ -55,12 +55,13 @@ function queueLog(log) { function injectScript(config) { options(config); // start(); not necessary given that autostart in place, and option is masked from WebExt users - filter(function (log) { + addCallbacks({function (log) { queueLog(Object.assign({}, log, { pageUrl: document.location.href, })); + console.log(log); return false; - }); + }}); } browser.runtime.onMessage.addListener(function (message) { diff --git a/src/main.js b/src/main.js index aa5e52a..f9b9fee 100644 --- a/src/main.js +++ b/src/main.js @@ -33,8 +33,7 @@ window.onload = function () { export let started = false; export {defineCustomDetails as details} from './attachHandlers.js'; export { - setLogMapper as map, - setLogFilter as filter, + addCallbacks as addCallbacks, packageLog as packageLog, packageCustomLog as packageCustomLog, getSelector as getSelector, diff --git a/src/packageLogs.js b/src/packageLogs.js index d2e4cee..7c4629a 100644 --- a/src/packageLogs.js +++ b/src/packageLogs.js @@ -29,26 +29,42 @@ let intervalTimer; let intervalCounter; let intervalLog; -export let filterHandler = null; -export let mapHandler = null; +export let cbHandlers = {}; /** - * Assigns a handler to filter logs out of the queue. - * @param {Function} callback The handler to invoke when logging. + * Adds named callbacks to be executed when logging. + * @param {Object } newCallbacks An object containing named callback functions. */ -export function setLogFilter(callback) { - filterHandler = callback; +export function addCallbacks(...newCallbacks) { + newCallbacks.forEach((source) => { + const descriptors = Object.keys(source).reduce((descriptors, key) => { + descriptors[key] = Object.getOwnPropertyDescriptor(source, key); + return descriptors; + }, {}); + + Object.getOwnPropertySymbols(source).forEach((sym) => { + const descriptor = Object.getOwnPropertyDescriptor(source, sym); + if (descriptor.enumerable) { + descriptors[sym] = descriptor; + } + }); + Object.defineProperties(cbHandlers, descriptors); + }); + return cbHandlers; } /** - * Assigns a handler to transform logs from their default structure. - * @param {Function} callback The handler to invoke when logging. + * Removes callbacks by name. + * @param {String[]} targetKeys A list of names of functions to remove. */ -export function setLogMapper(callback) { - mapHandler = callback; +export function removeCallbacks(targetKeys) { + targetKeys.forEach(key => { + if(Object.hasOwn(cbHandlers, key)) { + delete cbHandlers[key]; + } + }); } - /** * Assigns the config and log container to be used by the logging functions. * @param {Array} newLogs Log container. @@ -57,8 +73,7 @@ export function setLogMapper(callback) { export function initPackager(newLogs, newConfig) { logs = newLogs; config = newConfig; - filterHandler = null; - mapHandler = null; + cbHandlers = []; intervalID = null; intervalType = null; intervalPath = null; @@ -109,16 +124,16 @@ export function packageLog(e, detailFcn) { 'sessionID': config.sessionID, }; - if ((typeof filterHandler === 'function') && !filterHandler(log)) { - return false; - } - - if (typeof mapHandler === 'function') { - log = mapHandler(log, e); + for (const func of Object.values(cbHandlers)) { + if (typeof func === 'function') { + log = func(log, e); + if(!log) { + return false; + } + } } logs.push(log); - return true; } @@ -158,12 +173,13 @@ export function packageCustomLog(customLog, detailFcn, userAction) { let log = Object.assign(metaData, customLog); - if ((typeof filterHandler === 'function') && !filterHandler(log)) { - return false; - } - - if (typeof mapHandler === 'function') { - log = mapHandler(log); + for (const func of cbHandlers.values()) { + if (typeof func === 'function') { + log = func(log, null); + if(!log) { + return false; + } + } } logs.push(log); @@ -231,12 +247,13 @@ export function packageIntervalLog(e) { 'sessionID': config.sessionID }; - if (typeof filterHandler === 'function' && !filterHandler(intervalLog)) { - return false; - } - - if (typeof mapHandler === 'function') { - intervalLog = mapHandler(intervalLog, e); + for (const func of cbHandlers.values()) { + if (typeof func === 'function') { + intervalLog = func(intervalLog, null); + if(!intervalLog) { + return false; + } + } } logs.push(intervalLog); diff --git a/test/packageLogs_spec.js b/test/packageLogs_spec.js index 51aae05..def256b 100644 --- a/test/packageLogs_spec.js +++ b/test/packageLogs_spec.js @@ -18,44 +18,59 @@ import {expect} from 'chai'; import {JSDOM} from 'jsdom'; import 'global-jsdom/register' import { + addCallbacks, buildPath, + cbHandlers, extractTimeFields, - filterHandler, getLocation, getSelector, initPackager, logs, - mapHandler, packageLog, + removeCallbacks, selectorizePath, - setLogFilter, - setLogMapper, } from '../src/packageLogs'; describe('packageLogs', () => { - describe('setLogFilter', () => { - it('assigns the handler to the provided value', () => { - const func = x => true; - setLogFilter(func); - expect(filterHandler).to.equal(func); + describe('addCallbacks', () => { + it('adds a single callback', () => { + initPackager([], {on: false}); + const fn = { + func1() {return true} + }; + addCallbacks(fn); + expect(Object.keys(cbHandlers)).to.deep.equal(Object.keys(fn)); }); - it('allows the handler to be nulled', () => { - setLogFilter(x => true); - setLogFilter(null); - expect(filterHandler).to.equal(null); + it('adds a list of callbacks', () => { + initPackager([], {on: false}); + + const fns = { + func1() {return true}, + func2() {return false} + }; + + addCallbacks(fns); + expect(Object.keys(cbHandlers)).to.deep.equal(Object.keys(fns)); }); }); - - describe('setLogMapper', () => { - it('assigns the handler to the provided value', () => { - const func = x => true; - setLogMapper(func); - expect(mapHandler).to.equal(func); + + describe('removeCallbacks', () => { + it('removes a single callback', () => { + initPackager([], {on: false}); + const fn = {func() {return true}}; + addCallbacks(fn); + removeCallbacks(Object.keys(fn)); + expect(cbHandlers).to.be.empty; }); - it('allows the handler to be nulled', () => { - setLogMapper(x => true); - setLogMapper(null); - expect(mapHandler).to.equal(null); + it('removes a list of callbacks', () => { + initPackager([], {on: false}); + const fns = { + func1() {return true}, + func2() {return false} + }; + addCallbacks(fns); + removeCallbacks(Object.keys(fns)); + expect(cbHandlers).to.be.empty; }); }); @@ -90,9 +105,11 @@ describe('packageLogs', () => { it('filters logs when a handler is assigned and returns false', () => { let filterCalled = false; - const filter = (log) => { - filterCalled = true; - return false; + const filter = { + filterAll() { + filterCalled = true; + return false; + } }; const evt = { @@ -105,19 +122,22 @@ describe('packageLogs', () => { expect(logs.length).to.equal(1); - setLogFilter(filter); + addCallbacks(filter); packageLog(evt); + expect(filterCalled).to.equal(true); expect(logs.length).to.equal(1); }); - it('assigns logs to the mapper\'s return value if a handler is assigned', () => { + it('assigns logs to the callback\'s return value if a handler is assigned', () => { let mapperCalled = false; const mappedLog = {type: 'foo'}; - const mapper = (log) => { - mapperCalled = true; - return mappedLog; + const mapper = { + mapper() { + mapperCalled = true; + return mappedLog; + } }; const evt = { @@ -127,14 +147,14 @@ describe('packageLogs', () => { initPackager([], {on: true}); - setLogMapper(mapper); + addCallbacks(mapper); packageLog(evt); expect(mapperCalled).to.equal(true); expect(logs.indexOf(mappedLog)).to.equal(0); }); - it('does not call the map handler if the log is filtered out', () => { + it('does not call a subsequent handler if the log is filtered out', () => { let mapperCalled = false; const filter = () => false; const mapper = (log) => { @@ -148,8 +168,8 @@ describe('packageLogs', () => { }; initPackager([], {on: true}); - setLogFilter(filter); - setLogMapper(mapper); + addCallbacks(filter); + addCallbacks(mapper); packageLog(evt); @@ -157,35 +177,16 @@ describe('packageLogs', () => { }); it('does not attempt to call a non-function filter/mapper', () => { - let filterCalled = false; - let mapperCalled = false; - const filter = () => { - filterCalled = true; - return true; - }; - const mapper = (log) => { - mapperCalled = true; - return log; - }; - const evt = { target: {}, type: 'test', }; initPackager([], {on: true}); - setLogFilter(filter); - setLogMapper(mapper); - packageLog(evt); - - expect(filterCalled).to.equal(true); - expect(mapperCalled).to.equal(true); - - setLogFilter('foo'); - setLogMapper('bar'); - + addCallbacks('foo'); packageLog(evt); + expect(logs.length).to.equal(2); }); });
