@adobe/alloy 2.21.0-beta.1 → 2.21.0-beta.11

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.
Files changed (87) hide show
  1. package/LICENSE_BANNER +9 -0
  2. package/babel.config.cjs +93 -0
  3. package/libEs5/components/ActivityCollector/attachClickActivityCollector.js +4 -0
  4. package/libEs5/components/ActivityCollector/configValidators.js +17 -2
  5. package/libEs5/components/ActivityCollector/createClickActivityStorage.js +35 -0
  6. package/libEs5/components/ActivityCollector/createClickedElementProperties.js +215 -0
  7. package/libEs5/components/ActivityCollector/createGetClickedElementProperties.js +64 -0
  8. package/libEs5/components/ActivityCollector/createInjectClickedElementProperties.js +70 -0
  9. package/libEs5/components/ActivityCollector/createRecallAndInjectClickedElementProperties.js +46 -0
  10. package/libEs5/components/ActivityCollector/{createLinkClick.js → createStorePageViewProperties.js} +6 -21
  11. package/libEs5/components/ActivityCollector/getLinkName.js +9 -24
  12. package/libEs5/components/ActivityCollector/getLinkRegion.js +2 -2
  13. package/libEs5/components/ActivityCollector/index.js +54 -19
  14. package/libEs5/components/ActivityCollector/utils/activityMapExtensionEnabled.js +20 -0
  15. package/libEs5/components/ActivityCollector/utils/createTransientStorage.js +28 -0
  16. package/libEs5/components/ActivityCollector/utils/determineLinkType.js +28 -0
  17. package/libEs5/components/ActivityCollector/utils/dom/elementHasClickHandler.js +17 -0
  18. package/libEs5/components/ActivityCollector/utils/dom/extractDomain.js +22 -0
  19. package/libEs5/components/ActivityCollector/utils/dom/findClickableElement.js +28 -0
  20. package/libEs5/components/ActivityCollector/utils/dom/getAbsoluteUrlFromAnchorElement.js +42 -0
  21. package/libEs5/components/ActivityCollector/utils/dom/isButtonSubmitElement.js +17 -0
  22. package/libEs5/components/ActivityCollector/utils/dom/isDownloadLink.js +28 -0
  23. package/libEs5/components/ActivityCollector/utils/dom/isExitLink.js +25 -0
  24. package/libEs5/components/ActivityCollector/utils/dom/isInputSubmitElement.js +28 -0
  25. package/libEs5/components/ActivityCollector/utils/dom/isSupportedAnchorElement.js +20 -0
  26. package/libEs5/components/ActivityCollector/utils/dom/isSupportedTextNode.js +30 -0
  27. package/libEs5/components/ActivityCollector/utils/hasPageName.js +21 -0
  28. package/libEs5/components/ActivityCollector/utils/isDifferentDomains.js +20 -0
  29. package/libEs5/components/ActivityCollector/utils/trimQueryFromUrl.js +25 -0
  30. package/libEs5/components/ActivityCollector/utils/truncateWhiteSpace.js +24 -0
  31. package/libEs5/components/ActivityCollector/utils/urlStartsWithScheme.js +17 -0
  32. package/libEs5/constants/libraryVersion.js +1 -1
  33. package/libEs5/constants/sessionDataKeys.js +15 -0
  34. package/libEs5/core/componentCreators.js +4 -0
  35. package/libEs5/core/config/createCoreConfigs.js +1 -1
  36. package/libEs5/standalone.js +18 -0
  37. package/libEs5/utils/validation/createDeprecatedValidator.js +8 -23
  38. package/libEs5/utils/validation/createRenamedValidator.js +44 -0
  39. package/libEs5/utils/validation/index.js +7 -3
  40. package/libEs6/components/ActivityCollector/attachClickActivityCollector.js +4 -0
  41. package/libEs6/components/ActivityCollector/configValidators.js +17 -2
  42. package/libEs6/components/ActivityCollector/createClickActivityStorage.js +34 -0
  43. package/libEs6/components/ActivityCollector/createClickedElementProperties.js +218 -0
  44. package/libEs6/components/ActivityCollector/createGetClickedElementProperties.js +69 -0
  45. package/libEs6/components/ActivityCollector/createInjectClickedElementProperties.js +69 -0
  46. package/libEs6/components/ActivityCollector/createRecallAndInjectClickedElementProperties.js +45 -0
  47. package/libEs6/components/ActivityCollector/{createLinkClick.js → createStorePageViewProperties.js} +7 -22
  48. package/libEs6/components/ActivityCollector/getLinkName.js +2 -16
  49. package/libEs6/components/ActivityCollector/getLinkRegion.js +1 -1
  50. package/libEs6/components/ActivityCollector/index.js +50 -14
  51. package/libEs6/components/ActivityCollector/utils/activityMapExtensionEnabled.js +14 -0
  52. package/libEs6/components/ActivityCollector/utils/createTransientStorage.js +26 -0
  53. package/libEs6/components/ActivityCollector/utils/determineLinkType.js +26 -0
  54. package/libEs6/components/ActivityCollector/utils/dom/elementHasClickHandler.js +15 -0
  55. package/libEs6/components/ActivityCollector/utils/dom/extractDomain.js +20 -0
  56. package/libEs6/components/ActivityCollector/utils/dom/findClickableElement.js +26 -0
  57. package/libEs6/components/ActivityCollector/utils/dom/getAbsoluteUrlFromAnchorElement.js +42 -0
  58. package/libEs6/components/ActivityCollector/utils/dom/isButtonSubmitElement.js +15 -0
  59. package/libEs6/components/ActivityCollector/utils/dom/isDownloadLink.js +26 -0
  60. package/libEs6/components/ActivityCollector/utils/dom/isExitLink.js +23 -0
  61. package/libEs6/components/ActivityCollector/utils/dom/isInputSubmitElement.js +26 -0
  62. package/libEs6/components/ActivityCollector/utils/dom/isSupportedAnchorElement.js +18 -0
  63. package/libEs6/components/ActivityCollector/utils/dom/isSupportedTextNode.js +27 -0
  64. package/libEs6/components/ActivityCollector/utils/hasPageName.js +19 -0
  65. package/libEs6/components/ActivityCollector/utils/isDifferentDomains.js +18 -0
  66. package/libEs6/components/ActivityCollector/utils/trimQueryFromUrl.js +23 -0
  67. package/libEs6/components/ActivityCollector/utils/truncateWhiteSpace.js +22 -0
  68. package/libEs6/components/ActivityCollector/utils/urlStartsWithScheme.js +15 -0
  69. package/libEs6/constants/libraryVersion.js +1 -1
  70. package/libEs6/constants/sessionDataKeys.js +12 -0
  71. package/libEs6/core/componentCreators.js +8 -0
  72. package/libEs6/core/config/createCoreConfigs.js +1 -1
  73. package/libEs6/standalone.js +16 -0
  74. package/libEs6/utils/validation/createDeprecatedValidator.js +7 -20
  75. package/libEs6/utils/validation/createRenamedValidator.js +37 -0
  76. package/libEs6/utils/validation/index.js +7 -3
  77. package/package.json +35 -29
  78. package/rollup.config.js +164 -0
  79. package/scripts/alloyBuilder.js +215 -0
  80. package/scripts/helpers/alloyComponents.js +63 -0
  81. package/scripts/helpers/conditionalBuildBabelPlugin.js +57 -0
  82. package/scripts/helpers/versionBabelPlugin.js +43 -0
  83. package/libEs5/components/ActivityCollector/createGetLinkDetails.js +0 -68
  84. package/libEs5/components/ActivityCollector/utils.js +0 -104
  85. package/libEs6/components/ActivityCollector/createGetLinkDetails.js +0 -70
  86. package/libEs6/components/ActivityCollector/utils.js +0 -104
  87. package/scripts/build-alloy.js +0 -125
