@amplitude/plugin-autocapture-browser 0.9.0

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 +21 -0
  2. package/README.md +83 -0
  3. package/lib/cjs/autocapture-plugin.d.ts +44 -0
  4. package/lib/cjs/autocapture-plugin.d.ts.map +1 -0
  5. package/lib/cjs/autocapture-plugin.js +232 -0
  6. package/lib/cjs/autocapture-plugin.js.map +1 -0
  7. package/lib/cjs/constants.d.ts +29 -0
  8. package/lib/cjs/constants.d.ts.map +1 -0
  9. package/lib/cjs/constants.js +34 -0
  10. package/lib/cjs/constants.js.map +1 -0
  11. package/lib/cjs/helpers.d.ts +24 -0
  12. package/lib/cjs/helpers.d.ts.map +1 -0
  13. package/lib/cjs/helpers.js +228 -0
  14. package/lib/cjs/helpers.js.map +1 -0
  15. package/lib/cjs/index.d.ts +3 -0
  16. package/lib/cjs/index.d.ts.map +1 -0
  17. package/lib/cjs/index.js +10 -0
  18. package/lib/cjs/index.js.map +1 -0
  19. package/lib/cjs/libs/finder.d.ts +13 -0
  20. package/lib/cjs/libs/finder.d.ts.map +1 -0
  21. package/lib/cjs/libs/finder.js +345 -0
  22. package/lib/cjs/libs/finder.js.map +1 -0
  23. package/lib/cjs/libs/messenger.d.ts +57 -0
  24. package/lib/cjs/libs/messenger.d.ts.map +1 -0
  25. package/lib/cjs/libs/messenger.js +88 -0
  26. package/lib/cjs/libs/messenger.js.map +1 -0
  27. package/lib/cjs/typings/autocapture.d.ts +2 -0
  28. package/lib/cjs/typings/autocapture.d.ts.map +1 -0
  29. package/lib/cjs/typings/autocapture.js +2 -0
  30. package/lib/cjs/typings/autocapture.js.map +1 -0
  31. package/lib/cjs/version.d.ts +2 -0
  32. package/lib/cjs/version.d.ts.map +1 -0
  33. package/lib/cjs/version.js +4 -0
  34. package/lib/cjs/version.js.map +1 -0
  35. package/lib/esm/autocapture-plugin.d.ts +44 -0
  36. package/lib/esm/autocapture-plugin.d.ts.map +1 -0
  37. package/lib/esm/autocapture-plugin.js +228 -0
  38. package/lib/esm/autocapture-plugin.js.map +1 -0
  39. package/lib/esm/constants.d.ts +29 -0
  40. package/lib/esm/constants.d.ts.map +1 -0
  41. package/lib/esm/constants.js +32 -0
  42. package/lib/esm/constants.js.map +1 -0
  43. package/lib/esm/helpers.d.ts +24 -0
  44. package/lib/esm/helpers.d.ts.map +1 -0
  45. package/lib/esm/helpers.js +211 -0
  46. package/lib/esm/helpers.js.map +1 -0
  47. package/lib/esm/index.d.ts +3 -0
  48. package/lib/esm/index.d.ts.map +1 -0
  49. package/lib/esm/index.js +3 -0
  50. package/lib/esm/index.js.map +1 -0
  51. package/lib/esm/libs/finder.d.ts +13 -0
  52. package/lib/esm/libs/finder.d.ts.map +1 -0
  53. package/lib/esm/libs/finder.js +342 -0
  54. package/lib/esm/libs/finder.js.map +1 -0
  55. package/lib/esm/libs/messenger.d.ts +57 -0
  56. package/lib/esm/libs/messenger.d.ts.map +1 -0
  57. package/lib/esm/libs/messenger.js +86 -0
  58. package/lib/esm/libs/messenger.js.map +1 -0
  59. package/lib/esm/typings/autocapture.d.ts +2 -0
  60. package/lib/esm/typings/autocapture.d.ts.map +1 -0
  61. package/lib/esm/typings/autocapture.js +2 -0
  62. package/lib/esm/typings/autocapture.js.map +1 -0
  63. package/lib/esm/version.d.ts +2 -0
  64. package/lib/esm/version.d.ts.map +1 -0
  65. package/lib/esm/version.js +2 -0
  66. package/lib/esm/version.js.map +1 -0
  67. package/lib/scripts/amplitude-min.js +1 -0
  68. package/lib/scripts/amplitude-min.js.gz +0 -0
  69. package/lib/scripts/amplitude-min.umd.js +1 -0
  70. package/lib/scripts/amplitude-min.umd.js.gz +0 -0
  71. package/lib/scripts/autocapture-plugin.d.ts +44 -0
  72. package/lib/scripts/autocapture-plugin.d.ts.map +1 -0
  73. package/lib/scripts/constants.d.ts +29 -0
  74. package/lib/scripts/constants.d.ts.map +1 -0
  75. package/lib/scripts/helpers.d.ts +24 -0
  76. package/lib/scripts/helpers.d.ts.map +1 -0
  77. package/lib/scripts/index.d.ts +3 -0
  78. package/lib/scripts/index.d.ts.map +1 -0
  79. package/lib/scripts/libs/finder.d.ts +13 -0
  80. package/lib/scripts/libs/finder.d.ts.map +1 -0
  81. package/lib/scripts/libs/messenger.d.ts +57 -0
  82. package/lib/scripts/libs/messenger.d.ts.map +1 -0
  83. package/lib/scripts/typings/autocapture.d.ts +2 -0
  84. package/lib/scripts/typings/autocapture.d.ts.map +1 -0
  85. package/lib/scripts/version.d.ts +2 -0
  86. package/lib/scripts/version.d.ts.map +1 -0
  87. package/package.json +61 -0
