UNPKG

ngx-hotjar

Version:

A simple ng wrapper to load hotjar dependency by angular way

695 lines (678 loc) 28.4 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/router'), require('@angular/common')) : typeof define === 'function' && define.amd ? define('ngx-hotjar', ['exports', '@angular/core', '@angular/router', '@angular/common'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['ngx-hotjar'] = {}, global.ng.core, global.ng.router, global.ng.common)); }(this, (function (exports, i0, router, common) { 'use strict'; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function () { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function __param(paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); }; } function __metadata(metadataKey, metadataValue) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); } function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function () { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } var __createBinding = Object.create ? (function (o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function () { return m[k]; } }); }) : (function (o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; }); function __exportStar(m, o) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); } function __values(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } /** @deprecated */ function __spread() { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; } /** @deprecated */ function __spreadArrays() { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; } function __spreadArray(to, from) { for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i]; return to; } function __await(v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } function __asyncGenerator(thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } } function __asyncDelegator(o) { var i, p; return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } } function __asyncValues(o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function (v) { resolve({ value: v, done: d }); }, reject); } } function __makeTemplateObject(cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; } ; var __setModuleDefault = Object.create ? (function (o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function (o, v) { o["default"] = v; }; function __importStar(mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; } function __importDefault(mod) { return (mod && mod.__esModule) ? mod : { default: mod }; } function __classPrivateFieldGet(receiver, privateMap) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return privateMap.get(receiver); } function __classPrivateFieldSet(receiver, privateMap, value) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to set private field on non-instance"); } privateMap.set(receiver, value); return value; } /** * Check if this environment can access Window object and return window or null if false. */ function getWindow(platformId) { return (common.isPlatformBrowser(platformId)) ? window : null; } /** * Provide DOM Window reference or null if the environment is not a Browser. */ var WINDOW = new i0.InjectionToken('hj-window', { factory: function () { return getWindow(i0.inject(i0.PLATFORM_ID)); }, }); /** * Check if there is some global function called gtag on Window object, or create an empty function to doesn't brake codes... */ function getHjFn(window) { // // h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)}; return (window) ? window.hj : null; } /** * Provides an injection token to access Google Analytics Gtag Function */ var NGX_HJ_FN = new i0.InjectionToken('ngx-hj-fn', { providedIn: 'root', factory: function () { return getHjFn(i0.inject(WINDOW)); } }); /** * Provides a token to override default settings. You can use this token to enhance our library * and configure multiple sites/app on the same environment. */ var NGX_HOTJAR_SETTINGS_TOKEN = new i0.InjectionToken('ngx-hotjar-settings', { factory: function () { return ({ trackingCode: '', version: 6, ennableTracing: false }); } }); var NgxHotjarService = /** @class */ (function () { /** @ignore */ function NgxHotjarService( /** @ignore */ _hj, /** @ignore */ settings) { this._hj = _hj; this.settings = settings; } Object.defineProperty(NgxHotjarService.prototype, "lib", { /** * Provide direct access to the `hj.*` static functions. If the desired function is not available on type definition, you can cast to `any` as following. * ```typescript (hjService.lib as any).myBrandNewStaticFn() ``` */ get: function () { return this._hj; }, enumerable: false, configurable: true }); /** Expose Hotjar Function calls */ NgxHotjarService.prototype.hj = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } try { this._hj.apply(this, __spread(args)); } catch (err) { if (i0.isDevMode() || this.settings.ennableTracing) { console.error(err.message); } } }; /** * Fires an PageView event on Hotjar. Use this method to trigger an virtual url path. The same as * ```typescript hj('vpv', path) ``` */ NgxHotjarService.prototype.virtualPageView = function (path) { this.hj('vpv', path); }; /** * Fires an event on Hotjar. Use this method to trigger events on forms and start video recordings. Same as * ```typescript hj('trigger', path) ``` */ NgxHotjarService.prototype.trigger = function (path) { this.hj('trigger', path); }; NgxHotjarService.prototype.tagRecording = function (tagOrCollection) { var tags = []; for (var _i = 1; _i < arguments.length; _i++) { tags[_i - 1] = arguments[_i]; } // Retrocompatibility if (!Array.isArray(tagOrCollection)) { tagOrCollection = [tagOrCollection]; } this.hj('tagRecording', tagOrCollection.concat.apply(tagOrCollection, __spread(tags))); }; /** * This option is available in case you need to set up page change tracking manually * within your app's router. * ```typescript hj('stateChange', path) ``` */ NgxHotjarService.prototype.stateChange = function (path) { this.hj('stateChange', path); }; /** * Signals form submission success * ```typescript hj('formSubmitSuccessful'); ``` */ NgxHotjarService.prototype.formSubmitSuccessful = function () { this.hj('formSubmitSuccessful'); }; /** * Signals form submission failure * ```typescript hj('formSubmitFailed'); ``` */ NgxHotjarService.prototype.formSubmitFailed = function () { this.hj('formSubmitFailed'); }; return NgxHotjarService; }()); NgxHotjarService.ɵprov = i0.ɵɵdefineInjectable({ factory: function NgxHotjarService_Factory() { return new NgxHotjarService(i0.ɵɵinject(NGX_HJ_FN), i0.ɵɵinject(NGX_HOTJAR_SETTINGS_TOKEN)); }, token: NgxHotjarService, providedIn: "root" }); NgxHotjarService.decorators = [ { type: i0.Injectable, args: [{ providedIn: 'root' },] } ]; NgxHotjarService.ctorParameters = function () { return [ { type: undefined, decorators: [{ type: i0.Inject, args: [NGX_HJ_FN,] }] }, { type: undefined, decorators: [{ type: i0.Inject, args: [NGX_HOTJAR_SETTINGS_TOKEN,] }] } ]; }; /** * Provide a DI Configuration to attach Hotjar Trigger to Router Events at Angular Startup Cycle. */ var NGX_HOTJAR_ROUTER_INITIALIZER_PROVIDER = { provide: i0.APP_BOOTSTRAP_LISTENER, multi: true, useFactory: HotjarRouterInitializer, deps: [ NgxHotjarService ] }; /** * Attach a listener to `NavigationEnd` Router event. So, every time Router finish the page resolution it should call `NavigationEnd` event. * We assume that NavigationEnd is the final page resolution and call Hotjar `stateChange` command. * * To avoid double binds, we also destroy the subscription when de Bootstrap Component is destroied. But, we don't know for sure * that this strategy does not cause double bind on multiple bootstrap components. * * We are using de component's injector reference to resolve Router, sou I hope there is no problem w/ double bing. * * If you have this problem, I encourage not Use NgxHotjarRouterModule and atach the listener on AppComponent initialization. */ function HotjarRouterInitializer(hjService) { var _this = this; return function (c) { return __awaiter(_this, void 0, void 0, function () { var router$1, subs; return __generator(this, function (_a) { router$1 = c.injector.get(router.Router); subs = router$1 .events .subscribe(function (event) { if (event instanceof router.NavigationEnd) { hjService.stateChange(event.urlAfterRedirects); } }); // Cleanup c.onDestroy(function () { return subs.unsubscribe(); }); return [2 /*return*/]; }); }); }; } /** * Provides a TOKEN to manually configure Hojtar tracking code by angular way. */ var NGX_HOTJAR_INITIALIZER_PROVIDER = { provide: i0.APP_INITIALIZER, multi: true, useFactory: hotjarInitializer, deps: [ NGX_HOTJAR_SETTINGS_TOKEN, common.DOCUMENT, WINDOW ] }; /** * Configuration Factory to create hotjar install script tag and attache on DOM at angular initialization. */ function hotjarInitializer(settings, document, window) { var _this = this; return function () { return __awaiter(_this, void 0, void 0, function () { var head, script, uri; return __generator(this, function (_a) { if (!settings.trackingCode) { if (i0.isDevMode()) { console.error('Empty tracking code for Hotjar. Make sure to provide one when initializing NgxHotjarModule.'); } return [2 /*return*/]; } if (!document) { if (i0.isDevMode()) { console.error('Was not possible to access `document` instance. Make shure this environment works on a Broser like API'); } return [2 /*return*/]; } if (!window) { if (i0.isDevMode()) { console.error('Was not possible to access `window` api. Make sure this environment works like a browser.'); } return [2 /*return*/]; } Object.defineProperty(window, 'hj', { value: (window.hj || function () { (window.hj.q = window.hj.q || []).push(arguments); }), configurable: true, writable: true }); Object.defineProperty(window, '_hjSettings', { value: { hjid: settings.trackingCode, hjsv: (settings.version || 6) }, configurable: true, writable: true }); head = document.querySelector('head'), script = document.createElement('script'), uri = "https://static.hotjar.com/c/hotjar-" + window._hjSettings.hjid + ".js?sv=" + window._hjSettings.hjsv; script.async = true; script.src = (settings.uri || uri); head.appendChild(script); return [2 /*return*/]; }); }); }; } /** * Install Hotjar scripts on Angular Startup life cycle if this environment is a Browser, otherwise just ignore this step. * * You shall add this module on the Gighest level module of your application, aka `AppModule`. When * setup this module, you also have to provide you hotjat tracking code and the version of script. The default version * is 6. We do not recoment to expose the tracking code in the repository, so please, use angular environment variable. * * ## Exemple of Use * ```typescript \@NgModule({ ... imports: [ ... NgxHotjarModule.forRoot(envorinment.hj) // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ] }) ``` */ var NgxHotjarModule = /** @class */ (function () { function NgxHotjarModule() { } /** * Setup global settings and provide Hotjar Services. * * You private tracking code. This tracking code is also known as the same number as `SITE ID` inside Hotjar Dashboard. */ NgxHotjarModule.forRoot = function (trackingCode, version, uri) { if (version === void 0) { version = 6; } return { ngModule: NgxHotjarModule, providers: [ { provide: NGX_HOTJAR_SETTINGS_TOKEN, useValue: { trackingCode: trackingCode, version: version, uri: uri } }, NGX_HOTJAR_INITIALIZER_PROVIDER ] }; }; return NgxHotjarModule; }()); NgxHotjarModule.decorators = [ { type: i0.NgModule, args: [{ imports: [], declarations: [], exports: [] },] } ]; /** * Attach a listener to `NavigationEnd` Router event. So, every time Router finish the page resolution it should call `NavigationEnd` event. * We assume that NavigationEnd is the final page resolution and call Hotjar `stateChange` command. * * To avoid double binds, we also destroy the subscription when de Bootstrap Component is destroied. But, we don't know for sure * that this strategy does not cause double bind on multiple bootstrap components. * * We are using de component's injector reference to resolve Router, sou I hope there is no problem w/ double bing. * * If you have this problem, I encourage not Use NgxHotjarRouterModule and atach the listener on AppComponent initialization. * * This Module is just a sugar for: * ```typescript constructor(private router: Router) {} ... ngOnInit() { ... this.router .events .pipe(takeUntil(this.onDestroy$)) .subscribe(event => { if (event instanceof NavigationEnd) { hjService.pageView(event.urlAfterRedirects, undefined); } }); ``` */ var NgxHotjarRouterModule = /** @class */ (function () { function NgxHotjarRouterModule() { } return NgxHotjarRouterModule; }()); NgxHotjarRouterModule.decorators = [ { type: i0.NgModule, args: [{ imports: [ common.CommonModule, NgxHotjarModule ], providers: [ NGX_HOTJAR_ROUTER_INITIALIZER_PROVIDER ], declarations: [] },] } ]; /* * Public API Surface of ngx-hotjar */ /** * Generated bundle index. Do not edit. */ exports.HotjarRouterInitializer = HotjarRouterInitializer; exports.NGX_HJ_FN = NGX_HJ_FN; exports.NGX_HOTJAR_INITIALIZER_PROVIDER = NGX_HOTJAR_INITIALIZER_PROVIDER; exports.NGX_HOTJAR_ROUTER_INITIALIZER_PROVIDER = NGX_HOTJAR_ROUTER_INITIALIZER_PROVIDER; exports.NGX_HOTJAR_SETTINGS_TOKEN = NGX_HOTJAR_SETTINGS_TOKEN; exports.NgxHotjarModule = NgxHotjarModule; exports.NgxHotjarRouterModule = NgxHotjarRouterModule; exports.NgxHotjarService = NgxHotjarService; exports.WINDOW = WINDOW; exports.getHjFn = getHjFn; exports.getWindow = getWindow; exports.hotjarInitializer = hotjarInitializer; Object.defineProperty(exports, '__esModule', { value: true }); }))); //# sourceMappingURL=ngx-hotjar.umd.js.map