@@ -0,0 +1,215 @@
1
+ #!/usr/bin/env node
2
+
3
+ /*
4
+ Copyright 2023 Adobe. All rights reserved.
5
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License. You may obtain a copy
7
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
8
+ Unless required by applicable law or agreed to in writing, software distributed under
9
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
10
+ OF ANY KIND, either express or implied. See the License for the specific language
11
+ governing permissions and limitations under the License.
12
+ */
13
+
14
+ import fs from "fs";
15
+ import path from "path";
16
+ import { rollup } from "rollup";
17
+ import { Command, Option, InvalidOptionArgumentError } from "commander";
18
+ import inquirer from "inquirer";
19
+ import { fileURLToPath } from "url";
20
+ import { buildConfig } from "../rollup.config.js";
21
+ import conditionalBuildBabelPlugin from "./helpers/conditionalBuildBabelPlugin.js";
22
+ import components from "./helpers/alloyComponents.js";
23
+
24
+ const dirname = path.dirname(fileURLToPath(import.meta.url));
25
+
26
+ let sourceRootPath = `${dirname}/../src`;
27
+ if (!fs.existsSync(sourceRootPath)) {
28
+ sourceRootPath = `${dirname}/../libEs6`;
29
+ }
30
+
31
+ const getOptionalComponents = (() => {
32
+ const componentCreatorsPath = `${sourceRootPath}/core/componentCreators.js`;
33
+
34
+ // Read componentCreators.js
35
+ const componentCreatorsContent = fs.readFileSync(
36
+ componentCreatorsPath,
37
+ "utf8",
38
+ );
39
+
40
+ // Extract optional components based on @skipwhen directive
41
+ const optionalComponents = componentCreatorsContent
42
+ .split("\n")
43
+ .filter((line) => line.trim().startsWith("/* @skipwhen"))
44
+ .map((line) => {
45
+ const match = line.match(/ENV\.alloy_([a-zA-Z0-9]+) === false/);
46
+ if (match) {
47
+ const [, componentName] = match;
48
+ return componentName.toLowerCase(); // Ensure this matches the expected format for exclusion
49
+ }
50
+ return null;
51
+ })
52
+ .filter(Boolean);
53
+
54
+ return () => optionalComponents;
55
+ })();
56
+
57
+ const getDefaultPath = () => {
58
+ return process.cwd();
59
+ };
60
+
61
+ const getFile = (argv) => {
62
+ return `${[argv.outputDir, `alloy${argv.minify ? ".min" : ""}.js`].join(path.sep)}`;
63
+ };
64
+
65
+ const getFileSizeInKB = (filePath) => {
66
+ const stats = fs.statSync(filePath);
67
+ const fileSizeInBytes = stats.size;
68
+ return `${(fileSizeInBytes / 1024).toFixed(2)} K`;
69
+ };
70
+
71
+ const build = async (argv) => {
72
+ const rollupConfig = buildConfig({
73
+ input: `${sourceRootPath}/standalone.js`,
74
+ file: getFile(argv),
75
+ minify: argv.minify,
76
+ babelPlugins: [
77
+ conditionalBuildBabelPlugin(
78
+ argv.exclude.reduce((acc, module) => {
79
+ acc[`alloy_${module}`] = "false";
80
+ return acc;
81
+ }, {}),
82
+ ),
83
+ ],
84
+ });
85
+
86
+ const bundle = await rollup(rollupConfig);
87
+ await bundle.write(rollupConfig.output[0]);
88
+ console.log(
89
+ `🎉 Wrote ${
90
+ path.isAbsolute(argv.outputDir)
91
+ ? rollupConfig.output[0].file
92
+ : path.relative(process.cwd(), rollupConfig.output[0].file)
93
+ } (${getFileSizeInKB(rollupConfig.output[0].file)}).`,
94
+ );
95
+ };
96
+
97
+ const getMakeBuildCommand = () =>
98
+ new Command("build")
99
+ .description("Build a custom version of the alloy.js library.")
100
+ .addOption(
101
+ new Option(
102
+ "-e, --exclude <modules...>",
103
+ "optional components that can be excluded from the build",
104
+ )
105
+ .choices(getOptionalComponents())
106
+ .default([])
107
+ .argParser((value) => {
108
+ const modules = value.split(",");
109
+
110
+ modules.forEach((module) => {
111
+ if (!getOptionalComponents().includes(module))
112
+ throw new InvalidOptionArgumentError(
113
+ `Module "${module}" does not exists. Allowed choices are "${getOptionalComponents().join('", "')}".`,
114
+ );
115
+ });
116
+
117
+ return modules;
118
+ }),
119
+ )
120
+ .addOption(new Option("-M, --no-minify", "disable code minification"))
121
+ .addOption(
122
+ new Option(
123
+ "-o, --outputDir <dir>",
124
+ "the output directory for the generated build",
125
+ )
126
+ .default(getDefaultPath())
127
+ .argParser((value) => {
128
+ if (!path.isAbsolute(value)) {
129
+ value = `${getDefaultPath()}${path.sep}${value}`;
130
+ }
131
+
132
+ try {
133
+ const stats = fs.statSync(value);
134
+ if (!stats.isDirectory()) {
135
+ throw new InvalidOptionArgumentError(
136
+ `Output directory "${value}" is not a valid directory path.`,
137
+ );
138
+ }
139
+ } catch (error) {
140
+ throw new InvalidOptionArgumentError(
141
+ `Output directory "${value}" is not a valid directory path. ${error.message}`,
142
+ );
143
+ }
144
+
145
+ return value.replace(new RegExp(`${path.sep}+$`, "g"), "");
146
+ }),
147
+ )
148
+ .action(async (opts) => {
149
+ await build(opts);
150
+ });
151
+
152
+ const getInteractiveBuildCommand = () =>
153
+ new Command("interactive-build")
154
+ .description(
155
+ "Interactive process that will ask a series of questions and then it will generate a build.",
156
+ )
157
+ .action(async () => {
158
+ await inquirer
159
+ .prompt([
160
+ {
161
+ type: "checkbox",
162
+ name: "include",
163
+ message: "What components should be included in your Alloy build?",
164
+ choices: components,
165
+ },
166
+ {
167
+ type: "list",
168
+ name: "minify",
169
+ message: "How would you like your JavaScript to be?",
170
+ choices: [
171
+ { name: "Minified", value: true },
172
+ { name: "Unminified", value: false },
173
+ ],
174
+ },
175
+ {
176
+ type: "string",
177
+ name: "outputDir",
178
+ message: "Where would you like to save the build?",
179
+ default: process.cwd(),
180
+ },
181
+ ])
182
+ .then(async (opts) => {
183
+ const { include } = opts;
184
+ const exclude = components
185
+ .map((v) => v.value)
186
+ .filter((component) => !include.includes(component));
187
+
188
+ opts.exclude = exclude;
189
+ delete opts.include;
190
+
191
+ await build(opts);
192
+ })
193
+ .catch((error) => {
194
+ if (error.isTtyError) {
195
+ console.error(
196
+ "Prompt couldn't be rendered in the current environment",
197
+ );
198
+ } else {
199
+ console.error("An error occurred: ", error);
200
+ }
201
+ });
202
+ });
203
+
204
+ const program = new Command();
205
+
206
+ program
207
+ .name("alloy")
208
+ .description(
209
+ "Tool for generating custom Adobe Experience Platform Web SDK builds.",
210
+ )
211
+ .version("1.0.0");
212
+
213
+ program.addCommand(getMakeBuildCommand());
214
+ program.addCommand(getInteractiveBuildCommand(), { isDefault: true });
215
+ program.parse();
@@ -0,0 +1,63 @@
1
+ /*
2
+ Copyright 2024 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ Unless required by applicable law or agreed to in writing, software distributed under
7
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
8
+ OF ANY KIND, either express or implied. See the License for the specific language
9
+ governing permissions and limitations under the License.
10
+ */
11
+
12
+ export default [
13
+ {
14
+ name: "Activity Collector",
15
+ value: "activitycollector",
16
+ checked: true,
17
+ },
18
+ {
19
+ name: "Audiences",
20
+ value: "audiences",
21
+ checked: true,
22
+ },
23
+ {
24
+ name: "Context",
25
+ value: "context",
26
+ checked: true,
27
+ },
28
+ {
29
+ name: "Decision Engine",
30
+ value: "decisioningengine",
31
+ checked: true,
32
+ },
33
+ {
34
+ name: "Event Merge",
35
+ value: "eventmerge",
36
+ checked: true,
37
+ },
38
+ {
39
+ name: "Personalization",
40
+ value: "personalization",
41
+ checked: true,
42
+ },
43
+ {
44
+ name: "Privacy",
45
+ value: "privacy",
46
+ checked: true,
47
+ },
48
+ {
49
+ name: "Streaming Media",
50
+ value: "streamingmedia",
51
+ checked: true,
52
+ },
53
+ {
54
+ name: "Legacy Media Analytics",
55
+ value: "legacymediaanalytics",
56
+ checked: true,
57
+ },
58
+ {
59
+ name: "Machine Learning",
60
+ value: "machinelearning",
61
+ checked: true,
62
+ },
63
+ ];
@@ -0,0 +1,57 @@
1
+ /*
2
+ Copyright 2023 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+
13
+ export default (excludedModules) => ({
14
+ visitor: {
15
+ ImportDeclaration(path) {
16
+ let skipWhenComments = [];
17
+ if (path.node.leadingComments) {
18
+ skipWhenComments = path.node.leadingComments.filter((c) => {
19
+ return c.value.trim().startsWith("@skipwhen");
20
+ });
21
+ }
22
+
23
+ if (skipWhenComments.length > 0) {
24
+ const [, webSDKModuleName, value] = skipWhenComments[0].value.match(
25
+ "ENV.(.*) === (false|true)",
26
+ );
27
+
28
+ if (excludedModules[webSDKModuleName] === value) {
29
+ const variableName = path.node.specifiers[0].local.name;
30
+
31
+ // Wrap the variable declaration in an IIFE to turn it into an expression
32
+ path.replaceWithSourceString(
33
+ `(() => { const ${variableName} = () => {}; })()`,
34
+ );
35
+ }
36
+ }
37
+ },
38
+ ExportDefaultDeclaration(path) {
39
+ if (path.node.declaration.type === "ArrayExpression") {
40
+ path.node.declaration.elements = path.node.declaration.elements.filter(
41
+ (element) => {
42
+ if (element.name) {
43
+ const variableName = element.name;
44
+ const componentName = variableName
45
+ .replace("create", "")
46
+ .toLowerCase();
47
+ return !Object.keys(excludedModules).includes(
48
+ `alloy_${componentName}`,
49
+ );
50
+ }
51
+ return true;
52
+ },
53
+ );
54
+ }
55
+ },
56
+ },
57
+ });
@@ -0,0 +1,43 @@
1
+ import { createRequire } from "module";
2
+
3
+ const require = createRequire(import.meta.url);
4
+
5
+ const version = null;
6
+ const getVersion = ({ opts: { cwd } }) => {
7
+ if (version) {
8
+ return version;
9
+ }
10
+
11
+ // eslint-disable-next-line import/no-dynamic-require
12
+ const packageJson = require(`${cwd}/package.json`);
13
+ return packageJson.version;
14
+ };
15
+
16
+ export default (_ref) => {
17
+ const t = _ref.types;
18
+
19
+ return {
20
+ visitor: {
21
+ // __VERSION__
22
+ ReferencedIdentifier(path, state) {
23
+ const identifier = state.opts.identifier;
24
+ const transform = identifier === undefined ? true : identifier; // 默认转换
25
+
26
+ const define = state.opts.define || "__VERSION__"; // 默认值
27
+ if (transform && path.node.name === define) {
28
+ path.replaceWith(t.valueToNode(getVersion(state)));
29
+ }
30
+ },
31
+ // "__VERSION__"
32
+ StringLiteral(path, state) {
33
+ const stringLiteral = state.opts.stringLiteral;
34
+ const transform = stringLiteral === undefined ? true : stringLiteral;
35
+
36
+ const define = state.opts.define || "__VERSION__";
37
+ if (transform && path.node.value === define) {
38
+ path.replaceWith(t.valueToNode(getVersion(state)));
39
+ }
40
+ },
41
+ },
42
+ };
43
+ };
@@ -1,68 +0,0 @@
1
- "use strict";
2
-
3
- exports.default = void 0;
4
- /*
5
- Copyright 2022 Adobe. All rights reserved.
6
- This file is licensed to you under the Apache License, Version 2.0 (the "License");
7
- you may not use this file except in compliance with the License. You may obtain a copy
8
- of the License at http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software distributed under
11
- the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
12
- OF ANY KIND, either express or implied. See the License for the specific language
13
- governing permissions and limitations under the License.
14
- */
15
- var _default = exports.default = function _default(_ref) {
16
- var window = _ref.window,
17
- getLinkName = _ref.getLinkName,
18
- getLinkRegion = _ref.getLinkRegion,
19
- getAbsoluteUrlFromAnchorElement = _ref.getAbsoluteUrlFromAnchorElement,
20
- findSupportedAnchorElement = _ref.findSupportedAnchorElement,
21
- determineLinkType = _ref.determineLinkType;
22
- return function (_ref2) {
23
- var targetElement = _ref2.targetElement,
24
- config = _ref2.config,
25
- logger = _ref2.logger;
26
- var anchorElement = findSupportedAnchorElement(targetElement);
27
- if (!anchorElement) {
28
- logger.info("This link click event is not triggered because the HTML element is not an anchor.");
29
- return undefined;
30
- }
31
- var linkUrl = getAbsoluteUrlFromAnchorElement(window, anchorElement);
32
- if (!linkUrl) {
33
- logger.info("This link click event is not triggered because the HTML element doesn't have an URL.");
34
- return undefined;
35
- }
36
- var linkType = determineLinkType(window, config, linkUrl, anchorElement);
37
- var linkRegion = getLinkRegion(anchorElement);
38
- var linkName = getLinkName(anchorElement);
39
- var onBeforeLinkClickSend = config.onBeforeLinkClickSend;
40
- var options = {
41
- xdm: {
42
- eventType: "web.webinteraction.linkClicks",
43
- web: {
44
- webInteraction: {
45
- name: linkName,
46
- region: linkRegion,
47
- type: linkType,
48
- URL: linkUrl,
49
- linkClicks: {
50
- value: 1
51
- }
52
- }
53
- }
54
- },
55
- data: {},
56
- clickedElement: targetElement
57
- };
58
- if (!onBeforeLinkClickSend) {
59
- return options;
60
- }
61
- var shouldEventBeTracked = onBeforeLinkClickSend(options);
62
- if (shouldEventBeTracked !== false) {
63
- return options;
64
- }
65
- logger.info("This link click event is not triggered because it was canceled in onBeforeLinkClickSend.");
66
- return undefined;
67
- };
68
- };
@@ -1,104 +0,0 @@
1
- "use strict";
2
-
3
- exports.urlStartsWithScheme = exports.truncateWhiteSpace = exports.trimQueryFromUrl = exports.isSupportedAnchorElement = exports.isExitLink = exports.isEmptyString = exports.isDownloadLink = exports.getAbsoluteUrlFromAnchorElement = exports.findSupportedAnchorElement = exports.determineLinkType = void 0;
4
- /*
5
- Copyright 2019 Adobe. All rights reserved.
6
- This file is licensed to you under the Apache License, Version 2.0 (the "License");
7
- you may not use this file except in compliance with the License. You may obtain a copy
8
- of the License at http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software distributed under
11
- the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
12
- OF ANY KIND, either express or implied. See the License for the specific language
13
- governing permissions and limitations under the License.
14
- */
15
-
16
- var urlStartsWithScheme = exports.urlStartsWithScheme = function urlStartsWithScheme(url) {
17
- return url && /^[a-z0-9]+:\/\//i.test(url);
18
- };
19
- var getAbsoluteUrlFromAnchorElement = exports.getAbsoluteUrlFromAnchorElement = function getAbsoluteUrlFromAnchorElement(window, element) {
20
- var loc = window.location;
21
- var url = element.href ? element.href : "";
22
- var protocol = element.protocol,
23
- host = element.host;
24
- if (!urlStartsWithScheme(url)) {
25
- if (!protocol) {
26
- protocol = loc.protocol ? loc.protocol : "";
27
- }
28
- protocol = protocol ? protocol + "//" : "";
29
- if (!host) {
30
- host = loc.host ? loc.host : "";
31
- }
32
- var path = "";
33
- if (url.substring(0, 1) !== "/") {
34
- var indx = loc.pathname.lastIndexOf("/");
35
- indx = indx < 0 ? 0 : indx;
36
- path = loc.pathname.substring(0, indx);
37
- }
38
- url = "" + protocol + host + path + "/" + url;
39
- }
40
- return url;
41
- };
42
- var isSupportedAnchorElement = exports.isSupportedAnchorElement = function isSupportedAnchorElement(element) {
43
- if (element.href && (element.tagName === "A" || element.tagName === "AREA") && (!element.onclick || !element.protocol || element.protocol.toLowerCase().indexOf("javascript") < 0)) {
44
- return true;
45
- }
46
- return false;
47
- };
48
- var trimQueryFromUrl = exports.trimQueryFromUrl = function trimQueryFromUrl(url) {
49
- var questionMarkIndex = url.indexOf("?");
50
- var hashIndex = url.indexOf("#");
51
- if (questionMarkIndex >= 0 && (questionMarkIndex < hashIndex || hashIndex < 0)) {
52
- return url.substring(0, questionMarkIndex);
53
- }
54
- if (hashIndex >= 0) {
55
- return url.substring(0, hashIndex);
56
- }
57
- return url;
58
- };
59
- var isDownloadLink = exports.isDownloadLink = function isDownloadLink(downloadLinkQualifier, linkUrl, clickedObj) {
60
- var re = new RegExp(downloadLinkQualifier);
61
- var trimmedLinkUrl = trimQueryFromUrl(linkUrl).toLowerCase();
62
- return clickedObj.download ? true : re.test(trimmedLinkUrl);
63
- };
64
- var isExitLink = exports.isExitLink = function isExitLink(window, linkUrl) {
65
- var currentHostname = window.location.hostname.toLowerCase();
66
- var trimmedLinkUrl = trimQueryFromUrl(linkUrl).toLowerCase();
67
- if (trimmedLinkUrl.indexOf(currentHostname) >= 0) {
68
- return false;
69
- }
70
- return true;
71
- };
72
-
73
- /**
74
- * Reduces repeated whitespace within a string. Whitespace surrounding the string
75
- * is trimmed and any occurrence of whitespace within the string is replaced with
76
- * a single space.
77
- * @param {string} str String to be formatted.
78
- * @returns {string} Formatted string.
79
- */
80
- var truncateWhiteSpace = exports.truncateWhiteSpace = function truncateWhiteSpace(str) {
81
- return str && str.replace(/\s+/g, " ").trim();
82
- };
83
- var isEmptyString = exports.isEmptyString = function isEmptyString(str) {
84
- return !str || str.length === 0;
85
- };
86
- var determineLinkType = exports.determineLinkType = function determineLinkType(window, config, linkUrl, clickedObj) {
87
- var linkType = "other";
88
- if (isDownloadLink(config.downloadLinkQualifier, linkUrl, clickedObj)) {
89
- linkType = "download";
90
- } else if (isExitLink(window, linkUrl)) {
91
- linkType = "exit";
92
- }
93
- return linkType;
94
- };
95
- var findSupportedAnchorElement = exports.findSupportedAnchorElement = function findSupportedAnchorElement(targetElement) {
96
- var node = targetElement;
97
- while (node) {
98
- if (isSupportedAnchorElement(node)) {
99
- return node;
100
- }
101
- node = node.parentNode;
102
- }
103
- return null;
104
- };
@@ -1,70 +0,0 @@
1
- /*
2
- Copyright 2022 Adobe. All rights reserved.
3
- This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
- you may not use this file except in compliance with the License. You may obtain a copy
5
- of the License at http://www.apache.org/licenses/LICENSE-2.0
6
-
7
- Unless required by applicable law or agreed to in writing, software distributed under
8
- the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
- OF ANY KIND, either express or implied. See the License for the specific language
10
- governing permissions and limitations under the License.
11
- */
12
-
13
- export default (({
14
- window,
15
- getLinkName,
16
- getLinkRegion,
17
- getAbsoluteUrlFromAnchorElement,
18
- findSupportedAnchorElement,
19
- determineLinkType
20
- }) => {
21
- return ({
22
- targetElement,
23
- config,
24
- logger
25
- }) => {
26
- const anchorElement = findSupportedAnchorElement(targetElement);
27
- if (!anchorElement) {
28
- logger.info("This link click event is not triggered because the HTML element is not an anchor.");
29
- return undefined;
30
- }
31
- const linkUrl = getAbsoluteUrlFromAnchorElement(window, anchorElement);
32
- if (!linkUrl) {
33
- logger.info("This link click event is not triggered because the HTML element doesn't have an URL.");
34
- return undefined;
35
- }
36
- const linkType = determineLinkType(window, config, linkUrl, anchorElement);
37
- const linkRegion = getLinkRegion(anchorElement);
38
- const linkName = getLinkName(anchorElement);
39
- const {
40
- onBeforeLinkClickSend
41
- } = config;
42
- const options = {
43
- xdm: {
44
- eventType: "web.webinteraction.linkClicks",
45
- web: {
46
- webInteraction: {
47
- name: linkName,
48
- region: linkRegion,
49
- type: linkType,
50
- URL: linkUrl,
51
- linkClicks: {
52
- value: 1
53
- }
54
- }
55
- }
56
- },
57
- data: {},
58
- clickedElement: targetElement
59
- };
60
- if (!onBeforeLinkClickSend) {
61
- return options;
62
- }
63
- const shouldEventBeTracked = onBeforeLinkClickSend(options);
64
- if (shouldEventBeTracked !== false) {
65
- return options;
66
- }
67
- logger.info("This link click event is not triggered because it was canceled in onBeforeLinkClickSend.");
68
- return undefined;
69
- };
70
- });