govuk_publishing_components 35.3.5 → 35.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/component_guide/audit-filter.js +81 -0
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-link-tracker.js +4 -3
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-specialist-link-tracker.js +5 -1
- data/app/assets/javascripts/govuk_publishing_components/components/step-by-step-nav.js +1 -1
- data/app/assets/javascripts/govuk_publishing_components/vendor/lux/lux-reporter.js +245 -176
- data/app/assets/stylesheets/component_guide/application.scss +16 -0
- data/app/assets/stylesheets/govuk_publishing_components/components/_layout-super-navigation-header.scss +0 -5
- data/app/assets/stylesheets/govuk_publishing_components/components/_search.scss +0 -12
- data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_attachment.scss +0 -11
- data/app/models/govuk_publishing_components/audit_applications.rb +14 -0
- data/app/models/govuk_publishing_components/audit_comparer.rb +14 -0
- data/app/models/govuk_publishing_components/audit_components.rb +34 -32
- data/app/views/govuk_publishing_components/audit/_applications.html.erb +40 -32
- data/app/views/govuk_publishing_components/audit/_component_contents.html.erb +56 -12
- data/app/views/govuk_publishing_components/audit/_components.html.erb +9 -7
- data/app/views/govuk_publishing_components/audit/show.html.erb +5 -1
- data/app/views/govuk_publishing_components/components/_hint.html.erb +5 -1
- data/app/views/govuk_publishing_components/components/_label.html.erb +6 -6
- data/app/views/govuk_publishing_components/components/docs/hint.yml +1 -1
- data/lib/generators/govuk_publishing_components/component_generator.rb +2 -2
- data/lib/govuk_publishing_components/presenters/related_navigation_helper.rb +8 -8
- data/lib/govuk_publishing_components/version.rb +1 -1
- data/node_modules/axe-core/README.md +1 -3
- data/node_modules/axe-core/axe.js +4385 -1157
- data/node_modules/axe-core/axe.min.js +2 -2
- data/node_modules/axe-core/locales/_template.json +12 -0
- data/node_modules/axe-core/package.json +2 -1
- data/node_modules/axe-core/sri-history.json +4 -0
- metadata +3 -2
@@ -42,9 +42,10 @@
|
|
42
42
|
var autoMode = getProperty(obj, "auto", true);
|
43
43
|
return {
|
44
44
|
auto: autoMode,
|
45
|
+
autoWhenHidden: getProperty(obj, "autoWhenHidden", false),
|
45
46
|
beaconUrl: getProperty(obj, "beaconUrl", "https://lux.speedcurve.com/lux/"),
|
47
|
+
conversions: getProperty(obj, "conversions", undefined),
|
46
48
|
customerid: getProperty(obj, "customerid", undefined),
|
47
|
-
debug: getProperty(obj, "debug", false),
|
48
49
|
errorBeaconUrl: getProperty(obj, "errorBeaconUrl", "https://lux.speedcurve.com/error/"),
|
49
50
|
jspagelabel: getProperty(obj, "jspagelabel", undefined),
|
50
51
|
label: getProperty(obj, "label", undefined),
|
@@ -52,7 +53,6 @@
|
|
52
53
|
maxBeaconUTEntries: getProperty(obj, "maxBeaconUTEntries", 20),
|
53
54
|
maxErrors: getProperty(obj, "maxErrors", 5),
|
54
55
|
maxMeasureTime: getProperty(obj, "maxMeasureTime", 60000),
|
55
|
-
measureUntil: getProperty(obj, "measureUntil", "onload"),
|
56
56
|
minMeasureTime: getProperty(obj, "minMeasureTime", 0),
|
57
57
|
samplerate: getProperty(obj, "samplerate", 100),
|
58
58
|
sendBeaconOnPageHidden: getProperty(obj, "sendBeaconOnPageHidden", autoMode),
|
@@ -69,6 +69,7 @@
|
|
69
69
|
|
70
70
|
var START_MARK = "LUX_start";
|
71
71
|
var END_MARK = "LUX_end";
|
72
|
+
var BOOLEAN_TRUE = "true";
|
72
73
|
|
73
74
|
var customDataValues = {};
|
74
75
|
var updatedCustomData = {};
|
@@ -111,6 +112,104 @@
|
|
111
112
|
return encodeURIComponent(strings.join(","));
|
112
113
|
}
|
113
114
|
|
115
|
+
function floor(x) {
|
116
|
+
return Math.floor(x);
|
117
|
+
}
|
118
|
+
|
119
|
+
function now() {
|
120
|
+
return Date.now ? Date.now() : +new Date();
|
121
|
+
}
|
122
|
+
|
123
|
+
var scriptStartTime = now();
|
124
|
+
|
125
|
+
var _a;
|
126
|
+
// If the various performance APIs aren't available, we export an empty object to
|
127
|
+
// prevent having to make regular typeof checks.
|
128
|
+
var performance = window.performance || {};
|
129
|
+
var timing = performance.timing || {
|
130
|
+
// If performance.timing isn't available, we attempt to polyfill the navigationStart value.
|
131
|
+
// Our first attempt is from LUX.ns, which is the time that the snippet execution began. If this
|
132
|
+
// is not available, we fall back to the time that the current script execution began.
|
133
|
+
navigationStart: ((_a = window.LUX) === null || _a === void 0 ? void 0 : _a.ns) || scriptStartTime,
|
134
|
+
};
|
135
|
+
function msSinceNavigationStart() {
|
136
|
+
if (performance.now) {
|
137
|
+
return floor(performance.now());
|
138
|
+
}
|
139
|
+
return now() - timing.navigationStart;
|
140
|
+
}
|
141
|
+
function navigationType() {
|
142
|
+
if (performance.navigation && typeof performance.navigation.type !== "undefined") {
|
143
|
+
return performance.navigation.type;
|
144
|
+
}
|
145
|
+
return "";
|
146
|
+
}
|
147
|
+
function getNavigationEntry() {
|
148
|
+
var navEntries = getEntriesByType("navigation");
|
149
|
+
if (navEntries.length) {
|
150
|
+
var entry_1 = navEntries[0];
|
151
|
+
entry_1.navigationStart = 0;
|
152
|
+
if (typeof entry_1.activationStart === "undefined") {
|
153
|
+
entry_1.activationStart = 0;
|
154
|
+
}
|
155
|
+
return entry_1;
|
156
|
+
}
|
157
|
+
var navType = navigationType();
|
158
|
+
var entry = {
|
159
|
+
navigationStart: 0,
|
160
|
+
activationStart: 0,
|
161
|
+
startTime: 0,
|
162
|
+
type: navType == 2 ? "back_forward" : navType === 1 ? "reload" : "navigate",
|
163
|
+
};
|
164
|
+
if (__ENABLE_POLYFILLS) {
|
165
|
+
for (var key in timing) {
|
166
|
+
if (typeof timing[key] === "number" && key !== "navigationStart") {
|
167
|
+
entry[key] = Math.max(0, timing[key] - timing.navigationStart);
|
168
|
+
}
|
169
|
+
}
|
170
|
+
}
|
171
|
+
return entry;
|
172
|
+
}
|
173
|
+
/**
|
174
|
+
* Simple wrapper around performance.getEntriesByType to provide fallbacks for
|
175
|
+
* legacy browsers, and work around edge cases where undefined is returned instead
|
176
|
+
* of an empty PerformanceEntryList.
|
177
|
+
*/
|
178
|
+
function getEntriesByType(type) {
|
179
|
+
if (typeof performance.getEntriesByType === "function") {
|
180
|
+
var entries = performance.getEntriesByType(type);
|
181
|
+
if (entries && entries.length) {
|
182
|
+
return entries;
|
183
|
+
}
|
184
|
+
}
|
185
|
+
return [];
|
186
|
+
}
|
187
|
+
|
188
|
+
function isVisible() {
|
189
|
+
if (document.visibilityState) {
|
190
|
+
return document.visibilityState === "visible";
|
191
|
+
}
|
192
|
+
// For browsers that don't support document.visibilityState, we assume the page is visible.
|
193
|
+
return true;
|
194
|
+
}
|
195
|
+
function onVisible(cb) {
|
196
|
+
if (isVisible()) {
|
197
|
+
cb();
|
198
|
+
}
|
199
|
+
else {
|
200
|
+
var onVisibleCallback_1 = function () {
|
201
|
+
if (isVisible()) {
|
202
|
+
cb();
|
203
|
+
removeEventListener("visibilitychange", onVisibleCallback_1);
|
204
|
+
}
|
205
|
+
};
|
206
|
+
addEventListener("visibilitychange", onVisibleCallback_1, true);
|
207
|
+
}
|
208
|
+
}
|
209
|
+
function wasPrerendered() {
|
210
|
+
return document.prerendering || getNavigationEntry().activationStart > 0;
|
211
|
+
}
|
212
|
+
|
114
213
|
var Flags = {
|
115
214
|
InitCalled: 1 << 0,
|
116
215
|
NavTimingNotSupported: 1 << 1,
|
@@ -122,6 +221,7 @@
|
|
122
221
|
PageLabelFromLabelProp: 1 << 7,
|
123
222
|
PageLabelFromGlobalVariable: 1 << 8,
|
124
223
|
PageLabelFromPagegroup: 1 << 9,
|
224
|
+
PageWasPrerendered: 1 << 10,
|
125
225
|
};
|
126
226
|
function addFlag(flags, flag) {
|
127
227
|
return flags | flag;
|
@@ -177,10 +277,6 @@
|
|
177
277
|
return null;
|
178
278
|
}
|
179
279
|
|
180
|
-
function now() {
|
181
|
-
return Date.now ? Date.now() : +new Date();
|
182
|
-
}
|
183
|
-
|
184
280
|
var LogEvent = {
|
185
281
|
// Internal events
|
186
282
|
EvaluationStart: 1,
|
@@ -254,65 +350,6 @@
|
|
254
350
|
return sessionValue;
|
255
351
|
}
|
256
352
|
|
257
|
-
var scriptStartTime = now();
|
258
|
-
|
259
|
-
var _a;
|
260
|
-
// If the various performance APIs aren't available, we export an empty object to
|
261
|
-
// prevent having to make regular typeof checks.
|
262
|
-
var performance = window.performance || {};
|
263
|
-
var timing = performance.timing || {
|
264
|
-
// If performance.timing isn't available, we attempt to polyfill the navigationStart value.
|
265
|
-
// Our first attempt is from LUX.ns, which is the time that the snippet execution began. If this
|
266
|
-
// is not available, we fall back to the time that the current script execution began.
|
267
|
-
navigationStart: ((_a = window.LUX) === null || _a === void 0 ? void 0 : _a.ns) || scriptStartTime,
|
268
|
-
};
|
269
|
-
function msSinceNavigationStart() {
|
270
|
-
if (performance.now) {
|
271
|
-
return performance.now();
|
272
|
-
}
|
273
|
-
return now() - timing.navigationStart;
|
274
|
-
}
|
275
|
-
function navigationType() {
|
276
|
-
if (performance.navigation && typeof performance.navigation.type !== "undefined") {
|
277
|
-
return performance.navigation.type;
|
278
|
-
}
|
279
|
-
return "";
|
280
|
-
}
|
281
|
-
function getNavigationEntry() {
|
282
|
-
var navEntries = getEntriesByType("navigation");
|
283
|
-
if (navEntries.length) {
|
284
|
-
return navEntries[0];
|
285
|
-
}
|
286
|
-
var navType = navigationType();
|
287
|
-
var entry = {
|
288
|
-
activationStart: 0,
|
289
|
-
startTime: 0,
|
290
|
-
type: navType == 2 ? "back_forward" : navType === 1 ? "reload" : "navigate",
|
291
|
-
};
|
292
|
-
if (__ENABLE_POLYFILLS) {
|
293
|
-
for (var key in timing) {
|
294
|
-
if (typeof timing[key] === "number" && key !== "navigationStart") {
|
295
|
-
entry[key] = Math.max(0, timing[key] - timing.navigationStart);
|
296
|
-
}
|
297
|
-
}
|
298
|
-
}
|
299
|
-
return entry;
|
300
|
-
}
|
301
|
-
/**
|
302
|
-
* Simple wrapper around performance.getEntriesByType to provide fallbacks for
|
303
|
-
* legacy browsers, and work around edge cases where undefined is returned instead
|
304
|
-
* of an empty PerformanceEntryList.
|
305
|
-
*/
|
306
|
-
function getEntriesByType(type) {
|
307
|
-
if (typeof performance.getEntriesByType === "function") {
|
308
|
-
var entries = performance.getEntriesByType(type);
|
309
|
-
if (entries && entries.length) {
|
310
|
-
return entries;
|
311
|
-
}
|
312
|
-
}
|
313
|
-
return [];
|
314
|
-
}
|
315
|
-
|
316
353
|
/**
|
317
354
|
* This implementation is based on the web-vitals implementation, however it is stripped back to the
|
318
355
|
* bare minimum required to measure just the INP value and does not store the actual event entries.
|
@@ -342,7 +379,7 @@
|
|
342
379
|
slowestEntriesMap[interactionId] = { duration: duration, interactionId: interactionId, startTime: startTime };
|
343
380
|
slowestEntries.push(slowestEntriesMap[interactionId]);
|
344
381
|
}
|
345
|
-
|
382
|
+
// Only store the longest <MAX_INTERACTIONS> interactions
|
346
383
|
slowestEntries.sort(function (a, b) { return b.duration - a.duration; });
|
347
384
|
slowestEntries.splice(MAX_INTERACTIONS).forEach(function (entry) {
|
348
385
|
delete slowestEntriesMap[entry.interactionId];
|
@@ -368,6 +405,18 @@
|
|
368
405
|
return interactionCountEstimate;
|
369
406
|
}
|
370
407
|
|
408
|
+
/**
|
409
|
+
* Get the number of milliseconds between navigationStart and the given PerformanceNavigationTiming key
|
410
|
+
*/
|
411
|
+
function getNavTimingValue(key) {
|
412
|
+
var navEntry = getNavigationEntry();
|
413
|
+
var relativeTo = key === "activationStart" ? 0 : navEntry.activationStart;
|
414
|
+
if (typeof navEntry[key] === "number") {
|
415
|
+
return Math.max(0, navEntry[key] - relativeTo);
|
416
|
+
}
|
417
|
+
return undefined;
|
418
|
+
}
|
419
|
+
|
371
420
|
/******************************************************************************
|
372
421
|
Copyright (c) Microsoft Corporation.
|
373
422
|
|
@@ -416,6 +465,27 @@
|
|
416
465
|
ALL_ENTRIES.splice(0);
|
417
466
|
}
|
418
467
|
|
468
|
+
function getMatchesFromPatternMap(patternMap, hostname, pathname, firstOnly) {
|
469
|
+
var matches = [];
|
470
|
+
for (var key in patternMap) {
|
471
|
+
var patterns = patternMap[key];
|
472
|
+
if (Array.isArray(patterns)) {
|
473
|
+
for (var i in patterns) {
|
474
|
+
var pattern = patterns[i];
|
475
|
+
if (patternMatchesUrl(pattern, hostname, pathname)) {
|
476
|
+
if (firstOnly) {
|
477
|
+
return key;
|
478
|
+
}
|
479
|
+
matches.push(key);
|
480
|
+
}
|
481
|
+
}
|
482
|
+
}
|
483
|
+
}
|
484
|
+
if (firstOnly) {
|
485
|
+
return undefined;
|
486
|
+
}
|
487
|
+
return matches;
|
488
|
+
}
|
419
489
|
function patternMatchesUrl(pattern, hostname, pathname) {
|
420
490
|
var regex = createRegExpFromPattern(pattern);
|
421
491
|
if (pattern.charAt(0) === "/") {
|
@@ -444,7 +514,7 @@
|
|
444
514
|
// -------------------------------------------------------------------------
|
445
515
|
/// End
|
446
516
|
// -------------------------------------------------------------------------
|
447
|
-
var SCRIPT_VERSION = "
|
517
|
+
var SCRIPT_VERSION = "308";
|
448
518
|
var logger = new Logger();
|
449
519
|
var globalConfig = fromObject(LUX);
|
450
520
|
logger.logEvent(LogEvent.EvaluationStart, [SCRIPT_VERSION]);
|
@@ -542,6 +612,7 @@
|
|
542
612
|
var gUid = refreshUniqueId(gSyncId); // cookie for this session ("Unique ID")
|
543
613
|
var gCustomerDataTimeout; // setTimeout timer for sending a Customer Data beacon after onload
|
544
614
|
var gMaxMeasureTimeout; // setTimeout timer for sending the beacon after a maximum measurement time
|
615
|
+
var navEntry = getNavigationEntry();
|
545
616
|
if (_sample()) {
|
546
617
|
logger.logEvent(LogEvent.SessionIsSampled, [globalConfig.samplerate]);
|
547
618
|
}
|
@@ -564,7 +635,7 @@
|
|
564
635
|
// Record the FIRST input delay.
|
565
636
|
function recordDelay(delay) {
|
566
637
|
if (!gFirstInputDelay) {
|
567
|
-
gFirstInputDelay =
|
638
|
+
gFirstInputDelay = delay;
|
568
639
|
// remove event listeners
|
569
640
|
gaEventTypes.forEach(function (eventType) {
|
570
641
|
removeEventListener(eventType, onInput, ghListenerOptions);
|
@@ -631,12 +702,12 @@
|
|
631
702
|
});
|
632
703
|
////////////////////// FID END
|
633
704
|
/**
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
705
|
+
* Returns the time elapsed (in ms) since navigationStart. For SPAs, returns
|
706
|
+
* the time elapsed since the last LUX.init call.
|
707
|
+
*
|
708
|
+
* When `absolute = true` the time is always relative to navigationStart, even
|
709
|
+
* in SPAs.
|
710
|
+
*/
|
640
711
|
function _now(absolute) {
|
641
712
|
var sinceNavigationStart = msSinceNavigationStart();
|
642
713
|
var startMark = _getMark(START_MARK);
|
@@ -737,9 +808,9 @@
|
|
737
808
|
if (startMark) {
|
738
809
|
startTime = startMark.startTime;
|
739
810
|
}
|
740
|
-
else if (
|
811
|
+
else if (typeof navEntry[startMarkName] === "number") {
|
741
812
|
// the mark name can also be a property from Navigation Timing
|
742
|
-
startTime =
|
813
|
+
startTime = navEntry[startMarkName];
|
743
814
|
}
|
744
815
|
else {
|
745
816
|
throwError(startMarkName);
|
@@ -750,15 +821,15 @@
|
|
750
821
|
if (endMark) {
|
751
822
|
endTime = endMark.startTime;
|
752
823
|
}
|
753
|
-
else if (
|
824
|
+
else if (typeof navEntry[endMarkName] === "number") {
|
754
825
|
// the mark name can also be a property from Navigation Timing
|
755
|
-
endTime =
|
826
|
+
endTime = navEntry[endMarkName];
|
756
827
|
}
|
757
828
|
else {
|
758
829
|
throwError(endMarkName);
|
759
830
|
}
|
760
831
|
}
|
761
|
-
var duration =
|
832
|
+
var duration = endTime - startTime;
|
762
833
|
var detail = null;
|
763
834
|
if (options) {
|
764
835
|
if (options.duration) {
|
@@ -826,7 +897,7 @@
|
|
826
897
|
// Don't include the internal marks in the beacon
|
827
898
|
return;
|
828
899
|
}
|
829
|
-
var startTime =
|
900
|
+
var startTime = floor(mark.startTime - tZero);
|
830
901
|
if (startTime < 0) {
|
831
902
|
// Exclude marks that were taken before the current SPA page view
|
832
903
|
return;
|
@@ -845,8 +916,8 @@
|
|
845
916
|
return;
|
846
917
|
}
|
847
918
|
var name = measure.name;
|
848
|
-
var startTime =
|
849
|
-
var duration =
|
919
|
+
var startTime = floor(measure.startTime - tZero);
|
920
|
+
var duration = floor(measure.duration);
|
850
921
|
if (typeof hUT[name] === "undefined" || startTime > hUT[name].startTime) {
|
851
922
|
hUT[name] = { startTime: startTime, duration: duration };
|
852
923
|
}
|
@@ -872,7 +943,7 @@
|
|
872
943
|
getEntries("element").forEach(function (entry) {
|
873
944
|
if (entry.identifier && entry.startTime) {
|
874
945
|
logger.logEvent(LogEvent.PerformanceEntryProcessed, [entry]);
|
875
|
-
aET.push(entry.identifier + "|" +
|
946
|
+
aET.push(entry.identifier + "|" + floor(entry.startTime - tZero));
|
876
947
|
}
|
877
948
|
});
|
878
949
|
return aET.join(",");
|
@@ -904,7 +975,7 @@
|
|
904
975
|
}
|
905
976
|
}
|
906
977
|
longTaskEntries.forEach(function (entry) {
|
907
|
-
var dur =
|
978
|
+
var dur = floor(entry.duration);
|
908
979
|
if (entry.startTime < tZero_1) {
|
909
980
|
// In a SPA it is possible that we were in the middle of a Long Task when
|
910
981
|
// LUX.init() was called. If so, only include the duration after tZero.
|
@@ -924,7 +995,7 @@
|
|
924
995
|
}
|
925
996
|
hCPU[type] += dur;
|
926
997
|
// Send back the raw startTime and duration, as well as the adjusted duration.
|
927
|
-
hCPUDetails[type] += "," +
|
998
|
+
hCPUDetails[type] += "," + floor(entry.startTime) + "|" + dur;
|
928
999
|
});
|
929
1000
|
}
|
930
1001
|
// TODO - Add more types if/when they become available.
|
@@ -942,7 +1013,7 @@
|
|
942
1013
|
",x|" +
|
943
1014
|
hStats["max"] +
|
944
1015
|
(0 === hStats["fci"] ? "" : ",i|" + hStats["fci"]); // only add FCI if it is non-zero
|
945
|
-
|
1016
|
+
sCPU += "s|" + hCPU[jsType] + sStats + hCPUDetails[jsType];
|
946
1017
|
return sCPU;
|
947
1018
|
}
|
948
1019
|
// Return a hash of "stats" about the CPU details incl. count, max, and median.
|
@@ -995,7 +1066,7 @@
|
|
995
1066
|
if (0 === aValues.length) {
|
996
1067
|
return 0;
|
997
1068
|
}
|
998
|
-
var half =
|
1069
|
+
var half = floor(aValues.length / 2);
|
999
1070
|
aValues.sort(function (a, b) {
|
1000
1071
|
return a - b;
|
1001
1072
|
});
|
@@ -1020,10 +1091,10 @@
|
|
1020
1091
|
var r = aResources[0];
|
1021
1092
|
// DO NOT USE DURATION!!!!!
|
1022
1093
|
// See https://www.stevesouders.com/blog/2014/11/25/serious-confusion-with-resource-timing/
|
1023
|
-
var dns =
|
1024
|
-
var tcp =
|
1025
|
-
var fb =
|
1026
|
-
var content =
|
1094
|
+
var dns = floor(r.domainLookupEnd - r.domainLookupStart);
|
1095
|
+
var tcp = floor(r.connectEnd - r.connectStart);
|
1096
|
+
var fb = floor(r.responseStart - r.requestStart);
|
1097
|
+
var content = floor(r.responseEnd - r.responseStart);
|
1027
1098
|
var networkDuration = dns + tcp + fb + content;
|
1028
1099
|
var parseEval = scriptEndTime - scriptStartTime;
|
1029
1100
|
var transferSize = r.encodedBodySize ? r.encodedBodySize : 0;
|
@@ -1149,8 +1220,8 @@
|
|
1149
1220
|
!e.async &&
|
1150
1221
|
!e.defer &&
|
1151
1222
|
0 !== (e.compareDocumentPosition(lastViewportElem) & 4)) {
|
1152
|
-
|
1153
|
-
|
1223
|
+
// If the script has a SRC and async is false and it occurs BEFORE the last viewport element,
|
1224
|
+
// then increment the counter.
|
1154
1225
|
num++;
|
1155
1226
|
}
|
1156
1227
|
}
|
@@ -1236,9 +1307,9 @@
|
|
1236
1307
|
var endMark = _getMark(END_MARK);
|
1237
1308
|
if (startMark && endMark) {
|
1238
1309
|
// This is a SPA page view, so send the SPA marks & measures instead of Nav Timing.
|
1239
|
-
var start =
|
1310
|
+
var start = floor(startMark.startTime); // the start mark is "zero"
|
1240
1311
|
ns += start; // "navigationStart" for a SPA is the real navigationStart plus the start mark
|
1241
|
-
var end =
|
1312
|
+
var end = floor(endMark.startTime) - start; // delta from start mark
|
1242
1313
|
s =
|
1243
1314
|
ns +
|
1244
1315
|
"fs" +
|
@@ -1251,38 +1322,44 @@
|
|
1251
1322
|
}
|
1252
1323
|
else if (performance.timing) {
|
1253
1324
|
// Return the real Nav Timing metrics because this is the "main" page view (not a SPA)
|
1254
|
-
var
|
1255
|
-
var
|
1256
|
-
var
|
1257
|
-
var
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
(
|
1267
|
-
(
|
1268
|
-
(
|
1269
|
-
(
|
1270
|
-
(
|
1271
|
-
(
|
1272
|
-
(
|
1273
|
-
(
|
1274
|
-
(
|
1275
|
-
(
|
1276
|
-
(
|
1277
|
-
(
|
1278
|
-
(
|
1279
|
-
(
|
1280
|
-
(
|
1281
|
-
""
|
1325
|
+
var startRender = getStartRender();
|
1326
|
+
var fcp = getFcp();
|
1327
|
+
var lcp = getLcp();
|
1328
|
+
var prefixNTValue = function (key, prefix) {
|
1329
|
+
var value = getNavTimingValue(key);
|
1330
|
+
if (typeof value === "undefined") {
|
1331
|
+
return "";
|
1332
|
+
}
|
1333
|
+
return prefix + value;
|
1334
|
+
};
|
1335
|
+
s = [
|
1336
|
+
ns,
|
1337
|
+
prefixNTValue("activationStart", "as"),
|
1338
|
+
prefixNTValue("redirectStart", "rs"),
|
1339
|
+
prefixNTValue("redirectEnd", "re"),
|
1340
|
+
prefixNTValue("fetchStart", "fs"),
|
1341
|
+
prefixNTValue("domainLookupStart", "ds"),
|
1342
|
+
prefixNTValue("domainLookupEnd", "de"),
|
1343
|
+
prefixNTValue("connectStart", "cs"),
|
1344
|
+
prefixNTValue("secureConnectionStart", "sc"),
|
1345
|
+
prefixNTValue("connectEnd", "ce"),
|
1346
|
+
prefixNTValue("requestStart", "qs"),
|
1347
|
+
prefixNTValue("responseStart", "bs"),
|
1348
|
+
prefixNTValue("responseEnd", "be"),
|
1349
|
+
prefixNTValue("domInteractive", "oi"),
|
1350
|
+
prefixNTValue("domContentLoadedEventStart", "os"),
|
1351
|
+
prefixNTValue("domContentLoadedEventEnd", "oe"),
|
1352
|
+
prefixNTValue("domComplete", "oc"),
|
1353
|
+
prefixNTValue("loadEventStart", "ls"),
|
1354
|
+
prefixNTValue("loadEventEnd", "le"),
|
1355
|
+
typeof startRender !== "undefined" ? "sr" + startRender : "",
|
1356
|
+
typeof fcp !== "undefined" ? "fc" + fcp : "",
|
1357
|
+
typeof lcp !== "undefined" ? "lc" + lcp : "",
|
1358
|
+
].join("");
|
1282
1359
|
}
|
1283
1360
|
else if (endMark) {
|
1284
1361
|
// This is a "main" page view that does NOT support Navigation Timing - strange.
|
1285
|
-
var end =
|
1362
|
+
var end = floor(endMark.startTime);
|
1286
1363
|
s =
|
1287
1364
|
ns +
|
1288
1365
|
"fs" +
|
@@ -1301,7 +1378,7 @@
|
|
1301
1378
|
for (var i = 0; i < paintEntries.length; i++) {
|
1302
1379
|
var entry = paintEntries[i];
|
1303
1380
|
if (entry.name === "first-contentful-paint") {
|
1304
|
-
return
|
1381
|
+
return floor(entry.startTime);
|
1305
1382
|
}
|
1306
1383
|
}
|
1307
1384
|
return undefined;
|
@@ -1312,7 +1389,7 @@
|
|
1312
1389
|
if (lcpEntries.length) {
|
1313
1390
|
var lastEntry = lcpEntries[lcpEntries.length - 1];
|
1314
1391
|
logger.logEvent(LogEvent.PerformanceEntryProcessed, [lastEntry]);
|
1315
|
-
return
|
1392
|
+
return floor(lastEntry.startTime);
|
1316
1393
|
}
|
1317
1394
|
return undefined;
|
1318
1395
|
}
|
@@ -1320,22 +1397,18 @@
|
|
1320
1397
|
// Mostly works on just Chrome and IE.
|
1321
1398
|
// Return undefined if not supported.
|
1322
1399
|
function getStartRender() {
|
1323
|
-
if (
|
1400
|
+
if ("PerformancePaintTiming" in self) {
|
1324
1401
|
var paintEntries = getEntriesByType("paint");
|
1325
1402
|
if (paintEntries.length) {
|
1326
|
-
// If Paint Timing API is supported, use
|
1327
|
-
|
1328
|
-
|
1329
|
-
if (entry.name === "first-paint") {
|
1330
|
-
return Math.round(entry.startTime);
|
1331
|
-
}
|
1332
|
-
}
|
1333
|
-
}
|
1334
|
-
else if (timing.msFirstPaint && __ENABLE_POLYFILLS) {
|
1335
|
-
// If IE/Edge, use the prefixed `msFirstPaint` property (see http://msdn.microsoft.com/ff974719).
|
1336
|
-
return Math.round(timing.msFirstPaint - timing.navigationStart);
|
1403
|
+
// If the Paint Timing API is supported, use the value of the first paint event
|
1404
|
+
var paintValues = paintEntries.map(function (entry) { return entry.startTime; });
|
1405
|
+
return floor(Math.min.apply(null, paintValues));
|
1337
1406
|
}
|
1338
1407
|
}
|
1408
|
+
if (performance.timing && timing.msFirstPaint && __ENABLE_POLYFILLS) {
|
1409
|
+
// If IE/Edge, use the prefixed `msFirstPaint` property (see http://msdn.microsoft.com/ff974719).
|
1410
|
+
return floor(timing.msFirstPaint - timing.navigationStart);
|
1411
|
+
}
|
1339
1412
|
logger.logEvent(LogEvent.PaintTimingNotSupported);
|
1340
1413
|
return undefined;
|
1341
1414
|
}
|
@@ -1411,7 +1484,7 @@
|
|
1411
1484
|
}
|
1412
1485
|
// Return the main HTML document transfer size (in bytes).
|
1413
1486
|
function docSize() {
|
1414
|
-
return
|
1487
|
+
return navEntry.encodedBodySize || 0;
|
1415
1488
|
}
|
1416
1489
|
// Return the connection type based on Network Information API.
|
1417
1490
|
// Note this API is in flux.
|
@@ -1576,7 +1649,7 @@
|
|
1576
1649
|
if (!gbIxSent) {
|
1577
1650
|
sIx = ixValues();
|
1578
1651
|
if (sIx === "") {
|
1579
|
-
|
1652
|
+
// If there are no interaction metrics, we
|
1580
1653
|
INP = undefined;
|
1581
1654
|
}
|
1582
1655
|
}
|
@@ -1584,9 +1657,17 @@
|
|
1584
1657
|
var sCPU = cpuTimes();
|
1585
1658
|
var CLS = getCLS$1();
|
1586
1659
|
var sLuxjs = selfLoading();
|
1587
|
-
if (
|
1660
|
+
if (!isVisible()) {
|
1588
1661
|
gFlags = addFlag(gFlags, Flags.VisibilityStateNotVisible);
|
1589
1662
|
}
|
1663
|
+
if (wasPrerendered()) {
|
1664
|
+
gFlags = addFlag(gFlags, Flags.PageWasPrerendered);
|
1665
|
+
}
|
1666
|
+
if (LUX.conversions) {
|
1667
|
+
getMatchesFromPatternMap(LUX.conversions, location.hostname, location.pathname).forEach(function (conversion) {
|
1668
|
+
LUX.addData(conversion, BOOLEAN_TRUE);
|
1669
|
+
});
|
1670
|
+
}
|
1590
1671
|
// We want ALL beacons to have ALL the data used for query filters (geo, pagelabel, browser, & customerdata).
|
1591
1672
|
// So we create a base URL that has all the necessary information:
|
1592
1673
|
var baseUrl = _getBeaconUrl(getAllCustomData());
|
@@ -1676,7 +1757,7 @@
|
|
1676
1757
|
var sIx = ixValues(); // Interaction Metrics
|
1677
1758
|
var INP = getINP();
|
1678
1759
|
if (sIx) {
|
1679
|
-
|
1760
|
+
var beaconUrl = _getBeaconUrl(getUpdatedCustomData()) +
|
1680
1761
|
"&IX=" +
|
1681
1762
|
sIx +
|
1682
1763
|
(typeof gFirstInputDelay !== "undefined" ? "&FID=" + gFirstInputDelay : "") +
|
@@ -1718,13 +1799,13 @@
|
|
1718
1799
|
// Note for scroll input we don't remove the handlers or send the IX beacon because we want to
|
1719
1800
|
// capture click and key events as well, since these are typically more important than scrolls.
|
1720
1801
|
if (typeof ghIx["s"] === "undefined") {
|
1721
|
-
ghIx["s"] =
|
1802
|
+
ghIx["s"] = _now();
|
1722
1803
|
}
|
1723
1804
|
}
|
1724
1805
|
function _keyHandler(e) {
|
1725
1806
|
_removeIxHandlers();
|
1726
1807
|
if (typeof ghIx["k"] === "undefined") {
|
1727
|
-
ghIx["k"] =
|
1808
|
+
ghIx["k"] = _now();
|
1728
1809
|
if (e && e.target instanceof Element) {
|
1729
1810
|
var trackId = interactionAttributionForElement(e.target);
|
1730
1811
|
if (trackId) {
|
@@ -1737,7 +1818,7 @@
|
|
1737
1818
|
function _clickHandler(e) {
|
1738
1819
|
_removeIxHandlers();
|
1739
1820
|
if (typeof ghIx["c"] === "undefined") {
|
1740
|
-
ghIx["c"] =
|
1821
|
+
ghIx["c"] = _now();
|
1741
1822
|
var target = void 0;
|
1742
1823
|
try {
|
1743
1824
|
// Seeing "Permission denied" errors, so do a simple try-catch.
|
@@ -1865,30 +1946,11 @@
|
|
1865
1946
|
gFlags = addFlag(gFlags, Flags.PageLabelFromLabelProp);
|
1866
1947
|
return LUX.label;
|
1867
1948
|
}
|
1868
|
-
|
1869
|
-
var
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
1873
|
-
if (Array.isArray(rules)) {
|
1874
|
-
rules.every(function (rule) {
|
1875
|
-
if (patternMatchesUrl(rule, document.location.hostname, document.location.pathname)) {
|
1876
|
-
label_1 = pagegroup;
|
1877
|
-
return false; // stop when first match is found
|
1878
|
-
}
|
1879
|
-
return true;
|
1880
|
-
});
|
1881
|
-
}
|
1882
|
-
// exits loop when first match is found
|
1883
|
-
if (label_1) {
|
1884
|
-
gFlags = addFlag(gFlags, Flags.PageLabelFromPagegroup);
|
1885
|
-
return { value: label_1 };
|
1886
|
-
}
|
1887
|
-
};
|
1888
|
-
for (var pagegroup in pagegroups) {
|
1889
|
-
var state_1 = _loop_1(pagegroup);
|
1890
|
-
if (typeof state_1 === "object")
|
1891
|
-
return state_1.value;
|
1949
|
+
if (typeof LUX.pagegroups !== "undefined") {
|
1950
|
+
var label = getMatchesFromPatternMap(LUX.pagegroups, location.hostname, location.pathname, true);
|
1951
|
+
if (label) {
|
1952
|
+
gFlags = addFlag(gFlags, Flags.PageLabelFromPagegroup);
|
1953
|
+
return label;
|
1892
1954
|
}
|
1893
1955
|
}
|
1894
1956
|
if (typeof LUX.jspagelabel !== "undefined") {
|
@@ -1969,9 +2031,16 @@
|
|
1969
2031
|
setTimeout(sendBeaconAfterMinimumMeasureTime_1, timeRemaining);
|
1970
2032
|
}
|
1971
2033
|
};
|
1972
|
-
|
2034
|
+
if (globalConfig.autoWhenHidden) {
|
2035
|
+
// The autoWhenHidden config forces the beacon to be sent even when the page is not visible.
|
2036
|
+
sendBeaconAfterMinimumMeasureTime_1();
|
2037
|
+
}
|
2038
|
+
else {
|
2039
|
+
// Otherwise we only send the beacon when the page is visible.
|
2040
|
+
onVisible(sendBeaconAfterMinimumMeasureTime_1);
|
2041
|
+
}
|
1973
2042
|
}
|
1974
|
-
// Add the unload handlers
|
2043
|
+
// Add the unload handlers when sendBeaconOnPageHidden is enabled
|
1975
2044
|
if (globalConfig.sendBeaconOnPageHidden) {
|
1976
2045
|
_addUnloadHandlers();
|
1977
2046
|
}
|
@@ -1980,9 +2049,9 @@
|
|
1980
2049
|
// Set the maximum measurement timer
|
1981
2050
|
createMaxMeasureTimeout();
|
1982
2051
|
/**
|
1983
|
-
|
1984
|
-
|
1985
|
-
|
2052
|
+
* LUX functions and properties must be attached to the existing global object to ensure that
|
2053
|
+
* changes made to the global object are reflected in the "internal" LUX object, and vice versa.
|
2054
|
+
*/
|
1986
2055
|
var globalLux = globalConfig;
|
1987
2056
|
// Functions
|
1988
2057
|
globalLux.mark = _mark;
|
@@ -2007,8 +2076,8 @@
|
|
2007
2076
|
// Public properties
|
2008
2077
|
globalLux.version = SCRIPT_VERSION;
|
2009
2078
|
/**
|
2010
|
-
|
2011
|
-
|
2079
|
+
* Run a command from the command queue
|
2080
|
+
*/
|
2012
2081
|
function _runCommand(_a) {
|
2013
2082
|
var fn = _a[0], args = _a.slice(1);
|
2014
2083
|
if (typeof globalLux[fn] === "function") {
|