pushfeedback 0.1.66 → 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 +728 -153
- 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 +80 -0
- package/dist/collection/components/feedback-modal/feedback-modal.css +439 -12
- package/dist/collection/components/feedback-modal/feedback-modal.js +771 -127
- package/dist/components/feedback-button.js +12 -0
- package/dist/components/feedback-modal2.js +745 -154
- package/dist/esm/feedback-button_2.entry.js +728 -153
- 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 +4 -0
- package/dist/types/components/feedback-modal/feedback-modal.d.ts +79 -14
- package/dist/types/components.d.ts +16 -0
- package/package.json +1 -1
- package/dist/pushfeedback/p-e6c2f829.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:1px solid var(--feedback-modal-element-selected-border-color)}.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}.screenshot-preview img{width:100%;height:100%;object-fit:cover}.preview-modal{position:fixed;top:50%;left:50%;transform:translate(-50%, -50%);background-color:rgba(0, 0, 0, 0.8);padding:20px;border-radius:8px;z-index:1000}.preview-modal img{max-width:90vw;max-height:90vh}@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() {
|
|
@@ -8880,8 +8895,27 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
|
|
|
8880
8895
|
this.showScreenshotTopBar = false;
|
|
8881
8896
|
this.hasSelectedElement = false;
|
|
8882
8897
|
this.encodedScreenshot = null;
|
|
8883
|
-
|
|
8884
|
-
|
|
8898
|
+
// Remove highlight from ALL selected elements
|
|
8899
|
+
document.querySelectorAll('.feedback-modal-element-selected').forEach(el => {
|
|
8900
|
+
el.classList.remove('feedback-modal-element-selected');
|
|
8901
|
+
});
|
|
8902
|
+
// Reset canvas editor states
|
|
8903
|
+
this.takingScreenshot = false;
|
|
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
|
|
8885
8919
|
this.formSuccess = false;
|
|
8886
8920
|
this.formError = false;
|
|
8887
8921
|
this.formErrorStatus = 500;
|
|
@@ -8890,109 +8924,609 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
|
|
|
8890
8924
|
this.resetOverflow();
|
|
8891
8925
|
}, 200);
|
|
8892
8926
|
};
|
|
8893
|
-
this.openScreenShot = () => {
|
|
8894
|
-
|
|
8895
|
-
this.
|
|
8896
|
-
|
|
8897
|
-
|
|
8898
|
-
|
|
8899
|
-
|
|
8900
|
-
|
|
8901
|
-
|
|
8902
|
-
|
|
8927
|
+
this.openScreenShot = async () => {
|
|
8928
|
+
// Show loading state immediately
|
|
8929
|
+
this.takingScreenshot = true;
|
|
8930
|
+
try {
|
|
8931
|
+
// Capture viewport screenshot immediately
|
|
8932
|
+
const dataUrl = await this.captureViewportScreenshot();
|
|
8933
|
+
this.encodedScreenshot = dataUrl;
|
|
8934
|
+
this.originalImageData = dataUrl;
|
|
8935
|
+
// Reset loading state
|
|
8936
|
+
this.takingScreenshot = false;
|
|
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);
|
|
8944
|
+
}
|
|
8945
|
+
catch (error) {
|
|
8946
|
+
console.error('Failed to capture screenshot:', error);
|
|
8947
|
+
// Reset loading state on error
|
|
8948
|
+
this.takingScreenshot = false;
|
|
8949
|
+
// Show modal anyway
|
|
8950
|
+
this.showModal = true;
|
|
8903
8951
|
}
|
|
8904
|
-
const scrollY = window.scrollY;
|
|
8905
|
-
document.documentElement.style.top = `-${scrollY}px`;
|
|
8906
|
-
window.scrollTo(0, parseInt(document.documentElement.style.top || '0') * -1);
|
|
8907
|
-
document.documentElement.classList.add('feedback-modal-screenshot-open');
|
|
8908
8952
|
};
|
|
8909
|
-
this.
|
|
8953
|
+
this.openCanvasEditor = (event) => {
|
|
8954
|
+
if (event) {
|
|
8955
|
+
event.stopPropagation();
|
|
8956
|
+
}
|
|
8910
8957
|
this.showModal = false;
|
|
8911
|
-
this.
|
|
8912
|
-
|
|
8913
|
-
|
|
8914
|
-
|
|
8915
|
-
|
|
8916
|
-
|
|
8917
|
-
|
|
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;
|
|
8918
8976
|
};
|
|
8919
|
-
this.
|
|
8920
|
-
|
|
8921
|
-
if (this.hasSelectedElement)
|
|
8977
|
+
this.initializeCanvas = () => {
|
|
8978
|
+
if (!this.canvasRef || !this.originalImageData)
|
|
8922
8979
|
return;
|
|
8923
|
-
|
|
8924
|
-
|
|
8925
|
-
|
|
8926
|
-
|
|
8927
|
-
|
|
8928
|
-
|
|
8929
|
-
|
|
8930
|
-
|
|
8931
|
-
|
|
8932
|
-
|
|
8933
|
-
|
|
8934
|
-
|
|
8935
|
-
|
|
8936
|
-
|
|
8937
|
-
|
|
8938
|
-
|
|
8939
|
-
|
|
8940
|
-
|
|
8941
|
-
|
|
8942
|
-
|
|
8943
|
-
|
|
8944
|
-
|
|
8945
|
-
|
|
8946
|
-
|
|
8947
|
-
|
|
8948
|
-
|
|
8949
|
-
|
|
8950
|
-
|
|
8951
|
-
|
|
8952
|
-
|
|
8953
|
-
|
|
8954
|
-
|
|
8955
|
-
|
|
8956
|
-
|
|
8957
|
-
|
|
8958
|
-
|
|
8959
|
-
|
|
8960
|
-
|
|
8961
|
-
|
|
8962
|
-
|
|
8963
|
-
|
|
8964
|
-
// Restore the visibility of the screenshot-modal
|
|
8965
|
-
this.screenshotModal.style.backgroundColor = 'transparent';
|
|
8966
|
-
};
|
|
8967
|
-
this.handleMouseClickedSelectedElement = async (event) => {
|
|
8968
|
-
event.preventDefault();
|
|
8969
|
-
if (!this.elementSelected) {
|
|
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)
|
|
8970
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;
|
|
8971
9073
|
}
|
|
8972
|
-
|
|
8973
|
-
|
|
8974
|
-
|
|
8975
|
-
this.
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
this.
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
|
|
8982
|
-
|
|
8983
|
-
|
|
8984
|
-
|
|
8985
|
-
|
|
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;
|
|
8986
9118
|
}
|
|
8987
|
-
|
|
8988
|
-
|
|
8989
|
-
this.
|
|
9119
|
+
else {
|
|
9120
|
+
// Start editing this color slot
|
|
9121
|
+
this.editingColorIndex = colorIndex;
|
|
9122
|
+
this.showColorPicker = true;
|
|
9123
|
+
this.canvasDrawingColor = this.defaultColors[colorIndex];
|
|
8990
9124
|
}
|
|
8991
|
-
|
|
8992
|
-
|
|
8993
|
-
|
|
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;
|
|
8994
9186
|
}
|
|
8995
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
|
+
};
|
|
8996
9530
|
this.sending = false;
|
|
8997
9531
|
this.formMessage = '';
|
|
8998
9532
|
this.formEmail = '';
|
|
@@ -9006,6 +9540,26 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
|
|
|
9006
9540
|
this.selectedRating = -1;
|
|
9007
9541
|
this.overlayVisible = false;
|
|
9008
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'];
|
|
9009
9563
|
this.customFont = false;
|
|
9010
9564
|
this.emailAddress = '';
|
|
9011
9565
|
this.hideEmail = false;
|
|
@@ -9036,10 +9590,14 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
|
|
|
9036
9590
|
this.ratingPlaceholder = 'Was this page helpful?';
|
|
9037
9591
|
this.ratingStarsPlaceholder = 'How would you rate this page?';
|
|
9038
9592
|
this.sendButtonText = 'Send';
|
|
9039
|
-
this.screenshotButtonText = 'Add a screenshot';
|
|
9040
9593
|
this.screenshotAttachedText = 'Screenshot attached';
|
|
9594
|
+
this.screenshotButtonText = 'Add a screenshot';
|
|
9595
|
+
this.screenshotTakingText = 'Taking screenshot...';
|
|
9041
9596
|
this.screenshotTopbarText = 'Select an element on this page';
|
|
9042
9597
|
this.successMessage = '';
|
|
9598
|
+
this.canvasEditorTitle = 'Edit screenshot';
|
|
9599
|
+
this.canvasEditorCancelText = 'Cancel';
|
|
9600
|
+
this.canvasEditorSaveText = 'Save';
|
|
9043
9601
|
}
|
|
9044
9602
|
componentWillLoad() {
|
|
9045
9603
|
if (this.fetchData)
|
|
@@ -9063,15 +9621,10 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
|
|
|
9063
9621
|
}
|
|
9064
9622
|
}
|
|
9065
9623
|
resetOverflow() {
|
|
9624
|
+
// Just clean up any stray classes, don't add/remove during screenshot
|
|
9066
9625
|
document.documentElement.classList.remove('feedback-modal-screenshot-open');
|
|
9067
9626
|
document.documentElement.classList.remove('feedback-modal-screenshot-open--scroll');
|
|
9068
|
-
document.documentElement.classList.
|
|
9069
|
-
// Only restore scroll position if we previously modified it
|
|
9070
|
-
if (document.documentElement.style.top) {
|
|
9071
|
-
window.scrollTo(0, parseInt(document.documentElement.style.top || '0') * -1);
|
|
9072
|
-
document.documentElement.style.top = '';
|
|
9073
|
-
}
|
|
9074
|
-
window.addEventListener('scroll', this.onScrollDebounced);
|
|
9627
|
+
document.documentElement.classList.remove('feedback-modal-screenshot-closing');
|
|
9075
9628
|
}
|
|
9076
9629
|
handleMessageInput(event) {
|
|
9077
9630
|
this.formMessage = event.target.value;
|
|
@@ -9079,31 +9632,48 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
|
|
|
9079
9632
|
handleEmailInput(event) {
|
|
9080
9633
|
this.formEmail = event.target.value;
|
|
9081
9634
|
}
|
|
9082
|
-
|
|
9635
|
+
captureViewportScreenshot() {
|
|
9083
9636
|
return new Promise((resolve, reject) => {
|
|
9084
9637
|
requestAnimationFrame(() => {
|
|
9085
|
-
|
|
9086
|
-
|
|
9087
|
-
|
|
9088
|
-
|
|
9089
|
-
|
|
9090
|
-
|
|
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,
|
|
9091
9652
|
useCORS: true,
|
|
9092
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';
|
|
9668
|
+
}
|
|
9093
9669
|
})
|
|
9094
9670
|
.then((canvas) => {
|
|
9095
|
-
const
|
|
9096
|
-
|
|
9097
|
-
// Use the same color as HTML highlight
|
|
9098
|
-
context.strokeStyle = 'rgba(0, 123, 255, 0.8)'; // Example color
|
|
9099
|
-
context.lineWidth = 3;
|
|
9100
|
-
context.strokeRect(this.selectedElementBounds.left + window.scrollX, this.selectedElementBounds.top + window.scrollY, this.selectedElementBounds.width, this.selectedElementBounds.height);
|
|
9101
|
-
}
|
|
9102
|
-
const dataUrl = canvas.toDataURL();
|
|
9671
|
+
const dataUrl = canvas.toDataURL('image/png');
|
|
9672
|
+
console.log('Screenshot captured successfully, size:', canvas.width, 'x', canvas.height);
|
|
9103
9673
|
resolve(dataUrl);
|
|
9104
9674
|
})
|
|
9105
9675
|
.catch((error) => {
|
|
9106
|
-
console.error('Failed to capture screenshot:', error);
|
|
9676
|
+
console.error('Failed to capture viewport screenshot:', error);
|
|
9107
9677
|
reject(error);
|
|
9108
9678
|
});
|
|
9109
9679
|
});
|
|
@@ -9118,12 +9688,8 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
|
|
|
9118
9688
|
handleRatingChange(newRating) {
|
|
9119
9689
|
this.selectedRating = newRating;
|
|
9120
9690
|
}
|
|
9121
|
-
// Remove the preview modal toggle function
|
|
9122
|
-
// togglePreviewModal() {
|
|
9123
|
-
// this.showPreviewModal = !this.showPreviewModal;
|
|
9124
|
-
// }
|
|
9125
9691
|
render() {
|
|
9126
|
-
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
|
|
9127
9693
|
? 'feedback-modal-rating-button--selected'
|
|
9128
9694
|
: ''}`, onClick: (event) => {
|
|
9129
9695
|
event.preventDefault();
|
|
@@ -9138,7 +9704,8 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
|
|
|
9138
9704
|
: ''}`, onClick: (event) => {
|
|
9139
9705
|
event.preventDefault();
|
|
9140
9706
|
this.handleRatingChange(rating);
|
|
9141
|
-
} }, 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" }, h("img", { src: this.encodedScreenshot, alt: "Screenshot Preview" }))), !this.encodedScreenshot && (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.
|
|
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 }))))))));
|
|
9142
9709
|
}
|
|
9143
9710
|
componentDidRender() {
|
|
9144
9711
|
if (this.showModal) {
|
|
@@ -9187,10 +9754,14 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
|
|
|
9187
9754
|
"ratingPlaceholder": [1, "rating-placeholder"],
|
|
9188
9755
|
"ratingStarsPlaceholder": [1, "rating-stars-placeholder"],
|
|
9189
9756
|
"sendButtonText": [1, "send-button-text"],
|
|
9190
|
-
"screenshotButtonText": [1, "screenshot-button-text"],
|
|
9191
9757
|
"screenshotAttachedText": [1, "screenshot-attached-text"],
|
|
9758
|
+
"screenshotButtonText": [1, "screenshot-button-text"],
|
|
9759
|
+
"screenshotTakingText": [1, "screenshot-taking-text"],
|
|
9192
9760
|
"screenshotTopbarText": [1, "screenshot-topbar-text"],
|
|
9193
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"],
|
|
9194
9765
|
"sending": [32],
|
|
9195
9766
|
"formMessage": [32],
|
|
9196
9767
|
"formEmail": [32],
|
|
@@ -9204,6 +9775,26 @@ const FeedbackModal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement
|
|
|
9204
9775
|
"selectedRating": [32],
|
|
9205
9776
|
"overlayVisible": [32],
|
|
9206
9777
|
"isAnimating": [32],
|
|
9778
|
+
"takingScreenshot": [32],
|
|
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],
|
|
9207
9798
|
"openModal": [64]
|
|
9208
9799
|
}]);
|
|
9209
9800
|
function defineCustomElement() {
|