ghostfill 0.2.2 → 0.2.4
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.
- package/LICENSE +121 -0
- package/README.md +1 -1
- package/dist/{chunk-VMCU3BNJ.mjs → chunk-CKZ6PWBH.mjs} +2 -1
- package/dist/chunk-CKZ6PWBH.mjs.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +100 -32
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +101 -32
- package/dist/index.mjs.map +1 -1
- package/dist/server.d.mts +2 -2
- package/dist/server.d.ts +2 -2
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +1 -1
- package/dist/{types-B3DGbZyx.d.mts → types-BYkjRHCV.d.mts} +1 -1
- package/dist/{types-B3DGbZyx.d.ts → types-BYkjRHCV.d.ts} +1 -1
- package/package.json +2 -2
- package/dist/chunk-VMCU3BNJ.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -2,8 +2,9 @@ import {
|
|
|
2
2
|
PROVIDERS,
|
|
3
3
|
describeFields,
|
|
4
4
|
detectFields,
|
|
5
|
+
findLabel,
|
|
5
6
|
generateFillData
|
|
6
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-CKZ6PWBH.mjs";
|
|
7
8
|
|
|
8
9
|
// src/faker.ts
|
|
9
10
|
var FIRST_NAMES = ["James", "Sarah", "Michael", "Emma", "Robert", "Olivia", "David", "Sophia", "Daniel", "Isabella", "Ahmed", "Fatima", "Carlos", "Yuki", "Priya"];
|
|
@@ -55,8 +56,8 @@ function generateForField(field, context) {
|
|
|
55
56
|
return `https://www.${context.company.toLowerCase().replace(/\s+/g, "")}.com`;
|
|
56
57
|
}
|
|
57
58
|
if (field.type === "number" || field.type === "range") {
|
|
58
|
-
const min = field.min ? parseInt(field.min) : 1;
|
|
59
|
-
const max = field.max ? parseInt(field.max) : 100;
|
|
59
|
+
const min = field.min ? parseInt(field.min, 10) || 1 : 1;
|
|
60
|
+
const max = field.max ? parseInt(field.max, 10) || 100 : 100;
|
|
60
61
|
return String(randInt(min, max));
|
|
61
62
|
}
|
|
62
63
|
if (label.includes("first name") || label.includes("firstname")) return context.firstName;
|
|
@@ -116,14 +117,96 @@ function focusBlur(el) {
|
|
|
116
117
|
}
|
|
117
118
|
async function fillCustomSelect(button, value) {
|
|
118
119
|
button.click();
|
|
119
|
-
|
|
120
|
+
let waited = 0;
|
|
121
|
+
const step = 50;
|
|
122
|
+
while (waited < 500) {
|
|
123
|
+
await new Promise((r) => setTimeout(r, step));
|
|
124
|
+
waited += step;
|
|
125
|
+
const lb = button.getAttribute("aria-controls") ? document.getElementById(button.getAttribute("aria-controls")) : button.parentElement?.querySelector("[role=listbox]") || document.querySelector("[role=listbox]");
|
|
126
|
+
if (lb) break;
|
|
127
|
+
const cont = button.closest("[class*='relative']") || button.parentElement;
|
|
128
|
+
if (cont) {
|
|
129
|
+
const divs = cont.querySelectorAll("div");
|
|
130
|
+
for (const d of divs) {
|
|
131
|
+
if (d === button || d.contains(button) || button.contains(d)) continue;
|
|
132
|
+
if (d.classList.toString().includes("absolute") || d.classList.toString().includes("z-50")) {
|
|
133
|
+
waited = 999;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
120
139
|
const listboxId = button.getAttribute("aria-controls");
|
|
121
140
|
let listbox = listboxId ? document.getElementById(listboxId) : null;
|
|
122
141
|
if (!listbox) {
|
|
123
|
-
listbox = button.parentElement?.querySelector("[role=listbox]") ||
|
|
142
|
+
listbox = button.parentElement?.querySelector("[role=listbox]") || null;
|
|
124
143
|
}
|
|
125
|
-
if (listbox) {
|
|
126
|
-
const
|
|
144
|
+
if (!listbox) {
|
|
145
|
+
const all = document.querySelectorAll("[role=listbox]");
|
|
146
|
+
for (const lb of all) {
|
|
147
|
+
if (lb.offsetParent !== null || lb.offsetHeight > 0) {
|
|
148
|
+
listbox = lb;
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
let options = listbox ? listbox.querySelectorAll("[role=option]") : [];
|
|
154
|
+
if (!listbox || options.length === 0) {
|
|
155
|
+
let panel = null;
|
|
156
|
+
const container = button.closest("[class*='relative']") || button.parentElement;
|
|
157
|
+
if (container) {
|
|
158
|
+
for (const child of Array.from(container.children)) {
|
|
159
|
+
if (child === button || child.contains(button)) continue;
|
|
160
|
+
if (child.tagName === "LABEL" || child.tagName === "P" || child.tagName === "SPAN") continue;
|
|
161
|
+
const el = child;
|
|
162
|
+
const style = window.getComputedStyle(el);
|
|
163
|
+
if (el.classList.contains("absolute") || el.classList.contains("z-50") || style.position === "absolute" || style.position === "fixed") {
|
|
164
|
+
panel = el;
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (!panel) {
|
|
170
|
+
let sibling = button.nextElementSibling;
|
|
171
|
+
while (sibling) {
|
|
172
|
+
const tag = sibling.tagName;
|
|
173
|
+
if (tag !== "P" && tag !== "LABEL" && tag !== "SPAN" && tag === "DIV") {
|
|
174
|
+
panel = sibling;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
sibling = sibling.nextElementSibling;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (panel && panel !== button) {
|
|
181
|
+
let contentWait = 0;
|
|
182
|
+
while (contentWait < 1e3) {
|
|
183
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
184
|
+
contentWait += 100;
|
|
185
|
+
const btns = panel.querySelectorAll("button");
|
|
186
|
+
let realBtns = 0;
|
|
187
|
+
for (const b of btns) {
|
|
188
|
+
if (!b.querySelector("input")) realBtns++;
|
|
189
|
+
}
|
|
190
|
+
if (realBtns > 0) break;
|
|
191
|
+
}
|
|
192
|
+
const clickables = panel.querySelectorAll("button, [role=option], [data-value], li");
|
|
193
|
+
const filtered = [];
|
|
194
|
+
for (const c of clickables) {
|
|
195
|
+
const text = c.textContent?.trim() || "";
|
|
196
|
+
if (!text || text === "\xD7" || text === "\u2715") continue;
|
|
197
|
+
if (c.querySelector("input")) continue;
|
|
198
|
+
if (c === button) continue;
|
|
199
|
+
const hasInput = c.querySelector("input[type='text'], input[type='search']");
|
|
200
|
+
if (hasInput) continue;
|
|
201
|
+
filtered.push(c);
|
|
202
|
+
}
|
|
203
|
+
if (filtered.length > 0) {
|
|
204
|
+
options = filtered;
|
|
205
|
+
listbox = panel;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (options.length > 0) {
|
|
127
210
|
for (const opt of options) {
|
|
128
211
|
const text = opt.textContent?.trim();
|
|
129
212
|
if (text === value || text?.toLowerCase() === value.toLowerCase()) {
|
|
@@ -142,7 +225,7 @@ async function fillCustomSelect(button, value) {
|
|
|
142
225
|
}
|
|
143
226
|
for (const opt of options) {
|
|
144
227
|
const text = (opt.textContent?.trim() || "").toLowerCase();
|
|
145
|
-
const isPlaceholder = text.startsWith("select") || text === "" || text === "---" || text === "choose" || text.startsWith("choose");
|
|
228
|
+
const isPlaceholder = text.startsWith("select") || text === "" || text === "---" || text === "choose" || text.startsWith("choose") || text.startsWith("search");
|
|
146
229
|
if (!isPlaceholder) {
|
|
147
230
|
opt.click();
|
|
148
231
|
await new Promise((r) => setTimeout(r, 50));
|
|
@@ -264,26 +347,11 @@ async function fillFields(fields, fillData) {
|
|
|
264
347
|
}
|
|
265
348
|
return { filled, errors };
|
|
266
349
|
}
|
|
267
|
-
function findLabel(el) {
|
|
268
|
-
if (el.id) {
|
|
269
|
-
const label = document.querySelector(
|
|
270
|
-
`label[for="${CSS.escape(el.id)}"]`
|
|
271
|
-
);
|
|
272
|
-
if (label?.textContent?.trim()) return label.textContent.trim();
|
|
273
|
-
}
|
|
274
|
-
const parent = el.closest("label");
|
|
275
|
-
if (parent) {
|
|
276
|
-
const clone = parent.cloneNode(true);
|
|
277
|
-
clone.querySelectorAll("input").forEach((c) => c.remove());
|
|
278
|
-
return clone.textContent?.trim() || "";
|
|
279
|
-
}
|
|
280
|
-
return "";
|
|
281
|
-
}
|
|
282
350
|
|
|
283
351
|
// src/selector.ts
|
|
284
352
|
var currentHighlight = null;
|
|
285
353
|
var overlay = null;
|
|
286
|
-
function
|
|
354
|
+
function createSelectorOverlay(color) {
|
|
287
355
|
const div = document.createElement("div");
|
|
288
356
|
div.id = "ghostfill-selector-overlay";
|
|
289
357
|
const r = parseInt(color.slice(1, 3), 16);
|
|
@@ -302,7 +370,7 @@ function createOverlay(color) {
|
|
|
302
370
|
return div;
|
|
303
371
|
}
|
|
304
372
|
function positionOverlay(el, color) {
|
|
305
|
-
if (!overlay) overlay =
|
|
373
|
+
if (!overlay) overlay = createSelectorOverlay(color);
|
|
306
374
|
const rect = el.getBoundingClientRect();
|
|
307
375
|
Object.assign(overlay.style, {
|
|
308
376
|
top: `${rect.top}px`,
|
|
@@ -374,6 +442,9 @@ function startSelection(onSelect, onCancel, ghostfillRoot, highlightColor = "#63
|
|
|
374
442
|
return cleanup;
|
|
375
443
|
}
|
|
376
444
|
|
|
445
|
+
// package.json
|
|
446
|
+
var version = "0.2.4";
|
|
447
|
+
|
|
377
448
|
// src/overlay.ts
|
|
378
449
|
var STORAGE_KEY = "ghostfill_settings";
|
|
379
450
|
var POS_KEY = "ghostfill_pos";
|
|
@@ -598,7 +669,7 @@ var CSS2 = `
|
|
|
598
669
|
font-size: 13px; font-weight: 600; color: #fff;
|
|
599
670
|
letter-spacing: -0.0094em;
|
|
600
671
|
}
|
|
601
|
-
.gf-pop-header .gf-slash { color:
|
|
672
|
+
.gf-pop-header .gf-slash { color: #6366f1; }
|
|
602
673
|
.gf-pop-header .gf-header-right {
|
|
603
674
|
display: flex; align-items: center; gap: 6px;
|
|
604
675
|
}
|
|
@@ -863,7 +934,7 @@ var CSS2 = `
|
|
|
863
934
|
line-height: 1.5;
|
|
864
935
|
}
|
|
865
936
|
`;
|
|
866
|
-
function
|
|
937
|
+
function createOverlay(options) {
|
|
867
938
|
const aiConfig = options.ai || null;
|
|
868
939
|
const saved = loadSettings(aiConfig?.provider || "openai");
|
|
869
940
|
if (options.apiKey) {
|
|
@@ -884,9 +955,7 @@ function createOverlay2(options) {
|
|
|
884
955
|
active: false,
|
|
885
956
|
selecting: false,
|
|
886
957
|
selectedBlock: null,
|
|
887
|
-
fields: []
|
|
888
|
-
overlay: host,
|
|
889
|
-
shadowRoot: shadow
|
|
958
|
+
fields: []
|
|
890
959
|
};
|
|
891
960
|
const bar = document.createElement("div");
|
|
892
961
|
bar.className = "gf-bar";
|
|
@@ -1033,7 +1102,7 @@ function createOverlay2(options) {
|
|
|
1033
1102
|
<div class="gf-pop-header">
|
|
1034
1103
|
<h3><span class="gf-slash">/</span>ghostfill</h3>
|
|
1035
1104
|
<div class="gf-header-right">
|
|
1036
|
-
<span class="gf-version">
|
|
1105
|
+
<span class="gf-version">v${version}</span>
|
|
1037
1106
|
<button class="gf-theme-btn" id="gf-s-theme" title="Toggle theme">
|
|
1038
1107
|
${saved.theme === "dark" ? ICONS.sun : ICONS.moon}
|
|
1039
1108
|
</button>
|
|
@@ -1875,7 +1944,7 @@ function init(options = {}) {
|
|
|
1875
1944
|
instance.destroy();
|
|
1876
1945
|
instance = null;
|
|
1877
1946
|
}
|
|
1878
|
-
const { state, destroy } =
|
|
1947
|
+
const { state, destroy } = createOverlay(options);
|
|
1879
1948
|
instance = { destroy };
|
|
1880
1949
|
return { destroy };
|
|
1881
1950
|
}
|