@advanced-rest-client/app-analytics
Advanced tools
Comparing version 3.0.0-preview.3 to 3.0.0
@@ -15,6 +15,4 @@ /** | ||
import {PolymerElement} from '@polymer/polymer/polymer-element.js'; | ||
declare namespace LogicElements { | ||
declare namespace ArcElements { | ||
/** | ||
@@ -35,23 +33,14 @@ * `<app-analytics-custom>` Sets a custom metric/dimmenstion for `<app-analytics>`. | ||
*/ | ||
class AppAnalyticsCustom extends PolymerElement { | ||
class AppAnalyticsCustom extends HTMLElement { | ||
type: String|null; | ||
index: Number|null; | ||
/** | ||
* Type of custom value. Either metric or dimmension | ||
* Type of this attribute depends on the `type` property. It can be numeric or string value. | ||
* Internally the element keeps all values as string and the value is cast to | ||
* a number if represents numeric value. | ||
*/ | ||
type: string|null|undefined; | ||
/** | ||
* Index of the custom metric. It can be found in Google Analytics admin panel | ||
*/ | ||
index: number|null|undefined; | ||
/** | ||
* The value of the metric or dimension. Type of this attribute depends on the `type`. | ||
*/ | ||
value: string|null|undefined; | ||
/** | ||
* Full name of the metric/dimension. | ||
*/ | ||
readonly fullName: string|null|undefined; | ||
value: String|Number|null; | ||
readonly fullName: String|null; | ||
attributeChangedCallback(name: any, oldValue: any, newValue: any): void; | ||
connectedCallback(): void; | ||
@@ -63,7 +52,4 @@ _indexObserver(index: any, oldIndex: any): void; | ||
declare global { | ||
interface HTMLElementTagNameMap { | ||
"app-analytics-custom": ArcElements.AppAnalyticsCustom; | ||
} | ||
interface HTMLElementTagNameMap { | ||
"app-analytics-custom": LogicElements.AppAnalyticsCustom; | ||
} |
@@ -14,3 +14,2 @@ /** | ||
*/ | ||
import {PolymerElement} from '../../@polymer/polymer/polymer-element.js'; | ||
/** | ||
@@ -32,34 +31,101 @@ * `<app-analytics-custom>` Sets a custom metric/dimmenstion for `<app-analytics>`. | ||
* @customElement | ||
* @polymer | ||
* @demo demo/index.html | ||
* @memberof ArcElements | ||
* @memberof LogicElements | ||
*/ | ||
class AppAnalyticsCustom extends PolymerElement { | ||
static get properties() { | ||
return { | ||
// Type of custom value. Either metric or dimmension | ||
type: String, | ||
// Index of the custom metric. It can be found in Google Analytics admin panel | ||
index: { | ||
type: Number, | ||
observer: '_indexObserver' | ||
}, | ||
// The value of the metric or dimension. Type of this attribute depends on the `type`. | ||
value: String, | ||
// Full name of the metric/dimension. | ||
fullName: { | ||
type: String, | ||
readOnly: true | ||
class AppAnalyticsCustom extends HTMLElement { | ||
static get observedAttributes() { | ||
return [ | ||
'type', | ||
'index', | ||
'value' | ||
]; | ||
} | ||
attributeChangedCallback(name, oldValue, newValue) { | ||
this[name] = newValue; | ||
} | ||
/** | ||
* @return {String} Type of custom value. Either `metric` or `dimension`. | ||
*/ | ||
get type() { | ||
return this._type; | ||
} | ||
set type(value) { | ||
const old = this._type; | ||
if (old === value) { | ||
return; | ||
} | ||
if (value) { | ||
value = String(value); | ||
} else { | ||
this.removeAttribute('type'); | ||
} | ||
this._type = value; | ||
if (value) { | ||
this.setAttribute('type', value); | ||
} | ||
this._customChanged(); | ||
} | ||
/** | ||
* @return {Number} Index of the custom metric. It can be found in Google Analytics admin panel. | ||
*/ | ||
get index() { | ||
return this._index; | ||
} | ||
set index(value) { | ||
const old = this._index; | ||
if (isNaN(value)) { | ||
this._index = undefined; | ||
this.removeAttribute('index'); | ||
} else { | ||
value = Number(value); | ||
if (old === value) { | ||
return; | ||
} | ||
}; | ||
this._index = value; | ||
this.setAttribute('index', String(value)); | ||
} | ||
this._indexObserver(value, old); | ||
this._customChanged(); | ||
} | ||
/** | ||
* Type of this attribute depends on the `type` property. It can be numeric or string value. | ||
* Internally the element keeps all values as string and the value is cast to | ||
* a number if represents numeric value. | ||
* @return {String|Number} The value of the metric or dimension. | ||
*/ | ||
get value() { | ||
const v = this._value; | ||
if (isNaN(v)) { | ||
return v; | ||
} | ||
return Number(v); | ||
} | ||
static get observers() { | ||
return [ | ||
'_customChanged(type,index,value)' | ||
]; | ||
set value(value) { | ||
const old = this._value; | ||
if (old === value) { | ||
return; | ||
} | ||
if (value || value === 0) { | ||
value = String(value); | ||
} else { | ||
this.removeAttribute('value'); | ||
} | ||
this._value = value; | ||
if (value) { | ||
this.setAttribute('value', value); | ||
} | ||
this._customChanged(); | ||
} | ||
/** | ||
* @return {String} Full name of the metric/dimension. | ||
*/ | ||
get fullName() { | ||
return this._fullName; | ||
} | ||
connectedCallback() { | ||
super.connectedCallback(); | ||
this._customChanged(this.type, this.index, this.value); | ||
@@ -69,6 +135,6 @@ } | ||
_indexObserver(index, oldIndex) { | ||
if (oldIndex) { | ||
if (oldIndex || oldIndex === 0) { | ||
this.dispatchEvent(new CustomEvent('app-analytics-custom-removed', { | ||
composed: true, | ||
bubbles: true, | ||
composed: true, | ||
detail: { | ||
@@ -95,5 +161,4 @@ index: oldIndex, | ||
name += String(index); | ||
this._setFullName(name); | ||
this._fullName = name; | ||
this.dispatchEvent(new CustomEvent('app-analytics-custom-changed', { | ||
bubbles: true, | ||
composed: true, | ||
@@ -100,0 +165,0 @@ detail: { |
@@ -15,10 +15,4 @@ /** | ||
import {PolymerElement} from '@polymer/polymer/polymer-element.js'; | ||
declare namespace LogicElements { | ||
import {html} from '@polymer/polymer/lib/utils/html-tag.js'; | ||
import {FlattenedNodesObserver} from '@polymer/polymer/lib/utils/flattened-nodes-observer.js'; | ||
declare namespace ArcElements { | ||
/** | ||
@@ -183,17 +177,12 @@ * `<app-analytics>` An element that support Google Analytics analysis | ||
*/ | ||
class AppAnalytics extends PolymerElement { | ||
readonly cidKey: any; | ||
readonly disabledKey: any; | ||
class AppAnalytics extends HTMLElement { | ||
/** | ||
* If true the app probably is online. See `<connectivity-state>`. | ||
* Note, UUID generator is used only during the initialization and when | ||
* client id is not set and there's no coirresponding entry in local storage. | ||
* Otherwise it is unused. | ||
*/ | ||
isOnline: boolean|null|undefined; | ||
readonly _uuid: Element|null; | ||
/** | ||
* Generated POST parameters based on a params | ||
*/ | ||
readonly baseParams: any[]|null|undefined; | ||
/** | ||
* The Client ID for the mearusement protocol. | ||
@@ -210,3 +199,3 @@ * | ||
*/ | ||
clientId: string|null|undefined; | ||
clientId: String|null; | ||
@@ -222,3 +211,3 @@ /** | ||
*/ | ||
userId: string|null|undefined; | ||
userId: String|null; | ||
@@ -228,14 +217,2 @@ /** | ||
* | ||
* The Protocol version. The current value is '1'. This will only change when there | ||
* are changes made that are not backwards compatible. | ||
* | ||
* - Parameter: **v** | ||
* - Example value: 1 | ||
* - Example usage: v=1 | ||
*/ | ||
readonly protocolVersion: string|null|undefined; | ||
/** | ||
* **Required for all hit types.** | ||
* | ||
* The tracking ID / web property ID. The format is UA-XXXX-Y. | ||
@@ -248,3 +225,3 @@ * All collected data is associated by this ID. | ||
*/ | ||
trackingId: string|null|undefined; | ||
trackingId: String|null; | ||
@@ -260,3 +237,3 @@ /** | ||
*/ | ||
anonymizeIp: boolean|null|undefined; | ||
anonymizeIp: Boolean|null; | ||
@@ -271,3 +248,3 @@ /** | ||
*/ | ||
dataSource: string|null|undefined; | ||
dataSource: String|null; | ||
@@ -282,3 +259,3 @@ /** | ||
*/ | ||
useCacheBooster: boolean|null|undefined; | ||
useCacheBooster: Boolean|null; | ||
@@ -293,3 +270,3 @@ /** | ||
*/ | ||
referrer: string|null|undefined; | ||
referrer: String|null; | ||
@@ -303,3 +280,3 @@ /** | ||
*/ | ||
campaignName: string|null|undefined; | ||
campaignName: String|null; | ||
@@ -313,3 +290,3 @@ /** | ||
*/ | ||
campaignSource: string|null|undefined; | ||
campaignSource: String|null; | ||
@@ -323,3 +300,3 @@ /** | ||
*/ | ||
campaignMedium: string|null|undefined; | ||
campaignMedium: String|null; | ||
@@ -333,3 +310,3 @@ /** | ||
*/ | ||
appVersion: string|null|undefined; | ||
appVersion: String|null; | ||
@@ -345,3 +322,3 @@ /** | ||
*/ | ||
appName: string|null|undefined; | ||
appName: String|null; | ||
@@ -355,3 +332,3 @@ /** | ||
*/ | ||
appId: string|null|undefined; | ||
appId: String|null; | ||
@@ -365,27 +342,5 @@ /** | ||
*/ | ||
appInstallerId: string|null|undefined; | ||
appInstallerId: String|null; | ||
/** | ||
* Each custom metric has an associated index. There is a maximum of 20 custom | ||
* metrics (200 for Analytics 360 accounts). The metric index must be a positive | ||
* integer between 1 and 200, inclusive. | ||
* | ||
* - Parameter: **cm<metricIndex>** | ||
* - Example value: 47 | ||
* - Example usage: cm1=47 | ||
*/ | ||
readonly customMetrics: any[]|null|undefined; | ||
/** | ||
* Each custom dimension has an associated index. There is a maximum of 20 custom | ||
* dimensions (200 for Analytics 360 accounts). The dimension index must be a positive | ||
* integer between 1 and 200, inclusive. | ||
* | ||
* - Parameter: **cd<dimensionIndex>** | ||
* - Example value: Sports | ||
* - Example usage: cd1=Sports | ||
*/ | ||
readonly customDimensions: any[]|null|undefined; | ||
/** | ||
* True if current environment has localStorage suppport. | ||
@@ -399,3 +354,3 @@ * Chrome apps do not have localStorage property. | ||
*/ | ||
debug: boolean|null|undefined; | ||
debug: Boolean|null; | ||
@@ -409,4 +364,3 @@ /** | ||
*/ | ||
debugEndpoint: boolean|null|undefined; | ||
readonly _paramsMap: object|null|undefined; | ||
debugEndpoint: Boolean|null; | ||
@@ -419,10 +373,41 @@ /** | ||
*/ | ||
disabled: boolean|null|undefined; | ||
disabled: Boolean|null; | ||
/** | ||
* List of hist to be send when came back from offline state. | ||
* Note, this is in memory information only. | ||
* The component do not sotres this information. | ||
* When set it queues requests to GA in memory and attempts to send the requests | ||
* again when this flag is removed. | ||
*/ | ||
_offlineQueue: any[]|null|undefined; | ||
offline: Boolean|null; | ||
/** | ||
* Generated POST parameters based on a params | ||
*/ | ||
_baseParams: object|null; | ||
/** | ||
* Each custom metric has an associated index. There is a maximum of 20 custom | ||
* metrics (200 for Analytics 360 accounts). The metric index must be a positive | ||
* integer between 1 and 200, inclusive. | ||
* | ||
* - Parameter: **cm<metricIndex>** | ||
* - Example value: 47 | ||
* - Example usage: cm1=47 | ||
*/ | ||
_customMetrics: Array<object|null>|null; | ||
/** | ||
* Each custom dimension has an associated index. There is a maximum of 20 custom | ||
* dimensions (200 for Analytics 360 accounts). The dimension index must be a positive | ||
* integer between 1 and 200, inclusive. | ||
* | ||
* - Parameter: **cd<dimensionIndex>** | ||
* - Example value: Sports | ||
* - Example usage: cd1=Sports | ||
*/ | ||
_customDimensions: Array<object|null>|null; | ||
readonly cidKey: String|null; | ||
readonly disabledKey: String|null; | ||
attributeChangedCallback(name: any, oldValue: any, newValue: any): void; | ||
_setStringProperty(name: any, value: any): void; | ||
_setBooleanProperty(name: any, value: any): void; | ||
connectedCallback(): void; | ||
@@ -432,2 +417,8 @@ disconnectedCallback(): void; | ||
/** | ||
* A mutation observer callback function called when children or attributes changed. | ||
* It processes child nodes depending on mutation type and change record. | ||
*/ | ||
_childrenUpdated(mutations: Array<MutationRecord|null>|null): void; | ||
/** | ||
* Restores data stored in localStorage. | ||
@@ -465,12 +456,9 @@ */ | ||
/** | ||
* Handler for app-analytics-custom-changed event. Registers a new custom property. | ||
* Processes `MutationRecord` for attribute change | ||
* | ||
* @param mutation A mutation record that triggered the callback | ||
*/ | ||
_customPropertyChanged(e: any): void; | ||
_processChildAttribute(mutation: MutationRecord|null): void; | ||
/** | ||
* Handler for app-analytics-custom-removed event. Unregisters a custom property. | ||
*/ | ||
_customPropertyRemoved(e: any): void; | ||
/** | ||
* Sets custom dimension to be send with the hit. | ||
@@ -516,2 +504,20 @@ * Set dimension will be used in all hits until `removeCustomDimension()` is called | ||
/** | ||
* Adds custom metric / dimension to the corresponding array. | ||
* | ||
* @param prop The name of the property with the array of custom items. | ||
* @param index Index of the custom property. Free version of GA allows up to 20 | ||
* custom metrics/dimensions and up to 200 in premium. The index has to be in range 1 - 200. | ||
* @param value Value of the custom property to set. | ||
*/ | ||
_addCustom(prop: String|null, index: Number|null, value: Strnig|null): void; | ||
/** | ||
* Removes from this instance custom metric/dimension for given index. | ||
* | ||
* @param prop The name of the property with the array of custom items. | ||
* @param index Index of the custom metric. The index has to be in range 1 - 200. | ||
*/ | ||
_removeCustom(prop: String|null, index: Number|null): void; | ||
/** | ||
* Sends the screenview hit to the GA. | ||
@@ -521,3 +527,3 @@ * | ||
* @param opts Custom data definition. It should be an object that may contain two | ||
* keys: `customDimensions` and `customMetrics`. Both as an array of objects. Each object must | ||
* keys: `_customDimensions` and `_customMetrics`. Both as an array of objects. Each object must | ||
* contain `index` property - representing custom data index in GA - and `value` property - | ||
@@ -536,3 +542,3 @@ * representing value of the property. | ||
* @param opts Custom data definition. It should be an object that may contain two | ||
* keys: `customDimensions` and `customMetrics`. Both as an array of objects. Each object must | ||
* keys: `_customDimensions` and `_customMetrics`. Both as an array of objects. Each object must | ||
* contain `index` property - representing custom data index in GA - and `value` property - | ||
@@ -549,3 +555,3 @@ * representing value of the property. | ||
* @param opts Custom data definition. It should be an object that may contain two | ||
* keys: `customDimensions` and `customMetrics`. Both as an array of objects. Each object must | ||
* keys: `_customDimensions` and `_customMetrics`. Both as an array of objects. Each object must | ||
* contain `index` property - representing custom data index in GA - and `value` property - | ||
@@ -565,3 +571,3 @@ * representing value of the property. | ||
* @param opts Custom data definition. It should be an object that may contain two | ||
* keys: `customDimensions` and `customMetrics`. Both as an array of objects. Each object must | ||
* keys: `_customDimensions` and `_customMetrics`. Both as an array of objects. Each object must | ||
* contain `index` property - representing custom data index in GA - and `value` property - | ||
@@ -581,3 +587,3 @@ * representing value of the property. | ||
* @param cmOpts Custom data definition. It should be an object that may contain two | ||
* keys: `customDimensions` and `customMetrics`. Both as an array of objects. Each object must | ||
* keys: `_customDimensions` and `_customMetrics`. Both as an array of objects. Each object must | ||
* contain `index` property - representing custom data index in GA - and `value` property - | ||
@@ -627,3 +633,11 @@ * representing value of the property. | ||
_transport(body: any): any; | ||
_onlineChanged(value: any): any; | ||
_offlineChanged(value: any): any; | ||
/** | ||
* MutationObserver initialized in the constructor does not | ||
* triggers changes when the element is initialized. This | ||
* function processes nodes set up declaratively when the element is still | ||
* initializing. | ||
*/ | ||
_processInitialNodes(): void; | ||
} | ||
@@ -635,4 +649,6 @@ } | ||
interface HTMLElementTagNameMap { | ||
"app-analytics": ArcElements.AppAnalytics; | ||
"app-analytics": LogicElements.AppAnalytics; | ||
} | ||
} | ||
export {}; |
1254
app-analytics.js
@@ -14,8 +14,120 @@ /** | ||
*/ | ||
import {PolymerElement} from '../../@polymer/polymer/polymer-element.js'; | ||
import {html} from '../../@polymer/polymer/lib/utils/html-tag.js'; | ||
import {FlattenedNodesObserver} from '../../@polymer/polymer/lib/utils/flattened-nodes-observer.js'; | ||
import '../../@advanced-rest-client/uuid-generator/uuid-generator.js'; | ||
import '../../@advanced-rest-client/connectivity-state/connectivity-state.js'; | ||
import '@advanced-rest-client/uuid-generator/uuid-generator.js'; | ||
/** | ||
* **Required for all hit types.** | ||
* | ||
* The Protocol version. The current value is '1'. This will only change when there | ||
* are changes made that are not backwards compatible. | ||
* | ||
* - Parameter: **v** | ||
* - Example value: 1 | ||
* - Example usage: v=1 | ||
* | ||
* @type {Number} | ||
*/ | ||
const protocolVersion = 1; | ||
/** | ||
* A map of parameter names to its descriptions. | ||
* @type {Object} | ||
*/ | ||
export const paramsMap = { | ||
v: 'Protocol Version', | ||
tid: 'Tracking ID / Web Property ID', | ||
aip: 'Anonymize IP', | ||
ds: 'Data Source', | ||
qt: 'Queue Time', | ||
z: 'Cache Buster', | ||
cid: 'Client ID', | ||
uid: 'User ID', | ||
sc: 'Session Control', | ||
uip: 'IP Override', | ||
ua: 'User Agent Override', | ||
geoip: 'Geographical Override', | ||
dr: 'Document Referrer', | ||
cn: 'Campaign Name', | ||
cs: 'Campaign Source', | ||
cm: 'Campaign Medium', | ||
ck: 'Campaign Keyword', | ||
cc: 'Campaign Content', | ||
ci: 'Campaign ID', | ||
gclid: 'Google AdWords ID', | ||
dclid: 'Google Display Ads ID', | ||
sr: 'Screen Resolution', | ||
vp: 'Viewport size', | ||
de: 'Document Encoding', | ||
sd: 'Screen Colors', | ||
ul: 'User Language', | ||
je: 'Java Enabled', | ||
fl: 'Flash Version', | ||
t: 'Hit type', | ||
ni: 'Non-Interaction Hit', | ||
dl: 'Document location URL', | ||
dh: 'Document Host Name', | ||
dp: 'Document Path', | ||
dt: 'Document Title', | ||
cd: 'Screen Name', | ||
linkid: 'Link ID', | ||
an: 'Application Name', | ||
aid: 'Application ID', | ||
av: 'Application Version', | ||
aiid: 'Application Installer ID', | ||
ec: 'Event Category', | ||
ea: 'Event Action', | ||
el: 'Event Label', | ||
ev: 'Event Value', | ||
sn: 'Social Network', | ||
sa: 'Social Action', | ||
st: 'Social Action Target', | ||
utc: 'User timing category', | ||
utv: 'User timing variable name', | ||
utt: 'User timing time', | ||
utl: 'User timing label', | ||
plt: 'Page Load Time', | ||
dns: 'DNS Time', | ||
pdt: 'Page Download Time', | ||
rrt: 'Redirect Response Time', | ||
tcp: 'TCP Connect Time', | ||
srt: 'Server Response Time', | ||
dit: 'DOM Interactive Time', | ||
clt: 'Content Load Time', | ||
exd: 'Exception Description', | ||
exf: 'Is Exception Fatal?', | ||
xid: 'Experiment ID', | ||
xvar: 'Experiment Variant' | ||
}; | ||
for (let i = 1; i < 201; i++) { | ||
paramsMap['cd' + i] = 'Custom dimension #' + i; | ||
paramsMap['cm' + i] = 'Custom metric #' + i; | ||
} | ||
function detectLocalStorage() { | ||
/* global chrome */ | ||
if (typeof chrome !== 'undefined' && chrome.i18n) { | ||
// Chrome apps have `chrome.i18n` property, regular website doesn't. | ||
// This is to avoid annoying warning message in Chrome app. | ||
return false; | ||
} | ||
try { | ||
localStorage.getItem('test'); | ||
return true; | ||
} catch (_) { | ||
return false; | ||
} | ||
} | ||
/** | ||
* True if current environment has localStorage suppport. | ||
* Chrome apps do not have localStorage property. | ||
* | ||
* @type {Boolean} | ||
*/ | ||
export const hasLocalStorage = detectLocalStorage(); | ||
/** | ||
* List of hist to be send when came back from offline state. | ||
* Note, this is in memory information only. | ||
* The component do not sotres this information. | ||
* | ||
* @type {Array<Object>} | ||
*/ | ||
export const offlineQueue = []; | ||
/** | ||
* `<app-analytics>` An element that support Google Analytics analysis | ||
@@ -180,417 +292,508 @@ * | ||
* @customElement | ||
* @polymer | ||
* @demo demo/index.html | ||
* @memberof ArcElements | ||
* @memberof LogicElements | ||
*/ | ||
class AppAnalytics extends PolymerElement { | ||
static get template() { | ||
return html` | ||
<style> | ||
:host { | ||
display: none; | ||
class AppAnalytics extends HTMLElement { | ||
/** | ||
* Note, UUID generator is used only during the initialization and when | ||
* client id is not set and there's no coirresponding entry in local storage. | ||
* Otherwise it is unused. | ||
* @return {Element} A reference to `uuid-generator` element. | ||
*/ | ||
get _uuid() { | ||
if (!this.__uuid) { | ||
this.__uuid = document.createElement('uuid-generator'); | ||
} | ||
</style> | ||
<uuid-generator id="uuid"></uuid-generator> | ||
<connectivity-state online="{{isOnline}}"></connectivity-state> | ||
<slot></slot> | ||
`; | ||
return this.__uuid; | ||
} | ||
static get properties() { | ||
return { | ||
// If true the app probably is online. See `<connectivity-state>`. | ||
isOnline: {type: Boolean, observer: '_onlineChanged'}, | ||
// Generated POST parameters based on a params | ||
baseParams: { | ||
type: Array, | ||
readOnly: true, | ||
value: function() { | ||
return []; | ||
} | ||
}, | ||
/** | ||
* The Client ID for the mearusement protocol. | ||
* | ||
* **It is required for all types of calls.** | ||
* | ||
* The value of this field should be a random UUID (version 4) as described | ||
* in http://www.ietf.org/rfc/rfc4122.txt | ||
* | ||
* - Parameter: **cid** | ||
* - Example value: 35009a79-1a05-49d7-b876-2b884d0f825b | ||
* - Example usage: cid=35009a79-1a05-49d7-b876-2b884d0f825b | ||
*/ | ||
clientId: { | ||
type: String, | ||
observer: '_cidChanged', | ||
notify: true | ||
}, | ||
/** | ||
* This is intended to be a known identifier for a user provided by the site owner/tracking | ||
* library user. It must not itself be PII (personally identifiable information). | ||
* The value should never be persisted in GA cookies or other Analytics provided storage. | ||
* | ||
* - Parameter: **uid** | ||
* - Example value: as8eknlll | ||
* - Example usage: uid=as8eknlll | ||
* | ||
*/ | ||
userId: { | ||
type: String, | ||
observer: '_configureBaseParams' | ||
}, | ||
/** | ||
* **Required for all hit types.** | ||
* | ||
* The Protocol version. The current value is '1'. This will only change when there | ||
* are changes made that are not backwards compatible. | ||
* | ||
* - Parameter: **v** | ||
* - Example value: 1 | ||
* - Example usage: v=1 | ||
*/ | ||
protocolVersion: { | ||
type: String, | ||
value: '1', | ||
readOnly: true | ||
}, | ||
/** | ||
* **Required for all hit types.** | ||
* | ||
* The tracking ID / web property ID. The format is UA-XXXX-Y. | ||
* All collected data is associated by this ID. | ||
* | ||
* - Parameter: **tid** | ||
* - Example value: UA-XXXX-Y | ||
* - Example usage: tid=UA-XXXX-Y | ||
*/ | ||
trackingId: { | ||
type: String, | ||
observer: '_configureBaseParams' | ||
}, | ||
/** | ||
* When present, the IP address of the sender will be anonymized. | ||
* For example, the IP will be anonymized if any of the following parameters are present in | ||
* the payload: &aip=, &aip=0, or &aip=1 | ||
* | ||
* - Parameter: **aip** | ||
* - Example value: 1 | ||
* - Example usage: aip=1 | ||
*/ | ||
anonymizeIp: { | ||
type: Boolean, | ||
value: false, | ||
observer: '_configureBaseParams' | ||
}, | ||
/** | ||
* Indicates the data source of the hit. Hits sent from analytics.js will have data source | ||
* set to 'web'; hits sent from one of the mobile SDKs will have data source set to 'app'. | ||
* | ||
* - Parameter: **ds** | ||
* - Example value: call center | ||
* - Example usage: ds=call%20center | ||
*/ | ||
dataSource: { | ||
type: String, | ||
observer: '_configureBaseParams' | ||
}, | ||
/** | ||
* Used to send a random number in GET requests to ensure browsers and proxies | ||
* don't cache hits. | ||
* | ||
* - Parameter: **z** | ||
* - Example value: 289372387623 | ||
* - Example usage: z=289372387623 | ||
*/ | ||
useCacheBooster: Boolean, | ||
/** | ||
* Specifies which referral source brought traffic to a website. This value is also used to | ||
* compute the traffic source. The format of this value is a URL. | ||
* | ||
* - Parameter: **dr** | ||
* - Example value: http://example.com | ||
* - Example usage: dr=http%3A%2F%2Fexample.com | ||
*/ | ||
referrer: { | ||
type: String, | ||
observer: '_configureBaseParams' | ||
}, | ||
/** | ||
* Specifies the campaign name. | ||
* | ||
* - Parameter: **cn** | ||
* - Example value: (direct) | ||
* - Example usage: cn=%28direct%29 | ||
*/ | ||
campaignName: { | ||
type: String, | ||
observer: '_configureBaseParams' | ||
}, | ||
/** | ||
* Specifies the campaign source. | ||
* | ||
* - Parameter: **cs** | ||
* - Example value: (direct) | ||
* - Example usage: cs=%28direct%29 | ||
*/ | ||
campaignSource: { | ||
type: String, | ||
observer: '_configureBaseParams' | ||
}, | ||
/** | ||
* Specifies the campaign medium. | ||
* | ||
* - Parameter: **cm** | ||
* - Example value: organic | ||
* - Example usage: cm=organic | ||
*/ | ||
campaignMedium: { | ||
type: String, | ||
observer: '_configureBaseParams' | ||
}, | ||
/** | ||
* Specifies the application version. | ||
* | ||
* - Parameter: **av** | ||
* - Example value: 1.2 | ||
* - Example usage: av=1.2 | ||
*/ | ||
appVersion: { | ||
type: String, | ||
observer: '_configureBaseParams' | ||
}, | ||
/** | ||
* Specifies the application name. This field is required for any hit that has app related | ||
* data (i.e., app version, app ID, or app installer ID). For hits sent to web properties, | ||
* this field is optional. | ||
* | ||
* - Parameter: **an** | ||
* - Example My App | ||
* - Example usage: an=My%20App | ||
*/ | ||
appName: { | ||
type: String, | ||
observer: '_configureBaseParams' | ||
}, | ||
/** | ||
* Application identifier. | ||
* | ||
* - Parameter: **aid** | ||
* - Example value: com.company.app | ||
* - Example usage: aid=com.company.app | ||
*/ | ||
appId: { | ||
type: String, | ||
observer: '_configureBaseParams' | ||
}, | ||
/** | ||
* Application installer identifier. | ||
* | ||
* - Parameter: **aiid** | ||
* - Example value: com.platform.vending | ||
* - Example usage: aiid=com.platform.vending | ||
*/ | ||
appInstallerId: { | ||
type: String, | ||
observer: '_configureBaseParams' | ||
}, | ||
/** | ||
* Each custom metric has an associated index. There is a maximum of 20 custom | ||
* metrics (200 for Analytics 360 accounts). The metric index must be a positive | ||
* integer between 1 and 200, inclusive. | ||
* | ||
* - Parameter: **cm<metricIndex>** | ||
* - Example value: 47 | ||
* - Example usage: cm1=47 | ||
*/ | ||
customMetrics: { | ||
type: Array, | ||
readOnly: true, | ||
value: function() { | ||
return []; | ||
} | ||
}, | ||
/** | ||
* Each custom dimension has an associated index. There is a maximum of 20 custom | ||
* dimensions (200 for Analytics 360 accounts). The dimension index must be a positive | ||
* integer between 1 and 200, inclusive. | ||
* | ||
* - Parameter: **cd<dimensionIndex>** | ||
* - Example value: Sports | ||
* - Example usage: cd1=Sports | ||
*/ | ||
customDimensions: { | ||
type: Array, | ||
readOnly: true, | ||
value: function() { | ||
return []; | ||
} | ||
}, | ||
/** | ||
* True if current environment has localStorage suppport. | ||
* Chrome apps do not have localStorage property. | ||
*/ | ||
hasLocalStorage: { | ||
type: Boolean, | ||
readOnly: true, | ||
value: function() { | ||
/* global chrome */ | ||
if (typeof chrome !== 'undefined' && chrome.i18n) { | ||
// Chrome apps have `chrome.i18n` property, regular website doesn't. | ||
// This is to avoid annoying warning message in Chrome app. | ||
return false; | ||
} | ||
try { | ||
localStorage.getItem('test'); | ||
return true; | ||
} catch (_) { | ||
return false; | ||
} | ||
} | ||
}, | ||
/** | ||
* If set to true it will prints debug messages into the console. | ||
*/ | ||
debug: Boolean, | ||
/** | ||
* If set it will send the data to GA's debug endpoint | ||
* and the request won't be actually saved but only validated | ||
* and the validation results will be fired in the | ||
* `aapp-analytics-structure-debug` | ||
* event in the detail's `debug` property. | ||
*/ | ||
debugEndpoint: Boolean, | ||
_paramsMap: { | ||
type: Object, | ||
readOnly: true, | ||
value: function() { | ||
const data = { | ||
v: 'Protocol Version', | ||
tid: 'Tracking ID / Web Property ID', | ||
aip: 'Anonymize IP', | ||
ds: 'Data Source', | ||
qt: 'Queue Time', | ||
z: 'Cache Buster', | ||
cid: 'Client ID', | ||
uid: 'User ID', | ||
sc: 'Session Control', | ||
uip: 'IP Override', | ||
ua: 'User Agent Override', | ||
geoip: 'Geographical Override', | ||
dr: 'Document Referrer', | ||
cn: 'Campaign Name', | ||
cs: 'Campaign Source', | ||
cm: 'Campaign Medium', | ||
ck: 'Campaign Keyword', | ||
cc: 'Campaign Content', | ||
ci: 'Campaign ID', | ||
gclid: 'Google AdWords ID', | ||
dclid: 'Google Display Ads ID', | ||
sr: 'Screen Resolution', | ||
vp: 'Viewport size', | ||
de: 'Document Encoding', | ||
sd: 'Screen Colors', | ||
ul: 'User Language', | ||
je: 'Java Enabled', | ||
fl: 'Flash Version', | ||
t: 'Hit type', | ||
ni: 'Non-Interaction Hit', | ||
dl: 'Document location URL', | ||
dh: 'Document Host Name', | ||
dp: 'Document Path', | ||
dt: 'Document Title', | ||
cd: 'Screen Name', | ||
linkid: 'Link ID', | ||
an: 'Application Name', | ||
aid: 'Application ID', | ||
av: 'Application Version', | ||
aiid: 'Application Installer ID', | ||
ec: 'Event Category', | ||
ea: 'Event Action', | ||
el: 'Event Label', | ||
ev: 'Event Value', | ||
sn: 'Social Network', | ||
sa: 'Social Action', | ||
st: 'Social Action Target', | ||
utc: 'User timing category', | ||
utv: 'User timing variable name', | ||
utt: 'User timing time', | ||
utl: 'User timing label', | ||
plt: 'Page Load Time', | ||
dns: 'DNS Time', | ||
pdt: 'Page Download Time', | ||
rrt: 'Redirect Response Time', | ||
tcp: 'TCP Connect Time', | ||
srt: 'Server Response Time', | ||
dit: 'DOM Interactive Time', | ||
clt: 'Content Load Time', | ||
exd: 'Exception Description', | ||
exf: 'Is Exception Fatal?', | ||
xid: 'Experiment ID', | ||
xvar: 'Experiment Variant' | ||
}; | ||
for (let i = 1; i < 201; i++) { | ||
data['cd' + i] = 'Custom dimension #' + i; | ||
data['cm' + i] = 'Custom metric #' + i; | ||
} | ||
return data; | ||
} | ||
}, | ||
/** | ||
* If set disables Google Analytics reporting. | ||
* This information is stored in localStorage. As long as this | ||
* information is not cleared it is respected and data are not send to GA | ||
* server. | ||
*/ | ||
disabled: { | ||
type: Boolean, | ||
observer: '_disabledChanged' | ||
}, | ||
/** | ||
* List of hist to be send when came back from offline state. | ||
* Note, this is in memory information only. | ||
* The component do not sotres this information. | ||
*/ | ||
_offlineQueue: Array | ||
}; | ||
static get observedAttributes() { | ||
return [ | ||
'clientid', | ||
'userid', | ||
'trackingid', | ||
'anonymizeip', | ||
'datasource', | ||
'usecachebooster', | ||
'referrer', | ||
'campaignname', | ||
'campaignsource', | ||
'campaignmedium', | ||
'appversion', | ||
'appname', | ||
'appid', | ||
'appinstallerid', | ||
'debug', | ||
'debugendpoint', | ||
'disabled', | ||
'offline' | ||
]; | ||
} | ||
attributeChangedCallback(name, oldValue, newValue) { | ||
switch (name) { | ||
case 'clientid': this._setStringProperty('clientId', newValue); break; | ||
case 'userid': this._setStringProperty('userId', newValue); break; | ||
case 'trackingid': this._setStringProperty('trackingId', newValue); break; | ||
case 'datasource': this._setStringProperty('dataSource', newValue); break; | ||
case 'campaignname': this._setStringProperty('campaignName', newValue); break; | ||
case 'campaignsource': this._setStringProperty('campaignSource', newValue); break; | ||
case 'campaignmedium': this._setStringProperty('campaignMedium', newValue); break; | ||
case 'appversion': this._setStringProperty('appVersion', newValue); break; | ||
case 'appname': this._setStringProperty('appName', newValue); break; | ||
case 'appid': this._setStringProperty('appId', newValue); break; | ||
case 'appinstallerid': this._setStringProperty('appInstallerId', newValue); break; | ||
case 'referrer': this._setStringProperty(name, newValue); break; | ||
case 'anonymizeip': this._setBooleanProperty('anonymizeIp', newValue); break; | ||
case 'usecachebooster': this._setBooleanProperty('useCacheBooster', newValue); break; | ||
case 'debugendpoint': this._setBooleanProperty('debugEndpoint', newValue); break; | ||
case 'debug': | ||
case 'disabled': | ||
case 'offline': | ||
this._setBooleanProperty(name, newValue); | ||
break; | ||
} | ||
} | ||
_setStringProperty(name, value) { | ||
if (value === null) { | ||
this[name] = undefined; | ||
} else { | ||
this[name] = value; | ||
} | ||
} | ||
_setBooleanProperty(name, value) { | ||
if (value === null) { | ||
this[name] = false; | ||
} else { | ||
this[name] = true; | ||
} | ||
} | ||
/** | ||
* The Client ID for the mearusement protocol. | ||
* | ||
* **It is required for all types of calls.** | ||
* | ||
* The value of this field should be a random UUID (version 4) as described | ||
* in http://www.ietf.org/rfc/rfc4122.txt | ||
* | ||
* - Parameter: **cid** | ||
* - Example value: 35009a79-1a05-49d7-b876-2b884d0f825b | ||
* - Example usage: cid=35009a79-1a05-49d7-b876-2b884d0f825b | ||
* | ||
* @return {String} | ||
*/ | ||
get clientId() { | ||
return this._clientId; | ||
} | ||
set clientId(value) { | ||
this._clientId = value; | ||
this._cidChanged(value); | ||
this._configureBaseParams(); | ||
} | ||
/** | ||
* This is intended to be a known identifier for a user provided by the site owner/tracking | ||
* library user. It must not itself be PII (personally identifiable information). | ||
* The value should never be persisted in GA cookies or other Analytics provided storage. | ||
* | ||
* - Parameter: **uid** | ||
* - Example value: as8eknlll | ||
* - Example usage: uid=as8eknlll | ||
* | ||
* @return {String} | ||
*/ | ||
get userId() { | ||
return this._userId; | ||
} | ||
set userId(value) { | ||
this._userId = value; | ||
this._configureBaseParams(); | ||
} | ||
/** | ||
* **Required for all hit types.** | ||
* | ||
* The tracking ID / web property ID. The format is UA-XXXX-Y. | ||
* All collected data is associated by this ID. | ||
* | ||
* - Parameter: **tid** | ||
* - Example value: UA-XXXX-Y | ||
* - Example usage: tid=UA-XXXX-Y | ||
* | ||
* @return {String} | ||
*/ | ||
get trackingId() { | ||
return this._trackingId; | ||
} | ||
set trackingId(value) { | ||
this._trackingId = value; | ||
this._configureBaseParams(); | ||
} | ||
/** | ||
* When present, the IP address of the sender will be anonymized. | ||
* For example, the IP will be anonymized if any of the following parameters are present in | ||
* the payload: &aip=, &aip=0, or &aip=1 | ||
* | ||
* - Parameter: **aip** | ||
* - Example value: 1 | ||
* - Example usage: aip=1 | ||
* @return {Boolean} | ||
*/ | ||
get anonymizeIp() { | ||
return this._anonymizeIp; | ||
} | ||
set anonymizeIp(value) { | ||
this._anonymizeIp = value; | ||
this._configureBaseParams(); | ||
} | ||
/** | ||
* Indicates the data source of the hit. Hits sent from analytics.js will have data source | ||
* set to 'web'; hits sent from one of the mobile SDKs will have data source set to 'app'. | ||
* | ||
* - Parameter: **ds** | ||
* - Example value: call center | ||
* - Example usage: ds=call%20center | ||
* | ||
* @return {String} | ||
*/ | ||
get dataSource() { | ||
return this._dataSource; | ||
} | ||
set dataSource(value) { | ||
this._dataSource = value; | ||
this._configureBaseParams(); | ||
} | ||
/** | ||
* Used to send a random number in GET requests to ensure browsers and proxies | ||
* don't cache hits. | ||
* | ||
* - Parameter: **z** | ||
* - Example value: 289372387623 | ||
* - Example usage: z=289372387623 | ||
* | ||
* @return {Boolean} | ||
*/ | ||
get useCacheBooster() { | ||
return this._useCacheBooster; | ||
} | ||
set useCacheBooster(value) { | ||
this._useCacheBooster = value; | ||
} | ||
/** | ||
* Specifies which referral source brought traffic to a website. This value is also used to | ||
* compute the traffic source. The format of this value is a URL. | ||
* | ||
* - Parameter: **dr** | ||
* - Example value: http://example.com | ||
* - Example usage: dr=http%3A%2F%2Fexample.com | ||
* | ||
* @return {String} | ||
*/ | ||
get referrer() { | ||
return this._referrer; | ||
} | ||
set referrer(value) { | ||
this._referrer = value; | ||
this._configureBaseParams(); | ||
} | ||
/** | ||
* Specifies the campaign name. | ||
* | ||
* - Parameter: **cn** | ||
* - Example value: (direct) | ||
* - Example usage: cn=%28direct%29 | ||
* | ||
* @return {String} | ||
*/ | ||
get campaignName() { | ||
return this._campaignName; | ||
} | ||
set campaignName(value) { | ||
this._campaignName = value; | ||
this._configureBaseParams(); | ||
} | ||
/** | ||
* Specifies the campaign source. | ||
* | ||
* - Parameter: **cs** | ||
* - Example value: (direct) | ||
* - Example usage: cs=%28direct%29 | ||
* | ||
* @return {String} | ||
*/ | ||
get campaignSource() { | ||
return this._campaignSource; | ||
} | ||
set campaignSource(value) { | ||
this._campaignSource = value; | ||
this._configureBaseParams(); | ||
} | ||
/** | ||
* Specifies the campaign medium. | ||
* | ||
* - Parameter: **cm** | ||
* - Example value: organic | ||
* - Example usage: cm=organic | ||
* | ||
* @return {String} | ||
*/ | ||
get campaignMedium() { | ||
return this._campaignMedium; | ||
} | ||
set campaignMedium(value) { | ||
this._campaignMedium = value; | ||
this._configureBaseParams(); | ||
} | ||
/** | ||
* Specifies the application version. | ||
* | ||
* - Parameter: **av** | ||
* - Example value: 1.2 | ||
* - Example usage: av=1.2 | ||
* | ||
* @return {String} | ||
*/ | ||
get appVersion() { | ||
return this._appVersion; | ||
} | ||
set appVersion(value) { | ||
this._appVersion = value; | ||
this._configureBaseParams(); | ||
} | ||
/** | ||
* Specifies the application name. This field is required for any hit that has app related | ||
* data (i.e., app version, app ID, or app installer ID). For hits sent to web properties, | ||
* this field is optional. | ||
* | ||
* - Parameter: **an** | ||
* - Example My App | ||
* - Example usage: an=My%20App | ||
* | ||
* @return {String} | ||
*/ | ||
get appName() { | ||
return this._appName; | ||
} | ||
set appName(value) { | ||
this._appName = value; | ||
this._configureBaseParams(); | ||
} | ||
/** | ||
* Application identifier. | ||
* | ||
* - Parameter: **aid** | ||
* - Example value: com.company.app | ||
* - Example usage: aid=com.company.app | ||
* | ||
* @return {String} | ||
*/ | ||
get appId() { | ||
return this._appId; | ||
} | ||
set appId(value) { | ||
this._appId = value; | ||
this._configureBaseParams(); | ||
} | ||
/** | ||
* Application installer identifier. | ||
* | ||
* - Parameter: **aiid** | ||
* - Example value: com.platform.vending | ||
* - Example usage: aiid=com.platform.vending | ||
* | ||
* @return {String} | ||
*/ | ||
get appInstallerId() { | ||
return this._appInstallerId; | ||
} | ||
set appInstallerId(value) { | ||
this._appInstallerId = value; | ||
this._configureBaseParams(); | ||
} | ||
/** | ||
* If set to true it will prints debug messages into the console. | ||
* | ||
* @return {Boolean} | ||
*/ | ||
get debug() { | ||
return this._debug; | ||
} | ||
set debug(value) { | ||
this._debug = value; | ||
} | ||
/** | ||
* If set it will send the data to GA's debug endpoint | ||
* and the request won't be actually saved but only validated | ||
* and the validation results will be fired in the | ||
* `aapp-analytics-structure-debug` | ||
* event in the detail's `debug` property. | ||
* | ||
* @return {Boolean} | ||
*/ | ||
get debugEndpoint() { | ||
return this._debugEndpoint; | ||
} | ||
set debugEndpoint(value) { | ||
this._debugEndpoint = value; | ||
} | ||
/** | ||
* If set disables Google Analytics reporting. | ||
* This information is stored in localStorage. As long as this | ||
* information is not cleared it is respected and data are not send to GA | ||
* server. | ||
* | ||
* @return {Boolean} | ||
*/ | ||
get disabled() { | ||
return this._disabled; | ||
} | ||
set disabled(value) { | ||
this._disabled = value; | ||
this._disabledChanged(value); | ||
} | ||
/** | ||
* When set it queues requests to GA in memory and attempts to send the requests | ||
* again when this flag is removed. | ||
* | ||
* @return {Boolean} | ||
*/ | ||
get offline() { | ||
return this._offline; | ||
} | ||
set offline(value) { | ||
this._offline = value; | ||
this._offlineChanged(value); | ||
} | ||
/** | ||
* Generated POST parameters based on a params | ||
* @return {Object} | ||
*/ | ||
get _baseParams() { | ||
return this.__baseParams; | ||
} | ||
set _baseParams(value) { | ||
this.__baseParams = value; | ||
} | ||
/** | ||
* Each custom metric has an associated index. There is a maximum of 20 custom | ||
* metrics (200 for Analytics 360 accounts). The metric index must be a positive | ||
* integer between 1 and 200, inclusive. | ||
* | ||
* - Parameter: **cm<metricIndex>** | ||
* - Example value: 47 | ||
* - Example usage: cm1=47 | ||
* | ||
* @return {Array<Object>} | ||
*/ | ||
get _customMetrics() { | ||
return this.__customMetrics; | ||
} | ||
set _customMetrics(value) { | ||
this.__customMetrics = value; | ||
} | ||
/** | ||
* Each custom dimension has an associated index. There is a maximum of 20 custom | ||
* dimensions (200 for Analytics 360 accounts). The dimension index must be a positive | ||
* integer between 1 and 200, inclusive. | ||
* | ||
* - Parameter: **cd<dimensionIndex>** | ||
* - Example value: Sports | ||
* - Example usage: cd1=Sports | ||
* | ||
* @return {Array<Object>} | ||
*/ | ||
get _customDimensions() { | ||
return this.__customDimensions; | ||
} | ||
set _customDimensions(value) { | ||
this.__customDimensions = value; | ||
} | ||
/** | ||
* @return {String} Local storage key for clientId. | ||
*/ | ||
get cidKey() { | ||
return 'apic.ga.cid'; | ||
} | ||
/** | ||
* @return {String} Local storage key for disabled. | ||
*/ | ||
get disabledKey() { | ||
return 'apic.ga.disabled'; | ||
} | ||
constructor() { | ||
super(); | ||
this._customPropertyChanged = this._customPropertyChanged.bind(this); | ||
this._customPropertyRemoved = this._customPropertyRemoved.bind(this); | ||
this._sendHandler = this._sendHandler.bind(this); | ||
this._baseParams = {}; | ||
this._customMetrics = []; | ||
this._customDimensions = []; | ||
const config = { | ||
attributes: true, | ||
childList: true, | ||
subtree: true, | ||
attributeOldValue: true | ||
}; | ||
this._observer = new MutationObserver((mutations) => this._childrenUpdated(mutations)); | ||
this._observer.observe(this, config); | ||
this._restoreConfiguration(); | ||
} | ||
connectedCallback() { | ||
super.connectedCallback(); | ||
this.addEventListener('app-analytics-custom-changed', this._customPropertyChanged); | ||
this.addEventListener('app-analytics-custom-removed', this._customPropertyRemoved); | ||
if (!this.hasAttribute('aria-hidden')) { | ||
this.setAttribute('aria-hidden', 'true'); | ||
} | ||
window.addEventListener('send-analytics', this._sendHandler); | ||
this._restoreConfiguration(); | ||
this._observer = new FlattenedNodesObserver(this.shadowRoot.querySelector('slot'), (info) => { | ||
info.addedNodes = info.addedNodes.filter((node) => node.nodeType === Node.ELEMENT_NODE); | ||
info.removedNodes = info.removedNodes.filter((node) => node.nodeType === Node.ELEMENT_NODE); | ||
this._processAddedNodes(info.addedNodes); | ||
this._processRemovedNodes(info.removedNodes); | ||
}); | ||
if (!this.__initialized) { | ||
this.__initialized = true; | ||
setTimeout(() => { | ||
this._processInitialNodes(); | ||
}); | ||
} | ||
} | ||
disconnectedCallback() { | ||
super.disconnectedCallback(); | ||
this.removeEventListener('app-analytics-custom-changed', this._customPropertyChanged); | ||
this.removeEventListener('app-analytics-custom-removed', this._customPropertyRemoved); | ||
window.removeEventListener('send-analytics', this._sendHandler); | ||
this._observer.disconnect(); | ||
this.__uuid = undefined; | ||
} | ||
get cidKey() { | ||
return 'apic.ga.cid'; | ||
/** | ||
* A mutation observer callback function called when children or attributes changed. | ||
* It processes child nodes depending on mutation type and change record. | ||
* @param {Array<MutationRecord>} mutations | ||
*/ | ||
_childrenUpdated(mutations) { | ||
for (const mutation of mutations) { | ||
if (mutation.target === this && mutation.type === 'childList') { | ||
this._processAddedNodes(mutation.addedNodes); | ||
this._processRemovedNodes(mutation.removedNodes); | ||
} else if (mutation.target !== this && mutation.type === 'attributes') { | ||
this._processChildAttribute(mutation); | ||
} | ||
} | ||
} | ||
get disabledKey() { | ||
return 'apic.ga.disabled'; | ||
} | ||
/** | ||
@@ -600,6 +803,7 @@ * Restores data stored in localStorage. | ||
_restoreConfiguration() { | ||
if (this.clientId || !this.hasLocalStorage) { | ||
/* istanbul ignore if */ | ||
if (this.clientId || !hasLocalStorage) { | ||
return; | ||
} | ||
let disabled = localStorage.getItem(this.disabledKey); | ||
const disabled = localStorage.getItem(this.disabledKey); | ||
if (disabled === 'true') { | ||
@@ -612,5 +816,5 @@ this.disabled = true; | ||
if (!cid) { | ||
cid = this.$.uuid.generate(); | ||
cid = this._uuid.generate(); | ||
} | ||
this.set('clientId', cid); | ||
this.clientId = cid; | ||
} | ||
@@ -624,7 +828,8 @@ /** | ||
this._configureBaseParams(); | ||
if (!this.hasLocalStorage) { | ||
/* istanbul ignore if */ | ||
if (!hasLocalStorage) { | ||
return; | ||
} | ||
cid = cid || ''; | ||
let localCid = localStorage.getItem(this.cidKey); | ||
const localCid = localStorage.getItem(this.cidKey); | ||
if (cid !== localCid) { | ||
@@ -646,6 +851,7 @@ localStorage.setItem(this.cidKey, cid); | ||
} | ||
if (!this.hasLocalStorage) { | ||
/* istanbul ignore if */ | ||
if (!hasLocalStorage) { | ||
return; | ||
} | ||
let localState = localStorage.getItem(this.disabledKey); | ||
const localState = localStorage.getItem(this.disabledKey); | ||
if (localState !== String(state)) { | ||
@@ -663,14 +869,16 @@ localStorage.setItem(this.disabledKey, state); | ||
} | ||
nodes.forEach((i) => { | ||
if (i.nodeName !== 'APP-ANALYTICS-CUSTOM') { | ||
return; | ||
for (let i = 0, len = nodes.length; i < len; i++) { | ||
const node = nodes[i]; | ||
if (node.nodeName !== 'APP-ANALYTICS-CUSTOM') { | ||
continue; | ||
} | ||
if (i.index && i.type) { | ||
if (i.type === 'dimension') { | ||
this.addCustomDimension(i.index, i.value); | ||
} else if (i.type === 'metric') { | ||
this.addCustomMetric(i.index, i.value); | ||
node.setAttribute('aria-hidden', 'true'); | ||
if (node.index && node.type) { | ||
if (node.type === 'dimension') { | ||
this.addCustomDimension(node.index, node.value); | ||
} else if (node.type === 'metric') { | ||
this.addCustomMetric(node.index, node.value); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
@@ -689,31 +897,54 @@ /** | ||
} | ||
nodes.forEach((i) => { | ||
if (i.nodeName !== 'APP-ANALYTICS-CUSTOM') { | ||
for (let i = 0, len = nodes.length; i < len; i++) { | ||
const node = nodes[i]; | ||
if (node.nodeName !== 'APP-ANALYTICS-CUSTOM') { | ||
return; | ||
} | ||
if (i.index && i.type) { | ||
if (i.type === 'dimension') { | ||
this.removeCustomDimension(i.index); | ||
} else if (i.type === 'metric') { | ||
this.removeCustomMetric(i.index); | ||
if (node.index && node.type) { | ||
if (node.type === 'dimension') { | ||
this.removeCustomDimension(node.index); | ||
} else if (node.type === 'metric') { | ||
this.removeCustomMetric(node.index); | ||
} | ||
} | ||
}); | ||
} | ||
// Handler for app-analytics-custom-changed event. Registers a new custom property. | ||
_customPropertyChanged(e) { | ||
const d = e.detail; | ||
switch (d.type) { | ||
case 'dimension': this.addCustomDimension(d.index, d.value); break; | ||
case 'metric': this.addCustomMetric(d.index, d.value); break; | ||
} | ||
} | ||
// Handler for app-analytics-custom-removed event. Unregisters a custom property. | ||
_customPropertyRemoved(e) { | ||
e.stopPropagation(); | ||
const {type, index} = e.detail; | ||
switch (type) { | ||
case 'dimension': this.removeCustomDimension(index); break; | ||
case 'metric': this.removeCustomMetric(index); break; | ||
/** | ||
* Processes `MutationRecord` for attribute change | ||
* @param {MutationRecord} mutation A mutation record that triggered the callback | ||
*/ | ||
_processChildAttribute(mutation) { | ||
if (['index', 'value', 'type'].indexOf(mutation.attributeName) === -1) { | ||
return; | ||
} | ||
const target = mutation.target; | ||
const type = target.getAttribute('type'); | ||
const index = Number(target.getAttribute('index')); | ||
if (isNaN(index)) { | ||
return; | ||
} | ||
if (mutation.attributeName === 'type' && mutation.oldValue) { | ||
// Removes old type from the corresponding array. | ||
if (mutation.oldValue === 'dimension') { | ||
this.removeCustomDimension(index); | ||
} else if (mutation.oldValue === 'metric') { | ||
this.removeCustomMetric(index); | ||
} | ||
} else if (mutation.attributeName === 'index' && mutation.oldValue) { | ||
// Removes previously used index from the corresponding array. | ||
const index = Number(mutation.oldValue); | ||
if (!isNaN(index)) { | ||
if (type === 'dimension') { | ||
this.removeCustomDimension(index); | ||
} else if (type === 'metric') { | ||
this.removeCustomMetric(index); | ||
} | ||
} | ||
} | ||
const value = target.getAttribute('value'); | ||
if (type === 'dimension') { | ||
this.addCustomDimension(index, value); | ||
} else if (type === 'metric') { | ||
this.addCustomMetric(index, value); | ||
} | ||
} | ||
@@ -732,22 +963,3 @@ /** | ||
addCustomDimension(index, value) { | ||
index = Number(index); | ||
if (index !== index) { | ||
throw new Error('Index is not a number.'); | ||
} | ||
if (index <= 0 || index > 200) { | ||
throw new Error('Index out of bounds'); | ||
} | ||
const cd = this.customDimensions || []; | ||
const pos = cd.findIndex((i) => i.index === index); | ||
if (pos !== -1) { | ||
if (this.customDimensions[pos].value !== value) { | ||
this.set('customDimensions.' + pos + '.value', value); | ||
} | ||
} else { | ||
this.push('customDimensions', { | ||
index: index, | ||
value: value | ||
}); | ||
} | ||
this._configureBaseParams(); | ||
this._addCustom('_customDimensions', index, value); | ||
} | ||
@@ -760,10 +972,3 @@ /** | ||
removeCustomDimension(index) { | ||
index = Number(index); | ||
const cd = this.customDimensions || []; | ||
const pos = cd.findIndex((i) => i.index === index); | ||
if (pos === -1) { | ||
return; | ||
} | ||
this.splice('customDimensions', pos, 1); | ||
this._configureBaseParams(); | ||
this._removeCustom('_customDimensions', index); | ||
} | ||
@@ -782,18 +987,40 @@ /** | ||
addCustomMetric(index, value) { | ||
if (!isNaN(value)) { | ||
value = Number(value); | ||
} | ||
this._addCustom('_customMetrics', index, value); | ||
} | ||
/** | ||
* Removes from this instance custom metric for given index. | ||
* | ||
* @param {Number} index Index of the custom metric. The index has to be in range 1 - 200. | ||
*/ | ||
removeCustomMetric(index) { | ||
this._removeCustom('_customMetrics', index); | ||
} | ||
/** | ||
* Adds custom metric / dimension to the corresponding array. | ||
* @param {String} prop The name of the property with the array of custom items. | ||
* @param {Number} index Index of the custom property. Free version of GA allows up to 20 | ||
* custom metrics/dimensions and up to 200 in premium. The index has to be in range 1 - 200. | ||
* @param {Strnig} value Value of the custom property to set. | ||
*/ | ||
_addCustom(prop, index, value) { | ||
index = Number(index); | ||
if (index !== index) { | ||
throw new Error('Index is not a number.'); | ||
throw new TypeError('Index is not a number.'); | ||
} | ||
if (index <= 0 || index > 200) { | ||
throw new Error('Index out of bounds'); | ||
throw new RangeError('Index out of bounds'); | ||
} | ||
const cm = this.customMetrics || []; | ||
const pos = cm.findIndex((i) => i.index === index); | ||
const custom = this[prop]; | ||
const pos = custom.findIndex((i) => i.index === index); | ||
if (pos !== -1) { | ||
if (this.customMetrics[pos].value !== value) { | ||
this.set('customMetrics.' + pos + '.value', value); | ||
this._configureBaseParams(); | ||
if (this[prop][pos].value !== value) { | ||
this[prop][pos].value = value; | ||
} else { | ||
return; | ||
} | ||
} else { | ||
this.push('customMetrics', { | ||
this[prop].push({ | ||
index: index, | ||
@@ -806,14 +1033,15 @@ value: value | ||
/** | ||
* Removes from this instance custom metric for given index. | ||
* Removes from this instance custom metric/dimension for given index. | ||
* | ||
* @param {String} prop The name of the property with the array of custom items. | ||
* @param {Number} index Index of the custom metric. The index has to be in range 1 - 200. | ||
*/ | ||
removeCustomMetric(index) { | ||
_removeCustom(prop, index) { | ||
index = Number(index); | ||
const cm = this.customMetrics || []; | ||
const pos = cm.findIndex((i) => i.index === index); | ||
const custom = this[prop]; | ||
const pos = custom.findIndex((i) => i.index === index); | ||
if (pos === -1) { | ||
return; | ||
} | ||
this.splice('customMetrics', pos, 1); | ||
this[prop].splice(pos, 1); | ||
this._configureBaseParams(); | ||
@@ -1008,3 +1236,3 @@ } | ||
this._processParams(params); | ||
const post = Object.assign({}, this.baseParams, params); | ||
const post = Object.assign({}, this._baseParams, params); | ||
const body = this._createBody(post); | ||
@@ -1095,3 +1323,3 @@ if (this.debug) { | ||
const data = { | ||
v: this.protocolVersion, | ||
v: protocolVersion, | ||
tid: this.trackingId, | ||
@@ -1142,9 +1370,9 @@ cid: this.clientId, | ||
} | ||
if (this.customMetrics.length) { | ||
this.customMetrics.forEach((cm) => { | ||
if (this._customMetrics.length) { | ||
this._customMetrics.forEach((cm) => { | ||
data['cm' + cm.index] = this.encodeQueryString(cm.value); | ||
}); | ||
} | ||
if (this.customDimensions.length) { | ||
this.customDimensions.forEach((cd) => { | ||
if (this._customDimensions.length) { | ||
this._customDimensions.forEach((cd) => { | ||
data['cd' + cd.index] = this.encodeQueryString(cd.value); | ||
@@ -1156,3 +1384,3 @@ }); | ||
} | ||
this._setBaseParams(data); | ||
this._baseParams = data; | ||
} | ||
@@ -1164,3 +1392,3 @@ | ||
Object.keys(list).forEach((param) => { | ||
const name = this._paramsMap[param] || param; | ||
const name = paramsMap[param] || param; | ||
const value = decodeURIComponent(list[param]); | ||
@@ -1189,8 +1417,5 @@ map[param] = { | ||
} | ||
const offline = !this.isOnline; | ||
const offline = this.offline; | ||
if (offline) { | ||
if (!this._offlineQueue) { | ||
this._offlineQueue = []; | ||
} | ||
this._offlineQueue.push(body); | ||
offlineQueue.push(body); | ||
return Promise.resolve(); | ||
@@ -1200,3 +1425,3 @@ } | ||
method: 'POST', | ||
headers: {'content-type': 'application/x-www-form-urlencoded'}, | ||
headers: { 'content-type': 'application/x-www-form-urlencoded' }, | ||
body: body | ||
@@ -1218,10 +1443,6 @@ }; | ||
return fetch(url, init) | ||
.then((response) => { | ||
return fetch(url, init).then((response) => { | ||
if (response.status !== 200) { | ||
if (!offline) { | ||
if (!this._offlineQueue) { | ||
this._offlineQueue = []; | ||
} | ||
this._offlineQueue.push(body); | ||
offlineQueue.push(body); | ||
} else { | ||
@@ -1232,4 +1453,3 @@ throw new Error('Unable send data.'); | ||
if (this.debugEndpoint) { | ||
return response.json() | ||
.then((result) => { | ||
return response.json().then((result) => { | ||
this.dispatchEvent(new CustomEvent('app-analytics-structure-debug', { | ||
@@ -1242,9 +1462,5 @@ detail: { | ||
} | ||
}) | ||
.catch(() => { | ||
}).catch(() => { | ||
if (!navigator.onLine && !offline) { | ||
if (!this._offlineQueue) { | ||
this._offlineQueue = []; | ||
} | ||
this._offlineQueue.push(body); | ||
offlineQueue.push(body); | ||
return; | ||
@@ -1256,17 +1472,14 @@ } | ||
_onlineChanged(value) { | ||
if (!value) { | ||
_offlineChanged(value) { | ||
if (value || !offlineQueue.length) { | ||
// Nothing to do when offline of no panding tasks. | ||
return; | ||
} | ||
if (!this._offlineQueue || !this._offlineQueue.length) { | ||
return; | ||
} | ||
const p = []; | ||
for (let i = this._offlineQueue.length - 1; i >= 0; i--) { | ||
const body = this._offlineQueue[i]; | ||
this._offlineQueue.splice(i, 1); | ||
for (let i = offlineQueue.length - 1; i >= 0; i--) { | ||
const body = offlineQueue[i]; | ||
offlineQueue.splice(i, 1); | ||
p[p.length] = this._transport(body); | ||
} | ||
return Promise.all(p) | ||
.catch((cause) => { | ||
return Promise.all(p).catch((cause) => { | ||
console.warn(cause); | ||
@@ -1283,3 +1496,12 @@ }); | ||
} | ||
/** | ||
* MutationObserver initialized in the constructor does not | ||
* triggers changes when the element is initialized. This | ||
* function processes nodes set up declaratively when the element is still | ||
* initializing. | ||
*/ | ||
_processInitialNodes() { | ||
this._processAddedNodes(this.children); | ||
} | ||
} | ||
window.customElements.define('app-analytics', AppAnalytics); |
@@ -278,1 +278,15 @@ <a name="2.0.0"></a> | ||
## [2.0.1](https://github.com/advanced-rest-client/app-analytics/compare/1.0.15...2.0.1) (2019-03-10) | ||
### Fix | ||
* Fixing configuration when disabled/cid changes ([5b2d6e58b833d62e99f7347dad125a937fdc2d2b](https://github.com/advanced-rest-client/app-analytics/commit/5b2d6e58b833d62e99f7347dad125a937fdc2d2b)) | ||
### Update | ||
* Adding type check for localStorage ([040004f363f0374aa05893e8590db610ed6edb00](https://github.com/advanced-rest-client/app-analytics/commit/040004f363f0374aa05893e8590db610ed6edb00)) | ||
* Removed support for disabling GA. Remove element from the DOM instead. ([d6d04a56d63495b3b724f53eb355ccab7ccd46ef](https://github.com/advanced-rest-client/app-analytics/commit/d6d04a56d63495b3b724f53eb355ccab7ccd46ef)) | ||
{ | ||
"name": "@advanced-rest-client/app-analytics", | ||
"description": "An element that support Google Analytics analysis", | ||
"version": "3.0.0", | ||
"license": "Apache-2.0", | ||
"main": "app-analytics.js", | ||
"keywords": [ | ||
"web-components", | ||
"polymer", | ||
"google-analytics", | ||
"analytics" | ||
], | ||
"authors": [ | ||
"Pawel Psztyc", | ||
"The Advanced REST client authors <arc@mulesoft.com>" | ||
], | ||
"contributors": [ | ||
"Pawel Psztyc", | ||
"The Advanced REST client authors <arc@mulesoft.com>" | ||
], | ||
"repository": { | ||
@@ -13,11 +24,23 @@ "type": "git", | ||
}, | ||
"name": "@advanced-rest-client/app-analytics", | ||
"version": "3.0.0-preview.3", | ||
"license": "Apache-2.0", | ||
"bugs": { | ||
"url": "https://github.com/advanced-rest-client/app-analytics/issues", | ||
"email": "arc@mulesoft.com" | ||
}, | ||
"dependencies": { | ||
"@advanced-rest-client/uuid-generator": "^3.0.1" | ||
}, | ||
"devDependencies": { | ||
"@advanced-rest-client/form-action-bar": "^3.0.0-preview.1", | ||
"@advanced-rest-client/paper-fab-menu": "^3.0.0-preview.1", | ||
"@polymer/gen-typescript-declarations": "^1.6.1", | ||
"@polymer/iron-component-page": "^4.0.0", | ||
"@polymer/iron-demo-helpers": "^3.0.0", | ||
"@advanced-rest-client/connectivity-state": "^3.0.0", | ||
"@advanced-rest-client/a11y-suite": "^1.1.0", | ||
"@advanced-rest-client/arc-demo-helper": "^1.0.3", | ||
"@advanced-rest-client/form-action-bar": "^3.0.0", | ||
"@advanced-rest-client/paper-fab-menu": "^3.0.0", | ||
"@advanced-rest-client/testing-karma-sl": "^1.0.2", | ||
"@commitlint/cli": "^8.1.0", | ||
"@commitlint/config-conventional": "^7.0.0", | ||
"@open-wc/eslint-config": "^0.4.1", | ||
"@open-wc/prettier-config": "^0.1.0", | ||
"@open-wc/testing": "^0.11.1", | ||
"@open-wc/testing-karma": "^2.0.6", | ||
"@polymer/gen-typescript-declarations": "^1.6.2", | ||
"@polymer/iron-icons": "^3.0.0", | ||
@@ -34,34 +57,31 @@ "@polymer/iron-pages": "^3.0.0", | ||
"@polymer/paper-toggle-button": "^3.0.0", | ||
"@polymer/test-fixture": "^4.0.2", | ||
"@webcomponents/webcomponentsjs": "^2.0.0", | ||
"chai": "^4.2.0", | ||
"mocha": "^5.2.0", | ||
"husky": "^1.0.0", | ||
"lint-staged": "^8.0.0", | ||
"lit-element": "^2.0.1", | ||
"owc-dev-server": "^1.0.0", | ||
"sinon": "^7.2.3", | ||
"wct-mocha": "^1.0.0", | ||
"web-animations-js": "^2.3.1" | ||
"web-animations-js": "^2.3.1", | ||
"webpack-merge": "^4.1.5" | ||
}, | ||
"main": "app-analytics.js", | ||
"scripts": { | ||
"lint": "polymer lint app-analytics.html", | ||
"test-sauce": "polymer test --plugin sauce --job-name \"app-analytics:local-test\"", | ||
"test": "polymer test --plugin local", | ||
"update-types": "gen-typescript-declarations --deleteExisting --outDir ." | ||
"test": "karma start --coverage", | ||
"update-types": "gen-typescript-declarations --deleteExisting --outDir .", | ||
"start": "owc-dev-server --app-index demo/index.html --open --watch", | ||
"lint:eslint": "eslint --ext .js,.html .", | ||
"format:eslint": "eslint --ext .js,.html . --fix", | ||
"lint:prettier": "prettier \"**/*.js\" --list-different || (echo '↑↑ these files are not prettier formatted ↑↑' && exit 1)", | ||
"format:prettier": "prettier \"**/*.js\" --write", | ||
"lint": "npm run lint:eslint && npm run lint:prettier", | ||
"format": "npm run format:eslint && npm run format:prettier", | ||
"test:watch": "karma start --auto-watch=true --single-run=false", | ||
"test:legacy": "karma start --legacy --coverage", | ||
"test:legacy:watch": "karma start --legacy --auto-watch=true --single-run=false", | ||
"test:sl": "karma start karma.sl.config.js --legacy --coverage" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/advanced-rest-client/app-analytics/issues", | ||
"email": "arc@mulesoft.com" | ||
}, | ||
"authors": [ | ||
"Pawel Psztyc", | ||
"The Advanced REST client authors <arc@mulesoft.com>" | ||
], | ||
"contributors": [ | ||
"Pawel Psztyc", | ||
"The Advanced REST client authors <arc@mulesoft.com>" | ||
], | ||
"dependencies": { | ||
"@advanced-rest-client/connectivity-state": "^3.0.0-preview.1", | ||
"@advanced-rest-client/uuid-generator": "^3.0.0-preview.1", | ||
"@polymer/polymer": "^3.0.0" | ||
"lint-staged": { | ||
"*.js": [ | ||
"eslint --fix", | ||
"git add" | ||
] | ||
} | ||
} |
209
README.md
@@ -5,17 +5,36 @@ [](https://www.npmjs.com/package/@advanced-rest-client/app-analytics) | ||
[](https://www.webcomponents.org/element/advanced-rest-client/app-analytics) | ||
[](https://www.webcomponents.org/element/@advanced-rest-client/app-analytics) | ||
## <app-analytics> | ||
# app-analytics | ||
Event based component to support Google Analystics measurement protocols | ||
Event based component to support Google Analytics measurement protocol. | ||
The component support both imperative and declarative API so it can be used in regular HTML template using your favourite templating engine and in JavaScript. | ||
```html | ||
<app-analytics | ||
tracking-id="UA-XXXXXXX-Y" | ||
app-name="my app" | ||
app-version="1.0.0" | ||
data-source="app-analytics element"></app-analytics> | ||
``` | ||
The `appname` and `trackingid` attributes (`appName` and `trackingId` properties respectively) are required parameters. Without it the element won't initialize a call to GA endpoint. | ||
If `clientid` attribute (`clientId` property) is not set then it generates one automatically and store is in `localStorage`. Note, that if current environment does not support `localStorage` (like Chrome Apps) you need to provide this property manually or otherwise it will be regenerated each time the user opens the app. | ||
Note, Google Analytics does not allow sending any information that may lead to a user. | ||
Always give the user ability to disable tracking. Under EU laws you need to have permission from the user to store data on local device. To disable analytics simply remove the element from the DOM or set `disabled` property. | ||
Note, the `disabled` state is persistent in `localStorage` and automatically restored when element is initialized. If the environment does not support `localStorage` you need to set this attribute manually each time the element is initialized. | ||
## Using events API | ||
You can directly call one of `send*()` functions. See API Reference below for more info. | ||
- <a href="#method-sendEvent">sendEvent</a> | ||
- <a href="#method-sendException">sendException</a> | ||
- <a href="#method-sendScreen">sendScreen</a> | ||
- <a href="#method-sendSocial">sendSocial</a> | ||
- <a href="#method-sendTimings">sendTimings</a> | ||
You can also use HTML events to send a hit. In this case dispatch a `send-analytics` event with required `type` property on the `detail` object which describes what king of hit should be send. Possible values are: `pageview`, `screenview`, `event`, `social`, `exception` or `timing`. | ||
Other parameters depends on the type. | ||
### Sending `screenview` hit | ||
```javascript | ||
@@ -33,43 +52,134 @@ const event = new CustomEvent('send-analytics', { | ||
### API components | ||
#### Sending `event` hit | ||
This components is a part of [API components ecosystem](https://elements.advancedrestclient.com/) | ||
```javascript | ||
const event = new CustomEvent('send-analytics', { | ||
bubbles: true, | ||
composed: true, | ||
detail: { | ||
type: 'event', | ||
category: 'Some category', // required. | ||
action: 'Some action', // required. | ||
label: 'Some label', | ||
value: 123 | ||
} | ||
}); | ||
document.body.dispatchEvent(event); | ||
``` | ||
## Usage | ||
#### Sending `exception` hit | ||
### Installation | ||
```javascript | ||
const event = new CustomEvent('send-analytics', { | ||
bubbles: true, | ||
composed: true, | ||
detail: { | ||
type: 'exception', | ||
description: 'Exception description', // required. | ||
fatal: true, // default false | ||
} | ||
}); | ||
document.body.dispatchEvent(event); | ||
``` | ||
npm install --save @advanced-rest-client/app-analytics | ||
#### Sending `social` hit | ||
```javascript | ||
const event = new CustomEvent('send-analytics', { | ||
bubbles: true, | ||
composed: true, | ||
detail: { | ||
type: 'social', | ||
network: 'Facebook', // required. | ||
action: 'Share', // required | ||
target: 'https://www.shared.com/resource' // required | ||
} | ||
}); | ||
document.body.dispatchEvent(event); | ||
``` | ||
### In an html file | ||
#### Sending `timing` hit | ||
```javascript | ||
const event = new CustomEvent('send-analytics', { | ||
bubbles: true, | ||
composed: true, | ||
detail: { | ||
type: 'timing', | ||
category: 'Bootstrap', // required. | ||
variable: 'databaseInitTime', // required | ||
value: 123, // required | ||
label: 'Optional label' | ||
} | ||
}); | ||
document.body.dispatchEvent(event); | ||
``` | ||
## Custom metrics and dimensions | ||
Use `<app-analytics-custom>` element as a child of `<app-analytics>` to set custom properties. This metrics / dimensions will be used with every hit as long as this elements exists as a children of the `<app-analytics>` element. | ||
### Example | ||
```html | ||
<html> | ||
<head> | ||
<script type="module"> | ||
import '@advanced-rest-client/app-analytics/app-analytics.js'; | ||
</script> | ||
</head> | ||
<body> | ||
<app-analytics></app-analytics> | ||
</body> | ||
</html> | ||
<app-analytics trackingid="UA-XXXXXXX"> | ||
<app-analytics-custom type="metric" index="1" value="5"></app-analytics-custom> | ||
</app-analytics> | ||
``` | ||
### In a Polymer 3 element | ||
To send custom data with single hit only without creating `<app-analytics-custom>` children, add `customDimensions` or `customMetrics` to the event detail object. Both objects must be an array of custom definition objects that includes index and value. | ||
```js | ||
import {PolymerElement, html} from '@polymer/polymer'; | ||
### Example | ||
```javascript | ||
const event = new CustomEvent('send-analytics', { | ||
bubbles: true, | ||
composed: true, | ||
detail: { | ||
type: 'event', | ||
category: 'Engagement', | ||
action: 'Click', | ||
label: 'Movie start', | ||
customDimensions: [{ | ||
index: 1, // index of the custom dimension | ||
value: 'Author name' // Value of the custom dimension | ||
}] | ||
} | ||
}); | ||
document.body.dispatchEvent(event); | ||
``` | ||
## Usage | ||
### In a HTML page | ||
```html | ||
<script type="module" src="@advanced-rest-client/app-analytics/app-analytics.js"></script> | ||
<script type="module" src="@advanced-rest-client/app-analytics/app-analytics-custom.js"></script> | ||
<app-analytics trackingid="UA-XXXXXXX"> | ||
<app-analytics-custom type="metric" index="1" value="5"></app-analytics-custom> | ||
</app-analytics> | ||
``` | ||
### In a LitElement template | ||
```javascript | ||
import { LitElement, html } from 'lit-element'; | ||
import '@advanced-rest-client/app-analytics/app-analytics.js'; | ||
import '@advanced-rest-client/app-analytics/app-analytics-custom.js'; | ||
class SampleElement extends PolymerElement { | ||
static get template() { | ||
class SampleElement extends LitElement { | ||
render() { | ||
return html` | ||
<app-analytics></app-analytics> | ||
<button @click="${this._handler}">Click with action</button> | ||
<app-analytics trackingid="UA-XXXXXXX"> | ||
<app-analytics-custom type="metric" index="1" value="5"></app-analytics-custom> | ||
</app-analytics> | ||
`; | ||
} | ||
_authChanged(e) { | ||
console.log(e.detail); | ||
_handler(e) { | ||
this.shadowRoot.querySelector('app-analytics').sendScreen('Main screen'); | ||
} | ||
@@ -80,9 +190,27 @@ } | ||
### Installation | ||
### Imperative use | ||
```html | ||
<app-analytics trackingid="UA-XXXXXXX"> | ||
<app-analytics-custom type="metric" index="1" value="5"></app-analytics-custom> | ||
</app-analytics> | ||
<script> | ||
{ | ||
document..querySelector('app-analytics').sendScreen('Main screen'); | ||
} | ||
</script> | ||
``` | ||
## New in version 3 | ||
- Dropped support for Polymer library. It is now a plain web component. | ||
- Added `aria-hidden` attribute. | ||
- Removed internal recognition of offline mode. Use `offline` property instead to enable queueing for events to be send when back online. | ||
### Development | ||
```sh | ||
git clone https://github.com/advanced-rest-client/app-analytics | ||
cd api-url-editor | ||
git clone https://github.com/@advanced-rest-client/app-analytics | ||
cd app-analytics | ||
npm install | ||
npm install -g polymer-cli | ||
``` | ||
@@ -93,4 +221,3 @@ | ||
```sh | ||
polymer serve --npm | ||
open http://127.0.0.1:<port>/demo/ | ||
npm start | ||
``` | ||
@@ -100,3 +227,3 @@ | ||
```sh | ||
polymer test --npm | ||
npm test | ||
``` |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
119662
1
9
2234
1
225
31
- Removed@advanced-rest-client/connectivity-state@^3.0.0-preview.1
- Removed@polymer/polymer@^3.0.0
- Removed@advanced-rest-client/connectivity-state@3.0.0(transitive)
- Removed@polymer/polymer@3.5.2(transitive)
- Removed@webcomponents/shadycss@1.11.2(transitive)