@@ -0,0 +1,228 @@
1
+ Object.defineProperty(exports, "__esModule", { value: true });
2
+ exports.asyncLoadScript = exports.getEventTagProps = exports.getClosestElement = exports.querySelectUniqueElements = exports.getNearestLabel = exports.removeEmptyProperties = exports.isEmpty = exports.getAttributesWithPrefix = exports.isPageUrlAllowed = exports.getSelector = exports.getText = exports.isNonSensitiveElement = exports.isTextNode = exports.isNonSensitiveString = void 0;
3
+ var tslib_1 = require("tslib");
4
+ /* eslint-disable no-restricted-globals */
5
+ var finder_1 = require("./libs/finder");
6
+ var constants = tslib_1.__importStar(require("./constants"));
7
+ var SENTITIVE_TAGS = ['input', 'select', 'textarea'];
8
+ var isNonSensitiveString = function (text) {
9
+ if (text == null) {
10
+ return false;
11
+ }
12
+ if (typeof text === 'string') {
13
+ var ccRegex = /^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/;
14
+ if (ccRegex.test((text || '').replace(/[- ]/g, ''))) {
15
+ return false;
16
+ }
17
+ var ssnRegex = /(^\d{3}-?\d{2}-?\d{4}$)/;
18
+ if (ssnRegex.test(text)) {
19
+ return false;
20
+ }
21
+ }
22
+ return true;
23
+ };
24
+ exports.isNonSensitiveString = isNonSensitiveString;
25
+ var isTextNode = function (node) {
26
+ return !!node && node.nodeType === 3;
27
+ };
28
+ exports.isTextNode = isTextNode;
29
+ var isNonSensitiveElement = function (element) {
30
+ var _a, _b;
31
+ /* istanbul ignore next */
32
+ var tag = (_b = (_a = element === null || element === void 0 ? void 0 : element.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase) === null || _b === void 0 ? void 0 : _b.call(_a);
33
+ return !SENTITIVE_TAGS.includes(tag);
34
+ };
35
+ exports.isNonSensitiveElement = isNonSensitiveElement;
36
+ // Maybe this can be simplified with element.innerText, keep and manual concatenating for now, more research needed.
37
+ var getText = function (element) {
38
+ var text = '';
39
+ if ((0, exports.isNonSensitiveElement)(element) && element.childNodes && element.childNodes.length) {
40
+ element.childNodes.forEach(function (child) {
41
+ var childText = '';
42
+ if ((0, exports.isTextNode)(child)) {
43
+ if (child.textContent) {
44
+ childText = child.textContent;
45
+ }
46
+ }
47
+ else {
48
+ childText = (0, exports.getText)(child);
49
+ }
50
+ text += childText
51
+ .split(/(\s+)/)
52
+ .filter(exports.isNonSensitiveString)
53
+ .join('')
54
+ .replace(/[\r\n]/g, ' ')
55
+ .replace(/[ ]+/g, ' ')
56
+ .substring(0, 255);
57
+ });
58
+ }
59
+ return text;
60
+ };
61
+ exports.getText = getText;
62
+ var getSelector = function (element, logger) {
63
+ var _a, _b;
64
+ var selector = '';
65
+ try {
66
+ selector = (0, finder_1.finder)(element, {
67
+ className: function (name) { return name !== constants.AMPLITUDE_VISUAL_TAGGING_HIGHLIGHT_CLASS; },
68
+ });
69
+ return selector;
70
+ }
71
+ catch (error) {
72
+ if (logger) {
73
+ var typedError = error;
74
+ logger.warn("Failed to get selector with finder, use fallback strategy instead: ".concat(typedError.toString()));
75
+ }
76
+ }
77
+ // Fall back to use tag, id, and class name, if finder fails.
78
+ /* istanbul ignore next */
79
+ var tag = (_b = (_a = element === null || element === void 0 ? void 0 : element.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase) === null || _b === void 0 ? void 0 : _b.call(_a);
80
+ if (tag) {
81
+ selector = tag;
82
+ }
83
+ if (element.id) {
84
+ selector = "#".concat(element.id);
85
+ }
86
+ else if (element.className) {
87
+ var classes = element.className
88
+ .split(' ')
89
+ .filter(function (name) { return name !== constants.AMPLITUDE_VISUAL_TAGGING_HIGHLIGHT_CLASS; })
90
+ .join('.');
91
+ if (classes) {
92
+ selector = "".concat(selector, ".").concat(classes);
93
+ }
94
+ }
95
+ return selector;
96
+ };
97
+ exports.getSelector = getSelector;
98
+ var isPageUrlAllowed = function (url, pageUrlAllowlist) {
99
+ if (!pageUrlAllowlist || !pageUrlAllowlist.length) {
100
+ return true;
101
+ }
102
+ return pageUrlAllowlist.some(function (allowedUrl) {
103
+ if (typeof allowedUrl === 'string') {
104
+ return url === allowedUrl;
105
+ }
106
+ return url.match(allowedUrl);
107
+ });
108
+ };
109
+ exports.isPageUrlAllowed = isPageUrlAllowed;
110
+ var getAttributesWithPrefix = function (element, prefix) {
111
+ return element.getAttributeNames().reduce(function (attributes, attributeName) {
112
+ if (attributeName.startsWith(prefix)) {
113
+ var attributeKey = attributeName.replace(prefix, '');
114
+ var attributeValue = element.getAttribute(attributeName);
115
+ if (attributeKey) {
116
+ attributes[attributeKey] = attributeValue || '';
117
+ }
118
+ }
119
+ return attributes;
120
+ }, {});
121
+ };
122
+ exports.getAttributesWithPrefix = getAttributesWithPrefix;
123
+ var isEmpty = function (value) {
124
+ return (value === undefined ||
125
+ value === null ||
126
+ (typeof value === 'object' && Object.keys(value).length === 0) ||
127
+ (typeof value === 'string' && value.trim().length === 0));
128
+ };
129
+ exports.isEmpty = isEmpty;
130
+ var removeEmptyProperties = function (properties) {
131
+ return Object.keys(properties).reduce(function (filteredProperties, key) {
132
+ var value = properties[key];
133
+ if (!(0, exports.isEmpty)(value)) {
134
+ filteredProperties[key] = value;
135
+ }
136
+ return filteredProperties;
137
+ }, {});
138
+ };
139
+ exports.removeEmptyProperties = removeEmptyProperties;
140
+ var getNearestLabel = function (element) {
141
+ var parent = element.parentElement;
142
+ if (!parent) {
143
+ return '';
144
+ }
145
+ var labelElement = parent.querySelector(':scope>span,h1,h2,h3,h4,h5,h6');
146
+ if (labelElement) {
147
+ /* istanbul ignore next */
148
+ var labelText = labelElement.textContent || '';
149
+ return (0, exports.isNonSensitiveString)(labelText) ? labelText : '';
150
+ }
151
+ return (0, exports.getNearestLabel)(parent);
152
+ };
153
+ exports.getNearestLabel = getNearestLabel;
154
+ var querySelectUniqueElements = function (root, selectors) {
155
+ if (root && 'querySelectorAll' in root && typeof root.querySelectorAll === 'function') {
156
+ var elementSet = selectors.reduce(function (elements, selector) {
157
+ if (selector) {
158
+ var selectedElements = Array.from(root.querySelectorAll(selector));
159
+ selectedElements.forEach(function (element) {
160
+ elements.add(element);
161
+ });
162
+ }
163
+ return elements;
164
+ }, new Set());
165
+ return Array.from(elementSet);
166
+ }
167
+ return [];
168
+ };
169
+ exports.querySelectUniqueElements = querySelectUniqueElements;
170
+ // Similar as element.closest, but works with multiple selectors
171
+ var getClosestElement = function (element, selectors) {
172
+ if (!element) {
173
+ return null;
174
+ }
175
+ /* istanbul ignore next */
176
+ if (selectors.some(function (selector) { var _a; return (_a = element === null || element === void 0 ? void 0 : element.matches) === null || _a === void 0 ? void 0 : _a.call(element, selector); })) {
177
+ return element;
178
+ }
179
+ /* istanbul ignore next */
180
+ return (0, exports.getClosestElement)(element === null || element === void 0 ? void 0 : element.parentElement, selectors);
181
+ };
182
+ exports.getClosestElement = getClosestElement;
183
+ var getEventTagProps = function (element, logger) {
184
+ var _a;
185
+ var _b, _c;
186
+ if (!element) {
187
+ return {};
188
+ }
189
+ /* istanbul ignore next */
190
+ var tag = (_c = (_b = element === null || element === void 0 ? void 0 : element.tagName) === null || _b === void 0 ? void 0 : _b.toLowerCase) === null || _c === void 0 ? void 0 : _c.call(_b);
191
+ var selector = (0, exports.getSelector)(element, logger);
192
+ var properties = (_a = {},
193
+ _a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_TAG] = tag,
194
+ _a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_TEXT] = (0, exports.getText)(element),
195
+ _a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_SELECTOR] = selector,
196
+ _a[constants.AMPLITUDE_EVENT_PROP_PAGE_URL] = window.location.href.split('?')[0],
197
+ _a);
198
+ return (0, exports.removeEmptyProperties)(properties);
199
+ };
200
+ exports.getEventTagProps = getEventTagProps;
201
+ var asyncLoadScript = function (url) {
202
+ return new Promise(function (resolve, reject) {
203
+ var _a;
204
+ try {
205
+ var scriptElement = document.createElement('script');
206
+ scriptElement.type = 'text/javascript';
207
+ scriptElement.async = true;
208
+ scriptElement.src = url;
209
+ scriptElement.addEventListener('load', function () {
210
+ resolve({ status: true });
211
+ }, { once: true });
212
+ scriptElement.addEventListener('error', function () {
213
+ reject({
214
+ status: false,
215
+ message: "Failed to load the script ".concat(url),
216
+ });
217
+ });
218
+ /* istanbul ignore next */
219
+ (_a = document.head) === null || _a === void 0 ? void 0 : _a.appendChild(scriptElement);
220
+ }
221
+ catch (error) {
222
+ /* istanbul ignore next */
223
+ reject(error);
224
+ }
225
+ });
226
+ };
227
+ exports.asyncLoadScript = asyncLoadScript;
228
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-restricted-globals */\nimport { finder } from './libs/finder';\nimport * as constants from './constants';\nimport { Logger } from '@amplitude/analytics-types';\n\nconst SENTITIVE_TAGS = ['input', 'select', 'textarea'];\n\nexport const isNonSensitiveString = (text: string | null) => {\n if (text == null) {\n return false;\n }\n if (typeof text === 'string') {\n const ccRegex =\n /^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/;\n if (ccRegex.test((text || '').replace(/[- ]/g, ''))) {\n return false;\n }\n const ssnRegex = /(^\\d{3}-?\\d{2}-?\\d{4}$)/;\n if (ssnRegex.test(text)) {\n return false;\n }\n }\n return true;\n};\n\nexport const isTextNode = (node: Node) => {\n return !!node && node.nodeType === 3;\n};\n\nexport const isNonSensitiveElement = (element: Element) => {\n /* istanbul ignore next */\n const tag = element?.tagName?.toLowerCase?.();\n return !SENTITIVE_TAGS.includes(tag);\n};\n\n// Maybe this can be simplified with element.innerText, keep and manual concatenating for now, more research needed.\nexport const getText = (element: Element): string => {\n let text = '';\n if (isNonSensitiveElement(element) && element.childNodes && element.childNodes.length) {\n element.childNodes.forEach((child) => {\n let childText = '';\n if (isTextNode(child)) {\n if (child.textContent) {\n childText = child.textContent;\n }\n } else {\n childText = getText(child as Element);\n }\n text += childText\n .split(/(\\s+)/)\n .filter(isNonSensitiveString)\n .join('')\n .replace(/[\\r\\n]/g, ' ')\n .replace(/[ ]+/g, ' ')\n .substring(0, 255);\n });\n }\n return text;\n};\n\nexport const getSelector = (element: Element, logger?: Logger): string => {\n let selector = '';\n try {\n selector = finder(element, {\n className: (name: string) => name !== constants.AMPLITUDE_VISUAL_TAGGING_HIGHLIGHT_CLASS,\n });\n return selector;\n } catch (error) {\n if (logger) {\n const typedError = error as Error;\n logger.warn(`Failed to get selector with finder, use fallback strategy instead: ${typedError.toString()}`);\n }\n }\n // Fall back to use tag, id, and class name, if finder fails.\n /* istanbul ignore next */\n const tag = element?.tagName?.toLowerCase?.();\n if (tag) {\n selector = tag;\n }\n if (element.id) {\n selector = `#${element.id}`;\n } else if (element.className) {\n const classes = element.className\n .split(' ')\n .filter((name) => name !== constants.AMPLITUDE_VISUAL_TAGGING_HIGHLIGHT_CLASS)\n .join('.');\n if (classes) {\n selector = `${selector}.${classes}`;\n }\n }\n return selector;\n};\n\nexport const isPageUrlAllowed = (url: string, pageUrlAllowlist: (string | RegExp)[] | undefined) => {\n if (!pageUrlAllowlist || !pageUrlAllowlist.length) {\n return true;\n }\n return pageUrlAllowlist.some((allowedUrl) => {\n if (typeof allowedUrl === 'string') {\n return url === allowedUrl;\n }\n return url.match(allowedUrl);\n });\n};\n\nexport const getAttributesWithPrefix = (element: Element, prefix: string): { [key: string]: string } => {\n return element.getAttributeNames().reduce((attributes: { [key: string]: string }, attributeName) => {\n if (attributeName.startsWith(prefix)) {\n const attributeKey = attributeName.replace(prefix, '');\n const attributeValue = element.getAttribute(attributeName);\n if (attributeKey) {\n attributes[attributeKey] = attributeValue || '';\n }\n }\n return attributes;\n }, {});\n};\n\nexport const isEmpty = (value: unknown) => {\n return (\n value === undefined ||\n value === null ||\n (typeof value === 'object' && Object.keys(value).length === 0) ||\n (typeof value === 'string' && value.trim().length === 0)\n );\n};\n\nexport const removeEmptyProperties = (properties: { [key: string]: unknown }) => {\n return Object.keys(properties).reduce((filteredProperties: { [key: string]: unknown }, key) => {\n const value = properties[key];\n if (!isEmpty(value)) {\n filteredProperties[key] = value;\n }\n return filteredProperties;\n }, {});\n};\n\nexport const getNearestLabel = (element: Element): string => {\n const parent = element.parentElement;\n if (!parent) {\n return '';\n }\n const labelElement = parent.querySelector(':scope>span,h1,h2,h3,h4,h5,h6');\n if (labelElement) {\n /* istanbul ignore next */\n const labelText = labelElement.textContent || '';\n return isNonSensitiveString(labelText) ? labelText : '';\n }\n return getNearestLabel(parent);\n};\n\nexport const querySelectUniqueElements = (root: Element | Document, selectors: string[]): Element[] => {\n if (root && 'querySelectorAll' in root && typeof root.querySelectorAll === 'function') {\n const elementSet = selectors.reduce((elements: Set<Element>, selector) => {\n if (selector) {\n const selectedElements = Array.from(root.querySelectorAll(selector));\n selectedElements.forEach((element) => {\n elements.add(element);\n });\n }\n return elements;\n }, new Set<Element>());\n return Array.from(elementSet);\n }\n return [];\n};\n\n// Similar as element.closest, but works with multiple selectors\nexport const getClosestElement = (element: Element | null, selectors: string[]): Element | null => {\n if (!element) {\n return null;\n }\n /* istanbul ignore next */\n if (selectors.some((selector) => element?.matches?.(selector))) {\n return element;\n }\n /* istanbul ignore next */\n return getClosestElement(element?.parentElement, selectors);\n};\n\nexport const getEventTagProps = (element: Element, logger?: Logger) => {\n if (!element) {\n return {};\n }\n /* istanbul ignore next */\n const tag = element?.tagName?.toLowerCase?.();\n const selector = getSelector(element, logger);\n const properties: Record<string, string> = {\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TAG]: tag,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TEXT]: getText(element),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_SELECTOR]: selector,\n [constants.AMPLITUDE_EVENT_PROP_PAGE_URL]: window.location.href.split('?')[0],\n };\n return removeEmptyProperties(properties);\n};\n\nexport const asyncLoadScript = (url: string) => {\n return new Promise((resolve, reject) => {\n try {\n const scriptElement = document.createElement('script');\n scriptElement.type = 'text/javascript';\n scriptElement.async = true;\n scriptElement.src = url;\n scriptElement.addEventListener(\n 'load',\n () => {\n resolve({ status: true });\n },\n { once: true },\n );\n scriptElement.addEventListener('error', () => {\n reject({\n status: false,\n message: `Failed to load the script ${url}`,\n });\n });\n /* istanbul ignore next */\n document.head?.appendChild(scriptElement);\n } catch (error) {\n /* istanbul ignore next */\n reject(error);\n }\n });\n};\n"]}
@@ -0,0 +1,3 @@
1
+ export { autocapturePlugin as plugin, autocapturePlugin, DEFAULT_CSS_SELECTOR_ALLOWLIST, DEFAULT_DATA_ATTRIBUTE_PREFIX, } from './autocapture-plugin';
2
+ export { Messenger, Action, ActionData, Message, WindowMessenger } from './libs/messenger';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,IAAI,MAAM,EAC3B,iBAAiB,EACjB,8BAA8B,EAC9B,6BAA6B,GAC9B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,10 @@
1
+ Object.defineProperty(exports, "__esModule", { value: true });
2
+ exports.WindowMessenger = exports.DEFAULT_DATA_ATTRIBUTE_PREFIX = exports.DEFAULT_CSS_SELECTOR_ALLOWLIST = exports.autocapturePlugin = exports.plugin = void 0;
3
+ var autocapture_plugin_1 = require("./autocapture-plugin");
4
+ Object.defineProperty(exports, "plugin", { enumerable: true, get: function () { return autocapture_plugin_1.autocapturePlugin; } });
5
+ Object.defineProperty(exports, "autocapturePlugin", { enumerable: true, get: function () { return autocapture_plugin_1.autocapturePlugin; } });
6
+ Object.defineProperty(exports, "DEFAULT_CSS_SELECTOR_ALLOWLIST", { enumerable: true, get: function () { return autocapture_plugin_1.DEFAULT_CSS_SELECTOR_ALLOWLIST; } });
7
+ Object.defineProperty(exports, "DEFAULT_DATA_ATTRIBUTE_PREFIX", { enumerable: true, get: function () { return autocapture_plugin_1.DEFAULT_DATA_ATTRIBUTE_PREFIX; } });
8
+ var messenger_1 = require("./libs/messenger");
9
+ Object.defineProperty(exports, "WindowMessenger", { enumerable: true, get: function () { return messenger_1.WindowMessenger; } });
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;AAAA,2DAK8B;AAJ5B,4GAAA,iBAAiB,OAAU;AAC3B,uHAAA,iBAAiB,OAAA;AACjB,oIAAA,8BAA8B,OAAA;AAC9B,mIAAA,6BAA6B,OAAA;AAE/B,8CAA2F;AAA1C,4GAAA,eAAe,OAAA","sourcesContent":["export {\n autocapturePlugin as plugin,\n autocapturePlugin,\n DEFAULT_CSS_SELECTOR_ALLOWLIST,\n DEFAULT_DATA_ATTRIBUTE_PREFIX,\n} from './autocapture-plugin';\nexport { Messenger, Action, ActionData, Message, WindowMessenger } from './libs/messenger';\n"]}
@@ -0,0 +1,13 @@
1
+ export type Options = {
2
+ root: Element;
3
+ idName: (name: string) => boolean;
4
+ className: (name: string) => boolean;
5
+ tagName: (name: string) => boolean;
6
+ attr: (name: string, value: string) => boolean;
7
+ seedMinLength: number;
8
+ optimizedMinLength: number;
9
+ threshold: number;
10
+ maxNumberOfTries: number;
11
+ };
12
+ export declare function finder(input: Element, options?: Partial<Options>): string;
13
+ //# sourceMappingURL=finder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finder.d.ts","sourceRoot":"","sources":["../../../src/libs/finder.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAClC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACrC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACnC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAC/C,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAKF,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,UAmChE"}
@@ -0,0 +1,345 @@
1
+ /* istanbul ignore file */
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.finder = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var config;
6
+ var rootDocument;
7
+ function finder(input, options) {
8
+ if (input.nodeType !== Node.ELEMENT_NODE) {
9
+ throw new Error("Can't generate CSS selector for non-element node type.");
10
+ }
11
+ if ('html' === input.tagName.toLowerCase()) {
12
+ return 'html';
13
+ }
14
+ var defaults = {
15
+ root: document.body,
16
+ idName: function (_name) { return true; },
17
+ className: function (_name) { return true; },
18
+ tagName: function (_name) { return true; },
19
+ attr: function (_name, _value) { return false; },
20
+ seedMinLength: 1,
21
+ optimizedMinLength: 2,
22
+ threshold: 1000,
23
+ maxNumberOfTries: 10000,
24
+ };
25
+ config = tslib_1.__assign(tslib_1.__assign({}, defaults), options);
26
+ rootDocument = findRootDocument(config.root, defaults);
27
+ var path = bottomUpSearch(input, 'all', function () {
28
+ return bottomUpSearch(input, 'two', function () { return bottomUpSearch(input, 'one', function () { return bottomUpSearch(input, 'none'); }); });
29
+ });
30
+ if (path) {
31
+ var optimized = sort(optimize(path, input));
32
+ if (optimized.length > 0) {
33
+ path = optimized[0];
34
+ }
35
+ return selector(path);
36
+ }
37
+ else {
38
+ throw new Error("Selector was not found.");
39
+ }
40
+ }
41
+ exports.finder = finder;
42
+ function findRootDocument(rootNode, defaults) {
43
+ if (rootNode.nodeType === Node.DOCUMENT_NODE) {
44
+ return rootNode;
45
+ }
46
+ if (rootNode === defaults.root) {
47
+ return rootNode.ownerDocument;
48
+ }
49
+ return rootNode;
50
+ }
51
+ function bottomUpSearch(input, limit, fallback) {
52
+ var path = null;
53
+ var stack = [];
54
+ var current = input;
55
+ var i = 0;
56
+ var _loop_1 = function () {
57
+ var e_1, _a;
58
+ var level = maybe(id(current)) || maybe.apply(void 0, tslib_1.__spreadArray([], tslib_1.__read(attr(current)), false)) || maybe.apply(void 0, tslib_1.__spreadArray([], tslib_1.__read(classNames(current)), false)) ||
59
+ maybe(tagName(current)) || [any()];
60
+ var nth = index(current);
61
+ if (limit == 'all') {
62
+ if (nth) {
63
+ level = level.concat(level.filter(dispensableNth).map(function (node) { return nthChild(node, nth); }));
64
+ }
65
+ }
66
+ else if (limit == 'two') {
67
+ level = level.slice(0, 1);
68
+ if (nth) {
69
+ level = level.concat(level.filter(dispensableNth).map(function (node) { return nthChild(node, nth); }));
70
+ }
71
+ }
72
+ else if (limit == 'one') {
73
+ var _b = tslib_1.__read((level = level.slice(0, 1)), 1), node = _b[0];
74
+ if (nth && dispensableNth(node)) {
75
+ level = [nthChild(node, nth)];
76
+ }
77
+ }
78
+ else if (limit == 'none') {
79
+ level = [any()];
80
+ if (nth) {
81
+ level = [nthChild(level[0], nth)];
82
+ }
83
+ }
84
+ try {
85
+ for (var level_1 = (e_1 = void 0, tslib_1.__values(level)), level_1_1 = level_1.next(); !level_1_1.done; level_1_1 = level_1.next()) {
86
+ var node = level_1_1.value;
87
+ node.level = i;
88
+ }
89
+ }
90
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
91
+ finally {
92
+ try {
93
+ if (level_1_1 && !level_1_1.done && (_a = level_1.return)) _a.call(level_1);
94
+ }
95
+ finally { if (e_1) throw e_1.error; }
96
+ }
97
+ stack.push(level);
98
+ if (stack.length >= config.seedMinLength) {
99
+ path = findUniquePath(stack, fallback);
100
+ if (path) {
101
+ return "break";
102
+ }
103
+ }
104
+ current = current.parentElement;
105
+ i++;
106
+ };
107
+ while (current) {
108
+ var state_1 = _loop_1();
109
+ if (state_1 === "break")
110
+ break;
111
+ }
112
+ if (!path) {
113
+ path = findUniquePath(stack, fallback);
114
+ }
115
+ if (!path && fallback) {
116
+ return fallback();
117
+ }
118
+ return path;
119
+ }
120
+ function findUniquePath(stack, fallback) {
121
+ var e_2, _a;
122
+ var paths = sort(combinations(stack));
123
+ if (paths.length > config.threshold) {
124
+ return fallback ? fallback() : null;
125
+ }
126
+ try {
127
+ for (var paths_1 = tslib_1.__values(paths), paths_1_1 = paths_1.next(); !paths_1_1.done; paths_1_1 = paths_1.next()) {
128
+ var candidate = paths_1_1.value;
129
+ if (unique(candidate)) {
130
+ return candidate;
131
+ }
132
+ }
133
+ }
134
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
135
+ finally {
136
+ try {
137
+ if (paths_1_1 && !paths_1_1.done && (_a = paths_1.return)) _a.call(paths_1);
138
+ }
139
+ finally { if (e_2) throw e_2.error; }
140
+ }
141
+ return null;
142
+ }
143
+ function selector(path) {
144
+ var node = path[0];
145
+ var query = node.name;
146
+ for (var i = 1; i < path.length; i++) {
147
+ var level = path[i].level || 0;
148
+ if (node.level === level - 1) {
149
+ query = "".concat(path[i].name, " > ").concat(query);
150
+ }
151
+ else {
152
+ query = "".concat(path[i].name, " ").concat(query);
153
+ }
154
+ node = path[i];
155
+ }
156
+ return query;
157
+ }
158
+ function penalty(path) {
159
+ return path.map(function (node) { return node.penalty; }).reduce(function (acc, i) { return acc + i; }, 0);
160
+ }
161
+ function unique(path) {
162
+ var css = selector(path);
163
+ switch (rootDocument.querySelectorAll(css).length) {
164
+ case 0:
165
+ throw new Error("Can't select any node with this selector: ".concat(css));
166
+ case 1:
167
+ return true;
168
+ default:
169
+ return false;
170
+ }
171
+ }
172
+ function id(input) {
173
+ var elementId = input.getAttribute('id');
174
+ if (elementId && config.idName(elementId)) {
175
+ return {
176
+ name: '#' + CSS.escape(elementId),
177
+ penalty: 0,
178
+ };
179
+ }
180
+ return null;
181
+ }
182
+ function attr(input) {
183
+ var attrs = Array.from(input.attributes).filter(function (attr) { return config.attr(attr.name, attr.value); });
184
+ return attrs.map(function (attr) { return ({
185
+ name: "[".concat(CSS.escape(attr.name), "=\"").concat(CSS.escape(attr.value), "\"]"),
186
+ penalty: 0.5,
187
+ }); });
188
+ }
189
+ function classNames(input) {
190
+ var names = Array.from(input.classList).filter(config.className);
191
+ return names.map(function (name) { return ({
192
+ name: '.' + CSS.escape(name),
193
+ penalty: 1,
194
+ }); });
195
+ }
196
+ function tagName(input) {
197
+ var name = input.tagName.toLowerCase();
198
+ if (config.tagName(name)) {
199
+ return {
200
+ name: name,
201
+ penalty: 2,
202
+ };
203
+ }
204
+ return null;
205
+ }
206
+ function any() {
207
+ return {
208
+ name: '*',
209
+ penalty: 3,
210
+ };
211
+ }
212
+ function index(input) {
213
+ var parent = input.parentNode;
214
+ if (!parent) {
215
+ return null;
216
+ }
217
+ var child = parent.firstChild;
218
+ if (!child) {
219
+ return null;
220
+ }
221
+ var i = 0;
222
+ while (child) {
223
+ if (child.nodeType === Node.ELEMENT_NODE) {
224
+ i++;
225
+ }
226
+ if (child === input) {
227
+ break;
228
+ }
229
+ child = child.nextSibling;
230
+ }
231
+ return i;
232
+ }
233
+ function nthChild(node, i) {
234
+ return {
235
+ name: node.name + ":nth-child(".concat(i, ")"),
236
+ penalty: node.penalty + 1,
237
+ };
238
+ }
239
+ function dispensableNth(node) {
240
+ return node.name !== 'html' && !node.name.startsWith('#');
241
+ }
242
+ function maybe() {
243
+ var level = [];
244
+ for (var _i = 0; _i < arguments.length; _i++) {
245
+ level[_i] = arguments[_i];
246
+ }
247
+ var list = level.filter(notEmpty);
248
+ if (list.length > 0) {
249
+ return list;
250
+ }
251
+ return null;
252
+ }
253
+ function notEmpty(value) {
254
+ return value !== null && value !== undefined;
255
+ }
256
+ function combinations(stack, path) {
257
+ var _a, _b, node, e_3_1;
258
+ var e_3, _c;
259
+ if (path === void 0) { path = []; }
260
+ return tslib_1.__generator(this, function (_d) {
261
+ switch (_d.label) {
262
+ case 0:
263
+ if (!(stack.length > 0)) return [3 /*break*/, 9];
264
+ _d.label = 1;
265
+ case 1:
266
+ _d.trys.push([1, 6, 7, 8]);
267
+ _a = tslib_1.__values(stack[0]), _b = _a.next();
268
+ _d.label = 2;
269
+ case 2:
270
+ if (!!_b.done) return [3 /*break*/, 5];
271
+ node = _b.value;
272
+ return [5 /*yield**/, tslib_1.__values(combinations(stack.slice(1, stack.length), path.concat(node)))];
273
+ case 3:
274
+ _d.sent();
275
+ _d.label = 4;
276
+ case 4:
277
+ _b = _a.next();
278
+ return [3 /*break*/, 2];
279
+ case 5: return [3 /*break*/, 8];
280
+ case 6:
281
+ e_3_1 = _d.sent();
282
+ e_3 = { error: e_3_1 };
283
+ return [3 /*break*/, 8];
284
+ case 7:
285
+ try {
286
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
287
+ }
288
+ finally { if (e_3) throw e_3.error; }
289
+ return [7 /*endfinally*/];
290
+ case 8: return [3 /*break*/, 11];
291
+ case 9: return [4 /*yield*/, path];
292
+ case 10:
293
+ _d.sent();
294
+ _d.label = 11;
295
+ case 11: return [2 /*return*/];
296
+ }
297
+ });
298
+ }
299
+ function sort(paths) {
300
+ return tslib_1.__spreadArray([], tslib_1.__read(paths), false).sort(function (a, b) { return penalty(a) - penalty(b); });
301
+ }
302
+ function optimize(path, input, scope) {
303
+ var i, newPath, newPathKey;
304
+ if (scope === void 0) { scope = {
305
+ counter: 0,
306
+ visited: new Map(),
307
+ }; }
308
+ return tslib_1.__generator(this, function (_a) {
309
+ switch (_a.label) {
310
+ case 0:
311
+ if (!(path.length > 2 && path.length > config.optimizedMinLength)) return [3 /*break*/, 5];
312
+ i = 1;
313
+ _a.label = 1;
314
+ case 1:
315
+ if (!(i < path.length - 1)) return [3 /*break*/, 5];
316
+ if (scope.counter > config.maxNumberOfTries) {
317
+ return [2 /*return*/]; // Okay At least I tried!
318
+ }
319
+ scope.counter += 1;
320
+ newPath = tslib_1.__spreadArray([], tslib_1.__read(path), false);
321
+ newPath.splice(i, 1);
322
+ newPathKey = selector(newPath);
323
+ if (scope.visited.has(newPathKey)) {
324
+ return [2 /*return*/];
325
+ }
326
+ if (!(unique(newPath) && same(newPath, input))) return [3 /*break*/, 4];
327
+ return [4 /*yield*/, newPath];
328
+ case 2:
329
+ _a.sent();
330
+ scope.visited.set(newPathKey, true);
331
+ return [5 /*yield**/, tslib_1.__values(optimize(newPath, input, scope))];
332
+ case 3:
333
+ _a.sent();
334
+ _a.label = 4;
335
+ case 4:
336
+ i++;
337
+ return [3 /*break*/, 1];
338
+ case 5: return [2 /*return*/];
339
+ }
340
+ });
341
+ }
342
+ function same(path, input) {
343
+ return rootDocument.querySelector(selector(path)) === input;
344
+ }
345
+ //# sourceMappingURL=finder.js.map