Skip to content

Commit 28bf151

Browse files
Merge branch 'v12' into codex/add-test-for-data-metadata-collector
2 parents 8ed3786 + 2bfd05c commit 28bf151

File tree

6 files changed

+140
-38
lines changed

6 files changed

+140
-38
lines changed

dist/latest/auto-events.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/latest/latest.dev.js

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-04; 2fe0; v12) */
1+
22
/* eslint-env browser */
33

44
(function (
@@ -216,9 +216,9 @@
216216
overwriteOptions.strictUtm ||
217217
attr(scriptElement, "strict-utm") == trueText;
218218

219-
var getQueryParams = function (ignoreSource) {
219+
var getQueryParams = function (ignoreSource, overwriteSearch) {
220220
return (
221-
loc.search
221+
(overwriteSearch || loc.search)
222222
.slice(1)
223223
.split("&")
224224
.filter(function (keyValue) {
@@ -661,21 +661,26 @@
661661
isPushState,
662662
deleteSourceInfo,
663663
sameSite,
664-
metadata
664+
query,
665+
metadata,
666+
callback
665667
) {
666668
if (isPushState) sendOnLeave("" + payload.page_id, trueVar);
667669
if (collectDataOnLeave) payload.page_id = uuid();
668670

669671
var currentPage = definedHostname + getPath();
670672

671-
sendData({
672-
id: payload.page_id,
673-
type: pageviewText,
674-
referrer: !deleteSourceInfo || sameSite ? referrer : null,
675-
query: getQueryParams(deleteSourceInfo),
673+
sendData(
674+
{
675+
id: payload.page_id,
676+
type: pageviewText,
677+
referrer: !deleteSourceInfo || sameSite ? referrer : null,
678+
query: query || getQueryParams(deleteSourceInfo),
676679

677-
metadata: stringify(metadata),
678-
});
680+
metadata: stringify(metadata),
681+
},
682+
callback
683+
);
679684

680685
previousReferrer = referrer;
681686
referrer = currentPage;
@@ -685,7 +690,21 @@
685690

686691
var sameSite, userNavigated;
687692

688-
var pageview = function (isPushState, pathOverwrite, metadata) {
693+
var pageview = function (
694+
isPushState,
695+
pathOverwrite,
696+
metadata,
697+
callbackRaw
698+
) {
699+
if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;
700+
var callback = isFunction(callbackRaw) ? callbackRaw : function () {};
701+
var querySearch;
702+
if (isString(pathOverwrite) && pathOverwrite.indexOf("?") > -1) {
703+
// keep query from manual path
704+
var parts = pathOverwrite.split("?");
705+
pathOverwrite = parts.shift();
706+
querySearch = "?" + parts.join("?");
707+
}
689708
// Obfuscate personal data in URL by dropping the search and hash
690709
var path = getPath(pathOverwrite);
691710

@@ -760,11 +779,15 @@
760779

761780
var triggerSendPageView = function () {
762781
fetchedHighEntropyValues = trueVar;
782+
var delSrc =
783+
isPushState || userNavigated || !collectMetricByString("r");
763784
sendPageView(
764785
isPushState,
765-
isPushState || userNavigated || !collectMetricByString("r"), // r = referrers
786+
delSrc, // r = referrers
766787
sameSite,
767-
metadata
788+
querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar,
789+
metadata,
790+
callback
768791
);
769792
};
770793

@@ -855,8 +878,8 @@
855878

856879
if (autoCollect) pageview();
857880

858-
window.sa_pageview = function (path, metadata) {
859-
pageview(0, path, metadata);
881+
window.sa_pageview = function (path, metadata, callback) {
882+
pageview(0, path, metadata, callback);
860883
};
861884

862885

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"test": "node -r dotenv/config ./test/index.js",
1616
"posttest": "npm run build",
1717
"prettier": "prettier --check .",
18-
"test:unit": "mocha ./test/unit"
18+
"test:unit": "npm run build -- testing && mocha ./test/unit && git checkout dist"
1919
},
2020
"repository": {
2121
"type": "git",

src/default.js

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,9 @@
232232
overwriteOptions.strictUtm ||
233233
attr(scriptElement, "strict-utm") == trueText;
234234

235-
var getQueryParams = function (ignoreSource) {
235+
var getQueryParams = function (ignoreSource, overwriteSearch) {
236236
return (
237-
loc.search
237+
(overwriteSearch || loc.search)
238238
.slice(1)
239239
.split("&")
240240
.filter(function (keyValue) {
@@ -750,23 +750,28 @@
750750
isPushState,
751751
deleteSourceInfo,
752752
sameSite,
753-
metadata
753+
query,
754+
metadata,
755+
callback
754756
) {
755757
if (isPushState) sendOnLeave("" + payload.page_id, trueVar);
756758
if (collectDataOnLeave) payload.page_id = uuid();
757759

758760
var currentPage = definedHostname + getPath();
759761

760-
sendData({
761-
id: payload.page_id,
762-
type: pageviewText,
763-
referrer: !deleteSourceInfo || sameSite ? referrer : null,
764-
query: getQueryParams(deleteSourceInfo),
765-
766-
/** if metadata **/
767-
metadata: stringify(metadata),
768-
/** endif **/
769-
});
762+
sendData(
763+
{
764+
id: payload.page_id,
765+
type: pageviewText,
766+
referrer: !deleteSourceInfo || sameSite ? referrer : null,
767+
query: query || getQueryParams(deleteSourceInfo),
768+
769+
/** if metadata **/
770+
metadata: stringify(metadata),
771+
/** endif **/
772+
},
773+
callback
774+
);
770775

771776
previousReferrer = referrer;
772777
referrer = currentPage;
@@ -776,7 +781,21 @@
776781

777782
var sameSite, userNavigated;
778783

779-
var pageview = function (isPushState, pathOverwrite, metadata) {
784+
var pageview = function (
785+
isPushState,
786+
pathOverwrite,
787+
metadata,
788+
callbackRaw
789+
) {
790+
if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;
791+
var callback = isFunction(callbackRaw) ? callbackRaw : function () {};
792+
var querySearch;
793+
if (isString(pathOverwrite) && pathOverwrite.indexOf("?") > -1) {
794+
// keep query from manual path
795+
var parts = pathOverwrite.split("?");
796+
pathOverwrite = parts.shift();
797+
querySearch = "?" + parts.join("?");
798+
}
780799
// Obfuscate personal data in URL by dropping the search and hash
781800
var path = getPath(pathOverwrite);
782801

@@ -865,11 +884,15 @@
865884

866885
var triggerSendPageView = function () {
867886
fetchedHighEntropyValues = trueVar;
887+
var delSrc =
888+
isPushState || userNavigated || !collectMetricByString("r");
868889
sendPageView(
869890
isPushState,
870-
isPushState || userNavigated || !collectMetricByString("r"), // r = referrers
891+
delSrc, // r = referrers
871892
sameSite,
872-
metadata
893+
querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar,
894+
metadata,
895+
callback
873896
);
874897
};
875898

@@ -966,12 +989,12 @@
966989
if (autoCollect) pageview();
967990

968991
/** if metadata **/
969-
window.sa_pageview = function (path, metadata) {
970-
pageview(0, path, metadata);
992+
window.sa_pageview = function (path, metadata, callback) {
993+
pageview(0, path, metadata, callback);
971994
};
972995
/** else **/
973-
window.sa_pageview = function (path) {
974-
pageview(0, path);
996+
window.sa_pageview = function (path, callback) {
997+
pageview(0, path, undefinedVar, callback);
975998
};
976999
/** endif **/
9771000

test/unit/pageview-callback.test.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
const { expect } = require("chai");
2+
const { createDOM } = require("./helpers/dom");
3+
4+
describe("pageview callback", function () {
5+
it("executes callback after sending a pageview", function (done) {
6+
const dom = createDOM({ settings: { autoCollect: false } });
7+
8+
const sent = dom.sent;
9+
dom.window.Image = function () {
10+
return {
11+
onload: null,
12+
onerror: null,
13+
set src(value) {
14+
sent.push({ type: "image", url: value });
15+
if (this.onload) this.onload();
16+
},
17+
};
18+
};
19+
20+
let called = false;
21+
dom.window.sa_pageview("/callback", function () {
22+
called = true;
23+
});
24+
25+
setTimeout(() => {
26+
const req = dom.sent.find(
27+
(r) => r.type === "image" && /path=%2Fcallback/.test(r.url)
28+
);
29+
expect(req, "pageview request").to.exist;
30+
expect(called, "callback called").to.be.true;
31+
done();
32+
}, 10);
33+
});
34+
});

test/unit/pageview-query.test.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const { expect } = require("chai");
2+
const { createDOM } = require("./helpers/dom");
3+
4+
describe("pageview query", function () {
5+
it("sends query params from manual path", function (done) {
6+
const dom = createDOM({
7+
settings: { autoCollect: false, allowParams: "foo" },
8+
});
9+
10+
dom.window.sa_pageview("/manual?foo=bar");
11+
12+
setTimeout(() => {
13+
const req = dom.sent.find(
14+
(r) => r.type === "image" && /path=%2Fmanual/.test(r.url)
15+
);
16+
expect(req, "pageview request").to.exist;
17+
const url = new URL(req.url);
18+
expect(url.searchParams.get("query")).to.equal("foo=bar");
19+
done();
20+
}, 10);
21+
});
22+
});

0 commit comments

Comments
 (0)