@uxbertlabs/reportly 1.0.5 → 1.0.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.
@@ -15,6 +15,7 @@ declare class Reportly {
15
15
  init(userConfig?: Partial<ReportlyConfig>): void;
16
16
  private setupKeyboardShortcuts;
17
17
  private handleButtonClick;
18
+ private captureWithMode;
18
19
  private startAnnotation;
19
20
  private exitAnnotation;
20
21
  private finishAnnotation;
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/core/init.ts"],"names":[],"mappings":"AAUA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,cAAc,EAA4B,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEpG,cAAM,QAAQ;IACZ,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,aAAa,CAAU;;IAe/B,IAAI,CAAC,UAAU,GAAE,OAAO,CAAC,cAAc,CAAM,GAAG,IAAI;IAuDpD,OAAO,CAAC,sBAAsB;YAUhB,iBAAiB;IAoB/B,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,cAAc;YASR,gBAAgB;YA2BhB,gBAAgB;IAwB9B,OAAO,CAAC,iBAAiB;IA4BzB,OAAO,CAAC,gBAAgB;IAQxB,IAAI,IAAI,IAAI;IAIZ,KAAK,IAAI,IAAI;IAKb,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI;IAMtD,cAAc,IAAI,UAAU,EAAE;IAI9B,gBAAgB,IAAI,IAAI;IAIxB,eAAe,IAAI,IAAI;IAIvB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI;IAIhD,OAAO,IAAI,IAAI;CAOhB;AAGD,QAAA,MAAM,QAAQ,UAAiB,CAAC;AAGhC,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/core/init.ts"],"names":[],"mappings":"AAUA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,cAAc,EAA4B,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEpG,cAAM,QAAQ;IACZ,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,aAAa,CAAU;;IAe/B,IAAI,CAAC,UAAU,GAAE,OAAO,CAAC,cAAc,CAAM,GAAG,IAAI;IAwDpD,OAAO,CAAC,sBAAsB;YAUhB,iBAAiB;YAUjB,eAAe;IAyB7B,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,cAAc;YASR,gBAAgB;YA2BhB,gBAAgB;IA4B9B,OAAO,CAAC,iBAAiB;IA4BzB,OAAO,CAAC,gBAAgB;IAQxB,IAAI,IAAI,IAAI;IAIZ,KAAK,IAAI,IAAI;IAKb,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI;IAMtD,cAAc,IAAI,UAAU,EAAE;IAI9B,gBAAgB,IAAI,IAAI;IAIxB,eAAe,IAAI,IAAI;IAIvB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI;IAIhD,OAAO,IAAI,IAAI;CAOhB;AAGD,QAAA,MAAM,QAAQ,UAAiB,CAAC;AAGhC,eAAe,QAAQ,CAAC"}
@@ -6,6 +6,7 @@ declare class State {
6
6
  private screenshot;
7
7
  private annotations;
8
8
  private listeners;
9
+ private captureMode;
9
10
  constructor();
10
11
  setState(newState: StateType): void;
11
12
  getState(): StateType;
@@ -16,6 +17,8 @@ declare class State {
16
17
  addAnnotation(annotation: Annotation): void;
17
18
  getAnnotations(): Annotation[];
18
19
  clearAnnotations(): void;
20
+ setCaptureMode(mode: 'viewport' | 'fullpage'): void;
21
+ getCaptureMode(): 'viewport' | 'fullpage';
19
22
  reset(): void;
20
23
  on(event: string, callback: EventCallback): void;
21
24
  emit(event: string, data?: any): void;
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/core/state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAkB,aAAa,EAAE,MAAM,UAAU,CAAC;AAEhG,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAI3C,CAAC;AAEF,cAAM,KAAK;IACT,OAAO,CAAC,YAAY,CAAY;IAChC,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,SAAS,CAAiB;;IAUlC,QAAQ,CAAC,QAAQ,EAAE,SAAS,GAAG,IAAI;IAKnC,QAAQ,IAAI,SAAS;IAIrB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAIhC,QAAQ,IAAI,SAAS,GAAG,IAAI;IAI5B,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIvC,aAAa,IAAI,MAAM,GAAG,IAAI;IAI9B,aAAa,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IAI3C,cAAc,IAAI,UAAU,EAAE;IAI9B,gBAAgB,IAAI,IAAI;IAIxB,KAAK,IAAI,IAAI;IAQb,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI;IAOhD,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;CAKtC;AAED,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/core/state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAkB,aAAa,EAAE,MAAM,UAAU,CAAC;AAEhG,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAI3C,CAAC;AAEF,cAAM,KAAK;IACT,OAAO,CAAC,YAAY,CAAY;IAChC,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,WAAW,CAA0B;;IAW7C,QAAQ,CAAC,QAAQ,EAAE,SAAS,GAAG,IAAI;IAKnC,QAAQ,IAAI,SAAS;IAIrB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAIhC,QAAQ,IAAI,SAAS,GAAG,IAAI;IAI5B,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIvC,aAAa,IAAI,MAAM,GAAG,IAAI;IAI9B,aAAa,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IAI3C,cAAc,IAAI,UAAU,EAAE;IAI9B,gBAAgB,IAAI,IAAI;IAIxB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI;IAInD,cAAc,IAAI,UAAU,GAAG,UAAU;IAIzC,KAAK,IAAI,IAAI;IASb,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI;IAOhD,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;CAKtC;AAED,eAAe,KAAK,CAAC"}
@@ -15,7 +15,7 @@ declare class AnnotationManager {
15
15
  constructor();
16
16
  createCanvas(): HTMLCanvasElement;
17
17
  private updateCanvasSize;
18
- show(): void;
18
+ show(mode?: 'viewport' | 'fullpage'): void;
19
19
  hide(): void;
20
20
  setTool(tool: AnnotationTool): void;
21
21
  setColor(color: string): void;
@@ -1 +1 @@
1
- {"version":3,"file":"annotation.d.ts","sourceRoot":"","sources":["../../src/features/annotation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAqB,MAAM,UAAU,CAAC;AAElE,cAAM,iBAAiB;IACrB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,GAAG,CAAkC;IAC7C,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAU;IAC7B,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,qBAAqB,CAA6E;;IAiB1G,YAAY,IAAI,iBAAiB;IA2BjC,OAAO,CAAC,gBAAgB;IAwBxB,IAAI,IAAI,IAAI;IAYZ,IAAI,IAAI,IAAI;IASZ,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAInC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI7B,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,eAAe;IAoBvB,OAAO,CAAC,aAAa;IAsCrB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,QAAQ;IAehB,OAAO,CAAC,SAAS;IA8BjB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,eAAe;IA+DvB,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,QAAQ;IAuBhB,OAAO,CAAC,MAAM;IAmBd,IAAI,IAAI,IAAI;IAOZ,KAAK,IAAI,IAAI;IAKP,yBAAyB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA0BxE,OAAO,IAAI,IAAI;CAOhB;AAED,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"annotation.d.ts","sourceRoot":"","sources":["../../src/features/annotation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAqB,MAAM,UAAU,CAAC;AAElE,cAAM,iBAAiB;IACrB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,GAAG,CAAkC;IAC7C,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAU;IAC7B,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,qBAAqB,CAA6E;;IAiB1G,YAAY,IAAI,iBAAiB;IA2BjC,OAAO,CAAC,gBAAgB;IA8BxB,IAAI,CAAC,IAAI,GAAE,UAAU,GAAG,UAAuB,GAAG,IAAI;IAsBtD,IAAI,IAAI,IAAI;IAUZ,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAInC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI7B,OAAO,CAAC,eAAe;IA4BvB,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,aAAa;IA0CrB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,QAAQ;IAehB,OAAO,CAAC,SAAS;IA8BjB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,eAAe;IA+DvB,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,QAAQ;IAuBhB,OAAO,CAAC,MAAM;IAmBd,IAAI,IAAI,IAAI;IAOZ,KAAK,IAAI,IAAI;IAKP,yBAAyB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA0BxE,OAAO,IAAI,IAAI;CAOhB;AAED,eAAe,iBAAiB,CAAC"}
@@ -1,7 +1,7 @@
1
1
  declare class Screenshot {
2
2
  private currentScreenshot;
3
3
  constructor();
4
- capture(): Promise<string>;
4
+ capture(mode?: 'viewport' | 'fullpage'): Promise<string>;
5
5
  private hideUXbertElements;
6
6
  private showUXbertElements;
7
7
  getScreenshot(): string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/features/screenshot.ts"],"names":[],"mappings":"AAGA,cAAM,UAAU;IACd,OAAO,CAAC,iBAAiB,CAAgB;;IAMnC,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IAmDhC,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,kBAAkB;IAY1B,aAAa,IAAI,MAAM,GAAG,IAAI;IAI9B,KAAK,IAAI,IAAI;CAGd;AAED,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/features/screenshot.ts"],"names":[],"mappings":"AAGA,cAAM,UAAU;IACd,OAAO,CAAC,iBAAiB,CAAgB;;IAMnC,OAAO,CAAC,IAAI,GAAE,UAAU,GAAG,UAAuB,GAAG,OAAO,CAAC,MAAM,CAAC;IAoE1E,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,kBAAkB;IAY1B,aAAa,IAAI,MAAM,GAAG,IAAI;IAI9B,KAAK,IAAI,IAAI;CAGd;AAED,eAAe,UAAU,CAAC"}
@@ -82,6 +82,7 @@ class State {
82
82
  this.screenshot = null;
83
83
  this.annotations = [];
84
84
  this.listeners = {};
85
+ this.captureMode = 'viewport';
85
86
  }
86
87
  setState(newState) {
87
88
  this.currentState = newState;
@@ -111,11 +112,18 @@ class State {
111
112
  clearAnnotations() {
112
113
  this.annotations = [];
113
114
  }
115
+ setCaptureMode(mode) {
116
+ this.captureMode = mode;
117
+ }
118
+ getCaptureMode() {
119
+ return this.captureMode;
120
+ }
114
121
  reset() {
115
122
  this.currentState = STATE.IDLE;
116
123
  this.currentIssue = null;
117
124
  this.screenshot = null;
118
125
  this.annotations = [];
126
+ this.captureMode = 'viewport';
119
127
  }
120
128
  // Event system
121
129
  on(event, callback) {
@@ -189,6 +197,20 @@ class Modal {
189
197
  </div>
190
198
 
191
199
  <form class="uxbert-form" id="uxbert-issue-form">
200
+ <div class="uxbert-form-group">
201
+ <label class="uxbert-form-label">Capture Mode</label>
202
+ <div class="uxbert-capture-mode">
203
+ <label class="uxbert-radio-label">
204
+ <input type="radio" name="capture-mode" value="viewport" id="uxbert-capture-viewport" checked />
205
+ <span>Current View</span>
206
+ </label>
207
+ <label class="uxbert-radio-label">
208
+ <input type="radio" name="capture-mode" value="fullpage" id="uxbert-capture-fullpage" />
209
+ <span>Full Page</span>
210
+ </label>
211
+ </div>
212
+ </div>
213
+
192
214
  <div class="uxbert-form-group">
193
215
  <label class="uxbert-form-label" for="uxbert-title">Issue Title *</label>
194
216
  <input
@@ -219,6 +241,12 @@ class Modal {
219
241
  </select>
220
242
  </div>
221
243
 
244
+ <div class="uxbert-capture-action" id="uxbert-capture-action">
245
+ <button type="button" class="uxbert-btn uxbert-btn-primary" id="uxbert-capture-btn">
246
+ 📸 Take Screenshot
247
+ </button>
248
+ </div>
249
+
222
250
  <div class="uxbert-screenshot-preview" id="uxbert-screenshot-container" style="display: none;">
223
251
  <img id="uxbert-screenshot-img" src="" alt="Screenshot" />
224
252
  <div class="uxbert-screenshot-actions">
@@ -235,7 +263,7 @@ class Modal {
235
263
  <button type="button" class="uxbert-btn uxbert-btn-secondary" id="uxbert-cancel-btn">
236
264
  Cancel
237
265
  </button>
238
- <button type="submit" class="uxbert-btn uxbert-btn-primary">
266
+ <button type="submit" class="uxbert-btn uxbert-btn-primary" id="uxbert-submit-btn">
239
267
  📥 Download JSON
240
268
  </button>
241
269
  </div>
@@ -268,6 +296,13 @@ class Modal {
268
296
  e.preventDefault();
269
297
  this.handleSubmit();
270
298
  });
299
+ // Capture button
300
+ const captureBtn = this.modal.querySelector('#uxbert-capture-btn');
301
+ captureBtn.addEventListener('click', () => {
302
+ if (this.callbacks.onCapture) {
303
+ this.callbacks.onCapture();
304
+ }
305
+ });
271
306
  // Annotate button
272
307
  const annotateBtn = this.modal.querySelector('#uxbert-annotate-btn');
273
308
  annotateBtn.addEventListener('click', () => {
@@ -320,14 +355,26 @@ class Modal {
320
355
  return;
321
356
  const container = this.modal.querySelector('#uxbert-screenshot-container');
322
357
  const img = this.modal.querySelector('#uxbert-screenshot-img');
358
+ const captureAction = this.modal.querySelector('#uxbert-capture-action');
359
+ const submitBtn = this.modal.querySelector('#uxbert-submit-btn');
323
360
  if (screenshot) {
324
361
  img.src = screenshot;
325
362
  container.style.display = 'block';
363
+ captureAction.style.display = 'none';
364
+ submitBtn.disabled = false;
326
365
  }
327
366
  else {
328
367
  container.style.display = 'none';
368
+ captureAction.style.display = 'block';
369
+ submitBtn.disabled = true;
329
370
  }
330
371
  }
372
+ getCaptureMode() {
373
+ if (!this.modal)
374
+ return 'viewport';
375
+ const viewportRadio = this.modal.querySelector('#uxbert-capture-viewport');
376
+ return viewportRadio.checked ? 'viewport' : 'fullpage';
377
+ }
331
378
  reset() {
332
379
  if (!this.modal)
333
380
  return;
@@ -9402,26 +9449,43 @@ class Screenshot {
9402
9449
  constructor() {
9403
9450
  this.currentScreenshot = null;
9404
9451
  }
9405
- async capture() {
9452
+ async capture(mode = 'fullpage') {
9406
9453
  try {
9407
9454
  // Hide UXbert UI elements before capturing
9408
9455
  this.hideUXbertElements();
9409
- // Scroll to top to capture full page
9410
9456
  const originalScrollY = window.scrollY;
9411
- window.scrollTo(0, 0);
9412
- // Get full page dimensions
9413
- const fullPageHeight = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);
9414
- const fullPageWidth = Math.max(document.body.scrollWidth, document.body.offsetWidth, document.documentElement.clientWidth, document.documentElement.scrollWidth, document.documentElement.offsetWidth);
9415
- // Capture the full page
9416
- const canvas = await html2canvas(document.body, {
9417
- allowTaint: true,
9418
- useCORS: true,
9419
- logging: false,
9420
- width: fullPageWidth,
9421
- height: fullPageHeight,
9422
- });
9423
- // Restore scroll position
9424
- window.scrollTo(0, originalScrollY);
9457
+ let canvas;
9458
+ if (mode === 'viewport') {
9459
+ // Capture only the current viewport
9460
+ canvas = await html2canvas(document.body, {
9461
+ allowTaint: true,
9462
+ useCORS: true,
9463
+ logging: false,
9464
+ width: window.innerWidth,
9465
+ height: window.innerHeight,
9466
+ windowWidth: window.innerWidth,
9467
+ windowHeight: window.innerHeight,
9468
+ x: window.scrollX,
9469
+ y: window.scrollY,
9470
+ });
9471
+ }
9472
+ else {
9473
+ // Scroll to top to capture full page
9474
+ window.scrollTo(0, 0);
9475
+ // Get full page dimensions
9476
+ const fullPageHeight = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);
9477
+ const fullPageWidth = Math.max(document.body.scrollWidth, document.body.offsetWidth, document.documentElement.clientWidth, document.documentElement.scrollWidth, document.documentElement.offsetWidth);
9478
+ // Capture the full page
9479
+ canvas = await html2canvas(document.body, {
9480
+ allowTaint: true,
9481
+ useCORS: true,
9482
+ logging: false,
9483
+ width: fullPageWidth,
9484
+ height: fullPageHeight,
9485
+ });
9486
+ // Restore scroll position
9487
+ window.scrollTo(0, originalScrollY);
9488
+ }
9425
9489
  // Show UXbert UI elements again
9426
9490
  this.showUXbertElements();
9427
9491
  // Convert to base64
@@ -9497,29 +9561,46 @@ class AnnotationManager {
9497
9561
  document.body.appendChild(this.canvas);
9498
9562
  return this.canvas;
9499
9563
  }
9500
- updateCanvasSize() {
9564
+ updateCanvasSize(mode = 'fullpage') {
9501
9565
  if (!this.canvas)
9502
9566
  return;
9503
- // Get full page dimensions
9504
- const fullPageHeight = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);
9505
- const fullPageWidth = Math.max(document.body.scrollWidth, document.body.offsetWidth, document.documentElement.clientWidth, document.documentElement.scrollWidth, document.documentElement.offsetWidth);
9506
- this.canvas.width = fullPageWidth;
9507
- this.canvas.height = fullPageHeight;
9567
+ if (mode === 'viewport') {
9568
+ // Set canvas to viewport dimensions
9569
+ this.canvas.width = window.innerWidth;
9570
+ this.canvas.height = window.innerHeight;
9571
+ }
9572
+ else {
9573
+ // Get full page dimensions
9574
+ const fullPageHeight = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);
9575
+ const fullPageWidth = Math.max(document.body.scrollWidth, document.body.offsetWidth, document.documentElement.clientWidth, document.documentElement.scrollWidth, document.documentElement.offsetWidth);
9576
+ this.canvas.width = fullPageWidth;
9577
+ this.canvas.height = fullPageHeight;
9578
+ }
9508
9579
  }
9509
- show() {
9580
+ show(mode = 'fullpage') {
9510
9581
  if (this.canvas && this.ctx) {
9511
9582
  // Update canvas size to match current page dimensions
9512
- this.updateCanvasSize();
9583
+ this.updateCanvasSize(mode);
9513
9584
  // Reset context properties after resize
9514
9585
  this.ctx.lineCap = 'round';
9515
9586
  this.ctx.lineJoin = 'round';
9516
9587
  this.canvas.classList.add('active');
9588
+ // If viewport mode, add viewport-mode class
9589
+ if (mode === 'viewport') {
9590
+ this.canvas.classList.add('viewport-mode');
9591
+ // Note: We don't disable scrolling in viewport mode to allow users to scroll
9592
+ // and annotate different parts of the viewport
9593
+ }
9594
+ else {
9595
+ this.canvas.classList.remove('viewport-mode');
9596
+ }
9517
9597
  this.redraw();
9518
9598
  }
9519
9599
  }
9520
9600
  hide() {
9521
9601
  if (this.canvas) {
9522
9602
  this.canvas.classList.remove('active');
9603
+ this.canvas.classList.remove('viewport-mode');
9523
9604
  }
9524
9605
  // Clean up any active text input
9525
9606
  this.removeTextInput();
@@ -9532,10 +9613,13 @@ class AnnotationManager {
9532
9613
  this.currentColor = color;
9533
9614
  }
9534
9615
  handleMouseDown(e) {
9616
+ const isViewportMode = this.canvas?.classList.contains('viewport-mode');
9617
+ const scrollOffsetX = isViewportMode ? 0 : window.scrollX;
9618
+ const scrollOffsetY = isViewportMode ? 0 : window.scrollY;
9535
9619
  // Handle text tool separately
9536
9620
  if (this.currentTool === 'text') {
9537
- const x = e.clientX + window.scrollX;
9538
- const y = e.clientY + window.scrollY;
9621
+ const x = e.clientX + scrollOffsetX;
9622
+ const y = e.clientY + scrollOffsetY;
9539
9623
  // Check if clicking on existing text to edit
9540
9624
  const clickedText = this.getTextAnnotationAt(x, y);
9541
9625
  if (clickedText) {
@@ -9547,15 +9631,18 @@ class AnnotationManager {
9547
9631
  return;
9548
9632
  }
9549
9633
  this.isDrawing = true;
9550
- this.startX = e.clientX + window.scrollX;
9551
- this.startY = e.clientY + window.scrollY;
9634
+ this.startX = e.clientX + scrollOffsetX;
9635
+ this.startY = e.clientY + scrollOffsetY;
9552
9636
  this.currentPath = [{ x: this.startX, y: this.startY }];
9553
9637
  }
9554
9638
  handleMouseMove(e) {
9555
9639
  if (!this.isDrawing || !this.ctx)
9556
9640
  return;
9557
- const x = e.clientX + window.scrollX;
9558
- const y = e.clientY + window.scrollY;
9641
+ const isViewportMode = this.canvas?.classList.contains('viewport-mode');
9642
+ const scrollOffsetX = isViewportMode ? 0 : window.scrollX;
9643
+ const scrollOffsetY = isViewportMode ? 0 : window.scrollY;
9644
+ const x = e.clientX + scrollOffsetX;
9645
+ const y = e.clientY + scrollOffsetY;
9559
9646
  if (this.currentTool === 'pen') {
9560
9647
  this.currentPath.push({ x, y });
9561
9648
  this.redraw();
@@ -9575,8 +9662,11 @@ class AnnotationManager {
9575
9662
  if (!this.isDrawing)
9576
9663
  return;
9577
9664
  this.isDrawing = false;
9578
- const x = e.clientX + window.scrollX;
9579
- const y = e.clientY + window.scrollY;
9665
+ const isViewportMode = this.canvas?.classList.contains('viewport-mode');
9666
+ const scrollOffsetX = isViewportMode ? 0 : window.scrollX;
9667
+ const scrollOffsetY = isViewportMode ? 0 : window.scrollY;
9668
+ const x = e.clientX + scrollOffsetX;
9669
+ const y = e.clientY + scrollOffsetY;
9580
9670
  // Save the annotation
9581
9671
  if (this.currentTool === 'pen') {
9582
9672
  this.annotations.push({
@@ -10049,7 +10139,7 @@ function styleInject(css, ref) {
10049
10139
  }
10050
10140
  }
10051
10141
 
10052
- var css_248z = ":root{--uxbert-primary:#4f46e5;--uxbert-primary-hover:#4338ca;--uxbert-danger:#ef4444;--uxbert-success:#10b981;--uxbert-bg:#fff;--uxbert-text:#1f2937;--uxbert-border:#e5e7eb;--uxbert-shadow:0 10px 25px rgba(0,0,0,.1);--uxbert-z-button:999999;--uxbert-z-modal:1000000;--uxbert-z-canvas:1000001;--uxbert-z-toolbar:1000002}[data-theme=dark]{--uxbert-bg:#1f2937;--uxbert-text:#f9fafb;--uxbert-border:#374151}.uxbert-fab{align-items:center;background:var(--uxbert-primary);border:none;border-radius:50%;box-shadow:var(--uxbert-shadow);color:#fff;cursor:pointer;display:flex;font-size:24px;height:56px;justify-content:center;position:fixed;transition:all .3s ease;width:56px;z-index:var(--uxbert-z-button)}.uxbert-fab:hover{background:var(--uxbert-primary-hover);transform:scale(1.1)}.uxbert-fab.bottom-right{bottom:24px;right:24px}.uxbert-fab.bottom-left{bottom:24px;left:24px}.uxbert-fab.top-right{right:24px;top:24px}.uxbert-fab.top-left{left:24px;top:24px}.uxbert-overlay{align-items:center;animation:fadeIn .3s ease;background:rgba(0,0,0,.5);display:none;height:100%;justify-content:center;left:0;position:fixed;top:0;width:100%;z-index:var(--uxbert-z-modal)}.uxbert-overlay.active{display:flex}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.uxbert-modal{animation:slideUp .3s ease;background:var(--uxbert-bg);border-radius:12px;box-shadow:var(--uxbert-shadow);color:var(--uxbert-text);max-height:90vh;max-width:600px;overflow-y:auto;padding:24px;width:90%}@keyframes slideUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.uxbert-modal-header{align-items:center;display:flex;justify-content:space-between;margin-bottom:20px}.uxbert-modal-title{font-size:20px;font-weight:600;margin:0}.uxbert-modal-close{align-items:center;background:none;border:none;border-radius:4px;color:var(--uxbert-text);cursor:pointer;display:flex;font-size:24px;height:32px;justify-content:center;padding:0;width:32px}.uxbert-modal-close:hover{background:var(--uxbert-border)}.uxbert-form-group{margin-bottom:16px}.uxbert-form-label{display:block;font-size:14px;font-weight:500;margin-bottom:8px}.uxbert-form-input,.uxbert-form-select,.uxbert-form-textarea{background:var(--uxbert-bg);border:1px solid var(--uxbert-border);border-radius:6px;box-sizing:border-box;color:var(--uxbert-text);font-family:inherit;font-size:14px;padding:10px;width:100%}.uxbert-form-textarea{min-height:100px;resize:vertical}.uxbert-form-input:focus,.uxbert-form-select:focus,.uxbert-form-textarea:focus{border-color:var(--uxbert-primary);outline:none}.uxbert-screenshot-preview{border:1px solid var(--uxbert-border);border-radius:8px;margin:16px 0;overflow:hidden}.uxbert-screenshot-preview img{display:block;width:100%}.uxbert-screenshot-actions{background:var(--uxbert-border);display:flex;gap:8px;padding:12px}.uxbert-btn{align-items:center;border:none;border-radius:6px;cursor:pointer;display:inline-flex;font-size:14px;font-weight:500;gap:8px;padding:10px 20px;transition:all .2s ease}.uxbert-btn-primary{background:var(--uxbert-primary);color:#fff}.uxbert-btn-primary:hover{background:var(--uxbert-primary-hover)}.uxbert-btn-secondary{background:var(--uxbert-border);color:var(--uxbert-text)}.uxbert-btn-secondary:hover{background:#d1d5db}.uxbert-btn-danger{background:var(--uxbert-danger);color:#fff}.uxbert-btn-danger:hover{background:#dc2626}.uxbert-modal-actions{display:flex;gap:12px;justify-content:flex-end;margin-top:20px}.uxbert-toolbar-toggle{align-items:center;background:var(--uxbert-primary);border:none;border-radius:50%;bottom:24px;box-shadow:var(--uxbert-shadow);color:#fff;cursor:pointer;display:none;font-size:24px;height:56px;justify-content:center;position:fixed;right:24px;transition:all .3s ease;width:56px;z-index:var(--uxbert-z-toolbar)}.uxbert-toolbar-toggle.active{display:flex}.uxbert-toolbar-toggle.hidden{opacity:0;pointer-events:none;transform:scale(.8)}.uxbert-toolbar-toggle:hover{background:var(--uxbert-primary-hover);transform:scale(1.1)}.uxbert-toolbar{background:var(--uxbert-bg);border-radius:12px;bottom:24px;box-shadow:var(--uxbert-shadow);display:none;flex-direction:column;gap:8px;max-height:80vh;opacity:0;overflow-y:auto;padding:16px;pointer-events:none;position:fixed;right:24px;transform:translateY(20px);transition:all .3s ease;z-index:var(--uxbert-z-toolbar)}.uxbert-toolbar.active{display:flex}.uxbert-toolbar.expanded{opacity:1;pointer-events:all;transform:translateY(0)}.uxbert-toolbar-header{align-items:center;display:flex;gap:8px;justify-content:space-between;margin-bottom:8px}.uxbert-toolbar-title{flex:1;font-size:14px;font-weight:600}.uxbert-toolbar-exit,.uxbert-toolbar-minimize{align-items:center;background:var(--uxbert-border);border:none;border-radius:6px;color:var(--uxbert-text);cursor:pointer;display:flex;font-size:20px;font-weight:700;height:32px;justify-content:center;transition:all .2s ease;width:32px}.uxbert-toolbar-exit{background:var(--uxbert-danger);color:#fff}.uxbert-toolbar-minimize:hover{background:#d1d5db;transform:scale(1.1)}.uxbert-toolbar-exit:hover{background:#dc2626;transform:scale(1.1)}.uxbert-toolbar-tools{display:flex;flex-wrap:wrap;gap:8px}.uxbert-tool-btn{align-items:center;background:var(--uxbert-bg);border:2px solid var(--uxbert-border);border-radius:6px;cursor:pointer;display:flex;font-family:Arial,sans-serif;font-size:18px;font-weight:700;height:40px;justify-content:center;transition:all .2s ease;width:40px}.uxbert-tool-btn.active,.uxbert-tool-btn:hover{background:var(--uxbert-primary);border-color:var(--uxbert-primary);color:#fff}.uxbert-color-picker{display:flex;gap:6px;margin:8px 0}.uxbert-color-option{border:2px solid var(--uxbert-border);border-radius:50%;cursor:pointer;height:32px;transition:transform .2s ease;width:32px}.uxbert-color-option:hover{transform:scale(1.1)}.uxbert-color-option.active{border:3px solid var(--uxbert-text)}.uxbert-canvas-overlay{cursor:crosshair;display:none;left:0;position:absolute;top:0;z-index:var(--uxbert-z-canvas)}.uxbert-canvas-overlay.active{display:block}.uxbert-text-input{background:hsla(0,0%,100%,.95);border:2px solid var(--uxbert-primary);border-radius:6px;box-shadow:0 4px 12px rgba(0,0,0,.15);color:var(--uxbert-text);font-family:Arial,sans-serif;font-size:16px;font-weight:700;min-width:200px;outline:none;padding:8px 12px;z-index:var(--uxbert-z-toolbar)}.uxbert-text-input:focus{border-color:var(--uxbert-primary-hover);box-shadow:0 4px 16px rgba(79,70,229,.3)}.uxbert-text-input::placeholder{color:#9ca3af;font-weight:400}@media (max-width:768px){.uxbert-modal{max-height:95vh;padding:16px;width:95%}.uxbert-toolbar{bottom:90px;left:16px;max-height:60vh;right:16px;width:auto}.uxbert-toolbar-toggle{bottom:16px;height:56px;right:16px;width:56px}.uxbert-fab{font-size:20px;height:48px;width:48px}.uxbert-color-picker,.uxbert-toolbar-tools{justify-content:center}}";
10142
+ var css_248z = ":root{--uxbert-primary:#4f46e5;--uxbert-primary-hover:#4338ca;--uxbert-danger:#ef4444;--uxbert-success:#10b981;--uxbert-bg:#fff;--uxbert-text:#1f2937;--uxbert-border:#e5e7eb;--uxbert-shadow:0 10px 25px rgba(0,0,0,.1);--uxbert-z-button:999999;--uxbert-z-modal:1000000;--uxbert-z-canvas:1000001;--uxbert-z-toolbar:1000002}[data-theme=dark]{--uxbert-bg:#1f2937;--uxbert-text:#f9fafb;--uxbert-border:#374151}.uxbert-fab{align-items:center;background:var(--uxbert-primary);border:none;border-radius:50%;box-shadow:var(--uxbert-shadow);color:#fff;cursor:pointer;display:flex;font-size:24px;height:56px;justify-content:center;position:fixed;transition:all .3s ease;width:56px;z-index:var(--uxbert-z-button)}.uxbert-fab:hover{background:var(--uxbert-primary-hover);transform:scale(1.1)}.uxbert-fab.bottom-right{bottom:24px;right:24px}.uxbert-fab.bottom-left{bottom:24px;left:24px}.uxbert-fab.top-right{right:24px;top:24px}.uxbert-fab.top-left{left:24px;top:24px}.uxbert-overlay{align-items:center;animation:fadeIn .3s ease;background:rgba(0,0,0,.5);display:none;height:100%;justify-content:center;left:0;position:fixed;top:0;width:100%;z-index:var(--uxbert-z-modal)}.uxbert-overlay.active{display:flex}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.uxbert-modal{animation:slideUp .3s ease;background:var(--uxbert-bg);border-radius:12px;box-shadow:var(--uxbert-shadow);color:var(--uxbert-text);max-height:90vh;max-width:600px;overflow-y:auto;padding:24px;width:90%}@keyframes slideUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.uxbert-modal-header{align-items:center;display:flex;justify-content:space-between;margin-bottom:20px}.uxbert-modal-title{font-size:20px;font-weight:600;margin:0}.uxbert-modal-close{align-items:center;background:none;border:none;border-radius:4px;color:var(--uxbert-text);cursor:pointer;display:flex;font-size:24px;height:32px;justify-content:center;padding:0;width:32px}.uxbert-modal-close:hover{background:var(--uxbert-border)}.uxbert-form-group{margin-bottom:16px}.uxbert-form-label{display:block;font-size:14px;font-weight:500;margin-bottom:8px}.uxbert-capture-mode{display:flex;flex-wrap:wrap;gap:12px}.uxbert-radio-label{align-items:center;border:2px solid var(--uxbert-border);border-radius:8px;cursor:pointer;display:flex;flex:1;gap:8px;min-width:140px;padding:10px 16px;transition:all .2s ease}.uxbert-radio-label:hover{background:rgba(79,70,229,.05);border-color:var(--uxbert-primary)}.uxbert-radio-label input[type=radio]{cursor:pointer;height:18px;margin:0;width:18px}.uxbert-radio-label input[type=radio]:checked{accent-color:var(--uxbert-primary)}.uxbert-radio-label:has(input[type=radio]:checked){background:rgba(79,70,229,.1);border-color:var(--uxbert-primary)}.uxbert-radio-label span{flex:1;font-size:14px;font-weight:500}.uxbert-form-input,.uxbert-form-select,.uxbert-form-textarea{background:var(--uxbert-bg);border:1px solid var(--uxbert-border);border-radius:6px;box-sizing:border-box;color:var(--uxbert-text);font-family:inherit;font-size:14px;padding:10px;width:100%}.uxbert-form-textarea{min-height:100px;resize:vertical}.uxbert-form-input:focus,.uxbert-form-select:focus,.uxbert-form-textarea:focus{border-color:var(--uxbert-primary);outline:none}.uxbert-capture-action{margin:16px 0;text-align:center}.uxbert-capture-action .uxbert-btn{min-width:200px}.uxbert-screenshot-preview{border:1px solid var(--uxbert-border);border-radius:8px;margin:16px 0;overflow:hidden}.uxbert-screenshot-preview img{display:block;width:100%}.uxbert-screenshot-actions{background:var(--uxbert-border);display:flex;gap:8px;padding:12px}.uxbert-btn{align-items:center;border:none;border-radius:6px;cursor:pointer;display:inline-flex;font-size:14px;font-weight:500;gap:8px;padding:10px 20px;transition:all .2s ease}.uxbert-btn-primary{background:var(--uxbert-primary);color:#fff}.uxbert-btn-primary:hover{background:var(--uxbert-primary-hover)}.uxbert-btn-secondary{background:var(--uxbert-border);color:var(--uxbert-text)}.uxbert-btn-secondary:hover{background:#d1d5db}.uxbert-btn-danger{background:var(--uxbert-danger);color:#fff}.uxbert-btn-danger:hover{background:#dc2626}.uxbert-modal-actions{display:flex;gap:12px;justify-content:flex-end;margin-top:20px}.uxbert-toolbar-toggle{align-items:center;background:var(--uxbert-primary);border:none;border-radius:50%;bottom:24px;box-shadow:var(--uxbert-shadow);color:#fff;cursor:pointer;display:none;font-size:24px;height:56px;justify-content:center;position:fixed;right:24px;transition:all .3s ease;width:56px;z-index:var(--uxbert-z-toolbar)}.uxbert-toolbar-toggle.active{display:flex}.uxbert-toolbar-toggle.hidden{opacity:0;pointer-events:none;transform:scale(.8)}.uxbert-toolbar-toggle:hover{background:var(--uxbert-primary-hover);transform:scale(1.1)}.uxbert-toolbar{background:var(--uxbert-bg);border-radius:12px;bottom:24px;box-shadow:var(--uxbert-shadow);display:none;flex-direction:column;gap:8px;max-height:80vh;opacity:0;overflow-y:auto;padding:16px;pointer-events:none;position:fixed;right:24px;transform:translateY(20px);transition:all .3s ease;z-index:var(--uxbert-z-toolbar)}.uxbert-toolbar.active{display:flex}.uxbert-toolbar.expanded{opacity:1;pointer-events:all;transform:translateY(0)}.uxbert-toolbar-header{align-items:center;display:flex;gap:8px;justify-content:space-between;margin-bottom:8px}.uxbert-toolbar-title{flex:1;font-size:14px;font-weight:600}.uxbert-toolbar-exit,.uxbert-toolbar-minimize{align-items:center;background:var(--uxbert-border);border:none;border-radius:6px;color:var(--uxbert-text);cursor:pointer;display:flex;font-size:20px;font-weight:700;height:32px;justify-content:center;transition:all .2s ease;width:32px}.uxbert-toolbar-exit{background:var(--uxbert-danger);color:#fff}.uxbert-toolbar-minimize:hover{background:#d1d5db;transform:scale(1.1)}.uxbert-toolbar-exit:hover{background:#dc2626;transform:scale(1.1)}.uxbert-toolbar-tools{display:flex;flex-wrap:wrap;gap:8px}.uxbert-tool-btn{align-items:center;background:var(--uxbert-bg);border:2px solid var(--uxbert-border);border-radius:6px;cursor:pointer;display:flex;font-family:Arial,sans-serif;font-size:18px;font-weight:700;height:40px;justify-content:center;transition:all .2s ease;width:40px}.uxbert-tool-btn.active,.uxbert-tool-btn:hover{background:var(--uxbert-primary);border-color:var(--uxbert-primary);color:#fff}.uxbert-color-picker{display:flex;gap:6px;margin:8px 0}.uxbert-color-option{border:2px solid var(--uxbert-border);border-radius:50%;cursor:pointer;height:32px;transition:transform .2s ease;width:32px}.uxbert-color-option:hover{transform:scale(1.1)}.uxbert-color-option.active{border:3px solid var(--uxbert-text)}.uxbert-canvas-overlay{cursor:crosshair;display:none;left:0;position:absolute;top:0;z-index:var(--uxbert-z-canvas)}.uxbert-canvas-overlay.active{display:block}.uxbert-canvas-overlay.viewport-mode{left:0;position:fixed;top:0}.uxbert-text-input{background:hsla(0,0%,100%,.95);border:2px solid var(--uxbert-primary);border-radius:6px;box-shadow:0 4px 12px rgba(0,0,0,.15);color:var(--uxbert-text);font-family:Arial,sans-serif;font-size:16px;font-weight:700;min-width:200px;outline:none;padding:8px 12px;z-index:var(--uxbert-z-toolbar)}.uxbert-text-input:focus{border-color:var(--uxbert-primary-hover);box-shadow:0 4px 16px rgba(79,70,229,.3)}.uxbert-text-input::placeholder{color:#9ca3af;font-weight:400}@media (max-width:768px){.uxbert-modal{max-height:95vh;padding:16px;width:95%}.uxbert-toolbar{bottom:90px;left:16px;max-height:60vh;right:16px;width:auto}.uxbert-toolbar-toggle{bottom:16px;height:56px;right:16px;width:56px}.uxbert-fab{font-size:20px;height:48px;width:48px}.uxbert-color-picker,.uxbert-toolbar-tools{justify-content:center}}";
10053
10143
  styleInject(css_248z);
10054
10144
 
10055
10145
  // Main initialization file
@@ -10091,6 +10181,7 @@ class Reportly {
10091
10181
  onClose: () => this.handleModalClose(),
10092
10182
  onAnnotate: () => this.startAnnotation(),
10093
10183
  onRetake: () => this.retakeScreenshot(),
10184
+ onCapture: () => this.captureWithMode(),
10094
10185
  });
10095
10186
  this.toolbar = new Toolbar({
10096
10187
  onToolChange: (tool) => this.annotation?.setTool(tool),
@@ -10121,14 +10212,27 @@ class Reportly {
10121
10212
  });
10122
10213
  }
10123
10214
  async handleButtonClick() {
10215
+ try {
10216
+ // Open modal first to let user choose capture mode
10217
+ this.modal?.open();
10218
+ }
10219
+ catch (error) {
10220
+ console.error("Failed to open modal:", error);
10221
+ alert("Failed to open modal. Please try again.");
10222
+ }
10223
+ }
10224
+ async captureWithMode() {
10124
10225
  try {
10125
10226
  this.state?.setState(STATE.CAPTURING);
10227
+ // Get capture mode from modal
10228
+ const captureMode = this.modal?.getCaptureMode() || 'viewport';
10229
+ // Save capture mode in state
10230
+ this.state?.setCaptureMode(captureMode);
10126
10231
  // Capture screenshot
10127
- const screenshot = await this.screenshot.capture();
10232
+ const screenshot = await this.screenshot.capture(captureMode);
10128
10233
  this.state?.setScreenshot(screenshot);
10129
10234
  // Show modal with screenshot
10130
10235
  this.modal?.setScreenshot(screenshot);
10131
- this.modal?.open();
10132
10236
  this.state?.setState(STATE.IDLE);
10133
10237
  }
10134
10238
  catch (error) {
@@ -10141,7 +10245,8 @@ class Reportly {
10141
10245
  this.state?.setState(STATE.ANNOTATING);
10142
10246
  this.modal?.close();
10143
10247
  this.button?.hide();
10144
- this.annotation?.show();
10248
+ const captureMode = this.state?.getCaptureMode() || 'viewport';
10249
+ this.annotation?.show(captureMode);
10145
10250
  this.toolbar?.show();
10146
10251
  }
10147
10252
  exitAnnotation() {
@@ -10177,13 +10282,16 @@ class Reportly {
10177
10282
  }
10178
10283
  async retakeScreenshot() {
10179
10284
  try {
10285
+ // Get the current capture mode from modal before closing
10286
+ const captureMode = this.modal?.getCaptureMode() || 'viewport';
10180
10287
  this.modal?.close();
10181
10288
  this.state?.setState(STATE.CAPTURING);
10182
10289
  // Clear previous annotations
10183
10290
  this.annotation?.clear();
10184
- // Capture new screenshot
10185
- const screenshot = await this.screenshot.capture();
10291
+ // Capture new screenshot with the same mode
10292
+ const screenshot = await this.screenshot.capture(captureMode);
10186
10293
  this.state?.setScreenshot(screenshot);
10294
+ this.state?.setCaptureMode(captureMode);
10187
10295
  // Show modal with new screenshot
10188
10296
  this.modal?.setScreenshot(screenshot);
10189
10297
  this.modal?.open();