ghostfill 0.2.3 → 0.3.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.
- package/README.md +28 -2
- 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 +96 -31
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +97 -31
- package/dist/index.mjs.map +1 -1
- package/dist/mcp.d.mts +2 -0
- package/dist/mcp.mjs +315 -0
- package/dist/mcp.mjs.map +1 -0
- 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 +23 -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;
|
|
143
|
+
}
|
|
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
|
+
}
|
|
124
208
|
}
|
|
125
|
-
if (
|
|
126
|
-
const options = listbox.querySelectorAll("[role=option]");
|
|
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`,
|
|
@@ -598,7 +666,7 @@ var CSS2 = `
|
|
|
598
666
|
font-size: 13px; font-weight: 600; color: #fff;
|
|
599
667
|
letter-spacing: -0.0094em;
|
|
600
668
|
}
|
|
601
|
-
.gf-pop-header .gf-slash { color:
|
|
669
|
+
.gf-pop-header .gf-slash { color: #6366f1; }
|
|
602
670
|
.gf-pop-header .gf-header-right {
|
|
603
671
|
display: flex; align-items: center; gap: 6px;
|
|
604
672
|
}
|
|
@@ -863,7 +931,7 @@ var CSS2 = `
|
|
|
863
931
|
line-height: 1.5;
|
|
864
932
|
}
|
|
865
933
|
`;
|
|
866
|
-
function
|
|
934
|
+
function createOverlay(options) {
|
|
867
935
|
const aiConfig = options.ai || null;
|
|
868
936
|
const saved = loadSettings(aiConfig?.provider || "openai");
|
|
869
937
|
if (options.apiKey) {
|
|
@@ -884,9 +952,7 @@ function createOverlay2(options) {
|
|
|
884
952
|
active: false,
|
|
885
953
|
selecting: false,
|
|
886
954
|
selectedBlock: null,
|
|
887
|
-
fields: []
|
|
888
|
-
overlay: host,
|
|
889
|
-
shadowRoot: shadow
|
|
955
|
+
fields: []
|
|
890
956
|
};
|
|
891
957
|
const bar = document.createElement("div");
|
|
892
958
|
bar.className = "gf-bar";
|
|
@@ -1875,7 +1941,7 @@ function init(options = {}) {
|
|
|
1875
1941
|
instance.destroy();
|
|
1876
1942
|
instance = null;
|
|
1877
1943
|
}
|
|
1878
|
-
const { state, destroy } =
|
|
1944
|
+
const { state, destroy } = createOverlay(options);
|
|
1879
1945
|
instance = { destroy };
|
|
1880
1946
|
return { destroy };
|
|
1881
1947
|
}
|