pushfeedback 0.1.67 → 0.1.68
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/dist/cjs/feedback-button_2.cjs.entry.js +724 -186
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/pushfeedback.cjs.js +1 -1
- package/dist/collection/components/feedback-button/feedback-button.js +60 -0
- package/dist/collection/components/feedback-modal/feedback-modal.css +419 -11
- package/dist/collection/components/feedback-modal/feedback-modal.js +747 -158
- package/dist/components/feedback-button.js +9 -0
- package/dist/components/feedback-modal2.js +739 -186
- package/dist/esm/feedback-button_2.entry.js +724 -186
- package/dist/esm/loader.js +1 -1
- package/dist/esm/pushfeedback.js +1 -1
- package/dist/pushfeedback/p-7406f7be.entry.js +7 -0
- package/dist/pushfeedback/pushfeedback.css +1 -1
- package/dist/pushfeedback/pushfeedback.esm.js +1 -1
- package/dist/types/components/feedback-button/feedback-button.d.ts +3 -0
- package/dist/types/components/feedback-modal/feedback-modal.d.ts +77 -21
- package/dist/types/components.d.ts +12 -0
- package/package.json +1 -1
- package/dist/pushfeedback/p-51e790c7.entry.js +0 -22
|
@@ -18,14 +18,14 @@ function commonjsRequire () {
|
|
|
18
18
|
|
|
19
19
|
var html2canvasPro = createCommonjsModule(function (module, exports) {
|
|
20
20
|
/*!
|
|
21
|
-
* html2canvas-pro 1.5.
|
|
22
|
-
* Copyright (c) 2024 yorickshan
|
|
21
|
+
* html2canvas-pro 1.5.11 <https://yorickshan.github.io/html2canvas-pro/>
|
|
22
|
+
* Copyright (c) 2024-present yorickshan and html2canvas-pro contributors
|
|
23
23
|
* Released under MIT License
|
|
24
24
|
*/
|
|
25
25
|
(function (global, factory) {
|
|
26
26
|
module.exports = factory() ;
|
|
27
27
|
})(commonjsGlobal, (function () {
|
|
28
|
-
|
|
28
|
+
/******************************************************************************
|
|
29
29
|
Copyright (c) Microsoft Corporation.
|
|
30
30
|
|
|
31
31
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
@@ -39,7 +39,7 @@ var html2canvasPro = createCommonjsModule(function (module, exports) {
|
|
|
39
39
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
40
40
|
PERFORMANCE OF THIS SOFTWARE.
|
|
41
41
|
***************************************************************************** */
|
|
42
|
-
/* global Reflect, Promise */
|
|
42
|
+
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
43
43
|
|
|
44
44
|
var extendStatics = function(d, b) {
|
|
45
45
|
extendStatics = Object.setPrototypeOf ||
|
|
@@ -83,7 +83,7 @@ var html2canvasPro = createCommonjsModule(function (module, exports) {
|
|
|
83
83
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
84
84
|
function step(op) {
|
|
85
85
|
if (f) throw new TypeError("Generator is already executing.");
|
|
86
|
-
while (_) try {
|
|
86
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
87
87
|
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
88
88
|
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
89
89
|
switch (op[0]) {
|
|
@@ -112,8 +112,13 @@ var html2canvasPro = createCommonjsModule(function (module, exports) {
|
|
|
112
112
|
ar[i] = from[i];
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
-
return to.concat(ar || from);
|
|
116
|
-
}
|
|
115
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
119
|
+
var e = new Error(message);
|
|
120
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
121
|
+
};
|
|
117
122
|
|
|
118
123
|
var Bounds = /** @class */ (function () {
|
|
119
124
|
function Bounds(left, top, width, height) {
|
|
@@ -3748,7 +3753,7 @@ var html2canvasPro = createCommonjsModule(function (module, exports) {
|
|
|
3748
3753
|
case 'gurmukhi':
|
|
3749
3754
|
return 22 /* LIST_STYLE_TYPE.GURMUKHI */;
|
|
3750
3755
|
case 'hebrew':
|
|
3751
|
-
return
|
|
3756
|
+
return 52 /* LIST_STYLE_TYPE.HEBREW */;
|
|
3752
3757
|
case 'hiragana':
|
|
3753
3758
|
return 23 /* LIST_STYLE_TYPE.HIRAGANA */;
|
|
3754
3759
|
case 'hiragana-iroha':
|
|
@@ -6024,7 +6029,7 @@ var html2canvasPro = createCommonjsModule(function (module, exports) {
|
|
|
6024
6029
|
return createCounterStyleFromRange(value, 0xae6, 0xaef, true, defaultSuffix);
|
|
6025
6030
|
case 22 /* LIST_STYLE_TYPE.GURMUKHI */:
|
|
6026
6031
|
return createCounterStyleFromRange(value, 0xa66, 0xa6f, true, defaultSuffix);
|
|
6027
|
-
case
|
|
6032
|
+
case 52 /* LIST_STYLE_TYPE.HEBREW */:
|
|
6028
6033
|
return createAdditiveCounter(value, 1, 10999, HEBREW, 3 /* LIST_STYLE_TYPE.DECIMAL */, defaultSuffix);
|
|
6029
6034
|
case 23 /* LIST_STYLE_TYPE.HIRAGANA */:
|
|
6030
6035
|
return createCounterStyleFromSymbols(value, 'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわゐゑをん');
|
|
@@ -6483,8 +6488,8 @@ var html2canvasPro = createCommonjsModule(function (module, exports) {
|
|
|
6483
6488
|
});
|
|
6484
6489
|
};
|
|
6485
6490
|
var ignoredStyleProperties = [
|
|
6486
|
-
'all',
|
|
6487
|
-
'd',
|
|
6491
|
+
'all', // #2476
|
|
6492
|
+
'd', // #2483
|
|
6488
6493
|
'content' // Safari shows pseudoelements if content is set
|
|
6489
6494
|
];
|
|
6490
6495
|
var copyCSSStyles = function (style, target) {
|
|
@@ -6601,12 +6606,21 @@ var html2canvasPro = createCommonjsModule(function (module, exports) {
|
|
|
6601
6606
|
};
|
|
6602
6607
|
Cache.prototype.loadImage = function (key) {
|
|
6603
6608
|
return __awaiter(this, void 0, void 0, function () {
|
|
6604
|
-
var isSameOrigin, useCORS, useProxy, src;
|
|
6609
|
+
var isSameOrigin, _a, useCORS, useProxy, src;
|
|
6605
6610
|
var _this = this;
|
|
6606
|
-
return __generator(this, function (
|
|
6607
|
-
switch (
|
|
6611
|
+
return __generator(this, function (_b) {
|
|
6612
|
+
switch (_b.label) {
|
|
6608
6613
|
case 0:
|
|
6609
|
-
|
|
6614
|
+
if (!(typeof this._options.customIsSameOrigin === 'function')) return [3 /*break*/, 2];
|
|
6615
|
+
return [4 /*yield*/, this._options.customIsSameOrigin(key, CacheStorage.isSameOrigin)];
|
|
6616
|
+
case 1:
|
|
6617
|
+
_a = _b.sent();
|
|
6618
|
+
return [3 /*break*/, 3];
|
|
6619
|
+
case 2:
|
|
6620
|
+
_a = CacheStorage.isSameOrigin(key);
|
|
6621
|
+
_b.label = 3;
|
|
6622
|
+
case 3:
|
|
6623
|
+
isSameOrigin = _a;
|
|
6610
6624
|
useCORS = !isInlineImage(key) && this._options.useCORS === true && FEATURES.SUPPORT_CORS_IMAGES && !isSameOrigin;
|
|
6611
6625
|
useProxy = !isInlineImage(key) &&
|
|
6612
6626
|
!isSameOrigin &&
|
|
@@ -6623,12 +6637,12 @@ var html2canvasPro = createCommonjsModule(function (module, exports) {
|
|
|
6623
6637
|
return [2 /*return*/];
|
|
6624
6638
|
}
|
|
6625
6639
|
src = key;
|
|
6626
|
-
if (!useProxy) return [3 /*break*/,
|
|
6640
|
+
if (!useProxy) return [3 /*break*/, 5];
|
|
6627
6641
|
return [4 /*yield*/, this.proxy(src)];
|
|
6628
|
-
case
|
|
6629
|
-
src =
|
|
6630
|
-
|
|
6631
|
-
case
|
|
6642
|
+
case 4:
|
|
6643
|
+
src = _b.sent();
|
|
6644
|
+
_b.label = 5;
|
|
6645
|
+
case 5:
|
|
6632
6646
|
this.context.logger.debug("Added image ".concat(key.substring(0, 256)));
|
|
6633
6647
|
return [4 /*yield*/, new Promise(function (resolve, reject) {
|
|
6634
6648
|
var img = new Image();
|
|
@@ -6647,7 +6661,7 @@ var html2canvasPro = createCommonjsModule(function (module, exports) {
|
|
|
6647
6661
|
setTimeout(function () { return reject("Timed out (".concat(_this._options.imageTimeout, "ms) loading image")); }, _this._options.imageTimeout);
|
|
6648
6662
|
}
|
|
6649
6663
|
})];
|
|
6650
|
-
case
|
|
6664
|
+
case 6: return [2 /*return*/, _b.sent()];
|
|
6651
6665
|
}
|
|
6652
6666
|
});
|
|
6653
6667
|
});
|
|
@@ -7773,7 +7787,7 @@ var html2canvasPro = createCommonjsModule(function (module, exports) {
|
|
|
7773
7787
|
};
|
|
7774
7788
|
CanvasRenderer.prototype.renderNodeContent = function (paint) {
|
|
7775
7789
|
return __awaiter(this, void 0, void 0, function () {
|
|
7776
|
-
var container, curves, styles, _i, _a, child, image, image, iframeRenderer, canvas, size, _b, fontFamily, fontSize, baseline, bounds, x, textBounds, img, image, url,
|
|
7790
|
+
var container, curves, styles, _i, _a, child, image, image, iframeRenderer, canvas, size, _b, font, fontFamily, fontSize, baseline, bounds, x, textBounds, img, image, url, font, bounds;
|
|
7777
7791
|
return __generator(this, function (_c) {
|
|
7778
7792
|
switch (_c.label) {
|
|
7779
7793
|
case 0:
|
|
@@ -7873,9 +7887,9 @@ var html2canvasPro = createCommonjsModule(function (module, exports) {
|
|
|
7873
7887
|
}
|
|
7874
7888
|
}
|
|
7875
7889
|
if (isTextInputElement(container) && container.value.length) {
|
|
7876
|
-
_b = this.createFontStyle(styles),
|
|
7890
|
+
_b = this.createFontStyle(styles), font = _b[0], fontFamily = _b[1], fontSize = _b[2];
|
|
7877
7891
|
baseline = this.fontMetrics.getMetrics(fontFamily, fontSize).baseline;
|
|
7878
|
-
this.ctx.font =
|
|
7892
|
+
this.ctx.font = font;
|
|
7879
7893
|
this.ctx.fillStyle = asString(styles.color);
|
|
7880
7894
|
this.ctx.textBaseline = 'alphabetic';
|
|
7881
7895
|
this.ctx.textAlign = canvasTextAlign(container.styles.textAlign);
|
|
@@ -7924,8 +7938,8 @@ var html2canvasPro = createCommonjsModule(function (module, exports) {
|
|
|
7924
7938
|
case 18: return [3 /*break*/, 20];
|
|
7925
7939
|
case 19:
|
|
7926
7940
|
if (paint.listValue && container.styles.listStyleType !== -1 /* LIST_STYLE_TYPE.NONE */) {
|
|
7927
|
-
|
|
7928
|
-
this.ctx.font =
|
|
7941
|
+
font = this.createFontStyle(styles)[0];
|
|
7942
|
+
this.ctx.font = font;
|
|
7929
7943
|
this.ctx.fillStyle = asString(styles.color);
|
|
7930
7944
|
this.ctx.textBaseline = 'middle';
|
|
7931
7945
|
this.ctx.textAlign = 'right';
|
|
@@ -8155,7 +8169,7 @@ var html2canvasPro = createCommonjsModule(function (module, exports) {
|
|
|
8155
8169
|
canvas.height = height;
|
|
8156
8170
|
ctx = canvas.getContext('2d');
|
|
8157
8171
|
gradient_1 = ctx.createLinearGradient(x0, y0, x1, y1);
|
|
8158
|
-
processColorStops(backgroundImage.stops, lineLength).forEach(function (colorStop) {
|
|
8172
|
+
processColorStops(backgroundImage.stops, lineLength || 1).forEach(function (colorStop) {
|
|
8159
8173
|
return gradient_1.addColorStop(colorStop.stop, asString(colorStop.color));
|
|
8160
8174
|
});
|
|
8161
8175
|
ctx.fillStyle = gradient_1;
|
|
@@ -8690,7 +8704,8 @@ var html2canvasPro = createCommonjsModule(function (module, exports) {
|
|
|
8690
8704
|
allowTaint: (_b = opts.allowTaint) !== null && _b !== void 0 ? _b : false,
|
|
8691
8705
|
imageTimeout: (_c = opts.imageTimeout) !== null && _c !== void 0 ? _c : 15000,
|
|
8692
8706
|
proxy: opts.proxy,
|
|
8693
|
-
useCORS: (_d = opts.useCORS) !== null && _d !== void 0 ? _d : false
|
|
8707
|
+
useCORS: (_d = opts.useCORS) !== null && _d !== void 0 ? _d : false,
|
|
8708
|
+
customIsSameOrigin: opts.customIsSameOrigin
|
|
8694
8709
|
};
|
|
8695
8710
|
contextOptions = __assign({ logging: (_e = opts.logging) !== null && _e !== void 0 ? _e : true, cache: opts.cache }, resourceOptions);
|
|
8696
8711
|
windowOptions = {
|
|
@@ -8791,7 +8806,7 @@ var html2canvasPro = createCommonjsModule(function (module, exports) {
|
|
|
8791
8806
|
//# sourceMappingURL=html2canvas-pro.js.map
|
|
8792
8807
|
});
|
|
8793
8808
|
|
|
8794
|
-
const feedbackModalCss = ".text-center{flex-grow:1;text-align:center}.feedback-modal-wrapper *{font-family:var(--feedback-font-family)}.feedback-modal-wrapper--custom-font *{font-family:inherit}.feedback-modal-wrapper{position:absolute;z-index:var(--feedback-modal-modal-wrapper-z-index)}.feedback-overlay{background-color:var(--feedback-modal-screenshot-bg-color);height:100%;left:0;opacity:0;position:fixed;top:0;width:100%;z-index:var(--feedback-modal-screnshot-z-index);transition:opacity 0.2s ease-out}.feedback-overlay--visible{opacity:1}.feedback-modal{display:inline-block;position:relative}.feedback-modal-content{background-color:var(--feedback-modal-content-bg-color);border-color:1px solid var(--feedback-modal-header-text-color);border-radius:var(--feedback-modal-content-border-radius);box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .30), 0px 2px 6px 2px rgba(60, 64, 67, .15);box-sizing:border-box;color:var(--feedback-modal-content-text-color);display:flex;flex-direction:column;left:50%;max-width:90%;padding:20px;position:fixed;top:50%;transform:translate(-50%, -50%) scale(0.95);opacity:0;width:100%;z-index:var(--feedback-modal-content-z-index);transition:transform 0.2s ease-out, opacity 0.2s ease-out}.feedback-modal-content--open{transform:translate(-50%, -50%) scale(1);opacity:1}.feedback-modal-header{align-items:center;color:var(--feedback-modal-header-text-color);display:flex;font-size:var(--feedback-header-font-size);font-weight:var(--feedback-modal-header-font-weight);justify-content:space-between;margin-bottom:20px}.feedback-modal-rating-buttons{width:100%;margin-bottom:20px}.feedback-modal-rating-button{padding:0;background-color:transparent;border:transparent;margin-right:5px;cursor:pointer}.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button{border:1px solid var(--feedback-modal-button-border-color);border-radius:var(--feedback-modal-button-border-radius);color:var(--feedback-modal-button-text-color);font-size:var(--feedback-modal-button-font-size);font-weight:500;margin-right:10px;justify-content:center;padding:5px 10px}.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button:hover,.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button--selected{background-color:var(--feedback-modal-button-bg-color-active);border:1px solid var(--feedback-modal-button-border-color-active);color:var(--feedback-modal-button-text-color-active)}.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button:hover svg,.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button--selected svg{stroke:var(--feedback-modal-rating-button-selected-color)}.feedback-modal-rating-buttons svg{stroke:var(--feedback-modal-rating-button-color);cursor:pointer}.feedback-modal-rating-buttons--stars .feedback-modal-rating-button--selected svg{fill:var(--feedback-modal-rating-button-stars-selected-color);stroke:var(--feedback-modal-rating-button-stars-selected-color)}.feedback-modal-text textarea{background-color:var(--feedback-modal-input-bg-color);border:1px solid var(--feedback-modal-input-border-color);border-radius:var(--feedback-modal-input-border-radius);box-sizing:border-box;color:var(--feedback-modal-input-text-color);font-size:var(--feedback-modal-input-font-size);margin-bottom:20px;height:100px;min-height:100px;padding:10px;resize:vertical;width:100%}.feedback-modal-email input{background-color:var(--feedback-modal-input-bg-color);border:1px solid var(--feedback-modal-input-border-color);border-radius:var(--feedback-modal-input-border-radius);box-sizing:border-box;color:var(--feedback-modal-input-text-color);font-size:var(--feedback-modal-input-font-size);margin-bottom:20px;height:40px;padding:10px;width:100%;margin-bottom:20px}.feedback-modal-privacy{font-size:var(--feedback-modal-input-font-size);margin-bottom:20px}.feedback-modal-text textarea:focus,.feedback-modal-email input:focus{border:1px solid var(--feedback-modal-input-border-color-focused);outline:none}.feedback-modal-buttons{display:flex;flex-direction:column}.feedback-modal-buttons .feedback-modal-button{margin-bottom:20px}.feedback-modal-button{align-items:center;background-color:transparent;border:1px solid var(--feedback-modal-button-border-color);border-radius:var(--feedback-modal-button-border-radius);color:var(--feedback-modal-button-text-color);cursor:pointer;display:flex;font-size:var(--feedback-modal-button-font-size);font-weight:500;justify-content:center;min-height:40px;padding:5px 10px}.feedback-modal-button svg{margin-right:6px}.feedback-modal-button path{fill:var(--feedback-modal-button-icon-color)}.feedback-modal-button:hover path,.feedback-modal-button--active path{fill:var(--feedback-modal-button-icon-color-active)}.feedback-modal-button--submit{background-color:var(--feedback-modal-button-submit-bg-color);border:1px solid var(--feedback-modal-button-border-color-active);color:var(--feedback-modal-button-submit-text-color)}.feedback-modal-button:hover,.feedback-modal-button--active{background-color:var(--feedback-modal-button-bg-color-active);border:1px solid var(--feedback-modal-button-border-color-active);color:var(--feedback-modal-button-text-color-active)}.feedback-modal-button--submit:hover{background-color:var(--feedback-modal-button-submit-bg-color-hover);border:1px solid var(--feedback-modal-button-submit-border-color-hover);color:var(--feedback-modal-button-submit-text-color-hover)}.feedback-modal-input-heading{display:block;font-size:14px;font-weight:300;padding-bottom:10px}.feedback-modal-footer{font-size:12px;text-align:center}.feedback-modal-footer a{color:var(--feedback-modal-footer-link);font-weight:500;text-decoration:none}.feedback-logo,.feedback-footer-text{display:block;text-align:center;margin-top:5px}.feedback-footer-text{margin-top:10px;line-height:1.5}.feedback-modal-close{background-color:var(--feedback-modal-close-bg-color);border:0;border-radius:50%;cursor:pointer;height:22px;margin-left:auto;padding:0;width:22px}.feedback-modal-close svg{stroke:var(--feedback-modal-close-color)}.feedback-modal-screenshot{background-color:var(--feedback-modal-screenshot-bg-color);height:100%;left:0;position:fixed;top:0;width:100%;z-index:var(--feedback-modal-screnshot-z-index)}.feedback-modal-screenshot-header{align-items:center;background-color:var(--feedback-modal-screenshot-header-bg-color);border-radius:var(--feedback-modal-content-border-radius);box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .30), 0px 2px 6px 2px rgba(60, 64, 67, .15);box-sizing:border-box;color:var(--feedback-modal-screenshot-header-text-color);cursor:pointer;display:flex;left:50%;top:20px;transform:translateX(-50%);padding:10px;position:fixed;width:max-content;z-index:var(--feedback-modal-screenshot-header-z-index)}.feedback-modal-screenshot-close{height:24px;padding-left:10px;width:24px}.feedback-modal-screenshot-close svg{stroke:var(--feedback-modal-close-color)}.feedback-modal-message{font-size:var(--feedback-modal-message-font-size);margin-top:0}.feedback-modal-element-hover{background-color:transparent;cursor:pointer;border:1px solid var(--feedback-modal-element-hover-border-color)}.feedback-modal-element-selected{background-color:transparent;border:3px solid var(--feedback-modal-element-selected-border-color) !important;box-shadow:0 0 0 2px rgba(0, 123, 255, 0.3) !important}.screenshot-preview{display:inline-block;width:30px;height:30px;overflow:hidden;border-radius:4px;margin-right:10px;box-shadow:0 2px 4px rgba(0, 0, 0, 0.1);cursor:pointer;transition:transform 0.2s ease}.screenshot-preview:hover{transform:scale(1.1)}.screenshot-preview img{width:100%;height:100%;object-fit:cover}.preview-modal-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0, 0, 0, 0.8);z-index:10000;display:flex;align-items:center;justify-content:center;cursor:pointer}.preview-modal{position:relative;max-width:90vw;max-height:90vh;border-radius:8px;overflow:hidden;cursor:default}.preview-modal img{max-width:100%;max-height:100%;display:block}@media screen and (min-width: 768px){.feedback-modal-content{max-width:var(--feedback-modal-content-max-width)}.feedback-modal-content.feedback-modal-content--bottom-right{bottom:var(--feedback-modal-content-position-bottom);left:initial;right:var(--feedback-modal-content-position-right);top:initial;transform:initial}.feedback-modal-content.feedback-modal-content--bottom-left{bottom:var(--feedback-modal-content-position-bottom);left:var(--feedback-modal-content-position-left);top:initial;transform:initial}.feedback-modal-content.feedback-modal-content--top-right{right:var(--feedback-modal-content-position-right);top:var(--feedback-modal-content-position-top);transform:initial}.feedback-modal-content.feedback-modal-content--top-left{left:var(--feedback-modal-content-position-left);top:var(--feedback-modal-content-position-top);transform:initial}.feedback-modal-content.feedback-modal-content--center-left{left:5px;right:auto;top:50%;transform:translateY(-50%)}.feedback-modal-content.feedback-modal-content--center-right{left:auto;right:5px;top:50%;transform:translateY(-50%)}.feedback-modal-content.feedback-modal-content--sidebar-left.feedback-modal-content--open,.feedback-modal-content.feedback-modal-content--sidebar-right.feedback-modal-content--open{transform:translateX(0)}.feedback-modal-content.feedback-modal-content--sidebar-left{max-width:var(--feedback-modal-content-sidebar-max-width);left:0;right:auto;height:100vh;top:0;transform:translateX(-100%);transition:transform 0.5s ease-in-out;border-radius:0}.feedback-modal-content.feedback-modal-content--sidebar-right{max-width:var(--feedback-modal-content-sidebar-max-width);left:auto;right:0;height:100vh;top:0;transform:translateX(100%);transition:transform 0.5s ease-in-out;border-radius:0}.feedback-modal-text textarea{height:150px;min-height:150px}.feedback-modal-content.feedback-modal-content--bottom-right{transform:translateY(20px)}.feedback-modal-content.feedback-modal-content--bottom-right.feedback-modal-content--open{transform:translateY(0)}.feedback-modal-content.feedback-modal-content--bottom-left{transform:translateY(20px)}.feedback-modal-content.feedback-modal-content--bottom-left.feedback-modal-content--open{transform:translateY(0)}.feedback-modal-content.feedback-modal-content--top-right{transform:translateY(-20px)}.feedback-modal-content.feedback-modal-content--top-right.feedback-modal-content--open{transform:translateY(0)}.feedback-modal-content.feedback-modal-content--top-left{transform:translateY(-20px)}.feedback-modal-content.feedback-modal-content--top-left.feedback-modal-content--open{transform:translateY(0)}}";
|
|
8809
|
+
const feedbackModalCss = ".text-center{flex-grow:1;text-align:center}.feedback-modal-wrapper *{font-family:var(--feedback-font-family)}.feedback-modal-wrapper--custom-font *{font-family:inherit}.feedback-modal-wrapper{position:absolute;z-index:var(--feedback-modal-modal-wrapper-z-index)}.feedback-overlay{background-color:var(--feedback-modal-screenshot-bg-color);height:100%;left:0;opacity:0;position:fixed;top:0;width:100%;z-index:var(--feedback-modal-screnshot-z-index);transition:opacity 0.2s ease-out}.feedback-overlay--visible{opacity:1}.feedback-modal{display:inline-block;position:relative}.feedback-modal-content{background-color:var(--feedback-modal-content-bg-color);border-color:1px solid var(--feedback-modal-header-text-color);border-radius:var(--feedback-modal-content-border-radius);box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .30), 0px 2px 6px 2px rgba(60, 64, 67, .15);box-sizing:border-box;color:var(--feedback-modal-content-text-color);display:flex;flex-direction:column;left:50%;max-width:90%;padding:20px;position:fixed;top:50%;transform:translate(-50%, -50%) scale(0.95);opacity:0;width:100%;z-index:var(--feedback-modal-content-z-index);transition:transform 0.2s ease-out, opacity 0.2s ease-out}.feedback-modal-content--open{transform:translate(-50%, -50%) scale(1);opacity:1}.feedback-modal-header{align-items:center;color:var(--feedback-modal-header-text-color);display:flex;font-size:var(--feedback-header-font-size);font-weight:var(--feedback-modal-header-font-weight);justify-content:space-between;margin-bottom:20px}.feedback-modal-rating-buttons{width:100%;margin-bottom:20px}.feedback-modal-rating-button{padding:0;background-color:transparent;border:transparent;margin-right:5px;cursor:pointer}.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button{border:1px solid var(--feedback-modal-button-border-color);border-radius:var(--feedback-modal-button-border-radius);color:var(--feedback-modal-button-text-color);font-size:var(--feedback-modal-button-font-size);font-weight:500;margin-right:10px;justify-content:center;padding:5px 10px}.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button:hover,.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button--selected{background-color:var(--feedback-modal-button-bg-color-active);border:1px solid var(--feedback-modal-button-border-color-active);color:var(--feedback-modal-button-text-color-active)}.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button:hover svg,.feedback-modal-rating-buttons--thumbs .feedback-modal-rating-button--selected svg{stroke:var(--feedback-modal-rating-button-selected-color)}.feedback-modal-rating-buttons svg{stroke:var(--feedback-modal-rating-button-color);cursor:pointer}.feedback-modal-rating-buttons--stars .feedback-modal-rating-button--selected svg{fill:var(--feedback-modal-rating-button-stars-selected-color);stroke:var(--feedback-modal-rating-button-stars-selected-color)}.feedback-modal-text textarea{background-color:var(--feedback-modal-input-bg-color);border:1px solid var(--feedback-modal-input-border-color);border-radius:var(--feedback-modal-input-border-radius);box-sizing:border-box;color:var(--feedback-modal-input-text-color);font-size:var(--feedback-modal-input-font-size);margin-bottom:20px;height:100px;min-height:100px;padding:10px;resize:vertical;width:100%}.feedback-modal-email input{background-color:var(--feedback-modal-input-bg-color);border:1px solid var(--feedback-modal-input-border-color);border-radius:var(--feedback-modal-input-border-radius);box-sizing:border-box;color:var(--feedback-modal-input-text-color);font-size:var(--feedback-modal-input-font-size);margin-bottom:20px;height:40px;padding:10px;width:100%;margin-bottom:20px}.feedback-modal-privacy{font-size:var(--feedback-modal-input-font-size);margin-bottom:20px}.feedback-modal-text textarea:focus,.feedback-modal-email input:focus{border:1px solid var(--feedback-modal-input-border-color-focused);outline:none}.feedback-modal-buttons{display:flex;flex-direction:column}.feedback-modal-buttons .feedback-modal-button{margin-bottom:20px}.feedback-modal-button{align-items:center;background-color:transparent;border:1px solid var(--feedback-modal-button-border-color);border-radius:var(--feedback-modal-button-border-radius);color:var(--feedback-modal-button-text-color);cursor:pointer;display:flex;font-size:var(--feedback-modal-button-font-size);font-weight:500;justify-content:center;min-height:40px;padding:5px 10px}.feedback-modal-button svg{margin-right:6px}.feedback-modal-button path{fill:var(--feedback-modal-button-icon-color)}.feedback-modal-button:hover path,.feedback-modal-button--active path{fill:var(--feedback-modal-button-icon-color-active)}.feedback-modal-button--submit{background-color:var(--feedback-modal-button-submit-bg-color);border:1px solid var(--feedback-modal-button-border-color-active);color:var(--feedback-modal-button-submit-text-color)}.feedback-modal-button:hover,.feedback-modal-button--active{background-color:var(--feedback-modal-button-bg-color-active);border:1px solid var(--feedback-modal-button-border-color-active);color:var(--feedback-modal-button-text-color-active)}.feedback-modal-button--submit:hover{background-color:var(--feedback-modal-button-submit-bg-color-hover);border:1px solid var(--feedback-modal-button-submit-border-color-hover);color:var(--feedback-modal-button-submit-text-color-hover)}.feedback-modal-input-heading{display:block;font-size:14px;font-weight:300;padding-bottom:10px}.feedback-modal-footer{font-size:12px;text-align:center}.feedback-modal-footer a{color:var(--feedback-modal-footer-link);font-weight:500;text-decoration:none}.feedback-logo,.feedback-footer-text{display:block;text-align:center;margin-top:5px}.feedback-footer-text{margin-top:10px;line-height:1.5}.feedback-modal-close{background-color:var(--feedback-modal-close-bg-color);border:0;border-radius:50%;cursor:pointer;height:22px;margin-left:auto;padding:0;width:22px}.feedback-modal-close svg{stroke:var(--feedback-modal-close-color)}.feedback-modal-screenshot{background-color:var(--feedback-modal-screenshot-bg-color);height:100%;left:0;position:fixed;top:0;width:100%;z-index:var(--feedback-modal-screnshot-z-index)}.feedback-modal-screenshot-header{align-items:center;background-color:var(--feedback-modal-screenshot-header-bg-color);border-radius:var(--feedback-modal-content-border-radius);box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .30), 0px 2px 6px 2px rgba(60, 64, 67, .15);box-sizing:border-box;color:var(--feedback-modal-screenshot-header-text-color);cursor:pointer;display:flex;left:50%;top:20px;transform:translateX(-50%);padding:10px;position:fixed;width:max-content;z-index:var(--feedback-modal-screenshot-header-z-index)}.feedback-modal-screenshot-close{height:24px;padding-left:10px;width:24px}.feedback-modal-screenshot-close svg{stroke:var(--feedback-modal-close-color)}.feedback-modal-message{font-size:var(--feedback-modal-message-font-size);margin-top:0}.feedback-modal-element-hover{background-color:transparent;cursor:pointer;border:1px solid var(--feedback-modal-element-hover-border-color)}.feedback-modal-element-selected{background-color:transparent;border:3px solid var(--feedback-modal-element-selected-border-color) !important;box-shadow:0 0 0 2px rgba(0, 123, 255, 0.3) !important}.screenshot-preview{display:inline-block;width:30px;height:30px;overflow:hidden;border-radius:4px;margin-right:10px;box-shadow:0 2px 4px rgba(0, 0, 0, 0.1);cursor:pointer;transition:transform 0.2s ease}.screenshot-preview:hover{transform:scale(1.1)}.screenshot-preview img{width:100%;height:100%;object-fit:cover}.screenshot-loading{display:inline-flex;align-items:center;margin-right:8px}.canvas-editor-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background-color:var(--feedback-modal-screenshot-bg-color);z-index:10001;display:flex;align-items:center;justify-content:center}.canvas-editor-modal{width:95vw;height:98vh;background:var(--feedback-canvas-editor-bg-color);border-radius:var(--feedback-modal-content-border-radius);display:flex;flex-direction:column;overflow:hidden;box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .30), 0px 2px 6px 2px rgba(60, 64, 67, .15)}.canvas-editor-header{background:var(--feedback-canvas-editor-header-bg-color);border-bottom:1px solid var(--feedback-canvas-editor-border-color);padding:12px 16px;display:flex;flex-direction:column;gap:12px;flex-shrink:0}.canvas-editor-title h3{margin:0;font-size:var(--feedback-modal-header-font-size);font-weight:var(--feedback-modal-header-font-weight);color:var(--feedback-modal-header-text-color);font-family:var(--feedback-modal-header-font-family)}.canvas-editor-toolbar{display:flex;align-items:center;gap:20px;flex-wrap:wrap}.toolbar-section{display:flex;align-items:center}.toolbar-section:last-child{margin-left:auto;gap:10px}.tool-group{display:flex;align-items:center;background:var(--feedback-canvas-editor-tool-bg-color);border:1px solid var(--feedback-canvas-editor-border-color);border-radius:var(--feedback-modal-button-border-radius);padding:4px;box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .10)}.tool-btn{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border:none;background:none;border-radius:var(--feedback-modal-button-border-radius);cursor:pointer;color:var(--feedback-canvas-editor-tool-text-color);transition:all 0.2s ease;position:relative}.tool-btn:hover{background:var(--feedback-canvas-editor-tool-bg-hover);color:var(--feedback-modal-button-text-color-active)}.tool-btn.active{background:var(--feedback-canvas-editor-tool-bg-active);color:var(--feedback-canvas-editor-tool-text-active)}.tool-btn:disabled{opacity:0.4;cursor:not-allowed}.tool-btn:disabled:hover{background:none;color:var(--feedback-canvas-editor-tool-text-color)}.toolbar-divider{width:1px;height:20px;background:var(--feedback-canvas-editor-divider-color);margin:0 6px}.undo-btn{background:var(--feedback-canvas-editor-tool-bg-color) !important;border:1px solid var(--feedback-canvas-editor-border-color) !important}.undo-btn:hover:not(:disabled){background:var(--feedback-canvas-editor-tool-bg-hover) !important}.color-palette{display:flex;align-items:center;gap:6px;background:var(--feedback-canvas-editor-tool-bg-color);border:1px solid var(--feedback-canvas-editor-border-color);border-radius:var(--feedback-modal-button-border-radius);padding:6px;box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .10)}.color-slot-wrapper{position:relative}.color-btn{width:28px;height:28px;border-radius:var(--feedback-modal-button-border-radius);border:2px solid transparent;cursor:pointer;transition:all 0.2s ease;position:relative;box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .15);display:flex;align-items:center;justify-content:center}.color-btn:hover{transform:scale(1.05);box-shadow:0px 2px 4px 0px rgba(60, 64, 67, .25)}.color-btn.active{border-color:var(--feedback-primary-color);transform:scale(1.1);box-shadow:0 0 0 2px rgba(0, 112, 244, 0.2)}.color-btn.editing{border-color:var(--feedback-highlight-color);box-shadow:0 0 0 2px rgba(255, 180, 34, 0.3)}.color-btn.editing:hover{border-color:var(--feedback-highlight-color);box-shadow:0 0 0 2px rgba(255, 180, 34, 0.4)}.color-picker-dropdown{position:absolute;top:100%;left:50%;transform:translateX(-50%);margin-top:6px;background:var(--feedback-canvas-editor-tool-bg-color);border:1px solid var(--feedback-canvas-editor-border-color);border-radius:var(--feedback-modal-button-border-radius);padding:6px;box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .30), 0px 2px 6px 2px rgba(60, 64, 67, .15);z-index:1000}.color-picker-dropdown input[type=\"color\"]{width:50px;height:32px;border:none;border-radius:var(--feedback-modal-button-border-radius);cursor:pointer}.size-control{display:flex;align-items:center;gap:10px;background:var(--feedback-canvas-editor-tool-bg-color);border:1px solid var(--feedback-canvas-editor-border-color);border-radius:var(--feedback-modal-button-border-radius);padding:6px 12px;box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .10)}.size-slider{width:70px;height:4px;border-radius:2px;background:var(--feedback-canvas-editor-slider-track);outline:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;border:none}.size-slider::-webkit-slider-track{width:100%;height:4px;cursor:pointer;background:var(--feedback-canvas-editor-slider-track);border-radius:2px;border:none;box-shadow:none}.size-slider::-webkit-slider-thumb{-webkit-appearance:none;width:14px;height:14px;border-radius:50%;background:var(--feedback-primary-color);cursor:pointer;box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .20);border:none;margin-top:-5px;}.size-slider::-moz-range-track{width:100%;height:4px;cursor:pointer;background:var(--feedback-canvas-editor-slider-track);border-radius:2px;border:none;box-shadow:none}.size-slider::-moz-range-thumb{width:14px;height:14px;border-radius:50%;background:var(--feedback-primary-color);cursor:pointer;border:none;box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .20)}.size-slider::-moz-range-progress{background:var(--feedback-canvas-editor-slider-track);height:4px;border-radius:2px}.size-slider::-ms-track{width:100%;height:4px;cursor:pointer;background:transparent;border-color:transparent;color:transparent}.size-slider::-ms-fill-lower{background:var(--feedback-canvas-editor-slider-track);border-radius:2px}.size-slider::-ms-fill-upper{background:var(--feedback-canvas-editor-slider-track);border-radius:2px}.size-slider::-ms-thumb{width:14px;height:14px;border-radius:50%;background:var(--feedback-primary-color);cursor:pointer;border:none}.size-value{font-weight:500;color:var(--feedback-canvas-editor-tool-text-color);font-size:var(--feedback-text-font-size);min-width:30px}.action-btn{display:flex;align-items:center;gap:6px;padding:5px 12px;border:1px solid var(--feedback-canvas-editor-action-secondary-border);border-radius:var(--feedback-modal-button-border-radius);cursor:pointer;font-size:var(--feedback-modal-button-font-size);font-weight:500;transition:all 0.2s ease;min-width:65px;justify-content:center;height:36px;font-family:var(--feedback-font-family)}.action-btn.secondary{background:var(--feedback-canvas-editor-action-secondary-bg);color:var(--feedback-canvas-editor-action-secondary-text);border-color:var(--feedback-canvas-editor-action-secondary-border)}.action-btn.secondary:hover{background:var(--feedback-canvas-editor-tool-bg-hover);color:var(--feedback-modal-button-text-color-active);border-color:var(--feedback-modal-button-border-color-active)}.action-btn.primary{background:var(--feedback-canvas-editor-action-primary-bg);color:var(--feedback-canvas-editor-action-primary-text);border-color:var(--feedback-modal-button-border-color-active)}.action-btn.primary:hover{background:var(--feedback-modal-button-submit-bg-color-hover);border-color:var(--feedback-modal-button-submit-border-color-hover)}.canvas-editor-content{flex:1;display:flex;align-items:center;justify-content:center;padding:16px;background:var(--feedback-canvas-editor-content-bg);overflow:hidden;min-height:0;min-width:0}.annotation-canvas{max-width:100%;max-height:100%;width:auto;height:auto;cursor:crosshair;border-radius:var(--feedback-modal-content-border-radius);box-shadow:0px 1px 2px 0px rgba(60, 64, 67, .30), 0px 2px 6px 2px rgba(60, 64, 67, .15);background:var(--feedback-white-color);transition:box-shadow 0.3s ease;object-fit:contain;display:block}.annotation-canvas:hover{box-shadow:0px 2px 4px 0px rgba(60, 64, 67, .35), 0px 4px 12px 4px rgba(60, 64, 67, .20)}@media screen and (min-width: 768px){.feedback-modal-content{max-width:var(--feedback-modal-content-max-width)}.feedback-modal-content.feedback-modal-content--bottom-right{bottom:var(--feedback-modal-content-position-bottom);left:initial;right:var(--feedback-modal-content-position-right);top:initial;transform:initial}.feedback-modal-content.feedback-modal-content--bottom-left{bottom:var(--feedback-modal-content-position-bottom);left:var(--feedback-modal-content-position-left);top:initial;transform:initial}.feedback-modal-content.feedback-modal-content--top-right{right:var(--feedback-modal-content-position-right);top:var(--feedback-modal-content-position-top);transform:initial}.feedback-modal-content.feedback-modal-content--top-left{left:var(--feedback-modal-content-position-left);top:var(--feedback-modal-content-position-top);transform:initial}.feedback-modal-content.feedback-modal-content--center-left{left:5px;right:auto;top:50%;transform:translateY(-50%)}.feedback-modal-content.feedback-modal-content--center-right{left:auto;right:5px;top:50%;transform:translateY(-50%)}.feedback-modal-content.feedback-modal-content--sidebar-left.feedback-modal-content--open,.feedback-modal-content.feedback-modal-content--sidebar-right.feedback-modal-content--open{transform:translateX(0)}.feedback-modal-content.feedback-modal-content--sidebar-left{max-width:var(--feedback-modal-content-sidebar-max-width);left:0;right:auto;height:100vh;top:0;transform:translateX(-100%);transition:transform 0.5s ease-in-out;border-radius:0}.feedback-modal-content.feedback-modal-content--sidebar-right{max-width:var(--feedback-modal-content-sidebar-max-width);left:auto;right:0;height:100vh;top:0;transform:translateX(100%);transition:transform 0.5s ease-in-out;border-radius:0}.feedback-modal-text textarea{height:150px;min-height:150px}.feedback-modal-content.feedback-modal-content--bottom-right{transform:translateY(20px)}.feedback-modal-content.feedback-modal-content--bottom-right.feedback-modal-content--open{transform:translateY(0)}.feedback-modal-content.feedback-modal-content--bottom-left{transform:translateY(20px)}.feedback-modal-content.feedback-modal-content--bottom-left.feedback-modal-content--open{transform:translateY(0)}.feedback-modal-content.feedback-modal-content--top-right{transform:translateY(-20px)}.feedback-modal-content.feedback-modal-content--top-right.feedback-modal-content--open{transform:translateY(0)}.feedback-modal-content.feedback-modal-content--top-left{transform:translateY(-20px)}.feedback-modal-content.feedback-modal-content--top-left.feedback-modal-content--open{transform:translateY(0)}}@media (max-width: 768px){.canvas-editor-modal{width:100vw;height:100vh;border-radius:0}.canvas-editor-header{padding:8px 12px;gap:8px}.canvas-editor-toolbar{flex-direction:column;align-items:stretch;gap:12px}.toolbar-section{justify-content:center}.toolbar-section:last-child{margin-left:0;justify-content:stretch;gap:8px}.action-btn{flex:1;min-width:auto}.canvas-editor-content{padding:8px}.tool-group{flex-wrap:wrap;justify-content:center}.color-palette{flex-wrap:wrap;justify-content:center}.size-control{flex-direction:column;gap:6px;text-align:center}.size-slider{width:100px}}";
|
|
8795
8810
|
|
|
8796
8811
|
const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
|
|
8797
8812
|
constructor() {
|
|
@@ -8884,144 +8899,634 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
|
|
|
8884
8899
|
document.querySelectorAll('.feedback-modal-element-selected').forEach(el => {
|
|
8885
8900
|
el.classList.remove('feedback-modal-element-selected');
|
|
8886
8901
|
});
|
|
8902
|
+
// Reset canvas editor states
|
|
8887
8903
|
this.takingScreenshot = false;
|
|
8888
|
-
this.
|
|
8889
|
-
this.
|
|
8904
|
+
this.showPreviewModal = false;
|
|
8905
|
+
this.showCanvasEditor = false;
|
|
8906
|
+
this.annotations = [];
|
|
8907
|
+
this.currentAnnotation = null;
|
|
8908
|
+
this.isDrawing = false;
|
|
8909
|
+
this.canvasRef = null;
|
|
8910
|
+
this.canvasContext = null;
|
|
8911
|
+
this.originalImageData = null;
|
|
8912
|
+
// Reset resizing states
|
|
8913
|
+
this.isResizing = false;
|
|
8914
|
+
this.resizingAnnotation = null;
|
|
8915
|
+
this.resizeStartSize = 16;
|
|
8916
|
+
this.hoveredAnnotation = null;
|
|
8917
|
+
this.resizeHandle = false;
|
|
8918
|
+
// Reset form states
|
|
8890
8919
|
this.formSuccess = false;
|
|
8891
8920
|
this.formError = false;
|
|
8892
8921
|
this.formErrorStatus = 500;
|
|
8893
8922
|
this.formMessage = '';
|
|
8894
8923
|
this.formEmail = '';
|
|
8895
|
-
this.showPreviewModal = false;
|
|
8896
8924
|
this.resetOverflow();
|
|
8897
8925
|
}, 200);
|
|
8898
8926
|
};
|
|
8899
|
-
this.openScreenShot = () => {
|
|
8900
|
-
|
|
8901
|
-
this.showModal = false;
|
|
8902
|
-
this.showScreenshotMode = true;
|
|
8903
|
-
this.showScreenshotTopBar = true;
|
|
8904
|
-
// Clear previous screenshot and selection data
|
|
8905
|
-
this.encodedScreenshot = null;
|
|
8906
|
-
this.originalElement = null;
|
|
8907
|
-
this.selectedElementBounds = null;
|
|
8908
|
-
this.hoveredElement = null;
|
|
8909
|
-
this.hoveredElementBounds = null;
|
|
8910
|
-
// NO CSS CLASSES - they cause scroll jumping
|
|
8911
|
-
};
|
|
8912
|
-
this.closeScreenShot = () => {
|
|
8913
|
-
// Remove highlight from ALL selected elements
|
|
8914
|
-
document.querySelectorAll('.feedback-modal-element-selected').forEach(el => {
|
|
8915
|
-
el.classList.remove('feedback-modal-element-selected');
|
|
8916
|
-
});
|
|
8917
|
-
// Reset loading state
|
|
8918
|
-
this.takingScreenshot = false;
|
|
8919
|
-
this.showModal = false;
|
|
8920
|
-
this.showScreenshotMode = false;
|
|
8921
|
-
this.showScreenshotTopBar = false;
|
|
8922
|
-
};
|
|
8923
|
-
this.openPreviewModal = (event) => {
|
|
8924
|
-
event.stopPropagation(); // Prevent button click from firing
|
|
8925
|
-
this.showPreviewModal = true;
|
|
8926
|
-
};
|
|
8927
|
-
this.closePreviewModal = () => {
|
|
8928
|
-
this.showPreviewModal = false;
|
|
8929
|
-
};
|
|
8930
|
-
this.handleMouseOverScreenShot = (event) => {
|
|
8931
|
-
event.preventDefault();
|
|
8932
|
-
if (this.hasSelectedElement)
|
|
8933
|
-
return;
|
|
8934
|
-
const borderOffset = 2;
|
|
8935
|
-
this.screenshotModal.style.display = 'none';
|
|
8936
|
-
const elementUnder = document.elementFromPoint(event.clientX, event.clientY);
|
|
8937
|
-
const rect = elementUnder.getBoundingClientRect();
|
|
8938
|
-
this.screenshotModal.style.display = '';
|
|
8939
|
-
// Store the hovered element and its bounds for later use
|
|
8940
|
-
this.hoveredElement = elementUnder;
|
|
8941
|
-
this.hoveredElementBounds = rect;
|
|
8942
|
-
// Get the bounding box of the element selected
|
|
8943
|
-
this.elementSelected.style.position = 'absolute';
|
|
8944
|
-
this.elementSelected.style.left = `${rect.left}px`;
|
|
8945
|
-
this.elementSelected.style.top = `${rect.top}px`;
|
|
8946
|
-
this.elementSelected.style.width = `${rect.width}px`;
|
|
8947
|
-
this.elementSelected.style.height = `${rect.height}px`;
|
|
8948
|
-
this.elementSelected.classList.add('feedback-modal-element-hover');
|
|
8949
|
-
// Set the background color of nonselected areas
|
|
8950
|
-
// Top
|
|
8951
|
-
this.topSide.style.position = 'absolute';
|
|
8952
|
-
this.topSide.style.left = `${rect.left}px`;
|
|
8953
|
-
this.topSide.style.top = '0px';
|
|
8954
|
-
this.topSide.style.width = `${rect.width + borderOffset}px`;
|
|
8955
|
-
this.topSide.style.height = `${rect.top}px`;
|
|
8956
|
-
this.topSide.style.backgroundColor = 'rgba(0, 0, 0, 0.4)';
|
|
8957
|
-
// Left
|
|
8958
|
-
this.leftSide.style.position = 'absolute';
|
|
8959
|
-
this.leftSide.style.left = '0px';
|
|
8960
|
-
this.leftSide.style.top = '0px';
|
|
8961
|
-
this.leftSide.style.width = `${rect.left}px`;
|
|
8962
|
-
this.leftSide.style.height = '100vh';
|
|
8963
|
-
this.leftSide.style.backgroundColor = 'rgba(0, 0, 0, 0.4)';
|
|
8964
|
-
// Bottom
|
|
8965
|
-
this.bottomSide.style.position = 'absolute';
|
|
8966
|
-
this.bottomSide.style.left = `${rect.left}px`;
|
|
8967
|
-
this.bottomSide.style.top = `${rect.bottom + borderOffset}px`;
|
|
8968
|
-
this.bottomSide.style.width = `${rect.width + borderOffset}px`;
|
|
8969
|
-
this.bottomSide.style.height = '100vh';
|
|
8970
|
-
this.bottomSide.style.backgroundColor = 'rgba(0, 0, 0, 0.4)';
|
|
8971
|
-
// Right
|
|
8972
|
-
this.rightSide.style.position = 'absolute';
|
|
8973
|
-
this.rightSide.style.left = `${rect.right + borderOffset}px`;
|
|
8974
|
-
this.rightSide.style.top = '0px';
|
|
8975
|
-
this.rightSide.style.width = '100%';
|
|
8976
|
-
this.rightSide.style.height = '100vh';
|
|
8977
|
-
this.rightSide.style.backgroundColor = 'rgba(0, 0, 0, 0.4)';
|
|
8978
|
-
// Restore the visibility of the screenshot-modal
|
|
8979
|
-
this.screenshotModal.style.backgroundColor = 'transparent';
|
|
8980
|
-
};
|
|
8981
|
-
this.handleMouseClickedSelectedElement = async (event) => {
|
|
8982
|
-
event.preventDefault();
|
|
8983
|
-
if (!this.elementSelected || !this.hoveredElement) {
|
|
8984
|
-
return;
|
|
8985
|
-
}
|
|
8986
|
-
this.hasSelectedElement = true;
|
|
8987
|
-
// Remove highlight from ALL previously selected elements
|
|
8988
|
-
document.querySelectorAll('.feedback-modal-element-selected').forEach(el => {
|
|
8989
|
-
el.classList.remove('feedback-modal-element-selected');
|
|
8990
|
-
});
|
|
8991
|
-
// Add highlight to newly selected element
|
|
8992
|
-
this.hoveredElement.classList.add('feedback-modal-element-selected');
|
|
8993
|
-
// Store element bounds in viewport coordinates
|
|
8994
|
-
this.selectedElementBounds = this.hoveredElementBounds;
|
|
8995
|
-
this.originalElement = this.hoveredElement;
|
|
8996
|
-
// Show loading state in top bar
|
|
8927
|
+
this.openScreenShot = async () => {
|
|
8928
|
+
// Show loading state immediately
|
|
8997
8929
|
this.takingScreenshot = true;
|
|
8998
|
-
// Take screenshot FIRST while highlight is still visible
|
|
8999
8930
|
try {
|
|
9000
|
-
|
|
9001
|
-
|
|
8931
|
+
// Capture viewport screenshot immediately
|
|
8932
|
+
const dataUrl = await this.captureViewportScreenshot();
|
|
9002
8933
|
this.encodedScreenshot = dataUrl;
|
|
8934
|
+
this.originalImageData = dataUrl;
|
|
9003
8935
|
// Reset loading state
|
|
9004
8936
|
this.takingScreenshot = false;
|
|
9005
|
-
//
|
|
9006
|
-
this.
|
|
9007
|
-
this.
|
|
9008
|
-
//
|
|
9009
|
-
|
|
9010
|
-
|
|
9011
|
-
|
|
8937
|
+
// Skip preview modal and go directly to canvas editor
|
|
8938
|
+
this.showModal = false;
|
|
8939
|
+
this.showCanvasEditor = true;
|
|
8940
|
+
// Initialize canvas after a short delay to ensure DOM is ready
|
|
8941
|
+
setTimeout(() => {
|
|
8942
|
+
this.initializeCanvas();
|
|
8943
|
+
}, 100);
|
|
9012
8944
|
}
|
|
9013
8945
|
catch (error) {
|
|
9014
8946
|
console.error('Failed to capture screenshot:', error);
|
|
9015
|
-
this.hasSelectedElement = false;
|
|
9016
8947
|
// Reset loading state on error
|
|
9017
8948
|
this.takingScreenshot = false;
|
|
9018
|
-
//
|
|
9019
|
-
this.showScreenshotTopBar = false;
|
|
9020
|
-
this.showScreenshotMode = false;
|
|
9021
|
-
this.resetOverflow();
|
|
8949
|
+
// Show modal anyway
|
|
9022
8950
|
this.showModal = true;
|
|
9023
8951
|
}
|
|
9024
8952
|
};
|
|
8953
|
+
this.openCanvasEditor = (event) => {
|
|
8954
|
+
if (event) {
|
|
8955
|
+
event.stopPropagation();
|
|
8956
|
+
}
|
|
8957
|
+
this.showModal = false;
|
|
8958
|
+
this.showCanvasEditor = true;
|
|
8959
|
+
// Initialize canvas after a short delay to ensure DOM is ready
|
|
8960
|
+
setTimeout(() => {
|
|
8961
|
+
this.initializeCanvas();
|
|
8962
|
+
}, 100);
|
|
8963
|
+
};
|
|
8964
|
+
this.closeCanvasEditor = () => {
|
|
8965
|
+
this.showCanvasEditor = false;
|
|
8966
|
+
this.showModal = true;
|
|
8967
|
+
};
|
|
8968
|
+
this.saveAnnotations = () => {
|
|
8969
|
+
if (this.canvasRef) {
|
|
8970
|
+
// Create final image with annotations
|
|
8971
|
+
const finalDataUrl = this.canvasRef.toDataURL('image/png');
|
|
8972
|
+
this.encodedScreenshot = finalDataUrl;
|
|
8973
|
+
}
|
|
8974
|
+
this.showCanvasEditor = false;
|
|
8975
|
+
this.showModal = true;
|
|
8976
|
+
};
|
|
8977
|
+
this.initializeCanvas = () => {
|
|
8978
|
+
if (!this.canvasRef || !this.originalImageData)
|
|
8979
|
+
return;
|
|
8980
|
+
this.canvasContext = this.canvasRef.getContext('2d');
|
|
8981
|
+
const img = new Image();
|
|
8982
|
+
img.onload = () => {
|
|
8983
|
+
// Set canvas to original image dimensions
|
|
8984
|
+
this.canvasRef.width = img.width;
|
|
8985
|
+
this.canvasRef.height = img.height;
|
|
8986
|
+
// Get available container dimensions
|
|
8987
|
+
const containerWidth = this.canvasRef.parentElement.clientWidth - 32; // Account for reduced padding (16px * 2)
|
|
8988
|
+
const containerHeight = this.canvasRef.parentElement.clientHeight - 32;
|
|
8989
|
+
// Calculate scale factors for both dimensions
|
|
8990
|
+
const scaleX = containerWidth / img.width;
|
|
8991
|
+
const scaleY = containerHeight / img.height;
|
|
8992
|
+
// Use the smaller scale to ensure complete image fits
|
|
8993
|
+
const scale = Math.min(scaleX, scaleY, 1); // Never scale up, only down
|
|
8994
|
+
// Calculate final display dimensions
|
|
8995
|
+
const displayWidth = img.width * scale;
|
|
8996
|
+
const displayHeight = img.height * scale;
|
|
8997
|
+
// Set CSS size for display (this scales the canvas visually)
|
|
8998
|
+
this.canvasRef.style.width = `${displayWidth}px`;
|
|
8999
|
+
this.canvasRef.style.height = `${displayHeight}px`;
|
|
9000
|
+
console.log('Canvas initialized with complete image fit:', {
|
|
9001
|
+
originalWidth: img.width,
|
|
9002
|
+
originalHeight: img.height,
|
|
9003
|
+
displayWidth,
|
|
9004
|
+
displayHeight,
|
|
9005
|
+
scale,
|
|
9006
|
+
scaleX,
|
|
9007
|
+
scaleY,
|
|
9008
|
+
containerWidth,
|
|
9009
|
+
containerHeight,
|
|
9010
|
+
usingScale: scale === scaleX ? 'width-limited' : 'height-limited'
|
|
9011
|
+
});
|
|
9012
|
+
// Draw the original image at full resolution
|
|
9013
|
+
this.canvasContext.drawImage(img, 0, 0);
|
|
9014
|
+
// Redraw existing annotations
|
|
9015
|
+
this.redrawAnnotations();
|
|
9016
|
+
};
|
|
9017
|
+
img.src = this.originalImageData;
|
|
9018
|
+
};
|
|
9019
|
+
this.redrawAnnotations = () => {
|
|
9020
|
+
if (!this.canvasContext)
|
|
9021
|
+
return;
|
|
9022
|
+
// Clear and redraw background image
|
|
9023
|
+
const img = new Image();
|
|
9024
|
+
img.onload = () => {
|
|
9025
|
+
this.canvasContext.clearRect(0, 0, this.canvasRef.width, this.canvasRef.height);
|
|
9026
|
+
this.canvasContext.drawImage(img, 0, 0);
|
|
9027
|
+
// Draw all annotations
|
|
9028
|
+
this.annotations.forEach(annotation => {
|
|
9029
|
+
this.drawAnnotation(annotation);
|
|
9030
|
+
});
|
|
9031
|
+
};
|
|
9032
|
+
img.src = this.originalImageData;
|
|
9033
|
+
};
|
|
9034
|
+
this.drawAnnotation = (annotation) => {
|
|
9035
|
+
if (!this.canvasContext)
|
|
9036
|
+
return;
|
|
9037
|
+
this.canvasContext.strokeStyle = annotation.color;
|
|
9038
|
+
this.canvasContext.lineWidth = annotation.lineWidth;
|
|
9039
|
+
this.canvasContext.lineCap = 'round';
|
|
9040
|
+
this.canvasContext.lineJoin = 'round';
|
|
9041
|
+
switch (annotation.type) {
|
|
9042
|
+
case 'rectangle':
|
|
9043
|
+
this.canvasContext.strokeRect(annotation.startX, annotation.startY, annotation.width, annotation.height);
|
|
9044
|
+
// Rectangle resize handles disabled for now
|
|
9045
|
+
break;
|
|
9046
|
+
case 'line':
|
|
9047
|
+
this.canvasContext.beginPath();
|
|
9048
|
+
this.canvasContext.moveTo(annotation.startX, annotation.startY);
|
|
9049
|
+
this.canvasContext.lineTo(annotation.endX, annotation.endY);
|
|
9050
|
+
this.canvasContext.stroke();
|
|
9051
|
+
// Draw resize handles if this annotation is hovered
|
|
9052
|
+
if (this.hoveredAnnotation === annotation) {
|
|
9053
|
+
this.drawLineResizeHandles(annotation);
|
|
9054
|
+
}
|
|
9055
|
+
break;
|
|
9056
|
+
case 'arrow':
|
|
9057
|
+
this.drawArrow(annotation.startX, annotation.startY, annotation.endX, annotation.endY);
|
|
9058
|
+
// Draw resize handles if this annotation is hovered
|
|
9059
|
+
if (this.hoveredAnnotation === annotation) {
|
|
9060
|
+
this.drawLineResizeHandles(annotation); // Same as line
|
|
9061
|
+
}
|
|
9062
|
+
break;
|
|
9063
|
+
case 'text':
|
|
9064
|
+
const fontSize = annotation.fontSize || 16;
|
|
9065
|
+
this.canvasContext.fillStyle = annotation.color;
|
|
9066
|
+
this.canvasContext.font = `${fontSize}px Arial`;
|
|
9067
|
+
this.canvasContext.fillText(annotation.text, annotation.x, annotation.y);
|
|
9068
|
+
// Draw resize handle if this annotation is hovered
|
|
9069
|
+
if (this.hoveredAnnotation === annotation) {
|
|
9070
|
+
this.drawTextResizeHandle(annotation);
|
|
9071
|
+
}
|
|
9072
|
+
break;
|
|
9073
|
+
}
|
|
9074
|
+
};
|
|
9075
|
+
// Draw resize handle for text annotation
|
|
9076
|
+
this.drawTextResizeHandle = (annotation) => {
|
|
9077
|
+
if (!this.canvasContext || annotation.type !== 'text')
|
|
9078
|
+
return;
|
|
9079
|
+
const fontSize = annotation.fontSize || 16;
|
|
9080
|
+
const textWidth = this.getTextWidth(annotation.text, fontSize);
|
|
9081
|
+
const handleSize = 8;
|
|
9082
|
+
const handleX = annotation.x + textWidth;
|
|
9083
|
+
const handleY = annotation.y;
|
|
9084
|
+
// Draw resize handle (small square) - using widget primary color
|
|
9085
|
+
this.canvasContext.fillStyle = '#0070F4'; // var(--feedback-primary-color)
|
|
9086
|
+
this.canvasContext.strokeStyle = '#ffffff';
|
|
9087
|
+
this.canvasContext.lineWidth = 2;
|
|
9088
|
+
this.canvasContext.fillRect(handleX - handleSize / 2, handleY - handleSize / 2, handleSize, handleSize);
|
|
9089
|
+
this.canvasContext.strokeRect(handleX - handleSize / 2, handleY - handleSize / 2, handleSize, handleSize);
|
|
9090
|
+
};
|
|
9091
|
+
this.drawArrow = (fromX, fromY, toX, toY) => {
|
|
9092
|
+
const headlen = 15; // Arrow head length
|
|
9093
|
+
const angle = Math.atan2(toY - fromY, toX - fromX);
|
|
9094
|
+
// Draw line
|
|
9095
|
+
this.canvasContext.beginPath();
|
|
9096
|
+
this.canvasContext.moveTo(fromX, fromY);
|
|
9097
|
+
this.canvasContext.lineTo(toX, toY);
|
|
9098
|
+
this.canvasContext.stroke();
|
|
9099
|
+
// Draw arrow head
|
|
9100
|
+
this.canvasContext.beginPath();
|
|
9101
|
+
this.canvasContext.moveTo(toX, toY);
|
|
9102
|
+
this.canvasContext.lineTo(toX - headlen * Math.cos(angle - Math.PI / 6), toY - headlen * Math.sin(angle - Math.PI / 6));
|
|
9103
|
+
this.canvasContext.moveTo(toX, toY);
|
|
9104
|
+
this.canvasContext.lineTo(toX - headlen * Math.cos(angle + Math.PI / 6), toY - headlen * Math.sin(angle + Math.PI / 6));
|
|
9105
|
+
this.canvasContext.stroke();
|
|
9106
|
+
};
|
|
9107
|
+
this.undoLastAnnotation = () => {
|
|
9108
|
+
this.annotations = this.annotations.slice(0, -1);
|
|
9109
|
+
this.redrawAnnotations();
|
|
9110
|
+
};
|
|
9111
|
+
// Handle color slot editing
|
|
9112
|
+
this.handleColorSlotClick = (colorIndex) => {
|
|
9113
|
+
if (this.editingColorIndex === colorIndex) {
|
|
9114
|
+
// If already editing this slot, just select the color
|
|
9115
|
+
this.canvasDrawingColor = this.defaultColors[colorIndex];
|
|
9116
|
+
this.showColorPicker = false;
|
|
9117
|
+
this.editingColorIndex = -1;
|
|
9118
|
+
}
|
|
9119
|
+
else {
|
|
9120
|
+
// Start editing this color slot
|
|
9121
|
+
this.editingColorIndex = colorIndex;
|
|
9122
|
+
this.showColorPicker = true;
|
|
9123
|
+
this.canvasDrawingColor = this.defaultColors[colorIndex];
|
|
9124
|
+
}
|
|
9125
|
+
};
|
|
9126
|
+
// Update color in slot
|
|
9127
|
+
this.updateColorSlot = (newColor) => {
|
|
9128
|
+
if (this.editingColorIndex >= 0 && this.editingColorIndex < this.defaultColors.length) {
|
|
9129
|
+
this.defaultColors[this.editingColorIndex] = newColor;
|
|
9130
|
+
this.canvasDrawingColor = newColor;
|
|
9131
|
+
this.showColorPicker = false;
|
|
9132
|
+
this.editingColorIndex = -1;
|
|
9133
|
+
// Force reactivity
|
|
9134
|
+
this.defaultColors = [...this.defaultColors];
|
|
9135
|
+
}
|
|
9136
|
+
};
|
|
9137
|
+
// Handle color picker input without closing
|
|
9138
|
+
this.handleColorPickerInput = (event) => {
|
|
9139
|
+
event.stopPropagation();
|
|
9140
|
+
const newColor = event.target.value;
|
|
9141
|
+
if (this.editingColorIndex >= 0 && this.editingColorIndex < this.defaultColors.length) {
|
|
9142
|
+
this.defaultColors[this.editingColorIndex] = newColor;
|
|
9143
|
+
this.canvasDrawingColor = newColor;
|
|
9144
|
+
// Force reactivity
|
|
9145
|
+
this.defaultColors = [...this.defaultColors];
|
|
9146
|
+
}
|
|
9147
|
+
};
|
|
9148
|
+
// Handle color picker click to prevent closing
|
|
9149
|
+
this.handleColorPickerClick = (event) => {
|
|
9150
|
+
event.stopPropagation();
|
|
9151
|
+
};
|
|
9152
|
+
// Close color picker
|
|
9153
|
+
this.closeColorPicker = () => {
|
|
9154
|
+
this.showColorPicker = false;
|
|
9155
|
+
this.editingColorIndex = -1;
|
|
9156
|
+
};
|
|
9157
|
+
// Check if point is in resize handle for any annotation type
|
|
9158
|
+
this.isPointInResizeHandle = (x, y, annotation) => {
|
|
9159
|
+
const handleSize = 8;
|
|
9160
|
+
switch (annotation.type) {
|
|
9161
|
+
case 'text':
|
|
9162
|
+
const textWidth = this.getTextWidth(annotation.text, annotation.fontSize || 16);
|
|
9163
|
+
const handleX = annotation.x + textWidth;
|
|
9164
|
+
const handleY = annotation.y;
|
|
9165
|
+
return x >= handleX - handleSize / 2 && x <= handleX + handleSize / 2 &&
|
|
9166
|
+
y >= handleY - handleSize / 2 && y <= handleY + handleSize / 2;
|
|
9167
|
+
case 'rectangle':
|
|
9168
|
+
// Rectangle resizing disabled for now
|
|
9169
|
+
return false;
|
|
9170
|
+
case 'line':
|
|
9171
|
+
case 'arrow':
|
|
9172
|
+
// Check both endpoint handles
|
|
9173
|
+
const lineHandles = [
|
|
9174
|
+
{ x: annotation.startX, y: annotation.startY, point: 'start' },
|
|
9175
|
+
{ x: annotation.endX, y: annotation.endY, point: 'end' }
|
|
9176
|
+
];
|
|
9177
|
+
for (const handle of lineHandles) {
|
|
9178
|
+
if (x >= handle.x - handleSize / 2 && x <= handle.x + handleSize / 2 &&
|
|
9179
|
+
y >= handle.y - handleSize / 2 && y <= handle.y + handleSize / 2) {
|
|
9180
|
+
return handle.point; // Return which endpoint was clicked
|
|
9181
|
+
}
|
|
9182
|
+
}
|
|
9183
|
+
return false;
|
|
9184
|
+
default:
|
|
9185
|
+
return false;
|
|
9186
|
+
}
|
|
9187
|
+
};
|
|
9188
|
+
// Get text width for resize handle positioning
|
|
9189
|
+
this.getTextWidth = (text, fontSize) => {
|
|
9190
|
+
// Approximate text width calculation
|
|
9191
|
+
return text.length * fontSize * 0.6;
|
|
9192
|
+
};
|
|
9193
|
+
// Start text resize
|
|
9194
|
+
this.startTextResize = (annotation, startPos) => {
|
|
9195
|
+
this.isResizing = true;
|
|
9196
|
+
this.resizingAnnotation = annotation;
|
|
9197
|
+
this.resizeStartSize = annotation.fontSize || 16;
|
|
9198
|
+
this.dragStartPos = startPos;
|
|
9199
|
+
};
|
|
9200
|
+
// Handle text resize
|
|
9201
|
+
this.handleTextResize = (currentPos) => {
|
|
9202
|
+
if (!this.resizingAnnotation || !this.dragStartPos)
|
|
9203
|
+
return;
|
|
9204
|
+
const deltaX = currentPos.x - this.dragStartPos.x;
|
|
9205
|
+
const deltaY = currentPos.y - this.dragStartPos.y;
|
|
9206
|
+
const avgDelta = (deltaX + deltaY) / 2;
|
|
9207
|
+
// Calculate new font size (minimum 8px, maximum 72px)
|
|
9208
|
+
const newSize = Math.max(8, Math.min(72, this.resizeStartSize + avgDelta * 0.5));
|
|
9209
|
+
// Update annotation font size
|
|
9210
|
+
const index = this.annotations.findIndex(a => a === this.resizingAnnotation);
|
|
9211
|
+
if (index !== -1) {
|
|
9212
|
+
this.annotations[index] = Object.assign(Object.assign({}, this.resizingAnnotation), { fontSize: Math.round(newSize) });
|
|
9213
|
+
this.resizingAnnotation = this.annotations[index];
|
|
9214
|
+
}
|
|
9215
|
+
this.redrawAnnotations();
|
|
9216
|
+
};
|
|
9217
|
+
// Start resize for any annotation type
|
|
9218
|
+
this.startResize = (annotation, handle, startPos) => {
|
|
9219
|
+
this.isResizing = true;
|
|
9220
|
+
this.resizingAnnotation = annotation;
|
|
9221
|
+
this.resizeHandle = handle;
|
|
9222
|
+
this.dragStartPos = startPos;
|
|
9223
|
+
// Store original values for different annotation types
|
|
9224
|
+
if (annotation.type === 'text') {
|
|
9225
|
+
this.resizeStartSize = annotation.fontSize || 16;
|
|
9226
|
+
}
|
|
9227
|
+
};
|
|
9228
|
+
// Enhanced mouse down handler with resize detection for all annotation types
|
|
9229
|
+
this.handleCanvasMouseDown = (event) => {
|
|
9230
|
+
if (!this.canvasRef)
|
|
9231
|
+
return;
|
|
9232
|
+
// Close color picker if open
|
|
9233
|
+
if (this.showColorPicker) {
|
|
9234
|
+
this.closeColorPicker();
|
|
9235
|
+
}
|
|
9236
|
+
const coords = this.getCanvasCoordinates(event);
|
|
9237
|
+
// Check if clicking on existing annotation first
|
|
9238
|
+
const found = this.findAnnotationAt(coords.x, coords.y);
|
|
9239
|
+
if (found) {
|
|
9240
|
+
// Check if clicking on resize handle for any annotation type
|
|
9241
|
+
const handle = this.isPointInResizeHandle(coords.x, coords.y, found.annotation);
|
|
9242
|
+
if (handle) {
|
|
9243
|
+
this.startResize(found.annotation, handle, coords);
|
|
9244
|
+
this.canvasRef.style.cursor = 'nw-resize';
|
|
9245
|
+
return;
|
|
9246
|
+
}
|
|
9247
|
+
// Start dragging existing annotation
|
|
9248
|
+
if (!this.isDrawing) {
|
|
9249
|
+
this.isDragging = true;
|
|
9250
|
+
this.draggedAnnotation = found.annotation;
|
|
9251
|
+
this.dragStartPos = coords;
|
|
9252
|
+
this.canvasRef.style.cursor = 'grabbing';
|
|
9253
|
+
return;
|
|
9254
|
+
}
|
|
9255
|
+
}
|
|
9256
|
+
// Original drawing logic
|
|
9257
|
+
this.isDrawing = true;
|
|
9258
|
+
if (this.canvasDrawingTool === 'text') {
|
|
9259
|
+
const text = prompt('Enter text:');
|
|
9260
|
+
if (text) {
|
|
9261
|
+
const annotation = {
|
|
9262
|
+
type: 'text',
|
|
9263
|
+
x: coords.x,
|
|
9264
|
+
y: coords.y,
|
|
9265
|
+
text,
|
|
9266
|
+
color: this.canvasDrawingColor,
|
|
9267
|
+
fontSize: 16
|
|
9268
|
+
};
|
|
9269
|
+
this.annotations = [...this.annotations, annotation];
|
|
9270
|
+
this.redrawAnnotations();
|
|
9271
|
+
}
|
|
9272
|
+
this.isDrawing = false;
|
|
9273
|
+
}
|
|
9274
|
+
else {
|
|
9275
|
+
this.currentAnnotation = {
|
|
9276
|
+
type: this.canvasDrawingTool,
|
|
9277
|
+
startX: coords.x,
|
|
9278
|
+
startY: coords.y,
|
|
9279
|
+
color: this.canvasDrawingColor,
|
|
9280
|
+
lineWidth: this.canvasLineWidth
|
|
9281
|
+
};
|
|
9282
|
+
}
|
|
9283
|
+
};
|
|
9284
|
+
this.handleCanvasMouseMove = (event) => {
|
|
9285
|
+
if (!this.canvasRef)
|
|
9286
|
+
return;
|
|
9287
|
+
const coords = this.getCanvasCoordinates(event);
|
|
9288
|
+
// Handle resizing for any annotation type
|
|
9289
|
+
if (this.isResizing && this.resizingAnnotation) {
|
|
9290
|
+
this.handleResize(coords);
|
|
9291
|
+
return;
|
|
9292
|
+
}
|
|
9293
|
+
// Handle dragging existing annotation
|
|
9294
|
+
if (this.isDragging && this.draggedAnnotation && this.dragStartPos) {
|
|
9295
|
+
const deltaX = coords.x - this.dragStartPos.x;
|
|
9296
|
+
const deltaY = coords.y - this.dragStartPos.y;
|
|
9297
|
+
// Update annotation position
|
|
9298
|
+
const updatedAnnotation = Object.assign({}, this.draggedAnnotation);
|
|
9299
|
+
switch (updatedAnnotation.type) {
|
|
9300
|
+
case 'rectangle':
|
|
9301
|
+
updatedAnnotation.startX += deltaX;
|
|
9302
|
+
updatedAnnotation.startY += deltaY;
|
|
9303
|
+
break;
|
|
9304
|
+
case 'line':
|
|
9305
|
+
case 'arrow':
|
|
9306
|
+
updatedAnnotation.startX += deltaX;
|
|
9307
|
+
updatedAnnotation.startY += deltaY;
|
|
9308
|
+
updatedAnnotation.endX += deltaX;
|
|
9309
|
+
updatedAnnotation.endY += deltaY;
|
|
9310
|
+
break;
|
|
9311
|
+
case 'text':
|
|
9312
|
+
updatedAnnotation.x += deltaX;
|
|
9313
|
+
updatedAnnotation.y += deltaY;
|
|
9314
|
+
break;
|
|
9315
|
+
}
|
|
9316
|
+
// Update annotation in array
|
|
9317
|
+
const index = this.annotations.findIndex(a => a === this.draggedAnnotation);
|
|
9318
|
+
if (index !== -1) {
|
|
9319
|
+
this.annotations[index] = updatedAnnotation;
|
|
9320
|
+
this.draggedAnnotation = updatedAnnotation;
|
|
9321
|
+
}
|
|
9322
|
+
this.dragStartPos = coords;
|
|
9323
|
+
this.redrawAnnotations();
|
|
9324
|
+
return;
|
|
9325
|
+
}
|
|
9326
|
+
// Handle drawing new annotation
|
|
9327
|
+
if (this.isDrawing && this.currentAnnotation) {
|
|
9328
|
+
if (this.canvasDrawingTool === 'rectangle') {
|
|
9329
|
+
this.currentAnnotation.width = coords.x - this.currentAnnotation.startX;
|
|
9330
|
+
this.currentAnnotation.height = coords.y - this.currentAnnotation.startY;
|
|
9331
|
+
}
|
|
9332
|
+
else {
|
|
9333
|
+
this.currentAnnotation.endX = coords.x;
|
|
9334
|
+
this.currentAnnotation.endY = coords.y;
|
|
9335
|
+
}
|
|
9336
|
+
this.redrawAnnotations();
|
|
9337
|
+
this.drawAnnotation(this.currentAnnotation);
|
|
9338
|
+
return;
|
|
9339
|
+
}
|
|
9340
|
+
// Handle hover states and cursor changes
|
|
9341
|
+
const found = this.findAnnotationAt(coords.x, coords.y);
|
|
9342
|
+
if (found) {
|
|
9343
|
+
// Check if hovering over resize handle for any annotation type
|
|
9344
|
+
const handle = this.isPointInResizeHandle(coords.x, coords.y, found.annotation);
|
|
9345
|
+
if (handle) {
|
|
9346
|
+
this.canvasRef.style.cursor = 'nw-resize';
|
|
9347
|
+
this.hoveredAnnotation = found.annotation;
|
|
9348
|
+
this.redrawAnnotations();
|
|
9349
|
+
return;
|
|
9350
|
+
}
|
|
9351
|
+
// Regular hover over annotation
|
|
9352
|
+
this.canvasRef.style.cursor = 'grab';
|
|
9353
|
+
if (this.hoveredAnnotation !== found.annotation) {
|
|
9354
|
+
this.hoveredAnnotation = found.annotation;
|
|
9355
|
+
this.redrawAnnotations();
|
|
9356
|
+
}
|
|
9357
|
+
}
|
|
9358
|
+
else {
|
|
9359
|
+
// No annotation under cursor
|
|
9360
|
+
this.canvasRef.style.cursor = 'crosshair';
|
|
9361
|
+
if (this.hoveredAnnotation) {
|
|
9362
|
+
this.hoveredAnnotation = null;
|
|
9363
|
+
this.redrawAnnotations();
|
|
9364
|
+
}
|
|
9365
|
+
}
|
|
9366
|
+
};
|
|
9367
|
+
this.handleCanvasMouseUp = () => {
|
|
9368
|
+
// Handle end of text resizing
|
|
9369
|
+
if (this.isResizing) {
|
|
9370
|
+
this.isResizing = false;
|
|
9371
|
+
this.resizingAnnotation = null;
|
|
9372
|
+
this.dragStartPos = null;
|
|
9373
|
+
this.resizeHandle = false;
|
|
9374
|
+
if (this.canvasRef) {
|
|
9375
|
+
this.canvasRef.style.cursor = 'crosshair';
|
|
9376
|
+
}
|
|
9377
|
+
return;
|
|
9378
|
+
}
|
|
9379
|
+
// Handle end of dragging
|
|
9380
|
+
if (this.isDragging) {
|
|
9381
|
+
this.isDragging = false;
|
|
9382
|
+
this.draggedAnnotation = null;
|
|
9383
|
+
this.dragStartPos = null;
|
|
9384
|
+
if (this.canvasRef) {
|
|
9385
|
+
this.canvasRef.style.cursor = 'crosshair';
|
|
9386
|
+
}
|
|
9387
|
+
return;
|
|
9388
|
+
}
|
|
9389
|
+
// Handle end of drawing
|
|
9390
|
+
if (!this.isDrawing || !this.currentAnnotation)
|
|
9391
|
+
return;
|
|
9392
|
+
this.isDrawing = false;
|
|
9393
|
+
this.annotations = [...this.annotations, this.currentAnnotation];
|
|
9394
|
+
this.currentAnnotation = null;
|
|
9395
|
+
this.redrawAnnotations();
|
|
9396
|
+
};
|
|
9397
|
+
// Draw resize handles for rectangle annotation
|
|
9398
|
+
this.drawRectangleResizeHandles = (annotation) => {
|
|
9399
|
+
if (!this.canvasContext || annotation.type !== 'rectangle')
|
|
9400
|
+
return;
|
|
9401
|
+
const handleSize = 8;
|
|
9402
|
+
const left = annotation.startX;
|
|
9403
|
+
const top = annotation.startY;
|
|
9404
|
+
const right = annotation.startX + annotation.width;
|
|
9405
|
+
const bottom = annotation.startY + annotation.height;
|
|
9406
|
+
// Define handle positions (4 corners)
|
|
9407
|
+
const handles = [
|
|
9408
|
+
{ x: left, y: top },
|
|
9409
|
+
{ x: right, y: top },
|
|
9410
|
+
{ x: right, y: bottom },
|
|
9411
|
+
{ x: left, y: bottom } // Bottom-left
|
|
9412
|
+
];
|
|
9413
|
+
// Draw each handle
|
|
9414
|
+
this.canvasContext.fillStyle = '#0070F4'; // Primary color
|
|
9415
|
+
this.canvasContext.strokeStyle = '#ffffff';
|
|
9416
|
+
this.canvasContext.lineWidth = 2;
|
|
9417
|
+
handles.forEach(handle => {
|
|
9418
|
+
this.canvasContext.fillRect(handle.x - handleSize / 2, handle.y - handleSize / 2, handleSize, handleSize);
|
|
9419
|
+
this.canvasContext.strokeRect(handle.x - handleSize / 2, handle.y - handleSize / 2, handleSize, handleSize);
|
|
9420
|
+
});
|
|
9421
|
+
};
|
|
9422
|
+
// Draw resize handles for line/arrow annotation
|
|
9423
|
+
this.drawLineResizeHandles = (annotation) => {
|
|
9424
|
+
if (!this.canvasContext || (annotation.type !== 'line' && annotation.type !== 'arrow'))
|
|
9425
|
+
return;
|
|
9426
|
+
const handleSize = 8;
|
|
9427
|
+
// Define handle positions (2 endpoints)
|
|
9428
|
+
const handles = [
|
|
9429
|
+
{ x: annotation.startX, y: annotation.startY },
|
|
9430
|
+
{ x: annotation.endX, y: annotation.endY } // End point
|
|
9431
|
+
];
|
|
9432
|
+
// Draw each handle
|
|
9433
|
+
this.canvasContext.fillStyle = '#0070F4'; // Primary color
|
|
9434
|
+
this.canvasContext.strokeStyle = '#ffffff';
|
|
9435
|
+
this.canvasContext.lineWidth = 2;
|
|
9436
|
+
handles.forEach(handle => {
|
|
9437
|
+
this.canvasContext.fillRect(handle.x - handleSize / 2, handle.y - handleSize / 2, handleSize, handleSize);
|
|
9438
|
+
this.canvasContext.strokeRect(handle.x - handleSize / 2, handle.y - handleSize / 2, handleSize, handleSize);
|
|
9439
|
+
});
|
|
9440
|
+
};
|
|
9441
|
+
// Convert screen coordinates to canvas coordinates
|
|
9442
|
+
this.getCanvasCoordinates = (event) => {
|
|
9443
|
+
if (!this.canvasRef)
|
|
9444
|
+
return { x: 0, y: 0 };
|
|
9445
|
+
const rect = this.canvasRef.getBoundingClientRect();
|
|
9446
|
+
// Calculate the scale factor between display size and actual canvas size
|
|
9447
|
+
const scaleX = this.canvasRef.width / rect.width;
|
|
9448
|
+
const scaleY = this.canvasRef.height / rect.height;
|
|
9449
|
+
const x = (event.clientX - rect.left) * scaleX;
|
|
9450
|
+
const y = (event.clientY - rect.top) * scaleY;
|
|
9451
|
+
return { x, y };
|
|
9452
|
+
};
|
|
9453
|
+
// Find annotation under mouse cursor
|
|
9454
|
+
this.findAnnotationAt = (x, y) => {
|
|
9455
|
+
// Check in reverse order (top to bottom)
|
|
9456
|
+
for (let i = this.annotations.length - 1; i >= 0; i--) {
|
|
9457
|
+
const annotation = this.annotations[i];
|
|
9458
|
+
if (this.isPointInAnnotation(x, y, annotation)) {
|
|
9459
|
+
return { annotation, index: i };
|
|
9460
|
+
}
|
|
9461
|
+
}
|
|
9462
|
+
return null;
|
|
9463
|
+
};
|
|
9464
|
+
// Check if point is within annotation bounds
|
|
9465
|
+
this.isPointInAnnotation = (x, y, annotation) => {
|
|
9466
|
+
const tolerance = 10; // Click tolerance
|
|
9467
|
+
switch (annotation.type) {
|
|
9468
|
+
case 'rectangle':
|
|
9469
|
+
const left = Math.min(annotation.startX, annotation.startX + annotation.width);
|
|
9470
|
+
const right = Math.max(annotation.startX, annotation.startX + annotation.width);
|
|
9471
|
+
const top = Math.min(annotation.startY, annotation.startY + annotation.height);
|
|
9472
|
+
const bottom = Math.max(annotation.startY, annotation.startY + annotation.height);
|
|
9473
|
+
return x >= left - tolerance && x <= right + tolerance &&
|
|
9474
|
+
y >= top - tolerance && y <= bottom + tolerance;
|
|
9475
|
+
case 'line':
|
|
9476
|
+
case 'arrow':
|
|
9477
|
+
// Distance from point to line
|
|
9478
|
+
const A = annotation.endY - annotation.startY;
|
|
9479
|
+
const B = annotation.startX - annotation.endX;
|
|
9480
|
+
const C = annotation.endX * annotation.startY - annotation.startX * annotation.endY;
|
|
9481
|
+
const distance = Math.abs(A * x + B * y + C) / Math.sqrt(A * A + B * B);
|
|
9482
|
+
return distance <= tolerance;
|
|
9483
|
+
case 'text':
|
|
9484
|
+
// Simple bounding box for text
|
|
9485
|
+
return x >= annotation.x - tolerance && x <= annotation.x + 100 &&
|
|
9486
|
+
y >= annotation.y - 20 && y <= annotation.y + tolerance;
|
|
9487
|
+
default:
|
|
9488
|
+
return false;
|
|
9489
|
+
}
|
|
9490
|
+
};
|
|
9491
|
+
// Handle resize for different annotation types
|
|
9492
|
+
this.handleResize = (currentPos) => {
|
|
9493
|
+
if (!this.resizingAnnotation || !this.dragStartPos)
|
|
9494
|
+
return;
|
|
9495
|
+
const annotation = this.resizingAnnotation;
|
|
9496
|
+
const index = this.annotations.findIndex(a => a === annotation);
|
|
9497
|
+
if (index === -1)
|
|
9498
|
+
return;
|
|
9499
|
+
let updatedAnnotation = Object.assign({}, annotation);
|
|
9500
|
+
switch (annotation.type) {
|
|
9501
|
+
case 'text':
|
|
9502
|
+
// Text resize logic (existing)
|
|
9503
|
+
const deltaX = currentPos.x - this.dragStartPos.x;
|
|
9504
|
+
const deltaY = currentPos.y - this.dragStartPos.y;
|
|
9505
|
+
const avgDelta = (deltaX + deltaY) / 2;
|
|
9506
|
+
const newSize = Math.max(8, Math.min(72, this.resizeStartSize + avgDelta * 0.5));
|
|
9507
|
+
updatedAnnotation.fontSize = Math.round(newSize);
|
|
9508
|
+
break;
|
|
9509
|
+
case 'rectangle':
|
|
9510
|
+
// Rectangle resizing disabled for now
|
|
9511
|
+
return;
|
|
9512
|
+
case 'line':
|
|
9513
|
+
case 'arrow':
|
|
9514
|
+
// Line/arrow resize logic - move endpoints
|
|
9515
|
+
if (this.resizeHandle === 'start') {
|
|
9516
|
+
updatedAnnotation.startX = currentPos.x;
|
|
9517
|
+
updatedAnnotation.startY = currentPos.y;
|
|
9518
|
+
}
|
|
9519
|
+
else if (this.resizeHandle === 'end') {
|
|
9520
|
+
updatedAnnotation.endX = currentPos.x;
|
|
9521
|
+
updatedAnnotation.endY = currentPos.y;
|
|
9522
|
+
}
|
|
9523
|
+
break;
|
|
9524
|
+
}
|
|
9525
|
+
// Update annotation in array
|
|
9526
|
+
this.annotations[index] = updatedAnnotation;
|
|
9527
|
+
this.resizingAnnotation = updatedAnnotation;
|
|
9528
|
+
this.redrawAnnotations();
|
|
9529
|
+
};
|
|
9025
9530
|
this.sending = false;
|
|
9026
9531
|
this.formMessage = '';
|
|
9027
9532
|
this.formEmail = '';
|
|
@@ -9035,6 +9540,26 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
|
|
|
9035
9540
|
this.selectedRating = -1;
|
|
9036
9541
|
this.overlayVisible = false;
|
|
9037
9542
|
this.isAnimating = false;
|
|
9543
|
+
this.takingScreenshot = false;
|
|
9544
|
+
this.showPreviewModal = false;
|
|
9545
|
+
this.showCanvasEditor = false;
|
|
9546
|
+
this.canvasDrawingTool = 'rectangle';
|
|
9547
|
+
this.canvasDrawingColor = '#ff0000';
|
|
9548
|
+
this.canvasLineWidth = 3;
|
|
9549
|
+
this.isDrawing = false;
|
|
9550
|
+
this.annotations = [];
|
|
9551
|
+
this.currentAnnotation = null;
|
|
9552
|
+
this.isDragging = false;
|
|
9553
|
+
this.draggedAnnotation = null;
|
|
9554
|
+
this.dragStartPos = null;
|
|
9555
|
+
this.showColorPicker = false;
|
|
9556
|
+
this.editingColorIndex = -1;
|
|
9557
|
+
this.isResizing = false;
|
|
9558
|
+
this.resizingAnnotation = null;
|
|
9559
|
+
this.resizeStartSize = 16;
|
|
9560
|
+
this.hoveredAnnotation = null;
|
|
9561
|
+
this.resizeHandle = false;
|
|
9562
|
+
this.defaultColors = ['#ff0000', '#00ff00', '#0000ff', '#000000'];
|
|
9038
9563
|
this.customFont = false;
|
|
9039
9564
|
this.emailAddress = '';
|
|
9040
9565
|
this.hideEmail = false;
|
|
@@ -9070,8 +9595,9 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
|
|
|
9070
9595
|
this.screenshotTakingText = 'Taking screenshot...';
|
|
9071
9596
|
this.screenshotTopbarText = 'Select an element on this page';
|
|
9072
9597
|
this.successMessage = '';
|
|
9073
|
-
this.
|
|
9074
|
-
this.
|
|
9598
|
+
this.canvasEditorTitle = 'Edit screenshot';
|
|
9599
|
+
this.canvasEditorCancelText = 'Cancel';
|
|
9600
|
+
this.canvasEditorSaveText = 'Save';
|
|
9075
9601
|
}
|
|
9076
9602
|
componentWillLoad() {
|
|
9077
9603
|
if (this.fetchData)
|
|
@@ -9106,46 +9632,51 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
|
|
|
9106
9632
|
handleEmailInput(event) {
|
|
9107
9633
|
this.formEmail = event.target.value;
|
|
9108
9634
|
}
|
|
9109
|
-
|
|
9635
|
+
captureViewportScreenshot() {
|
|
9110
9636
|
return new Promise((resolve, reject) => {
|
|
9111
|
-
|
|
9112
|
-
|
|
9113
|
-
|
|
9114
|
-
|
|
9115
|
-
|
|
9116
|
-
|
|
9637
|
+
requestAnimationFrame(() => {
|
|
9638
|
+
// Get viewport dimensions and scroll position
|
|
9639
|
+
const viewportWidth = window.innerWidth;
|
|
9640
|
+
const viewportHeight = window.innerHeight;
|
|
9641
|
+
const scrollX = window.scrollX || window.pageXOffset || 0;
|
|
9642
|
+
const scrollY = window.scrollY || window.pageYOffset || 0;
|
|
9643
|
+
// Capture exactly what the user sees in their viewport
|
|
9644
|
+
html2canvasPro(document.documentElement, {
|
|
9645
|
+
x: scrollX,
|
|
9646
|
+
y: scrollY,
|
|
9647
|
+
width: viewportWidth,
|
|
9648
|
+
height: viewportHeight,
|
|
9649
|
+
scrollX: 0,
|
|
9650
|
+
scrollY: 0,
|
|
9651
|
+
allowTaint: false,
|
|
9652
|
+
useCORS: true,
|
|
9653
|
+
scale: 1,
|
|
9654
|
+
backgroundColor: '#ffffff',
|
|
9655
|
+
logging: false,
|
|
9656
|
+
foreignObjectRendering: false,
|
|
9657
|
+
imageTimeout: 15000,
|
|
9658
|
+
windowWidth: viewportWidth,
|
|
9659
|
+
windowHeight: viewportHeight,
|
|
9660
|
+
removeContainer: true,
|
|
9661
|
+
ignoreElements: (element) => {
|
|
9662
|
+
// Ignore all feedback modal elements
|
|
9663
|
+
return element.closest('feedback-modal') !== null ||
|
|
9664
|
+
element.classList.contains('feedback-overlay') ||
|
|
9665
|
+
element.classList.contains('feedback-modal-screenshot-header') ||
|
|
9666
|
+
element.tagName === 'FEEDBACK-MODAL' ||
|
|
9667
|
+
element.tagName === 'FEEDBACK-BUTTON';
|
|
9117
9668
|
}
|
|
9118
|
-
|
|
9119
|
-
|
|
9120
|
-
|
|
9121
|
-
|
|
9122
|
-
|
|
9123
|
-
|
|
9124
|
-
|
|
9125
|
-
|
|
9126
|
-
|
|
9127
|
-
useCORS: true,
|
|
9128
|
-
scale: 1,
|
|
9129
|
-
backgroundColor: '#ffffff',
|
|
9130
|
-
logging: true,
|
|
9131
|
-
foreignObjectRendering: false,
|
|
9132
|
-
imageTimeout: 10000,
|
|
9133
|
-
ignoreElements: (element) => {
|
|
9134
|
-
// Only ignore screenshot UI, keep everything else including highlights
|
|
9135
|
-
return element.classList.contains('feedback-modal-screenshot-header') ||
|
|
9136
|
-
element.classList.contains('feedback-overlay');
|
|
9137
|
-
}
|
|
9138
|
-
})
|
|
9139
|
-
.then((canvas) => {
|
|
9140
|
-
const dataUrl = canvas.toDataURL();
|
|
9141
|
-
resolve(dataUrl);
|
|
9142
|
-
})
|
|
9143
|
-
.catch((error) => {
|
|
9144
|
-
console.error('Failed to capture screenshot:', error);
|
|
9145
|
-
reject(error);
|
|
9146
|
-
});
|
|
9669
|
+
})
|
|
9670
|
+
.then((canvas) => {
|
|
9671
|
+
const dataUrl = canvas.toDataURL('image/png');
|
|
9672
|
+
console.log('Screenshot captured successfully, size:', canvas.width, 'x', canvas.height);
|
|
9673
|
+
resolve(dataUrl);
|
|
9674
|
+
})
|
|
9675
|
+
.catch((error) => {
|
|
9676
|
+
console.error('Failed to capture viewport screenshot:', error);
|
|
9677
|
+
reject(error);
|
|
9147
9678
|
});
|
|
9148
|
-
}
|
|
9679
|
+
});
|
|
9149
9680
|
});
|
|
9150
9681
|
}
|
|
9151
9682
|
handleCheckboxChange(event) {
|
|
@@ -9158,7 +9689,7 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
|
|
|
9158
9689
|
this.selectedRating = newRating;
|
|
9159
9690
|
}
|
|
9160
9691
|
render() {
|
|
9161
|
-
return (h("div", { class: `feedback-modal-wrapper ${this.customFont ? 'feedback-modal-wrapper--custom-font' : ''}` }, this.
|
|
9692
|
+
return (h("div", { class: `feedback-modal-wrapper ${this.customFont ? 'feedback-modal-wrapper--custom-font' : ''}` }, this.showModal && (h("div", { class: `feedback-overlay ${this.isAnimating ? 'feedback-overlay--visible' : ''}` })), this.showModal && (h("div", { class: `feedback-modal-content feedback-modal-content--${this.modalPosition} ${this.isAnimating ? 'feedback-modal-content--open' : ''}`, ref: (el) => (this.modalContent = el) }, h("div", { class: "feedback-modal-header" }, !this.formSuccess && !this.formError ? (h("span", null, this.modalTitle)) : this.formSuccess ? (h("span", null, this.modalTitleSuccess)) : (h("span", null, this.modalTitleError)), h("button", { class: "feedback-modal-close", onClick: this.close }, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "#191919", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", class: "feather feather-x" }, h("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), h("line", { x1: "6", y1: "6", x2: "18", y2: "18" })))), h("div", { class: "feedback-modal-body" }, !this.formSuccess && !this.formError ? (h("form", { onSubmit: this.handleSubmit }, !this.hideRating && (h("div", { class: "feedback-modal-rating" }, this.ratingMode === 'thumbs' ? (h("div", { class: "feedback-modal-rating-content" }, h("span", { class: "feedback-modal-input-heading" }, this.ratingPlaceholder), h("div", { class: "feedback-modal-rating-buttons feedback-modal-rating-buttons--thumbs" }, h("button", { title: "Yes", class: `feedback-modal-rating-button ${this.selectedRating === 1
|
|
9162
9693
|
? 'feedback-modal-rating-button--selected'
|
|
9163
9694
|
: ''}`, onClick: (event) => {
|
|
9164
9695
|
event.preventDefault();
|
|
@@ -9173,7 +9704,8 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
|
|
|
9173
9704
|
: ''}`, onClick: (event) => {
|
|
9174
9705
|
event.preventDefault();
|
|
9175
9706
|
this.handleRatingChange(rating);
|
|
9176
|
-
} }, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "28", height: "28", viewBox: "0 0 24 24", fill: "none", stroke: "#5F6368", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("polygon", { points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" })))))))))), h("div", { class: "feedback-modal-text" }, h("textarea", { placeholder: this.messagePlaceholder, value: this.formMessage, onInput: (event) => this.handleMessageInput(event) })), !this.hideEmail && (h("div", { class: "feedback-modal-email" }, h("input", { placeholder: this.emailPlaceholder, type: "email", onInput: (event) => this.handleEmailInput(event), value: this.formEmail, required: this.isEmailRequired }))), h("div", { class: "feedback-verification" }, h("input", { type: "text", name: "verification", style: { display: 'none' }, onInput: (event) => this.handleVerification(event), value: this.formVerification })), !this.hidePrivacyPolicy && (h("div", { class: "feedback-modal-privacy" }, h("input", { type: "checkbox", id: "privacyPolicy", onChange: (ev) => this.handleCheckboxChange(ev), required: true }), h("span", { innerHTML: this.privacyPolicyText }))), h("div", { class: `feedback-modal-buttons ${this.hideScreenshotButton ? 'single' : ''}` }, !this.hideScreenshotButton && (h("button", { type: "button", class: `feedback-modal-button feedback-modal-button--screenshot ${this.encodedScreenshot ? 'feedback-modal-button--active' : ''}`, onClick: this.openScreenShot, disabled: this.sending }, this.encodedScreenshot && (h("div", { class: "screenshot-preview", onClick: this.
|
|
9707
|
+
} }, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "28", height: "28", viewBox: "0 0 24 24", fill: "none", stroke: "#5F6368", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("polygon", { points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" })))))))))), h("div", { class: "feedback-modal-text" }, h("textarea", { placeholder: this.messagePlaceholder, value: this.formMessage, onInput: (event) => this.handleMessageInput(event) })), !this.hideEmail && (h("div", { class: "feedback-modal-email" }, h("input", { placeholder: this.emailPlaceholder, type: "email", onInput: (event) => this.handleEmailInput(event), value: this.formEmail, required: this.isEmailRequired }))), h("div", { class: "feedback-verification" }, h("input", { type: "text", name: "verification", style: { display: 'none' }, onInput: (event) => this.handleVerification(event), value: this.formVerification })), !this.hidePrivacyPolicy && (h("div", { class: "feedback-modal-privacy" }, h("input", { type: "checkbox", id: "privacyPolicy", onChange: (ev) => this.handleCheckboxChange(ev), required: true }), h("span", { innerHTML: this.privacyPolicyText }))), h("div", { class: `feedback-modal-buttons ${this.hideScreenshotButton ? 'single' : ''}` }, !this.hideScreenshotButton && (h("button", { type: "button", class: `feedback-modal-button feedback-modal-button--screenshot ${this.encodedScreenshot ? 'feedback-modal-button--active' : ''}`, onClick: this.openScreenShot, disabled: this.sending || this.takingScreenshot }, this.encodedScreenshot && (h("div", { class: "screenshot-preview", onClick: this.openCanvasEditor }, h("img", { src: this.encodedScreenshot, alt: "Screenshot Preview" }))), !this.encodedScreenshot && !this.takingScreenshot && (h("svg", { xmlns: "http://www.w3.org/2000/svg", height: "24", viewBox: "0 -960 960 960", width: "24" }, h("path", { d: "M680-80v-120H560v-80h120v-120h80v120h120v80H760v120h-80ZM200-200v-200h80v120h120v80H200Zm0-360v-200h200v80H280v120h-80Zm480 0v-120H560v-80h200v200h-80Z" }))), this.takingScreenshot && (h("div", { class: "screenshot-loading" }, h("svg", { width: "16", height: "16", viewBox: "0 0 16 16" }, h("circle", { cx: "8", cy: "8", r: "6", fill: "none", stroke: "#666", "stroke-width": "2", "stroke-dasharray": "6 6", "transform-origin": "8 8" }, h("animateTransform", { attributeName: "transform", type: "rotate", values: "0 8 8;360 8 8", dur: "1s", repeatCount: "indefinite" }))))), this.takingScreenshot ? this.screenshotTakingText :
|
|
9708
|
+
this.encodedScreenshot ? this.screenshotAttachedText : this.screenshotButtonText)), h("button", { class: "feedback-modal-button feedback-modal-button--submit", type: "submit", disabled: this.sending }, this.sendButtonText)))) : this.formSuccess && !this.formError ? (h("div", { class: "feedback-modal-success" }, h("p", { class: "feedback-modal-message" }, this.successMessage))) : this.formError && this.formErrorStatus == 404 ? (h("p", { class: "feedback-modal-message" }, this.errorMessage404)) : this.formError && this.formErrorStatus == 403 ? (h("p", { class: "feedback-modal-message" }, this.errorMessage403)) : this.formError ? (h("p", { class: "feedback-modal-message" }, this.errorMessage)) : (h("span", null))), h("div", { class: "feedback-modal-footer" }, h("div", { class: "feedback-logo", style: { display: this.whitelabel ? 'none' : 'block' } }, "Powered by", ' ', h("a", { target: "_blank", href: "https://pushfeedback.com" }, "PushFeedback.com")), this.footerText && (h("div", { class: "feedback-footer-text" }, h("span", { innerHTML: this.footerText })))))), this.showCanvasEditor && (h("div", { class: "canvas-editor-overlay" }, h("div", { class: "canvas-editor-modal" }, h("div", { class: "canvas-editor-header" }, h("div", { class: "canvas-editor-title" }, h("h3", null, this.canvasEditorTitle)), h("div", { class: "canvas-editor-toolbar" }, h("div", { class: "toolbar-section" }, h("div", { class: "tool-group" }, h("button", { class: `tool-btn ${this.canvasDrawingTool === 'rectangle' ? 'active' : ''}`, onClick: () => this.canvasDrawingTool = 'rectangle', title: "Rectangle" }, h("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }))), h("button", { class: `tool-btn ${this.canvasDrawingTool === 'line' ? 'active' : ''}`, onClick: () => this.canvasDrawingTool = 'line', title: "Line" }, h("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("line", { x1: "5", y1: "12", x2: "19", y2: "12" }))), h("button", { class: `tool-btn ${this.canvasDrawingTool === 'arrow' ? 'active' : ''}`, onClick: () => this.canvasDrawingTool = 'arrow', title: "Arrow" }, h("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("line", { x1: "7", y1: "17", x2: "17", y2: "7" }), h("polyline", { points: "7,7 17,7 17,17" }))), h("button", { class: `tool-btn ${this.canvasDrawingTool === 'text' ? 'active' : ''}`, onClick: () => this.canvasDrawingTool = 'text', title: "Text" }, h("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("polyline", { points: "4,7 4,4 20,4 20,7" }), h("line", { x1: "9", y1: "20", x2: "15", y2: "20" }), h("line", { x1: "12", y1: "4", x2: "12", y2: "20" }))), h("div", { class: "toolbar-divider" }), h("button", { class: "tool-btn undo-btn", onClick: this.undoLastAnnotation, disabled: this.annotations.length === 0, title: "Undo" }, h("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("polyline", { points: "1,4 1,10 7,10" }), h("path", { d: "M3.51,15a9,9,0,0,0,14.85-3.36,9,9,0,0,0-9.19-10.15L1.83,10" }))))), h("div", { class: "toolbar-section" }, h("div", { class: "color-palette" }, this.defaultColors.map((color, index) => (h("div", { class: "color-slot-wrapper" }, h("button", { class: `color-btn ${this.canvasDrawingColor === color ? 'active' : ''} ${this.editingColorIndex === index ? 'editing' : ''}`, style: { backgroundColor: color }, onClick: () => this.handleColorSlotClick(index), title: `Color ${index + 1} - Click to customize` }, this.editingColorIndex === index && (h("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "white", "stroke-width": "2" }, h("path", { d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z" })))), this.editingColorIndex === index && this.showColorPicker && (h("div", { class: "color-picker-dropdown" }, h("input", { type: "color", value: color, onInput: (e) => this.handleColorPickerInput(e), onClick: (e) => this.handleColorPickerClick(e) })))))))), h("div", { class: "toolbar-section" }, h("div", { class: "size-control" }, h("input", { type: "range", min: "1", max: "10", value: this.canvasLineWidth, onInput: (e) => this.canvasLineWidth = parseInt(e.target.value), class: "size-slider" }), h("span", { class: "size-value" }, this.canvasLineWidth, "px"))), h("div", { class: "toolbar-section" }, h("button", { class: "action-btn secondary", onClick: this.closeCanvasEditor }, this.canvasEditorCancelText), h("button", { class: "action-btn primary", onClick: this.saveAnnotations }, this.canvasEditorSaveText))), h("div", { class: "canvas-editor-content" }, h("canvas", { ref: (el) => this.canvasRef = el, class: "annotation-canvas", onMouseDown: this.handleCanvasMouseDown, onMouseMove: this.handleCanvasMouseMove, onMouseUp: this.handleCanvasMouseUp, onMouseLeave: this.handleCanvasMouseUp }))))))));
|
|
9177
9709
|
}
|
|
9178
9710
|
componentDidRender() {
|
|
9179
9711
|
if (this.showModal) {
|
|
@@ -9227,6 +9759,9 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
|
|
|
9227
9759
|
"screenshotTakingText": [1, "screenshot-taking-text"],
|
|
9228
9760
|
"screenshotTopbarText": [1, "screenshot-topbar-text"],
|
|
9229
9761
|
"successMessage": [1, "success-message"],
|
|
9762
|
+
"canvasEditorTitle": [1, "canvas-editor-title"],
|
|
9763
|
+
"canvasEditorCancelText": [1, "canvas-editor-cancel-text"],
|
|
9764
|
+
"canvasEditorSaveText": [1, "canvas-editor-save-text"],
|
|
9230
9765
|
"sending": [32],
|
|
9231
9766
|
"formMessage": [32],
|
|
9232
9767
|
"formEmail": [32],
|
|
@@ -9242,6 +9777,24 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
|
|
|
9242
9777
|
"isAnimating": [32],
|
|
9243
9778
|
"takingScreenshot": [32],
|
|
9244
9779
|
"showPreviewModal": [32],
|
|
9780
|
+
"showCanvasEditor": [32],
|
|
9781
|
+
"canvasDrawingTool": [32],
|
|
9782
|
+
"canvasDrawingColor": [32],
|
|
9783
|
+
"canvasLineWidth": [32],
|
|
9784
|
+
"isDrawing": [32],
|
|
9785
|
+
"annotations": [32],
|
|
9786
|
+
"currentAnnotation": [32],
|
|
9787
|
+
"isDragging": [32],
|
|
9788
|
+
"draggedAnnotation": [32],
|
|
9789
|
+
"dragStartPos": [32],
|
|
9790
|
+
"showColorPicker": [32],
|
|
9791
|
+
"editingColorIndex": [32],
|
|
9792
|
+
"isResizing": [32],
|
|
9793
|
+
"resizingAnnotation": [32],
|
|
9794
|
+
"resizeStartSize": [32],
|
|
9795
|
+
"hoveredAnnotation": [32],
|
|
9796
|
+
"resizeHandle": [32],
|
|
9797
|
+
"defaultColors": [32],
|
|
9245
9798
|
"openModal": [64]
|
|
9246
9799
|
}]);
|
|
9247
9800
|
function defineCustomElement() {
|