@zoho_apptics/apptics-js-sdk 2.0.0-beta → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +111 -5
- package/README.md +399 -300
- package/dist/apptics.esm.min.js +2 -2
- package/dist/apptics.esm.min.js.map +1 -1
- package/dist/apptics.min.js +2 -2
- package/dist/apptics.min.js.map +1 -1
- package/dist/chunks/lifecycle-VYr43KcB.min.js +3 -0
- package/dist/chunks/lifecycle-VYr43KcB.min.js.map +1 -0
- package/dist/cjs/auto-init.d.ts +3 -3
- package/dist/cjs/auto-init.js +1 -1
- package/dist/cjs/core/attempts.js +1 -1
- package/dist/cjs/core/batch.js +2 -1
- package/dist/cjs/core/callsite.d.ts +6 -0
- package/dist/cjs/core/callsite.js +25 -3
- package/dist/cjs/core/consent.d.ts +5 -1
- package/dist/cjs/core/consent.js +8 -6
- package/dist/cjs/core/constants.d.ts +35 -10
- package/dist/cjs/core/constants.js +31 -15
- package/dist/cjs/core/db.d.ts +12 -4
- package/dist/cjs/core/db.js +167 -34
- package/dist/cjs/core/debug.js +1 -1
- package/dist/cjs/core/env.js +1 -1
- package/dist/cjs/core/framework-id.d.ts +1 -1
- package/dist/cjs/core/framework-id.js +3 -3
- package/dist/cjs/core/guard.d.ts +9 -0
- package/dist/cjs/core/guard.js +27 -13
- package/dist/cjs/core/hooks.d.ts +2 -4
- package/dist/cjs/core/hooks.js +2 -3
- package/dist/cjs/core/locks.d.ts +9 -0
- package/dist/cjs/core/locks.js +22 -0
- package/dist/cjs/core/logger.d.ts +3 -4
- package/dist/cjs/core/logger.js +4 -40
- package/dist/cjs/core/state.d.ts +3 -2
- package/dist/cjs/core/state.js +2 -2
- package/dist/cjs/core/storage.d.ts +20 -5
- package/dist/cjs/core/storage.js +115 -17
- package/dist/cjs/core/stylesheet.d.ts +8 -0
- package/dist/cjs/core/stylesheet.js +29 -0
- package/dist/cjs/core/transport.d.ts +2 -0
- package/dist/cjs/core/transport.js +19 -4
- package/dist/cjs/core/utils.js +1 -1
- package/dist/cjs/core/validate.js +2 -2
- package/dist/cjs/device/appversion.d.ts +1 -6
- package/dist/cjs/device/appversion.js +13 -1
- package/dist/cjs/device/index.d.ts +11 -0
- package/dist/cjs/device/index.js +120 -20
- package/dist/cjs/engagement/api-rules.d.ts +32 -67
- package/dist/cjs/engagement/api-rules.js +144 -157
- package/dist/cjs/engagement/auto-api.js +2 -2
- package/dist/cjs/engagement/auto-screen.d.ts +2 -0
- package/dist/cjs/engagement/auto-screen.js +67 -3
- package/dist/cjs/engagement/defined-events.js +1 -1
- package/dist/cjs/engagement/send.js +6 -1
- package/dist/cjs/engagement/session.d.ts +12 -3
- package/dist/cjs/engagement/session.js +161 -25
- package/dist/cjs/engagement/track.js +45 -20
- package/dist/cjs/errors/send.js +1 -1
- package/dist/cjs/errors/track.d.ts +1 -1
- package/dist/cjs/errors/track.js +46 -6
- package/dist/cjs/feedback/controls.d.ts +6 -0
- package/dist/cjs/feedback/controls.js +31 -1
- package/dist/cjs/feedback/index.d.ts +8 -7
- package/dist/cjs/feedback/index.js +32 -13
- package/dist/cjs/feedback/logs.d.ts +10 -5
- package/dist/cjs/feedback/logs.js +52 -13
- package/dist/cjs/feedback/quartz.d.ts +18 -0
- package/dist/cjs/feedback/quartz.js +105 -0
- package/dist/cjs/feedback/send.d.ts +3 -0
- package/dist/cjs/feedback/send.js +28 -3
- package/dist/cjs/feedback/styles.d.ts +10 -0
- package/dist/cjs/feedback/styles.js +8 -0
- package/dist/cjs/feedback/template.d.ts +1 -1
- package/dist/cjs/feedback/template.js +12 -12
- package/dist/cjs/feedback/ui.d.ts +14 -6
- package/dist/cjs/feedback/ui.js +126 -48
- package/dist/cjs/heatmap/send.js +1 -1
- package/dist/cjs/heatmap/track.d.ts +1 -1
- package/dist/cjs/heatmap/track.js +87 -16
- package/dist/cjs/index.d.ts +17 -63
- package/dist/cjs/index.js +104 -92
- package/dist/cjs/lifecycle.d.ts +8 -1
- package/dist/cjs/lifecycle.js +258 -62
- package/dist/cjs/remoteconfig/country.d.ts +4 -0
- package/dist/cjs/remoteconfig/country.js +73 -0
- package/dist/cjs/remoteconfig/custom.d.ts +7 -7
- package/dist/cjs/remoteconfig/custom.js +31 -51
- package/dist/cjs/remoteconfig/evaluate.d.ts +3 -3
- package/dist/cjs/remoteconfig/evaluate.js +56 -43
- package/dist/cjs/remoteconfig/fetch.d.ts +3 -3
- package/dist/cjs/remoteconfig/fetch.js +9 -23
- package/dist/cjs/remoteconfig/index.d.ts +10 -8
- package/dist/cjs/remoteconfig/index.js +65 -39
- package/dist/cjs/remoteconfig/store.js +1 -1
- package/dist/cjs/remoteconfig/tz-countries.d.ts +8 -0
- package/dist/cjs/remoteconfig/tz-countries.js +13 -0
- package/dist/cjs/remotelog/gate.d.ts +2 -11
- package/dist/cjs/remotelog/gate.js +9 -35
- package/dist/cjs/remotelog/index.d.ts +4 -21
- package/dist/cjs/remotelog/logger.d.ts +11 -17
- package/dist/cjs/remotelog/logger.js +30 -58
- package/dist/cjs/remotelog/send.js +10 -10
- package/dist/cjs/remotelogger/index.d.ts +12 -0
- package/dist/cjs/remotelogger/index.js +18 -0
- package/dist/cjs/scheduler.js +2 -2
- package/dist/cjs/types.d.ts +155 -82
- package/dist/cjs/user/index.js +11 -6
- package/dist/esm/auto-init.d.ts +3 -3
- package/dist/esm/auto-init.js +1 -1
- package/dist/esm/core/attempts.js +1 -1
- package/dist/esm/core/batch.js +2 -1
- package/dist/esm/core/callsite.d.ts +6 -0
- package/dist/esm/core/callsite.js +25 -4
- package/dist/esm/core/consent.d.ts +5 -1
- package/dist/esm/core/consent.js +9 -7
- package/dist/esm/core/constants.d.ts +35 -10
- package/dist/esm/core/constants.js +30 -15
- package/dist/esm/core/db.d.ts +12 -4
- package/dist/esm/core/db.js +164 -35
- package/dist/esm/core/debug.js +1 -1
- package/dist/esm/core/env.js +1 -1
- package/dist/esm/core/framework-id.d.ts +1 -1
- package/dist/esm/core/framework-id.js +3 -3
- package/dist/esm/core/guard.d.ts +9 -0
- package/dist/esm/core/guard.js +27 -14
- package/dist/esm/core/hooks.d.ts +2 -4
- package/dist/esm/core/hooks.js +2 -3
- package/dist/esm/core/locks.d.ts +9 -0
- package/dist/esm/core/locks.js +20 -0
- package/dist/esm/core/logger.d.ts +3 -4
- package/dist/esm/core/logger.js +4 -40
- package/dist/esm/core/state.d.ts +3 -2
- package/dist/esm/core/state.js +2 -2
- package/dist/esm/core/storage.d.ts +20 -5
- package/dist/esm/core/storage.js +113 -18
- package/dist/esm/core/stylesheet.d.ts +8 -0
- package/dist/esm/core/stylesheet.js +27 -0
- package/dist/esm/core/transport.d.ts +2 -0
- package/dist/esm/core/transport.js +19 -5
- package/dist/esm/core/utils.js +1 -1
- package/dist/esm/core/validate.js +2 -2
- package/dist/esm/device/appversion.d.ts +1 -6
- package/dist/esm/device/appversion.js +13 -2
- package/dist/esm/device/index.d.ts +11 -0
- package/dist/esm/device/index.js +123 -24
- package/dist/esm/engagement/api-rules.d.ts +32 -67
- package/dist/esm/engagement/api-rules.js +143 -155
- package/dist/esm/engagement/auto-api.js +3 -3
- package/dist/esm/engagement/auto-screen.d.ts +2 -0
- package/dist/esm/engagement/auto-screen.js +67 -4
- package/dist/esm/engagement/defined-events.js +1 -1
- package/dist/esm/engagement/send.js +6 -1
- package/dist/esm/engagement/session.d.ts +12 -3
- package/dist/esm/engagement/session.js +162 -29
- package/dist/esm/engagement/track.js +52 -27
- package/dist/esm/errors/send.js +1 -1
- package/dist/esm/errors/track.d.ts +1 -1
- package/dist/esm/errors/track.js +46 -6
- package/dist/esm/feedback/controls.d.ts +6 -0
- package/dist/esm/feedback/controls.js +31 -2
- package/dist/esm/feedback/index.d.ts +8 -7
- package/dist/esm/feedback/index.js +34 -13
- package/dist/esm/feedback/logs.d.ts +10 -5
- package/dist/esm/feedback/logs.js +54 -15
- package/dist/esm/feedback/quartz.d.ts +18 -0
- package/dist/esm/feedback/quartz.js +99 -0
- package/dist/esm/feedback/send.d.ts +3 -0
- package/dist/esm/feedback/send.js +28 -5
- package/dist/esm/feedback/styles.d.ts +10 -0
- package/dist/esm/feedback/styles.js +4 -0
- package/dist/esm/feedback/template.d.ts +1 -1
- package/dist/esm/feedback/template.js +12 -12
- package/dist/esm/feedback/ui.d.ts +14 -6
- package/dist/esm/feedback/ui.js +126 -49
- package/dist/esm/heatmap/send.js +1 -1
- package/dist/esm/heatmap/track.d.ts +1 -1
- package/dist/esm/heatmap/track.js +87 -16
- package/dist/esm/index.d.ts +17 -63
- package/dist/esm/index.js +108 -80
- package/dist/esm/lifecycle.d.ts +8 -1
- package/dist/esm/lifecycle.js +266 -71
- package/dist/esm/remoteconfig/country.d.ts +4 -0
- package/dist/esm/remoteconfig/country.js +70 -0
- package/dist/esm/remoteconfig/custom.d.ts +7 -7
- package/dist/esm/remoteconfig/custom.js +32 -52
- package/dist/esm/remoteconfig/evaluate.d.ts +3 -3
- package/dist/esm/remoteconfig/evaluate.js +57 -44
- package/dist/esm/remoteconfig/fetch.d.ts +3 -3
- package/dist/esm/remoteconfig/fetch.js +9 -23
- package/dist/esm/remoteconfig/index.d.ts +10 -8
- package/dist/esm/remoteconfig/index.js +66 -40
- package/dist/esm/remoteconfig/store.js +1 -1
- package/dist/esm/remoteconfig/tz-countries.d.ts +8 -0
- package/dist/esm/remoteconfig/tz-countries.js +11 -0
- package/dist/esm/remotelog/gate.d.ts +2 -11
- package/dist/esm/remotelog/gate.js +10 -32
- package/dist/esm/remotelog/index.d.ts +4 -21
- package/dist/esm/remotelog/logger.d.ts +11 -17
- package/dist/esm/remotelog/logger.js +32 -60
- package/dist/esm/remotelog/send.js +12 -12
- package/dist/esm/remotelogger/index.d.ts +12 -0
- package/dist/esm/remotelogger/index.js +13 -0
- package/dist/esm/scheduler.js +2 -2
- package/dist/esm/types.d.ts +155 -82
- package/dist/esm/user/index.js +12 -6
- package/dist/feedback.esm.min.js +2 -2
- package/dist/feedback.esm.min.js.map +1 -1
- package/package.json +14 -16
- package/dist/chunks/batch-BU_mTpm1.min.js +0 -3
- package/dist/chunks/batch-BU_mTpm1.min.js.map +0 -1
- package/dist/chunks/logs-Bea5zUW_.min.js +0 -3
- package/dist/chunks/logs-Bea5zUW_.min.js.map +0 -1
- package/dist/cjs/heatmap/index.d.ts +0 -16
- package/dist/cjs/heatmap/index.js +0 -22
- package/dist/cjs/remotelog/index.js +0 -55
- package/dist/esm/heatmap/index.d.ts +0 -16
- package/dist/esm/heatmap/index.js +0 -17
- package/dist/esm/remotelog/index.js +0 -51
- package/dist/heatmap.esm.min.js +0 -3
- package/dist/heatmap.esm.min.js.map +0 -1
- package/dist/style.css +0 -1
package/dist/cjs/lifecycle.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var constants = require('./core/constants.js');
|
|
@@ -9,7 +9,6 @@ var storage = require('./core/storage.js');
|
|
|
9
9
|
var hooks = require('./core/hooks.js');
|
|
10
10
|
var debug = require('./core/debug.js');
|
|
11
11
|
var env = require('./core/env.js');
|
|
12
|
-
var consent = require('./core/consent.js');
|
|
13
12
|
var index = require('./device/index.js');
|
|
14
13
|
var appversion = require('./device/appversion.js');
|
|
15
14
|
var session = require('./engagement/session.js');
|
|
@@ -18,10 +17,10 @@ var autoScreen = require('./engagement/auto-screen.js');
|
|
|
18
17
|
var track = require('./engagement/track.js');
|
|
19
18
|
var track$1 = require('./errors/track.js');
|
|
20
19
|
var scheduler = require('./scheduler.js');
|
|
21
|
-
require('./remotelog/
|
|
20
|
+
var send = require('./remotelog/send.js');
|
|
22
21
|
var index$1 = require('./user/index.js');
|
|
23
22
|
var attempts = require('./core/attempts.js');
|
|
24
|
-
var
|
|
23
|
+
var frameworkId = require('./core/framework-id.js');
|
|
25
24
|
|
|
26
25
|
let listenersAttached = false;
|
|
27
26
|
/** The config init() was last called with; reset() starts again from it. */
|
|
@@ -40,16 +39,29 @@ function isBrowser() {
|
|
|
40
39
|
}
|
|
41
40
|
}
|
|
42
41
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
42
|
+
* The config as the SDK keeps it: base_url, auth_key and app_domain under their inside names
|
|
43
|
+
* (serviceUrl, zak, identifier; see CONFIG_KEYS), and appversion as text. An earlier name of a
|
|
44
|
+
* key is still read when the key itself is not given, with a warning naming the key to use.
|
|
45
|
+
* The base url loses any trailing slash, because request paths add their own.
|
|
46
46
|
*/
|
|
47
47
|
function normaliseConfig(config) {
|
|
48
48
|
var settings = Object.assign({}, config);
|
|
49
|
-
Object.keys(constants.
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
Object.keys(constants.CONFIG_KEYS).forEach(function (key) {
|
|
50
|
+
var inside = constants.CONFIG_KEYS[key];
|
|
51
|
+
if (!utils.isEmpty(config[key])) {
|
|
52
|
+
settings[inside] = config[key];
|
|
53
|
+
return;
|
|
52
54
|
}
|
|
55
|
+
delete settings[inside];
|
|
56
|
+
Object.keys(constants.RETIRED_CONFIG_NAMES).forEach(function (old) {
|
|
57
|
+
if (constants.RETIRED_CONFIG_NAMES[old] !== key || utils.isEmpty(config[old])) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
logger.warnAlways('Apptics.init: ' + old + ' is now ' + key + '; rename it in your config'); // no i18n
|
|
61
|
+
if (utils.isEmpty(settings[inside])) {
|
|
62
|
+
settings[inside] = config[old];
|
|
63
|
+
}
|
|
64
|
+
});
|
|
53
65
|
});
|
|
54
66
|
if (!utils.isEmpty(settings.serviceUrl)) {
|
|
55
67
|
settings.serviceUrl = String(settings.serviceUrl).replace(/\/+$/, ''); // no i18n
|
|
@@ -75,21 +87,51 @@ const APPVERSION_PLACEHOLDERS = ['YOUR_APP_VERSION', 'YOUR_BUILD_OR_APP_VERSION'
|
|
|
75
87
|
function isAppVersionPlaceholder(version) {
|
|
76
88
|
return APPVERSION_PLACEHOLDERS.indexOf(version.toUpperCase()) !== -1;
|
|
77
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* The framework id this SDK reports to serviceUrl. The id built into the package is the one
|
|
92
|
+
* sdk-apptics.zoho.com issued at publish time, and localzoho servers don't know it: any
|
|
93
|
+
* localzoho serviceUrl reports 5970 instead, the id apptics.localzoho.com issued for 2.0.0-beta
|
|
94
|
+
* (Browser), so the same package also runs there.
|
|
95
|
+
*/
|
|
96
|
+
const LOCALZOHO_FRAMEWORK_ID = 5970;
|
|
97
|
+
function frameworkIdFor(serviceUrl) {
|
|
98
|
+
var host = serviceUrl;
|
|
99
|
+
try {
|
|
100
|
+
host = new URL(serviceUrl).hostname;
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
// not a url: judge the text as it is
|
|
104
|
+
}
|
|
105
|
+
return host.indexOf('localzoho') !== -1 ? LOCALZOHO_FRAMEWORK_ID : frameworkId.FRAMEWORK_ID; // no i18n
|
|
106
|
+
}
|
|
78
107
|
/** Which app this browser's stored data belongs to, before app/addversion has named it. */
|
|
79
108
|
function appKey(settings) {
|
|
80
109
|
return settings.serviceUrl + '|' + settings.identifier; // no i18n
|
|
81
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* The app version stored data belongs to, read before app/addversion replaces it: what tells a
|
|
113
|
+
* new release of the app from a reload. '' on a first visit.
|
|
114
|
+
*/
|
|
115
|
+
var previousAppVersion = ''; // no i18n
|
|
82
116
|
/**
|
|
83
117
|
* Data stored for another app on this origin is discarded before anything else reads it,
|
|
84
118
|
* including the stored app/addversion answer that would otherwise hand out that app's ids.
|
|
85
119
|
*/
|
|
86
120
|
function discardOtherAppData(settings) {
|
|
87
|
-
|
|
121
|
+
// which app it is, and which version, are in app_version_info (serviceUrl, identifier and
|
|
122
|
+
// appversion): no keys of their own. 2.0.0-beta's appkey and appversion are read this once
|
|
123
|
+
var info = storage.user_defaults.item('app_version_info') || {}; // no i18n
|
|
124
|
+
var stored = !utils.isEmpty(info.serviceUrl) && !utils.isEmpty(info.identifier)
|
|
125
|
+
? appKey(info)
|
|
126
|
+
: storage.user_defaults.item('appkey'); // no i18n
|
|
127
|
+
previousAppVersion = String((!utils.isEmpty(info.appversion) ? info.appversion : storage.user_defaults.item('appversion')) || ''); // no i18n
|
|
128
|
+
storage.user_defaults.add('appkey', undefined); // no i18n
|
|
129
|
+
storage.user_defaults.add('appversion', undefined); // no i18n
|
|
88
130
|
if (!utils.isEmpty(stored) && stored !== appKey(settings)) {
|
|
89
131
|
logger.Console.log('init: stored data belongs to another app, resetting'); // no i18n
|
|
90
132
|
clearStorage();
|
|
133
|
+
previousAppVersion = ''; // no i18n
|
|
91
134
|
}
|
|
92
|
-
storage.user_defaults.add('appkey', appKey(settings)); // no i18n
|
|
93
135
|
}
|
|
94
136
|
/**
|
|
95
137
|
* Timing an app may tune in init(). Each has a range: a value outside it is ignored with a
|
|
@@ -142,18 +184,18 @@ function clearStorage() {
|
|
|
142
184
|
/**
|
|
143
185
|
* Starts the SDK. The config object is required: pass it directly, or let the console snippet
|
|
144
186
|
* supply it (auto-init reads window.appticssettings._defaultoptions and calls init with it).
|
|
145
|
-
* Returns true when the config has
|
|
187
|
+
* Returns true when the config has base_url, auth_key, app_domain and appversion and start-up has
|
|
146
188
|
* begun (see ready()), false when it was already running, the config is missing or incomplete, or
|
|
147
189
|
* there is no browser. Start-up calls app/addversion with those four, which answers with aaid, the
|
|
148
190
|
* portal and project ids and the rest; then device/add registers the browser, as in 1.x.
|
|
149
191
|
*/
|
|
150
192
|
function init(config) {
|
|
151
193
|
if (!config || typeof config !== 'object') { // no i18n
|
|
152
|
-
logger.warnAlways('Apptics.init: a config object is required, e.g.
|
|
194
|
+
logger.warnAlways('Apptics.init: a config object is required, e.g. Apptics.init({ base_url, auth_key, app_domain, appversion })'); // no i18n
|
|
153
195
|
return false;
|
|
154
196
|
}
|
|
155
197
|
if (state._ZAP._initialised) {
|
|
156
|
-
logger.Console.warn('Apptics.init: already initialised; call
|
|
198
|
+
logger.Console.warn('Apptics.init: already initialised; call Apptics.reset() to start again'); // no i18n
|
|
157
199
|
return false;
|
|
158
200
|
}
|
|
159
201
|
if (!isBrowser()) {
|
|
@@ -162,7 +204,7 @@ function init(config) {
|
|
|
162
204
|
}
|
|
163
205
|
var settings = normaliseConfig(config);
|
|
164
206
|
var missing = constants.REQUIRED_CONFIG.filter(function (key) {
|
|
165
|
-
return utils.isEmpty(settings[key]);
|
|
207
|
+
return utils.isEmpty(settings[constants.CONFIG_KEYS[key] || key]);
|
|
166
208
|
});
|
|
167
209
|
if (missing.length > 0) {
|
|
168
210
|
logger.warnAlways('Apptics.init: missing required config: ' + missing.join(', ')); // no i18n
|
|
@@ -176,16 +218,14 @@ function init(config) {
|
|
|
176
218
|
state._ZAP._defaultoptions = settings;
|
|
177
219
|
// every request goes to serviceUrl; there is no other host to learn about
|
|
178
220
|
state._ZAP._defaultoptions.base_domain = settings.serviceUrl;
|
|
221
|
+
// decided per init(), so a reset() or a page on another host never keeps the last one
|
|
222
|
+
state._ZAP._frameworkID = frameworkIdFor(settings.serviceUrl);
|
|
179
223
|
// marks the SDK as started for the checks that need it; app/addversion replaces it with aaid
|
|
180
224
|
state._ZAP._token = settings.identifier;
|
|
181
225
|
// console_log: the SDK's own activity in the browser console
|
|
182
226
|
if (!utils.isEmpty(config.console_log)) {
|
|
183
227
|
state._ZAP._config.debug = !!config.console_log;
|
|
184
228
|
}
|
|
185
|
-
// track_session: false records no sessions, as Android's automaticSessionsTrackingStatus
|
|
186
|
-
state._ZAP._config.track_session = typeof config.track_session === 'boolean' ? config.track_session : constants.AP_CONFIG.track_session; // no i18n
|
|
187
|
-
// show_logs: the app's own logger lines in the browser console, as Android's showLogs
|
|
188
|
-
state._ZAP._config.show_logs = typeof config.show_logs === 'boolean' ? config.show_logs : constants.AP_CONFIG.show_logs; // no i18n
|
|
189
229
|
if (typeof config.ignore_do_not_track === 'boolean') { // no i18n
|
|
190
230
|
state._ZAP._config.ignore_do_not_track = config.ignore_do_not_track;
|
|
191
231
|
}
|
|
@@ -198,10 +238,14 @@ function init(config) {
|
|
|
198
238
|
debug.applyDebugConfig(state._ZAP._config.debug_api);
|
|
199
239
|
// what to call this device in the debug stream; see devicename in core/transport.ts
|
|
200
240
|
state._ZAP._config.device_name = typeof config.device_name === 'string' ? config.device_name : constants.AP_CONFIG.device_name; // no i18n
|
|
201
|
-
//
|
|
202
|
-
|
|
203
|
-
if (
|
|
204
|
-
|
|
241
|
+
// the SDK no longer reports its own failures to the Remote Logger page: only the lines an app
|
|
242
|
+
// logs with AppticsLogger go there
|
|
243
|
+
if (config.remote_log !== undefined) {
|
|
244
|
+
logger.warnAlways('Apptics.init: remote_log is no longer read; the Remote Logger page shows the lines your app logs with AppticsLogger'); // no i18n
|
|
245
|
+
}
|
|
246
|
+
// AppticsLogger lines go to the Remote Logger page only, never to the browser console
|
|
247
|
+
if (config.show_logs !== undefined) {
|
|
248
|
+
logger.warnAlways('Apptics.init: show_logs is no longer read; AppticsLogger lines are not printed to the browser console'); // no i18n
|
|
205
249
|
}
|
|
206
250
|
// automatic api tracking: the app's own requests, wrapped. Which hosts it records is
|
|
207
251
|
// configureApiTracking's to say; the two keys that once did it are refused out loud rather
|
|
@@ -209,22 +253,38 @@ function init(config) {
|
|
|
209
253
|
state._ZAP._config.track_api = constants.AP_CONFIG.track_api;
|
|
210
254
|
['track_api_hosts', 'track_api_exclude_hosts'].forEach(function (key) {
|
|
211
255
|
if (config[key] !== undefined) {
|
|
212
|
-
logger.warnAlways('Apptics.init: ' + key + ' is no longer supported; use
|
|
256
|
+
logger.warnAlways('Apptics.init: ' + key + ' is no longer supported; use AppticsApi.configure(new AppticsApi.ApiTrackingBuilder().' // no i18n
|
|
213
257
|
+ (key === 'track_api_hosts' ? 'allowOnlyDomains' : 'ignoreDomains') + '(...).build())'); // no i18n
|
|
214
258
|
}
|
|
215
259
|
});
|
|
260
|
+
// screen recording is set up in the console now, and arrives with getsdkconfig
|
|
261
|
+
['DC', 'quartz_workspace_key', 'quartz_department_key'].forEach(function (key) {
|
|
262
|
+
if (config[key] !== undefined) {
|
|
263
|
+
logger.warnAlways('Apptics.init: ' + key + ' is no longer read; screen recording in the feedback form is set up from the Apptics console'); // no i18n
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
// sessions are what everything else is recorded in; an app that wants nothing tracked uses
|
|
267
|
+
// AppticsSettings.setTrackingStatus instead
|
|
268
|
+
if (config.track_session !== undefined) {
|
|
269
|
+
logger.warnAlways('Apptics.init: track_session is no longer read; sessions are always recorded. To stop tracking, use AppticsSettings.setTrackingStatus(AppticsSettings.AP_TRACKING_STATUS.NO_TRACKING)'); // no i18n
|
|
270
|
+
}
|
|
216
271
|
if (typeof config.track_api === 'boolean') { // no i18n
|
|
217
272
|
state._ZAP._config.track_api = config.track_api;
|
|
218
273
|
}
|
|
219
274
|
autoApi.enableApiTracking(state._ZAP._config.track_api);
|
|
220
|
-
// heatmap capture:
|
|
275
|
+
// heatmap capture: switched through the hook heatmap/track.ts sets
|
|
221
276
|
state._ZAP._config.track_heatmap = typeof config.track_heatmap === 'boolean' // no i18n
|
|
222
277
|
? config.track_heatmap
|
|
223
278
|
: constants.AP_CONFIG.track_heatmap;
|
|
224
|
-
hooks.hooks.
|
|
279
|
+
hooks.hooks.trackHeatmap(state._ZAP._config.track_heatmap);
|
|
225
280
|
// automatic screen tracking, on unless the config says false: switched on by start(), once a
|
|
226
281
|
// screen view can be stored
|
|
227
282
|
state._ZAP._config.track_screen = typeof config.track_screen === 'boolean' ? config.track_screen : constants.AP_CONFIG.track_screen; // no i18n
|
|
283
|
+
state._ZAP._config.screen_routes = screenRouteRules(config.screen_routes);
|
|
284
|
+
// a theme in the config wins; without one, what AppticsFeedback.setFeedbackTheme set stays
|
|
285
|
+
if (config.feedback_theme === 'light' || config.feedback_theme === 'dark' || config.feedback_theme === 'auto') { // no i18n
|
|
286
|
+
state._ZAP._config.feedback_theme = config.feedback_theme;
|
|
287
|
+
}
|
|
228
288
|
applyIntervals(config);
|
|
229
289
|
lastConfig = config;
|
|
230
290
|
state._ZAP._initialised = true;
|
|
@@ -250,6 +310,23 @@ function init(config) {
|
|
|
250
310
|
if (myGeneration !== generation) {
|
|
251
311
|
return false;
|
|
252
312
|
}
|
|
313
|
+
if (!registered && appversion.appVersionFailedForNetwork()) {
|
|
314
|
+
// a first visit with no network: start once it is back, keeping what the app
|
|
315
|
+
// tracks until then queued, rather than giving up for the rest of the page
|
|
316
|
+
logger.warnAlways('Apptics.init: offline, so app/addversion is tried again when the browser is back online; calls made until then are kept'); // no i18n
|
|
317
|
+
return registerWhenOnline(myGeneration).then(function (ok) {
|
|
318
|
+
if (myGeneration !== generation) {
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
if (!ok) {
|
|
322
|
+
state._ZAP._initialised = false;
|
|
323
|
+
state._ZAP._token = ''; // no i18n
|
|
324
|
+
state._ZAP._pending = [];
|
|
325
|
+
return false;
|
|
326
|
+
}
|
|
327
|
+
return start(config, myGeneration);
|
|
328
|
+
});
|
|
329
|
+
}
|
|
253
330
|
if (!registered) {
|
|
254
331
|
logger.warnAlways('Apptics.init: app/addversion did not return the app ids, not starting'); // no i18n
|
|
255
332
|
state._ZAP._initialised = false;
|
|
@@ -265,42 +342,137 @@ function init(config) {
|
|
|
265
342
|
});
|
|
266
343
|
return true;
|
|
267
344
|
}
|
|
345
|
+
/** How often a start-up waiting on the network tries app/addversion again, besides on `online`. */
|
|
346
|
+
const OFFLINE_RETRY_MS = 60 * 1000;
|
|
347
|
+
/**
|
|
348
|
+
* app/addversion again once the network is back: on the `online` event, and every minute for a
|
|
349
|
+
* network that came back without one. Resolves true once registered, false when the server
|
|
350
|
+
* refuses it or a reset()/new init() took over.
|
|
351
|
+
*/
|
|
352
|
+
function registerWhenOnline(myGeneration) {
|
|
353
|
+
return new Promise(function (resolve) {
|
|
354
|
+
var timer = null;
|
|
355
|
+
var trying = false;
|
|
356
|
+
function done(ok) {
|
|
357
|
+
window.removeEventListener('online', attempt); // no i18n
|
|
358
|
+
if (timer !== null)
|
|
359
|
+
clearInterval(timer);
|
|
360
|
+
resolve(ok);
|
|
361
|
+
}
|
|
362
|
+
function attempt() {
|
|
363
|
+
if (myGeneration !== generation) {
|
|
364
|
+
done(false);
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
if (trying || navigator.onLine === false) {
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
trying = true;
|
|
371
|
+
appversion.registerAppVersion().then(function (registered) {
|
|
372
|
+
trying = false;
|
|
373
|
+
if (registered) {
|
|
374
|
+
done(true);
|
|
375
|
+
}
|
|
376
|
+
else if (!appversion.appVersionFailedForNetwork()) {
|
|
377
|
+
logger.warnAlways('Apptics.init: app/addversion did not return the app ids, not starting'); // no i18n
|
|
378
|
+
done(false);
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
window.addEventListener('online', attempt); // no i18n
|
|
383
|
+
timer = setInterval(attempt, OFFLINE_RETRY_MS);
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* screen_routes as init() keeps it: each entry checked, an exact path cleaned up, a regex given as
|
|
388
|
+
* a string compiled. An entry that cannot be used is left out, and said, rather than matching
|
|
389
|
+
* something its author did not mean.
|
|
390
|
+
*/
|
|
391
|
+
function screenRouteRules(routes) {
|
|
392
|
+
if (!Array.isArray(routes)) {
|
|
393
|
+
return [];
|
|
394
|
+
}
|
|
395
|
+
var out = [];
|
|
396
|
+
routes.forEach(function (route) {
|
|
397
|
+
if (typeof route === 'string') { // no i18n
|
|
398
|
+
if (route.trim() !== '') { // no i18n
|
|
399
|
+
out.push({ kind: 'pattern', pattern: route.trim() }); // no i18n
|
|
400
|
+
}
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
var rule = route && typeof route === 'object' ? route : null; // no i18n
|
|
404
|
+
var name = rule && typeof rule.name === 'string' ? rule.name.trim() : ''; // no i18n
|
|
405
|
+
if (rule && name !== '' && typeof rule.equals === 'string' && rule.equals.trim() !== '') { // no i18n
|
|
406
|
+
out.push({ kind: 'equals', path: autoScreen.routePath(rule.equals.trim()), name: name }); // no i18n
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
if (rule && name !== '' && rule.regex !== undefined) {
|
|
410
|
+
var regex = null;
|
|
411
|
+
if (rule.regex instanceof RegExp) {
|
|
412
|
+
regex = rule.regex;
|
|
413
|
+
}
|
|
414
|
+
else if (typeof rule.regex === 'string' && rule.regex !== '') { // no i18n
|
|
415
|
+
try {
|
|
416
|
+
regex = new RegExp(rule.regex);
|
|
417
|
+
}
|
|
418
|
+
catch (err) {
|
|
419
|
+
regex = null;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
if (regex) {
|
|
423
|
+
out.push({ kind: 'regex', regex: regex, name: name }); // no i18n
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
logger.warnAlways('Apptics.init: screen_routes entry ' + safeJson(route) + ' is left out: give a route pattern, { equals, name } or { regex, name }'); // no i18n
|
|
428
|
+
});
|
|
429
|
+
return out;
|
|
430
|
+
}
|
|
431
|
+
/** An entry as the warning shows it: a RegExp as its source, which JSON.stringify would hide. */
|
|
432
|
+
function safeJson(value) {
|
|
433
|
+
try {
|
|
434
|
+
return JSON.stringify(value, function (_key, one) { return one instanceof RegExp ? String(one) : one; }) || String(value);
|
|
435
|
+
}
|
|
436
|
+
catch (err) {
|
|
437
|
+
return String(value);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
268
440
|
/** Resolves true once start-up has finished, false if init() refused or storage is unusable. */
|
|
269
441
|
function ready() {
|
|
270
442
|
return state._ZAP._readyPromise || Promise.resolve(false);
|
|
271
443
|
}
|
|
272
444
|
function start(config, myGeneration) {
|
|
445
|
+
// this tab's lock, before any screen view: it is how other tabs tell this one is still open
|
|
446
|
+
session.holdTabLock();
|
|
273
447
|
// app/addversion named the app; data stored for another one was discarded before it ran
|
|
274
448
|
state._ZAP._token = String(state._ZAP._defaultoptions.aaid);
|
|
275
|
-
storage.user_defaults.add('token', state._ZAP._token); // no i18n
|
|
276
449
|
// last known server settings (getupdates) apply before anything is tracked
|
|
277
450
|
index.restoreServerSettings();
|
|
278
|
-
//
|
|
279
|
-
//
|
|
280
|
-
|
|
281
|
-
var uuid = storage.user_defaults.item('uuid'); // no i18n
|
|
282
|
-
if (utils.isEmpty(uuid)) {
|
|
283
|
-
uuid = utils.getNewUUID();
|
|
284
|
-
storage.user_defaults.add('uuid', uuid); // no i18n
|
|
285
|
-
}
|
|
286
|
-
state._ZAP._uuid = uuid;
|
|
287
|
-
var stored_appversion = storage.user_defaults.item('appversion'); // no i18n
|
|
288
|
-
if (utils.isEmpty(stored_appversion)) {
|
|
289
|
-
storage.user_defaults.add('appversion', state._ZAP._defaultoptions.appversion); // no i18n
|
|
290
|
-
stored_appversion = state._ZAP._defaultoptions.appversion;
|
|
291
|
-
}
|
|
292
|
-
var appVersionChanged = stored_appversion != state._ZAP._defaultoptions.appversion;
|
|
451
|
+
// a new release of the app, against the version the stored data was for (see
|
|
452
|
+
// discardOtherAppData): a first visit has none, and is no change
|
|
453
|
+
var appVersionChanged = previousAppVersion !== '' && previousAppVersion != state._ZAP._defaultoptions.appversion; // no i18n
|
|
293
454
|
state._ZAP._ignoreDnt = state._ZAP._config.ignore_do_not_track;
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
//
|
|
298
|
-
|
|
455
|
+
// the visitor's own stored choice, not getTrackingStatus(): that answers NO_TRACKING while Do
|
|
456
|
+
// Not Track is on, and storing it made one such visit switch tracking off for good
|
|
457
|
+
storage.tracking_preference.update_status(storage.tracking_preference.opt_in_status());
|
|
458
|
+
// the uuid and device info, and a registration on a first visit, under a lock shared with the
|
|
459
|
+
// site's other tabs (see prepareDevice)
|
|
460
|
+
return index.prepareDevice().then(function () {
|
|
461
|
+
if (myGeneration !== generation) {
|
|
462
|
+
return false;
|
|
463
|
+
}
|
|
464
|
+
return startTracking(appVersionChanged, myGeneration);
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
/** The rest of start-up, once the device is set up. */
|
|
468
|
+
function startTracking(appVersionChanged, myGeneration) {
|
|
469
|
+
// no getsdkconfig here, straight after app/addversion: it is asked for once device/add has
|
|
470
|
+
// succeeded (registerDeviceWithApptics), then every getupdates_interval. A returning visit
|
|
471
|
+
// starts from the settings saved by the last one (restoreServerSettings, in start())
|
|
299
472
|
if (appVersionChanged) {
|
|
300
473
|
state._ZAP._device_info.appversionid = ''; // no i18n
|
|
301
474
|
index.updateDeviceWithApptics(state._ZAP._device_info).then(function (result) {
|
|
302
475
|
if (utils.isSuccess(result)) {
|
|
303
|
-
storage.user_defaults.add('appversion', state._ZAP._defaultoptions.appversion); // no i18n
|
|
304
476
|
logger.Console.log('init: appversion updated to ' + state._ZAP._defaultoptions.appversion); // no i18n
|
|
305
477
|
}
|
|
306
478
|
}).catch(function (err) {
|
|
@@ -351,7 +523,7 @@ function reset() {
|
|
|
351
523
|
autoApi.enableApiTracking(false);
|
|
352
524
|
autoScreen.enableScreenTracking(false);
|
|
353
525
|
appversion.clearAppVersion();
|
|
354
|
-
hooks.hooks.
|
|
526
|
+
hooks.hooks.trackHeatmap(false);
|
|
355
527
|
hooks.hooks.resetHeatmap();
|
|
356
528
|
hooks.hooks.resetRemoteConfig();
|
|
357
529
|
clearStorage();
|
|
@@ -367,7 +539,7 @@ function reset() {
|
|
|
367
539
|
state._ZAP._apid = ''; // no i18n
|
|
368
540
|
state._ZAP._mapid = ''; // no i18n
|
|
369
541
|
state._ZAP._sending = false;
|
|
370
|
-
logger.Console.log('
|
|
542
|
+
logger.Console.log('Apptics.reset()'); // no i18n
|
|
371
543
|
// start again with the config init() was called with
|
|
372
544
|
if (lastConfig) {
|
|
373
545
|
init(lastConfig);
|
|
@@ -376,7 +548,20 @@ function reset() {
|
|
|
376
548
|
function isActive() {
|
|
377
549
|
return state._ZAP._ready;
|
|
378
550
|
}
|
|
379
|
-
|
|
551
|
+
/**
|
|
552
|
+
* A click-tracking attribute, in either spelling: `apeventaction`, or `data-apeventaction`, which
|
|
553
|
+
* is valid HTML and what React and TypeScript accept without declaring the attribute.
|
|
554
|
+
*/
|
|
555
|
+
function trackingAttribute(el, name) {
|
|
556
|
+
var value = el.getAttribute(name);
|
|
557
|
+
return value !== null && value !== '' ? value : el.getAttribute('data-' + name); // no i18n
|
|
558
|
+
}
|
|
559
|
+
/** `[name]` and `[data-name]`, empty values left out, for closest(). */
|
|
560
|
+
function trackingSelector(name) {
|
|
561
|
+
return '[' + name + ']:not([' + name + '=""]),[data-' + name + ']:not([data-' + name + '=""])'; // no i18n
|
|
562
|
+
}
|
|
563
|
+
// Declarative click tracking: <el apeventaction="name" apeventprops='{"k":"v"}'> inside <el apgroupaction="group">,
|
|
564
|
+
// or the same attributes with a data- prefix
|
|
380
565
|
function onDocumentClick(event) {
|
|
381
566
|
if (!window.appticsReadyStatus || !isActive()) {
|
|
382
567
|
return;
|
|
@@ -388,15 +573,15 @@ function onDocumentClick(event) {
|
|
|
388
573
|
if (!start) {
|
|
389
574
|
return;
|
|
390
575
|
}
|
|
391
|
-
var targetElem = start.closest('
|
|
576
|
+
var targetElem = start.closest(trackingSelector('apeventaction')); // no i18n
|
|
392
577
|
if (!targetElem) {
|
|
393
578
|
return;
|
|
394
579
|
}
|
|
395
|
-
var eventName = targetElem
|
|
396
|
-
var groupElem = targetElem.closest('
|
|
397
|
-
var groupName = (groupElem && groupElem
|
|
580
|
+
var eventName = trackingAttribute(targetElem, 'apeventaction') || ''; // no i18n
|
|
581
|
+
var groupElem = targetElem.closest(trackingSelector('apgroupaction')); // no i18n
|
|
582
|
+
var groupName = (groupElem && trackingAttribute(groupElem, 'apgroupaction')) || constants.AP_CONFIG.default_group_name; // no i18n
|
|
398
583
|
var eventProps = {};
|
|
399
|
-
var rawProps = targetElem
|
|
584
|
+
var rawProps = trackingAttribute(targetElem, 'apeventprops'); // no i18n
|
|
400
585
|
if (!utils.isEmpty(rawProps)) {
|
|
401
586
|
try {
|
|
402
587
|
eventProps = JSON.parse(rawProps);
|
|
@@ -502,8 +687,8 @@ function attachListeners() {
|
|
|
502
687
|
// until it has them: register before flushing, and flush once that has landed
|
|
503
688
|
if (index.needsDevice()) {
|
|
504
689
|
logger.Console.log('back online: registering this device before sending'); // no i18n
|
|
505
|
-
|
|
506
|
-
index.
|
|
690
|
+
// the same locked path as start-up, so two tabs coming back online register it once
|
|
691
|
+
index.prepareDevice().then(index.deviceReady).then(function () {
|
|
507
692
|
if (!isActive())
|
|
508
693
|
return;
|
|
509
694
|
scheduler.flush();
|
|
@@ -525,14 +710,25 @@ function attachListeners() {
|
|
|
525
710
|
track$1.trackError(event);
|
|
526
711
|
}
|
|
527
712
|
});
|
|
713
|
+
// in the capture phase: a <script>, <img> or <link> that fails to load fires `error` on the
|
|
714
|
+
// element, and it does not bubble, so a bubbling listener never hears of it. One listener
|
|
715
|
+
// hears both kinds, the window's own errors included, so none is counted twice
|
|
528
716
|
window.addEventListener('error', function (event) {
|
|
529
|
-
if (isActive()
|
|
530
|
-
|
|
717
|
+
if (!isActive() || !state._ZAP._isGlobalErrorTracking) {
|
|
718
|
+
return;
|
|
531
719
|
}
|
|
532
|
-
|
|
720
|
+
var target = event.target;
|
|
721
|
+
if (target && target !== window && typeof target.tagName === 'string') { // no i18n
|
|
722
|
+
// named by describeTarget: Event "error" on <script src="...">
|
|
723
|
+
track$1.trackError({ type: 'error', reason: event }); // no i18n
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
track$1.trackError(event);
|
|
727
|
+
}, true);
|
|
533
728
|
window.addEventListener('click', onDocumentClick, true); // no i18n
|
|
534
729
|
}
|
|
535
730
|
|
|
536
731
|
exports.init = init;
|
|
537
732
|
exports.ready = ready;
|
|
538
733
|
exports.reset = reset;
|
|
734
|
+
exports.screenRouteRules = screenRouteRules;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** The ISO code of a time zone's country, '' for one with none (UTC) or unknown. */
|
|
2
|
+
export declare function timeZoneCountryCode(timeZone: string): string;
|
|
3
|
+
/** The country: the user's, else the time zone's. '' when neither says. */
|
|
4
|
+
export declare function deviceCountry(): string;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var state = require('../core/state.js');
|
|
5
|
+
var env = require('../core/env.js');
|
|
6
|
+
var tzCountries = require('./tz-countries.js');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The country of this device, for remote config's `country` criteria, by its English name as the
|
|
10
|
+
* console lists it ("India").
|
|
11
|
+
*
|
|
12
|
+
* The one AppticsUser.setUser registered comes first. Otherwise it is the country of the
|
|
13
|
+
* browser's time zone, which is the device clock's: Asia/Kolkata (or Chrome's Asia/Calcutta) is
|
|
14
|
+
* India, whatever language the browser is in. A browser has no other source short of asking for
|
|
15
|
+
* the user's location, which is a permission prompt. A zone shared by several countries is the
|
|
16
|
+
* one tzdata names for it.
|
|
17
|
+
*/
|
|
18
|
+
/** Zone -> ISO code, unpacked on first use. */
|
|
19
|
+
var byZone = null;
|
|
20
|
+
function zones() {
|
|
21
|
+
if (byZone !== null) {
|
|
22
|
+
return byZone;
|
|
23
|
+
}
|
|
24
|
+
var out = {};
|
|
25
|
+
tzCountries.TZ_COUNTRIES.split(';').forEach(function (entry) {
|
|
26
|
+
var colon = entry.indexOf(':'); // no i18n
|
|
27
|
+
var code = entry.slice(0, colon);
|
|
28
|
+
entry.slice(colon + 1).split('|').forEach(function (group) {
|
|
29
|
+
// "Area/City,City", or bare names with no area ("Cuba,Egypt")
|
|
30
|
+
var slash = group.indexOf('/'); // no i18n
|
|
31
|
+
var area = slash === -1 ? '' : group.slice(0, slash + 1); // no i18n
|
|
32
|
+
group.slice(area.length).split(',').forEach(function (city) {
|
|
33
|
+
out[area + city] = code;
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
byZone = out;
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
/** The ISO code of a time zone's country, '' for one with none (UTC) or unknown. */
|
|
41
|
+
function timeZoneCountryCode(timeZone) {
|
|
42
|
+
var all = zones();
|
|
43
|
+
return Object.prototype.hasOwnProperty.call(all, timeZone) ? all[timeZone] : ''; // no i18n
|
|
44
|
+
}
|
|
45
|
+
/** IN -> India, in English; the code itself where the browser has no region names. */
|
|
46
|
+
function regionName(code) {
|
|
47
|
+
try {
|
|
48
|
+
var names = new Intl.DisplayNames(['en'], { type: 'region' }); // no i18n
|
|
49
|
+
return names.of(code) || code;
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
return code;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** The country: the user's, else the time zone's. '' when neither says. */
|
|
56
|
+
function deviceCountry() {
|
|
57
|
+
var named = String(state._ZAP._user_info.country || '').trim(); // no i18n
|
|
58
|
+
if (named !== '') {
|
|
59
|
+
return named;
|
|
60
|
+
}
|
|
61
|
+
var timeZone = ''; // no i18n
|
|
62
|
+
try {
|
|
63
|
+
timeZone = String(env.getTimeZone() || ''); // no i18n
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
timeZone = ''; // no i18n
|
|
67
|
+
}
|
|
68
|
+
var code = timeZoneCountryCode(timeZone);
|
|
69
|
+
return code === '' ? '' : regionName(code); // no i18n
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
exports.deviceCountry = deviceCountry;
|
|
73
|
+
exports.timeZoneCountryCode = timeZoneCountryCode;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
/** The
|
|
2
|
-
export declare function
|
|
1
|
+
/** The values set for a condition, by its name; empty when none are. */
|
|
2
|
+
export declare function customConditionValues(conditionname: string): string[];
|
|
3
3
|
/**
|
|
4
|
-
* Sets what this device is for a custom
|
|
5
|
-
* the stored rules
|
|
6
|
-
* fetch.
|
|
4
|
+
* Sets what this device is for a custom condition, by its name, as comma separated values; an
|
|
5
|
+
* empty value removes it. Re-applies the stored rules once storage is ready, so the next read sees
|
|
6
|
+
* the new result without a fetch.
|
|
7
7
|
*/
|
|
8
|
-
export declare function setCustomConditionValue(
|
|
9
|
-
/** reset(): forgets the values set on this page
|
|
8
|
+
export declare function setCustomConditionValue(conditionname: string, value: string | number | boolean | null | undefined): void;
|
|
9
|
+
/** reset(): forgets the values set on this page. */
|
|
10
10
|
export declare function clearCustomConditionValues(): void;
|