@blotoutio/providers-auto-form-fill-sdk 0.26.4 → 0.26.6

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 (3) hide show
  1. package/index.cjs.js +222 -0
  2. package/index.mjs +220 -0
  3. package/package.json +5 -2
package/index.cjs.js ADDED
@@ -0,0 +1,222 @@
1
+ 'use strict';
2
+
3
+ const formFillCountKey = 'formFillCount';
4
+
5
+ const extractHighPrioritySelector = (element) => {
6
+ if (!element) {
7
+ return '';
8
+ }
9
+ const attributes = element ? element.attributes : [];
10
+ if (element.id) {
11
+ return `#${element.id}`;
12
+ }
13
+ if (element.className) {
14
+ return `.${element.className.split(' ').join('.')}`;
15
+ }
16
+ if (element.name) {
17
+ return `${element.tagName.toLowerCase()}[name="${element.name}"]`;
18
+ }
19
+ for (let i = 0; i < attributes.length; i++) {
20
+ if (/^data-(.+)$/.test(attributes[i].name)) {
21
+ return `${element.tagName.toLowerCase()}[${attributes[i].name}="${attributes[i].value}"]`;
22
+ }
23
+ }
24
+ if (element.tagName.toLowerCase() === 'input' && element.type) {
25
+ return `input[type="${element.type}"]`;
26
+ }
27
+ for (let i = 0; i < attributes.length; i++) {
28
+ const attrName = attributes[i].name;
29
+ if (attrName !== 'type') {
30
+ const attrValue = attributes[i].value;
31
+ return `${element.tagName.toLowerCase()}[${attrName}="${attrValue}"]`;
32
+ }
33
+ }
34
+ return element.tagName.toLowerCase();
35
+ };
36
+ const extractFields = (formSelector) => {
37
+ const data = [];
38
+ const formElement = document.querySelector(formSelector);
39
+ const selectElements = formElement === null || formElement === void 0 ? void 0 : formElement.querySelectorAll('select');
40
+ selectElements === null || selectElements === void 0 ? void 0 : selectElements.forEach((selectElement) => {
41
+ const selectValue = selectElement.value;
42
+ const selectSelector = extractHighPrioritySelector(selectElement);
43
+ if (selectValue && selectSelector) {
44
+ data.push({
45
+ selector: selectSelector,
46
+ value: selectValue,
47
+ });
48
+ }
49
+ });
50
+ const inputElements = formElement === null || formElement === void 0 ? void 0 : formElement.querySelectorAll('input');
51
+ inputElements === null || inputElements === void 0 ? void 0 : inputElements.forEach((inputElement) => {
52
+ if (inputElement.type === 'password' ||
53
+ inputElement.type === 'file' ||
54
+ inputElement.type === 'button' ||
55
+ inputElement.type === 'hidden' ||
56
+ inputElement.type === 'image' ||
57
+ inputElement.type === 'submit') {
58
+ return;
59
+ }
60
+ const inputValue = inputElement.type === 'radio' || inputElement.type === 'checkbox'
61
+ ? inputElement.checked
62
+ : inputElement.value;
63
+ const inputSelector = extractHighPrioritySelector(inputElement);
64
+ if (inputValue && inputSelector) {
65
+ data.push({
66
+ selector: inputSelector,
67
+ value: inputValue,
68
+ });
69
+ }
70
+ });
71
+ const textAreaElements = formElement === null || formElement === void 0 ? void 0 : formElement.querySelectorAll('textarea');
72
+ textAreaElements === null || textAreaElements === void 0 ? void 0 : textAreaElements.forEach((textAreaElement) => {
73
+ const textAreaValue = textAreaElement.value;
74
+ const textAreaSelector = extractHighPrioritySelector(textAreaElement);
75
+ if (textAreaValue && textAreaSelector) {
76
+ data.push({
77
+ selector: textAreaSelector,
78
+ value: textAreaValue,
79
+ });
80
+ }
81
+ });
82
+ return JSON.stringify(data);
83
+ };
84
+ const updateFormFields = (formSelector, keys, cachedKvData) => {
85
+ try {
86
+ formSelector = formSelector.trim();
87
+ const formElement = document.querySelector(formSelector);
88
+ const formattedSelector = `AUTO_FILL_${formSelector}`;
89
+ if (!formSelector ||
90
+ !formElement ||
91
+ !(formattedSelector in { ...keys, ...cachedKvData })) {
92
+ return false;
93
+ }
94
+ const isDataCached = Object.keys(cachedKvData).includes(formattedSelector);
95
+ const fields = isDataCached
96
+ ? JSON.parse(cachedKvData[formattedSelector].toString())
97
+ : JSON.parse(keys[formattedSelector].toString());
98
+ if (!fields || !fields.length) {
99
+ return false;
100
+ }
101
+ fields.forEach((field) => {
102
+ const element = formElement === null || formElement === void 0 ? void 0 : formElement.querySelector(field.selector);
103
+ if (element) {
104
+ if ((element.tagName.toLowerCase() === 'input' &&
105
+ element.type === 'checkbox') ||
106
+ element.type === 'radio') {
107
+ ;
108
+ element.checked = field.value;
109
+ }
110
+ else {
111
+ element.value = field.value;
112
+ }
113
+ }
114
+ });
115
+ return true;
116
+ }
117
+ catch (e) {
118
+ console.log(`Unable to auto fill the form with selector ${formSelector.trim()}`);
119
+ console.error(e);
120
+ return false;
121
+ }
122
+ };
123
+ const getFormattedSelectorName = (selector) => {
124
+ return `AUTO_FILL_${selector}`;
125
+ };
126
+
127
+ const sendAutoFillCountToWorker = (successCount, getEdgeData, sendEdgeData) => {
128
+ if (successCount) {
129
+ getEdgeData([formFillCountKey], (keys) => {
130
+ if (!isNaN(parseInt(keys[formFillCountKey]))) {
131
+ successCount = successCount + parseInt(keys[formFillCountKey]);
132
+ }
133
+ sendEdgeData({ [formFillCountKey]: successCount.toString() }, {}, { method: 'beacon' });
134
+ });
135
+ }
136
+ };
137
+ const init = (params) => {
138
+ const { manifest, getEdgeData, sendEdgeData, keyName } = params;
139
+ try {
140
+ if (!manifest ||
141
+ !manifest.variables ||
142
+ !manifest.variables['formSelectors']) {
143
+ return;
144
+ }
145
+ const formSelectors = JSON.parse(manifest.variables['formSelectors']);
146
+ if (!formSelectors || !formSelectors.length) {
147
+ console.error('Enter a valid form selectors to auto-fill');
148
+ return;
149
+ }
150
+ // forms which are present in curr page
151
+ const curFormSelectors = formSelectors.filter((item) => item && document.querySelector(item) != null);
152
+ if (!curFormSelectors.length) {
153
+ return;
154
+ }
155
+ const formattedSelectors = curFormSelectors.map((item) => getFormattedSelectorName(item));
156
+ const sessionData = JSON.parse(sessionStorage.getItem(keyName) || '{}');
157
+ const kvData = sessionData && 'kv' in sessionData ? sessionData['kv'] : {};
158
+ const formSelectorsWOCache = formattedSelectors.filter((formSelector) => !Object.keys(kvData).includes(formSelector));
159
+ let successCount = 0;
160
+ if (formSelectorsWOCache.length) {
161
+ getEdgeData(formSelectorsWOCache, (keys) => {
162
+ curFormSelectors.forEach((formSelector) => {
163
+ var _a;
164
+ const result = updateFormFields(formSelector, keys, kvData);
165
+ successCount = successCount + (result === true ? 1 : 0);
166
+ const formattedSelector = `AUTO_FILL_${formSelector}`;
167
+ // storing the form data in session if the form gets successfully auto-filled
168
+ if (formattedSelector in keys && result === true) {
169
+ const curSessionData = JSON.parse(sessionStorage.getItem(keyName) || '{}');
170
+ const curKvData = (_a = curSessionData['kv']) !== null && _a !== void 0 ? _a : {};
171
+ sessionStorage.setItem(keyName, JSON.stringify({
172
+ ...curSessionData,
173
+ kv: {
174
+ ...curKvData,
175
+ [formattedSelector]: keys[formattedSelector].toString(),
176
+ },
177
+ }));
178
+ }
179
+ });
180
+ sendAutoFillCountToWorker(successCount, getEdgeData, sendEdgeData);
181
+ });
182
+ }
183
+ else {
184
+ curFormSelectors.forEach((formSelector) => {
185
+ const result = updateFormFields(formSelector, {}, kvData);
186
+ successCount = successCount + (result === true ? 1 : 0);
187
+ });
188
+ sendAutoFillCountToWorker(successCount, getEdgeData, sendEdgeData);
189
+ }
190
+ curFormSelectors.forEach((formSelector) => {
191
+ const element = document.querySelector(formSelector);
192
+ if (element) {
193
+ element.addEventListener('submit', () => {
194
+ const formData = extractFields(formSelector);
195
+ const formattedSelector = getFormattedSelectorName(formSelector);
196
+ sendEdgeData({ [formattedSelector]: formData }, {}, { method: 'beacon' });
197
+ });
198
+ }
199
+ });
200
+ }
201
+ catch (e) {
202
+ console.error(e);
203
+ }
204
+ };
205
+
206
+ const data = {
207
+ name: 'autoFormFill',
208
+ init,
209
+ };
210
+ try {
211
+ if (window) {
212
+ if (!window.edgetagProviders) {
213
+ window.edgetagProviders = [];
214
+ }
215
+ window.edgetagProviders.push(data);
216
+ }
217
+ }
218
+ catch {
219
+ // No window
220
+ }
221
+
222
+ module.exports = data;
package/index.mjs ADDED
@@ -0,0 +1,220 @@
1
+ const formFillCountKey = 'formFillCount';
2
+
3
+ const extractHighPrioritySelector = (element) => {
4
+ if (!element) {
5
+ return '';
6
+ }
7
+ const attributes = element ? element.attributes : [];
8
+ if (element.id) {
9
+ return `#${element.id}`;
10
+ }
11
+ if (element.className) {
12
+ return `.${element.className.split(' ').join('.')}`;
13
+ }
14
+ if (element.name) {
15
+ return `${element.tagName.toLowerCase()}[name="${element.name}"]`;
16
+ }
17
+ for (let i = 0; i < attributes.length; i++) {
18
+ if (/^data-(.+)$/.test(attributes[i].name)) {
19
+ return `${element.tagName.toLowerCase()}[${attributes[i].name}="${attributes[i].value}"]`;
20
+ }
21
+ }
22
+ if (element.tagName.toLowerCase() === 'input' && element.type) {
23
+ return `input[type="${element.type}"]`;
24
+ }
25
+ for (let i = 0; i < attributes.length; i++) {
26
+ const attrName = attributes[i].name;
27
+ if (attrName !== 'type') {
28
+ const attrValue = attributes[i].value;
29
+ return `${element.tagName.toLowerCase()}[${attrName}="${attrValue}"]`;
30
+ }
31
+ }
32
+ return element.tagName.toLowerCase();
33
+ };
34
+ const extractFields = (formSelector) => {
35
+ const data = [];
36
+ const formElement = document.querySelector(formSelector);
37
+ const selectElements = formElement === null || formElement === void 0 ? void 0 : formElement.querySelectorAll('select');
38
+ selectElements === null || selectElements === void 0 ? void 0 : selectElements.forEach((selectElement) => {
39
+ const selectValue = selectElement.value;
40
+ const selectSelector = extractHighPrioritySelector(selectElement);
41
+ if (selectValue && selectSelector) {
42
+ data.push({
43
+ selector: selectSelector,
44
+ value: selectValue,
45
+ });
46
+ }
47
+ });
48
+ const inputElements = formElement === null || formElement === void 0 ? void 0 : formElement.querySelectorAll('input');
49
+ inputElements === null || inputElements === void 0 ? void 0 : inputElements.forEach((inputElement) => {
50
+ if (inputElement.type === 'password' ||
51
+ inputElement.type === 'file' ||
52
+ inputElement.type === 'button' ||
53
+ inputElement.type === 'hidden' ||
54
+ inputElement.type === 'image' ||
55
+ inputElement.type === 'submit') {
56
+ return;
57
+ }
58
+ const inputValue = inputElement.type === 'radio' || inputElement.type === 'checkbox'
59
+ ? inputElement.checked
60
+ : inputElement.value;
61
+ const inputSelector = extractHighPrioritySelector(inputElement);
62
+ if (inputValue && inputSelector) {
63
+ data.push({
64
+ selector: inputSelector,
65
+ value: inputValue,
66
+ });
67
+ }
68
+ });
69
+ const textAreaElements = formElement === null || formElement === void 0 ? void 0 : formElement.querySelectorAll('textarea');
70
+ textAreaElements === null || textAreaElements === void 0 ? void 0 : textAreaElements.forEach((textAreaElement) => {
71
+ const textAreaValue = textAreaElement.value;
72
+ const textAreaSelector = extractHighPrioritySelector(textAreaElement);
73
+ if (textAreaValue && textAreaSelector) {
74
+ data.push({
75
+ selector: textAreaSelector,
76
+ value: textAreaValue,
77
+ });
78
+ }
79
+ });
80
+ return JSON.stringify(data);
81
+ };
82
+ const updateFormFields = (formSelector, keys, cachedKvData) => {
83
+ try {
84
+ formSelector = formSelector.trim();
85
+ const formElement = document.querySelector(formSelector);
86
+ const formattedSelector = `AUTO_FILL_${formSelector}`;
87
+ if (!formSelector ||
88
+ !formElement ||
89
+ !(formattedSelector in { ...keys, ...cachedKvData })) {
90
+ return false;
91
+ }
92
+ const isDataCached = Object.keys(cachedKvData).includes(formattedSelector);
93
+ const fields = isDataCached
94
+ ? JSON.parse(cachedKvData[formattedSelector].toString())
95
+ : JSON.parse(keys[formattedSelector].toString());
96
+ if (!fields || !fields.length) {
97
+ return false;
98
+ }
99
+ fields.forEach((field) => {
100
+ const element = formElement === null || formElement === void 0 ? void 0 : formElement.querySelector(field.selector);
101
+ if (element) {
102
+ if ((element.tagName.toLowerCase() === 'input' &&
103
+ element.type === 'checkbox') ||
104
+ element.type === 'radio') {
105
+ ;
106
+ element.checked = field.value;
107
+ }
108
+ else {
109
+ element.value = field.value;
110
+ }
111
+ }
112
+ });
113
+ return true;
114
+ }
115
+ catch (e) {
116
+ console.log(`Unable to auto fill the form with selector ${formSelector.trim()}`);
117
+ console.error(e);
118
+ return false;
119
+ }
120
+ };
121
+ const getFormattedSelectorName = (selector) => {
122
+ return `AUTO_FILL_${selector}`;
123
+ };
124
+
125
+ const sendAutoFillCountToWorker = (successCount, getEdgeData, sendEdgeData) => {
126
+ if (successCount) {
127
+ getEdgeData([formFillCountKey], (keys) => {
128
+ if (!isNaN(parseInt(keys[formFillCountKey]))) {
129
+ successCount = successCount + parseInt(keys[formFillCountKey]);
130
+ }
131
+ sendEdgeData({ [formFillCountKey]: successCount.toString() }, {}, { method: 'beacon' });
132
+ });
133
+ }
134
+ };
135
+ const init = (params) => {
136
+ const { manifest, getEdgeData, sendEdgeData, keyName } = params;
137
+ try {
138
+ if (!manifest ||
139
+ !manifest.variables ||
140
+ !manifest.variables['formSelectors']) {
141
+ return;
142
+ }
143
+ const formSelectors = JSON.parse(manifest.variables['formSelectors']);
144
+ if (!formSelectors || !formSelectors.length) {
145
+ console.error('Enter a valid form selectors to auto-fill');
146
+ return;
147
+ }
148
+ // forms which are present in curr page
149
+ const curFormSelectors = formSelectors.filter((item) => item && document.querySelector(item) != null);
150
+ if (!curFormSelectors.length) {
151
+ return;
152
+ }
153
+ const formattedSelectors = curFormSelectors.map((item) => getFormattedSelectorName(item));
154
+ const sessionData = JSON.parse(sessionStorage.getItem(keyName) || '{}');
155
+ const kvData = sessionData && 'kv' in sessionData ? sessionData['kv'] : {};
156
+ const formSelectorsWOCache = formattedSelectors.filter((formSelector) => !Object.keys(kvData).includes(formSelector));
157
+ let successCount = 0;
158
+ if (formSelectorsWOCache.length) {
159
+ getEdgeData(formSelectorsWOCache, (keys) => {
160
+ curFormSelectors.forEach((formSelector) => {
161
+ var _a;
162
+ const result = updateFormFields(formSelector, keys, kvData);
163
+ successCount = successCount + (result === true ? 1 : 0);
164
+ const formattedSelector = `AUTO_FILL_${formSelector}`;
165
+ // storing the form data in session if the form gets successfully auto-filled
166
+ if (formattedSelector in keys && result === true) {
167
+ const curSessionData = JSON.parse(sessionStorage.getItem(keyName) || '{}');
168
+ const curKvData = (_a = curSessionData['kv']) !== null && _a !== void 0 ? _a : {};
169
+ sessionStorage.setItem(keyName, JSON.stringify({
170
+ ...curSessionData,
171
+ kv: {
172
+ ...curKvData,
173
+ [formattedSelector]: keys[formattedSelector].toString(),
174
+ },
175
+ }));
176
+ }
177
+ });
178
+ sendAutoFillCountToWorker(successCount, getEdgeData, sendEdgeData);
179
+ });
180
+ }
181
+ else {
182
+ curFormSelectors.forEach((formSelector) => {
183
+ const result = updateFormFields(formSelector, {}, kvData);
184
+ successCount = successCount + (result === true ? 1 : 0);
185
+ });
186
+ sendAutoFillCountToWorker(successCount, getEdgeData, sendEdgeData);
187
+ }
188
+ curFormSelectors.forEach((formSelector) => {
189
+ const element = document.querySelector(formSelector);
190
+ if (element) {
191
+ element.addEventListener('submit', () => {
192
+ const formData = extractFields(formSelector);
193
+ const formattedSelector = getFormattedSelectorName(formSelector);
194
+ sendEdgeData({ [formattedSelector]: formData }, {}, { method: 'beacon' });
195
+ });
196
+ }
197
+ });
198
+ }
199
+ catch (e) {
200
+ console.error(e);
201
+ }
202
+ };
203
+
204
+ const data = {
205
+ name: 'autoFormFill',
206
+ init,
207
+ };
208
+ try {
209
+ if (window) {
210
+ if (!window.edgetagProviders) {
211
+ window.edgetagProviders = [];
212
+ }
213
+ window.edgetagProviders.push(data);
214
+ }
215
+ }
216
+ catch {
217
+ // No window
218
+ }
219
+
220
+ export { data as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blotoutio/providers-auto-form-fill-sdk",
3
- "version": "0.26.4",
3
+ "version": "0.26.6",
4
4
  "description": "Auto Form Fill Browser SDK for EdgeTag",
5
5
  "author": "Blotout",
6
6
  "license": "MIT",
@@ -8,13 +8,16 @@
8
8
  "publishConfig": {
9
9
  "access": "public"
10
10
  },
11
- "main": "./index.js",
11
+ "main": "./index.cjs.js",
12
+ "module": "./index.mjs",
12
13
  "repository": {
13
14
  "type": "git",
14
15
  "url": "git+https://github.com/blotoutio/edgetag-sdk.git"
15
16
  },
16
17
  "files": [
17
18
  "index.js",
19
+ "index.cjs.js",
20
+ "index.mjs",
18
21
  "package.json",
19
22
  "README.md"
20
23
  ]