quikchat 1.1.16 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +160 -354
- package/dist/build-manifest.json +157 -0
- package/dist/quikchat-md-full.cjs.js +2742 -0
- package/dist/quikchat-md-full.cjs.js.map +1 -0
- package/dist/quikchat-md-full.cjs.min.js +10 -0
- package/dist/quikchat-md-full.cjs.min.js.map +1 -0
- package/dist/quikchat-md-full.esm.js +2740 -0
- package/dist/quikchat-md-full.esm.js.map +1 -0
- package/dist/quikchat-md-full.esm.min.js +10 -0
- package/dist/quikchat-md-full.esm.min.js.map +1 -0
- package/dist/quikchat-md-full.umd.js +2748 -0
- package/dist/quikchat-md-full.umd.js.map +1 -0
- package/dist/quikchat-md-full.umd.min.js +10 -0
- package/dist/quikchat-md-full.umd.min.js.map +1 -0
- package/dist/quikchat-md.cjs.js +1641 -0
- package/dist/quikchat-md.cjs.js.map +1 -0
- package/dist/quikchat-md.cjs.min.js +8 -0
- package/dist/quikchat-md.cjs.min.js.map +1 -0
- package/dist/quikchat-md.esm.js +1639 -0
- package/dist/quikchat-md.esm.js.map +1 -0
- package/dist/quikchat-md.esm.min.js +8 -0
- package/dist/quikchat-md.esm.min.js.map +1 -0
- package/dist/quikchat-md.umd.js +1647 -0
- package/dist/quikchat-md.umd.js.map +1 -0
- package/dist/quikchat-md.umd.min.js +8 -0
- package/dist/quikchat-md.umd.min.js.map +1 -0
- package/dist/quikchat.cjs.js +449 -1421
- package/dist/quikchat.cjs.js.map +1 -1
- package/dist/quikchat.cjs.min.js +1 -1
- package/dist/quikchat.cjs.min.js.map +1 -1
- package/dist/quikchat.css +753 -226
- package/dist/quikchat.esm.js +449 -1421
- package/dist/quikchat.esm.js.map +1 -1
- package/dist/quikchat.esm.min.js +1 -1
- package/dist/quikchat.esm.min.js.map +1 -1
- package/dist/quikchat.min.css +1 -1
- package/dist/quikchat.umd.js +449 -1421
- package/dist/quikchat.umd.js.map +1 -1
- package/dist/quikchat.umd.min.js +1 -1
- package/dist/quikchat.umd.min.js.map +1 -1
- package/package.json +59 -34
- package/dist/quikchat.d.ts +0 -194
package/dist/quikchat.esm.js
CHANGED
|
@@ -3,37 +3,76 @@ function _arrayLikeToArray(r, a) {
|
|
|
3
3
|
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
4
4
|
return n;
|
|
5
5
|
}
|
|
6
|
-
function _arrayWithoutHoles(r) {
|
|
7
|
-
if (Array.isArray(r)) return _arrayLikeToArray(r);
|
|
8
|
-
}
|
|
9
6
|
function _classCallCheck(a, n) {
|
|
10
7
|
if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
|
|
11
8
|
}
|
|
12
9
|
function _defineProperties(e, r) {
|
|
13
10
|
for (var t = 0; t < r.length; t++) {
|
|
14
11
|
var o = r[t];
|
|
15
|
-
o.enumerable = o.enumerable ||
|
|
12
|
+
o.enumerable = o.enumerable || false, o.configurable = true, "value" in o && (o.writable = true), Object.defineProperty(e, _toPropertyKey(o.key), o);
|
|
16
13
|
}
|
|
17
14
|
}
|
|
18
15
|
function _createClass(e, r, t) {
|
|
19
16
|
return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
|
|
20
|
-
writable:
|
|
17
|
+
writable: false
|
|
21
18
|
}), e;
|
|
22
19
|
}
|
|
20
|
+
function _createForOfIteratorHelper(r, e) {
|
|
21
|
+
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
22
|
+
if (!t) {
|
|
23
|
+
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e) {
|
|
24
|
+
t && (r = t);
|
|
25
|
+
var n = 0,
|
|
26
|
+
F = function () {};
|
|
27
|
+
return {
|
|
28
|
+
s: F,
|
|
29
|
+
n: function () {
|
|
30
|
+
return n >= r.length ? {
|
|
31
|
+
done: true
|
|
32
|
+
} : {
|
|
33
|
+
done: false,
|
|
34
|
+
value: r[n++]
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
e: function (r) {
|
|
38
|
+
throw r;
|
|
39
|
+
},
|
|
40
|
+
f: F
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
44
|
+
}
|
|
45
|
+
var o,
|
|
46
|
+
a = true,
|
|
47
|
+
u = false;
|
|
48
|
+
return {
|
|
49
|
+
s: function () {
|
|
50
|
+
t = t.call(r);
|
|
51
|
+
},
|
|
52
|
+
n: function () {
|
|
53
|
+
var r = t.next();
|
|
54
|
+
return a = r.done, r;
|
|
55
|
+
},
|
|
56
|
+
e: function (r) {
|
|
57
|
+
u = true, o = r;
|
|
58
|
+
},
|
|
59
|
+
f: function () {
|
|
60
|
+
try {
|
|
61
|
+
a || null == t.return || t.return();
|
|
62
|
+
} finally {
|
|
63
|
+
if (u) throw o;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
23
68
|
function _defineProperty(e, r, t) {
|
|
24
69
|
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
25
70
|
value: t,
|
|
26
|
-
enumerable:
|
|
27
|
-
configurable:
|
|
28
|
-
writable:
|
|
71
|
+
enumerable: true,
|
|
72
|
+
configurable: true,
|
|
73
|
+
writable: true
|
|
29
74
|
}) : e[r] = t, e;
|
|
30
75
|
}
|
|
31
|
-
function _iterableToArray(r) {
|
|
32
|
-
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
|
|
33
|
-
}
|
|
34
|
-
function _nonIterableSpread() {
|
|
35
|
-
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
36
|
-
}
|
|
37
76
|
function ownKeys(e, r) {
|
|
38
77
|
var t = Object.keys(e);
|
|
39
78
|
if (Object.getOwnPropertySymbols) {
|
|
@@ -47,7 +86,7 @@ function ownKeys(e, r) {
|
|
|
47
86
|
function _objectSpread2(e) {
|
|
48
87
|
for (var r = 1; r < arguments.length; r++) {
|
|
49
88
|
var t = null != arguments[r] ? arguments[r] : {};
|
|
50
|
-
r % 2 ? ownKeys(Object(t),
|
|
89
|
+
r % 2 ? ownKeys(Object(t), true).forEach(function (r) {
|
|
51
90
|
_defineProperty(e, r, t[r]);
|
|
52
91
|
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
|
|
53
92
|
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|
@@ -55,14 +94,11 @@ function _objectSpread2(e) {
|
|
|
55
94
|
}
|
|
56
95
|
return e;
|
|
57
96
|
}
|
|
58
|
-
function _toConsumableArray(r) {
|
|
59
|
-
return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
|
|
60
|
-
}
|
|
61
97
|
function _toPrimitive(t, r) {
|
|
62
98
|
if ("object" != typeof t || !t) return t;
|
|
63
99
|
var e = t[Symbol.toPrimitive];
|
|
64
100
|
if (void 0 !== e) {
|
|
65
|
-
var i = e.call(t, r
|
|
101
|
+
var i = e.call(t, r);
|
|
66
102
|
if ("object" != typeof i) return i;
|
|
67
103
|
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
68
104
|
}
|
|
@@ -80,358 +116,11 @@ function _unsupportedIterableToArray(r, a) {
|
|
|
80
116
|
}
|
|
81
117
|
}
|
|
82
118
|
|
|
83
|
-
// Auto-generated version file - DO NOT EDIT MANUALLY
|
|
84
|
-
// This file is automatically updated by tools/updateVersion.js
|
|
85
|
-
|
|
86
|
-
var quikchatVersion = {
|
|
87
|
-
version: "1.1.16",
|
|
88
|
-
license: "BSD-2",
|
|
89
|
-
url: "https://github/deftio/quikchat",
|
|
90
|
-
fun: true
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Simplified virtual scrolling implementation for QuikChat
|
|
95
|
-
* @private
|
|
96
|
-
*/
|
|
97
|
-
var SimpleVirtualScroller = /*#__PURE__*/function () {
|
|
98
|
-
function SimpleVirtualScroller(container) {
|
|
99
|
-
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
100
|
-
_classCallCheck(this, SimpleVirtualScroller);
|
|
101
|
-
this.container = container;
|
|
102
|
-
this.items = [];
|
|
103
|
-
this.itemHeight = options.itemHeight || 80; // Default/estimate height
|
|
104
|
-
this.buffer = options.buffer || 5;
|
|
105
|
-
this.visibleRange = {
|
|
106
|
-
start: 0,
|
|
107
|
-
end: 0
|
|
108
|
-
};
|
|
109
|
-
this.renderedElements = new Map();
|
|
110
|
-
this.itemHeights = new Map(); // Cache actual heights
|
|
111
|
-
this.itemPositions = new Map(); // Cache positions
|
|
112
|
-
this.totalHeight = 0;
|
|
113
|
-
this.onRenderItem = options.onRenderItem || function () {};
|
|
114
|
-
this._initStructure();
|
|
115
|
-
this._attachScrollListener();
|
|
116
|
-
}
|
|
117
|
-
return _createClass(SimpleVirtualScroller, [{
|
|
118
|
-
key: "_initStructure",
|
|
119
|
-
value: function _initStructure() {
|
|
120
|
-
var _this = this;
|
|
121
|
-
var existingClasses = this.container.className;
|
|
122
|
-
this.container.innerHTML = '';
|
|
123
|
-
this.container.className = existingClasses;
|
|
124
|
-
this.container.style.position = 'relative';
|
|
125
|
-
this.container.style.overflow = 'auto';
|
|
126
|
-
|
|
127
|
-
// Ensure container has height
|
|
128
|
-
if (!this.container.style.height && this.container.offsetHeight === 0) {
|
|
129
|
-
this.container.style.height = '100%';
|
|
130
|
-
}
|
|
131
|
-
this.spacer = document.createElement('div');
|
|
132
|
-
this.spacer.style.cssText = 'position: absolute; top: 0; left: 0; width: 1px; pointer-events: none; z-index: -1;';
|
|
133
|
-
this.content = document.createElement('div');
|
|
134
|
-
this.content.style.cssText = 'position: relative; width: 100%;';
|
|
135
|
-
this.container.appendChild(this.spacer);
|
|
136
|
-
this.container.appendChild(this.content);
|
|
137
|
-
|
|
138
|
-
// Initial render after structure is set up
|
|
139
|
-
setTimeout(function () {
|
|
140
|
-
_this._updateVisibleRange();
|
|
141
|
-
_this._renderVisibleItems();
|
|
142
|
-
}, 0);
|
|
143
|
-
}
|
|
144
|
-
}, {
|
|
145
|
-
key: "_attachScrollListener",
|
|
146
|
-
value: function _attachScrollListener() {
|
|
147
|
-
var _this2 = this;
|
|
148
|
-
var ticking = false;
|
|
149
|
-
this.container.addEventListener('scroll', function () {
|
|
150
|
-
if (!ticking) {
|
|
151
|
-
requestAnimationFrame(function () {
|
|
152
|
-
_this2._updateVisibleRange();
|
|
153
|
-
_this2._renderVisibleItems();
|
|
154
|
-
ticking = false;
|
|
155
|
-
});
|
|
156
|
-
ticking = true;
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
}, {
|
|
161
|
-
key: "_getItemHeight",
|
|
162
|
-
value: function _getItemHeight(index) {
|
|
163
|
-
// Return cached height or estimate
|
|
164
|
-
return this.itemHeights.get(index) || this.itemHeight;
|
|
165
|
-
}
|
|
166
|
-
}, {
|
|
167
|
-
key: "_getItemPosition",
|
|
168
|
-
value: function _getItemPosition(index) {
|
|
169
|
-
// Return cached position or calculate
|
|
170
|
-
if (this.itemPositions.has(index)) {
|
|
171
|
-
return this.itemPositions.get(index);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Calculate position based on previous items
|
|
175
|
-
var position = 0;
|
|
176
|
-
for (var i = 0; i < index; i++) {
|
|
177
|
-
position += this._getItemHeight(i);
|
|
178
|
-
}
|
|
179
|
-
this.itemPositions.set(index, position);
|
|
180
|
-
return position;
|
|
181
|
-
}
|
|
182
|
-
}, {
|
|
183
|
-
key: "_recalculatePositions",
|
|
184
|
-
value: function _recalculatePositions(fromIndex) {
|
|
185
|
-
// Recalculate positions from a specific index onwards
|
|
186
|
-
var position = fromIndex > 0 ? this._getItemPosition(fromIndex) : 0;
|
|
187
|
-
for (var i = fromIndex; i < this.items.length; i++) {
|
|
188
|
-
this.itemPositions.set(i, position);
|
|
189
|
-
position += this._getItemHeight(i);
|
|
190
|
-
|
|
191
|
-
// Update position of rendered elements
|
|
192
|
-
var element = this.renderedElements.get(i);
|
|
193
|
-
if (element) {
|
|
194
|
-
element.style.top = "".concat(this.itemPositions.get(i), "px");
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// Update total height
|
|
199
|
-
this.totalHeight = position;
|
|
200
|
-
this.spacer.style.height = "".concat(this.totalHeight, "px");
|
|
201
|
-
}
|
|
202
|
-
}, {
|
|
203
|
-
key: "_updateVisibleRange",
|
|
204
|
-
value: function _updateVisibleRange() {
|
|
205
|
-
var scrollTop = this.container.scrollTop;
|
|
206
|
-
var viewportHeight = this.container.clientHeight;
|
|
207
|
-
|
|
208
|
-
// Find first visible item based on positions
|
|
209
|
-
var startIndex = 0;
|
|
210
|
-
var endIndex = this.items.length;
|
|
211
|
-
|
|
212
|
-
// Use cached positions when available
|
|
213
|
-
if (this.itemPositions.size > 0) {
|
|
214
|
-
// Find start index
|
|
215
|
-
for (var i = 0; i < this.items.length; i++) {
|
|
216
|
-
var pos = this._getItemPosition(i);
|
|
217
|
-
if (pos + this._getItemHeight(i) > scrollTop) {
|
|
218
|
-
startIndex = Math.max(0, i - this.buffer);
|
|
219
|
-
break;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// Find end index
|
|
224
|
-
for (var _i = startIndex; _i < this.items.length; _i++) {
|
|
225
|
-
var _pos = this._getItemPosition(_i);
|
|
226
|
-
if (_pos > scrollTop + viewportHeight) {
|
|
227
|
-
endIndex = Math.min(this.items.length, _i + this.buffer);
|
|
228
|
-
break;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
} else {
|
|
232
|
-
// Fallback to estimate if no positions cached yet
|
|
233
|
-
startIndex = Math.max(0, Math.floor(scrollTop / this.itemHeight) - this.buffer);
|
|
234
|
-
endIndex = Math.min(this.items.length, Math.ceil((scrollTop + viewportHeight) / this.itemHeight) + this.buffer);
|
|
235
|
-
}
|
|
236
|
-
this.visibleRange = {
|
|
237
|
-
start: startIndex,
|
|
238
|
-
end: endIndex
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
}, {
|
|
242
|
-
key: "_renderVisibleItems",
|
|
243
|
-
value: function _renderVisibleItems() {
|
|
244
|
-
var _this3 = this;
|
|
245
|
-
var _this$visibleRange = this.visibleRange,
|
|
246
|
-
start = _this$visibleRange.start,
|
|
247
|
-
end = _this$visibleRange.end;
|
|
248
|
-
|
|
249
|
-
// Remove elements outside range
|
|
250
|
-
this.renderedElements.forEach(function (element, index) {
|
|
251
|
-
if (index < start || index >= end) {
|
|
252
|
-
element.remove();
|
|
253
|
-
_this3.renderedElements["delete"](index);
|
|
254
|
-
// Don't clear height cache - we might need it again
|
|
255
|
-
}
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
// Add new visible elements
|
|
259
|
-
var _loop = function _loop(i) {
|
|
260
|
-
var item = _this3.items[i];
|
|
261
|
-
if (!item || _this3.renderedElements.has(i)) return 1; // continue
|
|
262
|
-
var element = _this3._createItemElement(item, i);
|
|
263
|
-
element.style.position = 'absolute';
|
|
264
|
-
element.style.top = "".concat(_this3._getItemPosition(i), "px");
|
|
265
|
-
element.style.left = '0';
|
|
266
|
-
element.style.right = '0';
|
|
267
|
-
_this3.renderedElements.set(i, element);
|
|
268
|
-
_this3.content.appendChild(element);
|
|
269
|
-
|
|
270
|
-
// Measure actual height after rendering
|
|
271
|
-
requestAnimationFrame(function () {
|
|
272
|
-
if (_this3.renderedElements.has(i)) {
|
|
273
|
-
var actualHeight = element.offsetHeight;
|
|
274
|
-
if (actualHeight && actualHeight !== _this3._getItemHeight(i)) {
|
|
275
|
-
_this3.itemHeights.set(i, actualHeight);
|
|
276
|
-
_this3._recalculatePositions(i);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
});
|
|
280
|
-
};
|
|
281
|
-
for (var i = start; i < end; i++) {
|
|
282
|
-
if (_loop(i)) continue;
|
|
283
|
-
}
|
|
284
|
-
this.onRenderItem(this.content);
|
|
285
|
-
}
|
|
286
|
-
}, {
|
|
287
|
-
key: "_createItemElement",
|
|
288
|
-
value: function _createItemElement(item, index) {
|
|
289
|
-
var messageDiv = document.createElement('div');
|
|
290
|
-
messageDiv.className = "quikchat-message quikchat-message-".concat(item.align || 'left', " quikchat-msgid-").concat(String(item.msgid).padStart(10, '0'));
|
|
291
|
-
messageDiv.setAttribute('data-index', index);
|
|
292
|
-
messageDiv.setAttribute('data-msgid', item.msgid);
|
|
293
|
-
if (item.tags && item.tags.length > 0) {
|
|
294
|
-
item.tags.forEach(function (tag) {
|
|
295
|
-
return messageDiv.classList.add("quikchat-tag-".concat(tag));
|
|
296
|
-
});
|
|
297
|
-
}
|
|
298
|
-
var userDiv = document.createElement('div');
|
|
299
|
-
userDiv.className = 'quikchat-message-user';
|
|
300
|
-
userDiv.innerHTML = item.userString || '';
|
|
301
|
-
var contentDiv = document.createElement('div');
|
|
302
|
-
contentDiv.className = 'quikchat-message-content';
|
|
303
|
-
contentDiv.innerHTML = item.content || '';
|
|
304
|
-
messageDiv.appendChild(userDiv);
|
|
305
|
-
messageDiv.appendChild(contentDiv);
|
|
306
|
-
if (!item.visible) {
|
|
307
|
-
messageDiv.style.display = 'none';
|
|
308
|
-
}
|
|
309
|
-
return messageDiv;
|
|
310
|
-
}
|
|
311
|
-
}, {
|
|
312
|
-
key: "addItem",
|
|
313
|
-
value: function addItem(item) {
|
|
314
|
-
this.items.push(item);
|
|
315
|
-
var index = this.items.length - 1;
|
|
316
|
-
|
|
317
|
-
// Calculate position for new item
|
|
318
|
-
var position = index > 0 ? this._getItemPosition(index - 1) + this._getItemHeight(index - 1) : 0;
|
|
319
|
-
this.itemPositions.set(index, position);
|
|
320
|
-
|
|
321
|
-
// Update total height (using estimate for new item)
|
|
322
|
-
this.totalHeight = position + this.itemHeight;
|
|
323
|
-
this.spacer.style.height = "".concat(this.totalHeight, "px");
|
|
324
|
-
if (index >= this.visibleRange.start && index < this.visibleRange.end) {
|
|
325
|
-
this._renderVisibleItems();
|
|
326
|
-
}
|
|
327
|
-
if (item.scrollIntoView) {
|
|
328
|
-
this.container.scrollTop = this.container.scrollHeight;
|
|
329
|
-
}
|
|
330
|
-
return index;
|
|
331
|
-
}
|
|
332
|
-
}, {
|
|
333
|
-
key: "addItems",
|
|
334
|
-
value: function addItems(items) {
|
|
335
|
-
var _this$items;
|
|
336
|
-
// Batch add items for better performance
|
|
337
|
-
var startLength = this.items.length;
|
|
338
|
-
(_this$items = this.items).push.apply(_this$items, _toConsumableArray(items));
|
|
339
|
-
|
|
340
|
-
// Calculate positions for new items
|
|
341
|
-
var position = startLength > 0 ? this._getItemPosition(startLength - 1) + this._getItemHeight(startLength - 1) : 0;
|
|
342
|
-
for (var i = startLength; i < this.items.length; i++) {
|
|
343
|
-
this.itemPositions.set(i, position);
|
|
344
|
-
position += this.itemHeight; // Use estimate for new items
|
|
345
|
-
}
|
|
346
|
-
this.totalHeight = position;
|
|
347
|
-
this.spacer.style.height = "".concat(this.totalHeight, "px");
|
|
348
|
-
|
|
349
|
-
// Update visible range and render
|
|
350
|
-
this._updateVisibleRange();
|
|
351
|
-
this._renderVisibleItems();
|
|
352
|
-
|
|
353
|
-
// Handle scrollIntoView for last item if needed
|
|
354
|
-
if (items.length > 0 && items[items.length - 1].scrollIntoView) {
|
|
355
|
-
this.container.scrollTop = this.container.scrollHeight;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
}, {
|
|
359
|
-
key: "clear",
|
|
360
|
-
value: function clear() {
|
|
361
|
-
this.items = [];
|
|
362
|
-
this.renderedElements.clear();
|
|
363
|
-
this.itemHeights.clear();
|
|
364
|
-
this.itemPositions.clear();
|
|
365
|
-
this.totalHeight = 0;
|
|
366
|
-
this.content.innerHTML = '';
|
|
367
|
-
this.spacer.style.height = '0px';
|
|
368
|
-
this.visibleRange = {
|
|
369
|
-
start: 0,
|
|
370
|
-
end: 0
|
|
371
|
-
};
|
|
372
|
-
|
|
373
|
-
// Force update after clear
|
|
374
|
-
this._updateVisibleRange();
|
|
375
|
-
this._renderVisibleItems();
|
|
376
|
-
}
|
|
377
|
-
}, {
|
|
378
|
-
key: "updateItem",
|
|
379
|
-
value: function updateItem(index, updates) {
|
|
380
|
-
if (index >= 0 && index < this.items.length) {
|
|
381
|
-
this.items[index] = _objectSpread2(_objectSpread2({}, this.items[index]), updates);
|
|
382
|
-
if (this.renderedElements.has(index)) {
|
|
383
|
-
this._renderVisibleItems();
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
}, {
|
|
388
|
-
key: "destroy",
|
|
389
|
-
value: function destroy() {
|
|
390
|
-
this.container.innerHTML = '';
|
|
391
|
-
this.items = [];
|
|
392
|
-
this.renderedElements.clear();
|
|
393
|
-
}
|
|
394
|
-
}]);
|
|
395
|
-
}();
|
|
396
|
-
/**
|
|
397
|
-
* QuikChat - A zero-dependency JavaScript chat widget for modern web applications
|
|
398
|
-
* @class quikchat
|
|
399
|
-
* @version 1.1.16-dev1
|
|
400
|
-
*/
|
|
401
119
|
var quikchat = /*#__PURE__*/function () {
|
|
402
120
|
/**
|
|
403
|
-
*
|
|
404
|
-
* @
|
|
405
|
-
* @param {
|
|
406
|
-
* @param {Function} [onSend] - Callback function triggered when user sends a message
|
|
407
|
-
* @param {Object} [options] - Configuration options
|
|
408
|
-
* @param {string} [options.theme='quikchat-theme-light'] - CSS theme class name
|
|
409
|
-
* @param {boolean} [options.trackHistory=true] - Whether to track message history
|
|
410
|
-
* @param {Object} [options.titleArea] - Title area configuration
|
|
411
|
-
* @param {string} [options.titleArea.title='Chat'] - Title text/HTML
|
|
412
|
-
* @param {boolean} [options.titleArea.show=false] - Whether to show title area initially
|
|
413
|
-
* @param {'left'|'center'|'right'} [options.titleArea.align='center'] - Title alignment
|
|
414
|
-
* @param {Object} [options.messagesArea] - Messages area configuration
|
|
415
|
-
* @param {boolean} [options.messagesArea.alternating=true] - Alternate message colors
|
|
416
|
-
* @param {Object} [options.inputArea] - Input area configuration
|
|
417
|
-
* @param {boolean} [options.inputArea.show=true] - Whether to show input area initially
|
|
418
|
-
* @param {boolean} [options.sendOnEnter=true] - Send message on Enter key
|
|
419
|
-
* @param {boolean} [options.sendOnShiftEnter=false] - Send message on Shift+Enter
|
|
420
|
-
* @param {string} [options.instanceClass=''] - Additional CSS class for the widget instance
|
|
421
|
-
* @example
|
|
422
|
-
* // Basic usage
|
|
423
|
-
* const chat = new quikchat('#chat-container', (instance, message) => {
|
|
424
|
-
* console.log('User sent:', message);
|
|
425
|
-
* });
|
|
426
|
-
*
|
|
427
|
-
* @example
|
|
428
|
-
* // With options
|
|
429
|
-
* const chat = new quikchat('#chat', handleMessage, {
|
|
430
|
-
* theme: 'quikchat-theme-dark',
|
|
431
|
-
* titleArea: { title: 'Support Chat', show: true },
|
|
432
|
-
* sendOnEnter: false,
|
|
433
|
-
* sendOnShiftEnter: true
|
|
434
|
-
* });
|
|
121
|
+
*
|
|
122
|
+
* @param string or DOM element parentElement
|
|
123
|
+
* @param {*} meta
|
|
435
124
|
*/
|
|
436
125
|
function quikchat(parentElement) {
|
|
437
126
|
var onSend = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
|
|
@@ -440,6 +129,7 @@ var quikchat = /*#__PURE__*/function () {
|
|
|
440
129
|
var defaultOpts = {
|
|
441
130
|
theme: 'quikchat-theme-light',
|
|
442
131
|
trackHistory: true,
|
|
132
|
+
showTimestamps: false,
|
|
443
133
|
titleArea: {
|
|
444
134
|
title: "Chat",
|
|
445
135
|
show: false,
|
|
@@ -447,31 +137,19 @@ var quikchat = /*#__PURE__*/function () {
|
|
|
447
137
|
},
|
|
448
138
|
messagesArea: {
|
|
449
139
|
alternating: true
|
|
450
|
-
}
|
|
451
|
-
inputArea: {
|
|
452
|
-
show: true
|
|
453
|
-
},
|
|
454
|
-
sendOnEnter: true,
|
|
455
|
-
sendOnShiftEnter: false,
|
|
456
|
-
instanceClass: '',
|
|
457
|
-
virtualScrolling: true,
|
|
458
|
-
// Default to true for better performance
|
|
459
|
-
virtualScrollingThreshold: 500 // Lower threshold since it performs so well
|
|
140
|
+
}
|
|
460
141
|
};
|
|
461
142
|
var meta = _objectSpread2(_objectSpread2({}, defaultOpts), options); // merge options with defaults
|
|
462
143
|
|
|
463
144
|
if (typeof parentElement === 'string') {
|
|
464
145
|
parentElement = document.querySelector(parentElement);
|
|
465
146
|
}
|
|
466
|
-
//console.log(parentElement, meta);
|
|
467
147
|
this._parentElement = parentElement;
|
|
468
148
|
this._theme = meta.theme;
|
|
469
149
|
this._onSend = onSend ? onSend : function () {}; // call back function for onSend
|
|
150
|
+
this._messageFormatter = meta.messageFormatter || null;
|
|
151
|
+
this._sanitize = meta.sanitize || false;
|
|
470
152
|
this._createWidget();
|
|
471
|
-
if (meta.instanceClass) {
|
|
472
|
-
this._chatWidget.classList.add(meta.instanceClass);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
153
|
// title area
|
|
476
154
|
if (meta.titleArea) {
|
|
477
155
|
this.titleAreaSetContents(meta.titleArea.title, meta.titleArea.align);
|
|
@@ -485,94 +163,30 @@ var quikchat = /*#__PURE__*/function () {
|
|
|
485
163
|
if (meta.messagesArea) {
|
|
486
164
|
this.messagesAreaAlternateColors(meta.messagesArea.alternating);
|
|
487
165
|
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
166
|
+
// timestamps
|
|
167
|
+
if (meta.showTimestamps) {
|
|
168
|
+
this.messagesAreaShowTimestamps(true);
|
|
169
|
+
}
|
|
170
|
+
// direction (ltr/rtl)
|
|
171
|
+
if (meta.direction) {
|
|
172
|
+
this.setDirection(meta.direction);
|
|
492
173
|
}
|
|
493
174
|
// plumbing
|
|
494
175
|
this._attachEventListeners();
|
|
495
|
-
this.trackHistory = meta.trackHistory
|
|
176
|
+
this.trackHistory = meta.trackHistory !== false;
|
|
496
177
|
this._historyLimit = 10000000;
|
|
497
178
|
this._history = [];
|
|
498
|
-
this._activeTags = new Set();
|
|
499
|
-
|
|
500
|
-
// send on enter / shift enter
|
|
501
|
-
this.sendOnEnter = meta.sendOnEnter;
|
|
502
|
-
this.sendOnShiftEnter = meta.sendOnShiftEnter;
|
|
503
|
-
|
|
504
|
-
// Virtual scrolling setup
|
|
505
|
-
this.virtualScrollingEnabled = meta.virtualScrolling;
|
|
506
|
-
this.virtualScrollingThreshold = meta.virtualScrollingThreshold;
|
|
507
|
-
this.virtualScroller = null;
|
|
508
|
-
|
|
509
|
-
// Don't initialize virtual scrolling immediately - wait for threshold
|
|
510
|
-
// Virtual scrolling will be initialized when message count exceeds threshold
|
|
511
179
|
}
|
|
512
|
-
|
|
513
|
-
/**
|
|
514
|
-
* Initialize virtual scrolling
|
|
515
|
-
* @private
|
|
516
|
-
*/
|
|
517
180
|
return _createClass(quikchat, [{
|
|
518
|
-
key: "_initVirtualScrolling",
|
|
519
|
-
value: function _initVirtualScrolling() {
|
|
520
|
-
var _this4 = this;
|
|
521
|
-
if (this.virtualScrollingEnabled && this._messagesArea && !this.virtualScroller) {
|
|
522
|
-
// Check if we've hit the threshold (or about to with the next message)
|
|
523
|
-
if (this._history.length >= this.virtualScrollingThreshold - 1) {
|
|
524
|
-
this.virtualScroller = new SimpleVirtualScroller(this._messagesArea, {
|
|
525
|
-
itemHeight: 80,
|
|
526
|
-
buffer: 5,
|
|
527
|
-
onRenderItem: function onRenderItem(content) {
|
|
528
|
-
// Apply alternating colors if enabled
|
|
529
|
-
if (_this4._messagesArea.classList.contains('quikchat-messages-area-alt')) {
|
|
530
|
-
_this4._updateMessageStyles();
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
});
|
|
534
|
-
|
|
535
|
-
// Migrate existing messages to virtual scroller
|
|
536
|
-
this._migrateToVirtualScrolling();
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
/**
|
|
542
|
-
* Migrate existing messages to virtual scrolling
|
|
543
|
-
* @private
|
|
544
|
-
*/
|
|
545
|
-
}, {
|
|
546
|
-
key: "_migrateToVirtualScrolling",
|
|
547
|
-
value: function _migrateToVirtualScrolling() {
|
|
548
|
-
if (!this.virtualScroller) return;
|
|
549
|
-
|
|
550
|
-
// Clear DOM but keep history
|
|
551
|
-
this._messagesArea.innerHTML = '';
|
|
552
|
-
|
|
553
|
-
// Add all messages to virtual scroller
|
|
554
|
-
var items = this._history.map(function (msg) {
|
|
555
|
-
return {
|
|
556
|
-
msgid: msg.msgid,
|
|
557
|
-
content: msg.content,
|
|
558
|
-
userString: msg.userString,
|
|
559
|
-
align: msg.align,
|
|
560
|
-
role: msg.role,
|
|
561
|
-
visible: msg.visible,
|
|
562
|
-
tags: msg.tags || [],
|
|
563
|
-
scrollIntoView: false
|
|
564
|
-
};
|
|
565
|
-
});
|
|
566
|
-
this.virtualScroller.addItems(items);
|
|
567
|
-
}
|
|
568
|
-
}, {
|
|
569
181
|
key: "_createWidget",
|
|
570
182
|
value: function _createWidget() {
|
|
571
|
-
var widgetHTML = "\n <div class=\"quikchat-base ".concat(this.theme, "\">\n <div class=\"quikchat-title-area\">\n
|
|
183
|
+
var widgetHTML = "\n <div class=\"quikchat-base ".concat(this.theme, "\">\n <div class=\"quikchat-title-area\"></div>\n <div class=\"quikchat-messages-wrapper\"><div class=\"quikchat-messages-area\" role=\"log\" aria-live=\"polite\" aria-label=\"Chat messages\"></div><button class=\"quikchat-scroll-bottom\" aria-label=\"Scroll to bottom\"></button></div>\n <div class=\"quikchat-input-area\">\n <textarea class=\"quikchat-input-textbox\" rows=\"1\" aria-label=\"Type a message\"></textarea>\n <button class=\"quikchat-input-send-btn\">Send</button>\n </div>\n </div>\n ");
|
|
572
184
|
this._parentElement.innerHTML = widgetHTML;
|
|
573
185
|
this._chatWidget = this._parentElement.querySelector('.quikchat-base');
|
|
574
186
|
this._titleArea = this._chatWidget.querySelector('.quikchat-title-area');
|
|
187
|
+
this._messagesWrapper = this._chatWidget.querySelector('.quikchat-messages-wrapper');
|
|
575
188
|
this._messagesArea = this._chatWidget.querySelector('.quikchat-messages-area');
|
|
189
|
+
this._scrollBottomBtn = this._messagesWrapper.querySelector('.quikchat-scroll-bottom');
|
|
576
190
|
this._inputArea = this._chatWidget.querySelector('.quikchat-input-area');
|
|
577
191
|
this._textEntry = this._inputArea.querySelector('.quikchat-input-textbox');
|
|
578
192
|
this._sendButton = this._inputArea.querySelector('.quikchat-input-send-btn');
|
|
@@ -585,40 +199,55 @@ var quikchat = /*#__PURE__*/function () {
|
|
|
585
199
|
}, {
|
|
586
200
|
key: "_attachEventListeners",
|
|
587
201
|
value: function _attachEventListeners() {
|
|
588
|
-
var
|
|
589
|
-
this._sendButton.addEventListener('click', function (
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
window.addEventListener('resize', function () {
|
|
594
|
-
return _this5._handleContainerResize();
|
|
595
|
-
});
|
|
596
|
-
this._chatWidget.addEventListener('resize', function () {
|
|
597
|
-
return _this5._handleContainerResize();
|
|
202
|
+
var _this = this;
|
|
203
|
+
this._sendButton.addEventListener('click', function () {
|
|
204
|
+
var text = _this._textEntry.value.trim();
|
|
205
|
+
if (text === '') return;
|
|
206
|
+
_this._onSend(_this, text);
|
|
598
207
|
});
|
|
599
208
|
this._textEntry.addEventListener('keydown', function (event) {
|
|
600
|
-
// Check if Shift + Enter is pressed
|
|
209
|
+
// Check if Shift + Enter is pressed
|
|
601
210
|
if (event.shiftKey && event.keyCode === 13) {
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
}
|
|
607
|
-
} else if (event.keyCode === 13) {
|
|
608
|
-
// Enter but not Shift + Enter
|
|
609
|
-
if (_this5.sendOnEnter) {
|
|
610
|
-
event.preventDefault();
|
|
611
|
-
_this5._onSend(_this5, _this5._textEntry.value.trim());
|
|
612
|
-
}
|
|
211
|
+
event.preventDefault();
|
|
212
|
+
var text = _this._textEntry.value.trim();
|
|
213
|
+
if (text === '') return;
|
|
214
|
+
_this._onSend(_this, text);
|
|
613
215
|
}
|
|
614
216
|
});
|
|
217
|
+
|
|
218
|
+
// Auto-grow textarea
|
|
219
|
+
this._textEntry.addEventListener('input', function () {
|
|
220
|
+
return _this._autoGrowTextarea();
|
|
221
|
+
});
|
|
615
222
|
this._messagesArea.addEventListener('scroll', function () {
|
|
616
|
-
var
|
|
617
|
-
scrollTop =
|
|
618
|
-
scrollHeight =
|
|
619
|
-
clientHeight =
|
|
620
|
-
|
|
223
|
+
var _this$_messagesArea = _this._messagesArea,
|
|
224
|
+
scrollTop = _this$_messagesArea.scrollTop,
|
|
225
|
+
scrollHeight = _this$_messagesArea.scrollHeight,
|
|
226
|
+
clientHeight = _this$_messagesArea.clientHeight;
|
|
227
|
+
_this.userScrolledUp = scrollTop + clientHeight < scrollHeight - 1;
|
|
228
|
+
_this._updateScrollBottomBtn();
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
// Scroll-to-bottom button
|
|
232
|
+
this._scrollBottomBtn.addEventListener('click', function () {
|
|
233
|
+
return _this.scrollToBottom();
|
|
621
234
|
});
|
|
235
|
+
|
|
236
|
+
// Ctrl+End to scroll to bottom
|
|
237
|
+
this._chatWidget.addEventListener('keydown', function (event) {
|
|
238
|
+
if (event.ctrlKey && event.key === 'End') {
|
|
239
|
+
event.preventDefault();
|
|
240
|
+
_this.scrollToBottom();
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// Use ResizeObserver to detect parent container resize
|
|
245
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
246
|
+
this._resizeObserver = new ResizeObserver(function () {
|
|
247
|
+
return _this._handleContainerResize();
|
|
248
|
+
});
|
|
249
|
+
this._resizeObserver.observe(this._parentElement);
|
|
250
|
+
}
|
|
622
251
|
}
|
|
623
252
|
|
|
624
253
|
// set the onSend function callback.
|
|
@@ -633,54 +262,16 @@ var quikchat = /*#__PURE__*/function () {
|
|
|
633
262
|
value: function setCallbackonMessageAdded(callback) {
|
|
634
263
|
this._onMessageAdded = callback;
|
|
635
264
|
}
|
|
636
|
-
|
|
637
|
-
/**
|
|
638
|
-
* Sets the callback function for when content is appended to a message
|
|
639
|
-
* @param {Function} callback - Function to call when content is appended
|
|
640
|
-
* @param {quikchat} callback.instance - The QuikChat instance
|
|
641
|
-
* @param {number} callback.msgId - The ID of the message being appended to
|
|
642
|
-
* @param {string} callback.content - The content being appended
|
|
643
|
-
* @since 1.1.15
|
|
644
|
-
* @example
|
|
645
|
-
* chat.setCallbackonMessageAppend((instance, msgId, content) => {
|
|
646
|
-
* console.log(`Appended "${content}" to message ${msgId}`);
|
|
647
|
-
* });
|
|
648
|
-
*/
|
|
649
265
|
}, {
|
|
650
266
|
key: "setCallbackonMessageAppend",
|
|
651
267
|
value: function setCallbackonMessageAppend(callback) {
|
|
652
268
|
this._onMessageAppend = callback;
|
|
653
269
|
}
|
|
654
|
-
|
|
655
|
-
/**
|
|
656
|
-
* Sets the callback function for when a message's content is replaced
|
|
657
|
-
* @param {Function} callback - Function to call when content is replaced
|
|
658
|
-
* @param {quikchat} callback.instance - The QuikChat instance
|
|
659
|
-
* @param {number} callback.msgId - The ID of the message being replaced
|
|
660
|
-
* @param {string} callback.content - The new content
|
|
661
|
-
* @since 1.1.15
|
|
662
|
-
* @example
|
|
663
|
-
* chat.setCallbackonMessageReplace((instance, msgId, content) => {
|
|
664
|
-
* console.log(`Message ${msgId} replaced with: ${content}`);
|
|
665
|
-
* });
|
|
666
|
-
*/
|
|
667
270
|
}, {
|
|
668
271
|
key: "setCallbackonMessageReplace",
|
|
669
272
|
value: function setCallbackonMessageReplace(callback) {
|
|
670
273
|
this._onMessageReplace = callback;
|
|
671
274
|
}
|
|
672
|
-
|
|
673
|
-
/**
|
|
674
|
-
* Sets the callback function for when a message is deleted
|
|
675
|
-
* @param {Function} callback - Function to call when a message is deleted
|
|
676
|
-
* @param {quikchat} callback.instance - The QuikChat instance
|
|
677
|
-
* @param {number} callback.msgId - The ID of the deleted message
|
|
678
|
-
* @since 1.1.15
|
|
679
|
-
* @example
|
|
680
|
-
* chat.setCallbackonMessageDelete((instance, msgId) => {
|
|
681
|
-
* console.log(`Message ${msgId} was deleted`);
|
|
682
|
-
* });
|
|
683
|
-
*/
|
|
684
275
|
}, {
|
|
685
276
|
key: "setCallbackonMessageDelete",
|
|
686
277
|
value: function setCallbackonMessageDelete(callback) {
|
|
@@ -688,46 +279,25 @@ var quikchat = /*#__PURE__*/function () {
|
|
|
688
279
|
}
|
|
689
280
|
|
|
690
281
|
// Public methods
|
|
691
|
-
/**
|
|
692
|
-
* Toggles the visibility of the title area
|
|
693
|
-
* @returns {void}
|
|
694
|
-
*/
|
|
695
282
|
}, {
|
|
696
283
|
key: "titleAreaToggle",
|
|
697
284
|
value: function titleAreaToggle() {
|
|
698
|
-
this._titleArea.style.display === 'none'
|
|
285
|
+
if (this._titleArea.style.display === 'none') {
|
|
286
|
+
this.titleAreaShow();
|
|
287
|
+
} else {
|
|
288
|
+
this.titleAreaHide();
|
|
289
|
+
}
|
|
699
290
|
}
|
|
700
|
-
|
|
701
|
-
/**
|
|
702
|
-
* Shows the title area
|
|
703
|
-
* @returns {void}
|
|
704
|
-
*/
|
|
705
291
|
}, {
|
|
706
292
|
key: "titleAreaShow",
|
|
707
293
|
value: function titleAreaShow() {
|
|
708
294
|
this._titleArea.style.display = '';
|
|
709
|
-
this._adjustMessagesAreaHeight();
|
|
710
295
|
}
|
|
711
|
-
|
|
712
|
-
/**
|
|
713
|
-
* Hides the title area
|
|
714
|
-
* @returns {void}
|
|
715
|
-
*/
|
|
716
296
|
}, {
|
|
717
297
|
key: "titleAreaHide",
|
|
718
298
|
value: function titleAreaHide() {
|
|
719
299
|
this._titleArea.style.display = 'none';
|
|
720
|
-
this._adjustMessagesAreaHeight();
|
|
721
300
|
}
|
|
722
|
-
|
|
723
|
-
/**
|
|
724
|
-
* Sets the contents of the title area
|
|
725
|
-
* @param {string} title - HTML content to display in the title area
|
|
726
|
-
* @param {'left'|'center'|'right'} [align='center'] - Text alignment
|
|
727
|
-
* @returns {void}
|
|
728
|
-
* @example
|
|
729
|
-
* chat.titleAreaSetContents('<h2>Support Chat</h2>', 'center');
|
|
730
|
-
*/
|
|
731
301
|
}, {
|
|
732
302
|
key: "titleAreaSetContents",
|
|
733
303
|
value: function titleAreaSetContents(title) {
|
|
@@ -735,11 +305,6 @@ var quikchat = /*#__PURE__*/function () {
|
|
|
735
305
|
this._titleArea.innerHTML = title;
|
|
736
306
|
this._titleArea.style.textAlign = align;
|
|
737
307
|
}
|
|
738
|
-
|
|
739
|
-
/**
|
|
740
|
-
* Gets the current contents of the title area
|
|
741
|
-
* @returns {string} The HTML content of the title area
|
|
742
|
-
*/
|
|
743
308
|
}, {
|
|
744
309
|
key: "titleAreaGetContents",
|
|
745
310
|
value: function titleAreaGetContents() {
|
|
@@ -748,48 +313,133 @@ var quikchat = /*#__PURE__*/function () {
|
|
|
748
313
|
}, {
|
|
749
314
|
key: "inputAreaToggle",
|
|
750
315
|
value: function inputAreaToggle() {
|
|
751
|
-
this._inputArea.
|
|
752
|
-
|
|
316
|
+
if (this._inputArea.style.display === 'none') {
|
|
317
|
+
this.inputAreaShow();
|
|
318
|
+
} else {
|
|
319
|
+
this.inputAreaHide();
|
|
320
|
+
}
|
|
753
321
|
}
|
|
754
322
|
}, {
|
|
755
323
|
key: "inputAreaShow",
|
|
756
324
|
value: function inputAreaShow() {
|
|
757
325
|
this._inputArea.style.display = '';
|
|
758
|
-
this._adjustMessagesAreaHeight();
|
|
759
326
|
}
|
|
760
327
|
}, {
|
|
761
328
|
key: "inputAreaHide",
|
|
762
329
|
value: function inputAreaHide() {
|
|
763
330
|
this._inputArea.style.display = 'none';
|
|
764
|
-
this._adjustMessagesAreaHeight();
|
|
765
331
|
}
|
|
766
332
|
}, {
|
|
767
|
-
key: "
|
|
768
|
-
value: function
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
333
|
+
key: "inputAreaSetEnabled",
|
|
334
|
+
value: function inputAreaSetEnabled(enabled) {
|
|
335
|
+
this._textEntry.disabled = !enabled;
|
|
336
|
+
this._sendButton.disabled = !enabled;
|
|
337
|
+
}
|
|
338
|
+
}, {
|
|
339
|
+
key: "inputAreaSetButtonText",
|
|
340
|
+
value: function inputAreaSetButtonText(text) {
|
|
341
|
+
this._sendButton.textContent = text;
|
|
342
|
+
}
|
|
343
|
+
}, {
|
|
344
|
+
key: "inputAreaGetButtonText",
|
|
345
|
+
value: function inputAreaGetButtonText() {
|
|
346
|
+
return this._sendButton.textContent;
|
|
347
|
+
}
|
|
348
|
+
}, {
|
|
349
|
+
key: "setDirection",
|
|
350
|
+
value: function setDirection(dir) {
|
|
351
|
+
var d = dir === 'rtl' ? 'rtl' : 'ltr';
|
|
352
|
+
this._chatWidget.setAttribute('dir', d);
|
|
353
|
+
if (d === 'rtl') {
|
|
354
|
+
this._chatWidget.classList.add('quikchat-rtl');
|
|
355
|
+
} else {
|
|
356
|
+
this._chatWidget.classList.remove('quikchat-rtl');
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}, {
|
|
360
|
+
key: "getDirection",
|
|
361
|
+
value: function getDirection() {
|
|
362
|
+
return this._chatWidget.getAttribute('dir') || 'ltr';
|
|
777
363
|
}
|
|
778
364
|
}, {
|
|
779
365
|
key: "_handleContainerResize",
|
|
780
366
|
value: function _handleContainerResize() {
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
return true;
|
|
367
|
+
// Layout is handled by CSS flexbox — no JS height calculation needed.
|
|
368
|
+
// This hook exists for future use or custom resize callbacks.
|
|
784
369
|
}
|
|
785
370
|
}, {
|
|
786
|
-
key: "
|
|
787
|
-
value: function
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
371
|
+
key: "scrollToBottom",
|
|
372
|
+
value: function scrollToBottom() {
|
|
373
|
+
this._messagesArea.scrollTop = this._messagesArea.scrollHeight;
|
|
374
|
+
this.userScrolledUp = false;
|
|
375
|
+
this._updateScrollBottomBtn();
|
|
376
|
+
}
|
|
377
|
+
}, {
|
|
378
|
+
key: "_updateScrollBottomBtn",
|
|
379
|
+
value: function _updateScrollBottomBtn() {
|
|
380
|
+
if (this.userScrolledUp) {
|
|
381
|
+
this._scrollBottomBtn.classList.add('quikchat-scroll-bottom-visible');
|
|
382
|
+
} else {
|
|
383
|
+
this._scrollBottomBtn.classList.remove('quikchat-scroll-bottom-visible');
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}, {
|
|
387
|
+
key: "_autoGrowTextarea",
|
|
388
|
+
value: function _autoGrowTextarea() {
|
|
389
|
+
var el = this._textEntry;
|
|
390
|
+
el.style.height = 'auto';
|
|
391
|
+
var maxHeight = parseInt(getComputedStyle(el).getPropertyValue('--quikchat-input-max-height')) || 120;
|
|
392
|
+
el.style.height = Math.min(el.scrollHeight, maxHeight) + 'px';
|
|
393
|
+
el.style.overflowY = el.scrollHeight > maxHeight ? 'auto' : 'hidden';
|
|
394
|
+
}
|
|
395
|
+
}, {
|
|
396
|
+
key: "_formatTimestamp",
|
|
397
|
+
value: function _formatTimestamp(isoString) {
|
|
398
|
+
var d = new Date(isoString);
|
|
399
|
+
var h = d.getHours();
|
|
400
|
+
var m = String(d.getMinutes()).padStart(2, '0');
|
|
401
|
+
var ampm = h >= 12 ? 'PM' : 'AM';
|
|
402
|
+
var h12 = h % 12 || 12;
|
|
403
|
+
return h12 + ':' + m + ' ' + ampm;
|
|
404
|
+
}
|
|
405
|
+
}, {
|
|
406
|
+
key: "messagesAreaShowTimestamps",
|
|
407
|
+
value: function messagesAreaShowTimestamps(show) {
|
|
408
|
+
if (show) {
|
|
409
|
+
this._messagesArea.classList.add('quikchat-show-timestamps');
|
|
410
|
+
} else {
|
|
411
|
+
this._messagesArea.classList.remove('quikchat-show-timestamps');
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}, {
|
|
415
|
+
key: "messagesAreaShowTimestampsGet",
|
|
416
|
+
value: function messagesAreaShowTimestampsGet() {
|
|
417
|
+
return this._messagesArea.classList.contains('quikchat-show-timestamps');
|
|
418
|
+
}
|
|
419
|
+
}, {
|
|
420
|
+
key: "messagesAreaShowTimestampsToggle",
|
|
421
|
+
value: function messagesAreaShowTimestampsToggle() {
|
|
422
|
+
this._messagesArea.classList.toggle('quikchat-show-timestamps');
|
|
423
|
+
}
|
|
424
|
+
}, {
|
|
425
|
+
key: "_escapeHTML",
|
|
426
|
+
value: function _escapeHTML(str) {
|
|
427
|
+
var div = document.createElement('div');
|
|
428
|
+
div.textContent = str;
|
|
429
|
+
return div.innerHTML;
|
|
430
|
+
}
|
|
431
|
+
}, {
|
|
432
|
+
key: "_processContent",
|
|
433
|
+
value: function _processContent(content) {
|
|
434
|
+
if (this._sanitize === true) {
|
|
435
|
+
content = this._escapeHTML(content);
|
|
436
|
+
} else if (typeof this._sanitize === 'function') {
|
|
437
|
+
content = this._sanitize(content);
|
|
438
|
+
}
|
|
439
|
+
if (this._messageFormatter) {
|
|
440
|
+
content = this._messageFormatter(content);
|
|
441
|
+
}
|
|
442
|
+
return content;
|
|
793
443
|
}
|
|
794
444
|
|
|
795
445
|
//messagesArea functions
|
|
@@ -814,149 +464,67 @@ var quikchat = /*#__PURE__*/function () {
|
|
|
814
464
|
value: function messagesAreaAlternateColorsGet() {
|
|
815
465
|
return this._messagesArea.classList.contains('quikchat-messages-area-alt');
|
|
816
466
|
}
|
|
817
|
-
|
|
818
|
-
* Adds a new message to the chat with full configuration options
|
|
819
|
-
* @param {Object} input - Message configuration object
|
|
820
|
-
* @param {string} [input.content=''] - Message content (HTML allowed)
|
|
821
|
-
* @param {string} [input.userString='user'] - Display name for the message sender
|
|
822
|
-
* @param {'left'|'right'|'center'} [input.align='right'] - Message alignment
|
|
823
|
-
* @param {string} [input.role='user'] - Role identifier (user, assistant, system)
|
|
824
|
-
* @param {number} [input.userID=-1] - User ID for the message
|
|
825
|
-
* @param {string|false} [input.timestamp=false] - ISO timestamp or false for auto
|
|
826
|
-
* @param {string|false} [input.updatedtime=false] - Last updated timestamp
|
|
827
|
-
* @param {boolean|'smart'} [input.scrollIntoView=true] - Scroll behavior (true/false/'smart')
|
|
828
|
-
* @param {boolean} [input.visible=true] - Whether message is initially visible
|
|
829
|
-
* @param {string[]} [input.tags=[]] - Tags for message categorization
|
|
830
|
-
* @returns {number} Message ID for the newly added message
|
|
831
|
-
* @example
|
|
832
|
-
* const msgId = chat.messageAddFull({
|
|
833
|
-
* content: 'Hello!',
|
|
834
|
-
* userString: 'Bot',
|
|
835
|
-
* align: 'left',
|
|
836
|
-
* scrollIntoView: 'smart',
|
|
837
|
-
* tags: ['greeting']
|
|
838
|
-
* });
|
|
839
|
-
*/
|
|
467
|
+
// message functions
|
|
840
468
|
}, {
|
|
841
469
|
key: "messageAddFull",
|
|
842
470
|
value: function messageAddFull() {
|
|
843
|
-
var _this6 = this;
|
|
844
471
|
var input = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
|
|
845
472
|
content: "",
|
|
846
473
|
userString: "user",
|
|
847
474
|
align: "right",
|
|
848
475
|
role: "user",
|
|
849
|
-
userID: -1
|
|
850
|
-
timestamp: false,
|
|
851
|
-
updatedtime: false,
|
|
852
|
-
scrollIntoView: true,
|
|
853
|
-
visible: true,
|
|
854
|
-
tags: []
|
|
476
|
+
userID: -1
|
|
855
477
|
};
|
|
856
478
|
var msgid = this.msgid;
|
|
479
|
+
var messageDiv = document.createElement('div');
|
|
480
|
+
var msgidClass = 'quikchat-msgid-' + String(msgid).padStart(10, '0');
|
|
481
|
+
messageDiv.classList.add('quikchat-message', msgidClass);
|
|
482
|
+
messageDiv.classList.add('quikchat-role-' + (input.role || 'user'));
|
|
483
|
+
messageDiv.classList.add('quikchat-align-' + (input.align || 'right'));
|
|
857
484
|
this.msgid++;
|
|
858
|
-
|
|
485
|
+
messageDiv.classList.add(this._messagesArea.children.length % 2 === 1 ? 'quikchat-message-1' : 'quikchat-message-2');
|
|
859
486
|
|
|
860
|
-
//
|
|
861
|
-
|
|
862
|
-
|
|
487
|
+
// Visibility: default true, hidden messages get display:none
|
|
488
|
+
var visible = input.visible !== false;
|
|
489
|
+
if (!visible) {
|
|
490
|
+
messageDiv.style.display = 'none';
|
|
863
491
|
}
|
|
864
492
|
|
|
865
|
-
//
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
}
|
|
884
|
-
});
|
|
885
|
-
}
|
|
886
|
-
|
|
887
|
-
// Add to virtual scroller
|
|
888
|
-
this.virtualScroller.addItem(messageData);
|
|
889
|
-
|
|
890
|
-
// Clear text entry
|
|
891
|
-
this._textEntry.value = '';
|
|
892
|
-
this._adjustMessagesAreaHeight();
|
|
893
|
-
} else {
|
|
894
|
-
// Original DOM-based implementation
|
|
895
|
-
messageDiv = document.createElement('div');
|
|
896
|
-
var msgidClass = 'quikchat-msgid-' + String(msgid).padStart(10, '0');
|
|
897
|
-
'quikchat-userid-' + String(input.userString).padStart(10, '0'); // hash this..
|
|
898
|
-
messageDiv.classList.add('quikchat-message', msgidClass, 'quikchat-structure');
|
|
899
|
-
if (Array.isArray(input.tags)) {
|
|
900
|
-
input.tags.forEach(function (tag) {
|
|
901
|
-
if (typeof tag === 'string' && /^[a-zA-Z0-9-]+$/.test(tag)) {
|
|
902
|
-
messageDiv.classList.add("quikchat-tag-".concat(tag));
|
|
903
|
-
_this6._activeTags.add(tag);
|
|
904
|
-
}
|
|
905
|
-
});
|
|
906
|
-
}
|
|
907
|
-
var userDiv = document.createElement('div');
|
|
908
|
-
userDiv.innerHTML = input.userString;
|
|
909
|
-
userDiv.classList.add('quikchat-user-label');
|
|
910
|
-
userDiv.style.textAlign = input.align;
|
|
911
|
-
var contentDiv = document.createElement('div');
|
|
912
|
-
contentDiv.classList.add('quikchat-message-content');
|
|
913
|
-
|
|
914
|
-
// Determine text alignment for right-aligned messages
|
|
915
|
-
if (input.align === "right") {
|
|
916
|
-
var isMultiLine = input.content.includes("\n");
|
|
917
|
-
var isLong = input.content.length > 50; // Adjust length threshold
|
|
918
|
-
|
|
919
|
-
if (isMultiLine || isLong) {
|
|
920
|
-
contentDiv.classList.add("quikchat-right-multiline");
|
|
921
|
-
} else {
|
|
922
|
-
contentDiv.classList.add("quikchat-right-singleline");
|
|
923
|
-
}
|
|
924
|
-
}
|
|
925
|
-
contentDiv.innerHTML = input.content;
|
|
926
|
-
messageDiv.appendChild(userDiv);
|
|
927
|
-
messageDiv.appendChild(contentDiv);
|
|
928
|
-
this._messagesArea.appendChild(messageDiv);
|
|
929
|
-
if (input.visible === false) {
|
|
930
|
-
messageDiv.style.display = 'none';
|
|
931
|
-
}
|
|
932
|
-
|
|
933
|
-
// Handle scroll behavior based on scrollIntoView parameter
|
|
934
|
-
// 'smart' = only scroll if near bottom, true = always scroll, false = never scroll
|
|
935
|
-
if (input.scrollIntoView === true) {
|
|
936
|
-
this.messageScrollToBottom();
|
|
937
|
-
} else if (input.scrollIntoView === 'smart' && !this.userScrolledUp) {
|
|
938
|
-
this.messageScrollToBottom();
|
|
939
|
-
}
|
|
940
|
-
// If scrollIntoView is false, don't scroll at all
|
|
493
|
+
// Tags: array of strings for group-based visibility control
|
|
494
|
+
var tags = Array.isArray(input.tags) ? input.tags.slice() : [];
|
|
495
|
+
var userDiv = document.createElement('div');
|
|
496
|
+
userDiv.classList.add('quikchat-user-label');
|
|
497
|
+
userDiv.style.textAlign = input.align;
|
|
498
|
+
userDiv.innerHTML = input.userString;
|
|
499
|
+
var contentDiv = document.createElement('div');
|
|
500
|
+
contentDiv.classList.add('quikchat-message-content');
|
|
501
|
+
contentDiv.style.textAlign = input.align;
|
|
502
|
+
contentDiv.innerHTML = this._processContent(input.content);
|
|
503
|
+
var timestamp = new Date().toISOString();
|
|
504
|
+
var timestampSpan = document.createElement('span');
|
|
505
|
+
timestampSpan.classList.add('quikchat-timestamp');
|
|
506
|
+
timestampSpan.textContent = this._formatTimestamp(timestamp);
|
|
507
|
+
messageDiv.appendChild(userDiv);
|
|
508
|
+
messageDiv.appendChild(contentDiv);
|
|
509
|
+
messageDiv.appendChild(timestampSpan);
|
|
510
|
+
this._messagesArea.appendChild(messageDiv);
|
|
941
511
|
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
this.
|
|
945
|
-
this._updateMessageStyles();
|
|
512
|
+
// Scroll to the last message only if the user is not actively scrolling up
|
|
513
|
+
if (!this.userScrolledUp) {
|
|
514
|
+
this._messagesArea.scrollTop = this._messagesArea.scrollHeight;
|
|
946
515
|
}
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
var
|
|
950
|
-
var updatedtime = input.updatedtime ? input.updatedtime : timestamp;
|
|
951
|
-
var visible = input.visible !== undefined ? input.visible : true;
|
|
516
|
+
this._textEntry.value = '';
|
|
517
|
+
this._autoGrowTextarea();
|
|
518
|
+
var updatedtime = timestamp;
|
|
952
519
|
if (this.trackHistory) {
|
|
953
520
|
this._history.push(_objectSpread2(_objectSpread2({
|
|
954
521
|
msgid: msgid
|
|
955
522
|
}, input), {}, {
|
|
956
523
|
visible: visible,
|
|
524
|
+
tags: tags,
|
|
957
525
|
timestamp: timestamp,
|
|
958
526
|
updatedtime: updatedtime,
|
|
959
|
-
messageDiv: messageDiv
|
|
527
|
+
messageDiv: messageDiv
|
|
960
528
|
}));
|
|
961
529
|
if (this._history.length > this._historyLimit) {
|
|
962
530
|
this._history.shift();
|
|
@@ -967,24 +535,6 @@ var quikchat = /*#__PURE__*/function () {
|
|
|
967
535
|
}
|
|
968
536
|
return msgid;
|
|
969
537
|
}
|
|
970
|
-
|
|
971
|
-
/**
|
|
972
|
-
* Adds a new message to the chat (simplified version of messageAddFull)
|
|
973
|
-
* @param {string} [content=''] - Message content (HTML allowed)
|
|
974
|
-
* @param {string} [userString='user'] - Display name for the message sender
|
|
975
|
-
* @param {'left'|'right'|'center'} [align='right'] - Message alignment
|
|
976
|
-
* @param {string} [role='user'] - Role identifier (user, assistant, system)
|
|
977
|
-
* @param {boolean|'smart'} [scrollIntoView=true] - Scroll behavior
|
|
978
|
-
* @param {boolean} [visible=true] - Whether message is initially visible
|
|
979
|
-
* @param {string[]} [tags=[]] - Tags for message categorization
|
|
980
|
-
* @returns {number} Message ID for the newly added message
|
|
981
|
-
* @example
|
|
982
|
-
* // Simple message
|
|
983
|
-
* chat.messageAddNew('Hello!', 'User', 'right');
|
|
984
|
-
*
|
|
985
|
-
* // Bot message with smart scroll
|
|
986
|
-
* chat.messageAddNew('Hi there!', 'Bot', 'left', 'assistant', 'smart');
|
|
987
|
-
*/
|
|
988
538
|
}, {
|
|
989
539
|
key: "messageAddNew",
|
|
990
540
|
value: function messageAddNew() {
|
|
@@ -992,115 +542,125 @@ var quikchat = /*#__PURE__*/function () {
|
|
|
992
542
|
var userString = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "user";
|
|
993
543
|
var align = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "right";
|
|
994
544
|
var role = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : "user";
|
|
995
|
-
|
|
996
|
-
var visible = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;
|
|
997
|
-
var tags = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : [];
|
|
998
|
-
var retvalue = this.messageAddFull({
|
|
545
|
+
return this.messageAddFull({
|
|
999
546
|
content: content,
|
|
1000
547
|
userString: userString,
|
|
1001
548
|
align: align,
|
|
1002
|
-
role: role
|
|
1003
|
-
scrollIntoView: scrollIntoView,
|
|
1004
|
-
visible: visible,
|
|
1005
|
-
tags: tags
|
|
549
|
+
role: role
|
|
1006
550
|
});
|
|
1007
|
-
// this.messageScrollToBottom();
|
|
1008
|
-
return retvalue;
|
|
1009
551
|
}
|
|
1010
|
-
|
|
1011
|
-
/**
|
|
1012
|
-
* Removes a message from the chat by its ID
|
|
1013
|
-
* @param {number} n - Message ID to remove
|
|
1014
|
-
* @returns {boolean} True if message was removed, false if not found
|
|
1015
|
-
* @example
|
|
1016
|
-
* const success = chat.messageRemove(5);
|
|
1017
|
-
*/
|
|
1018
552
|
}, {
|
|
1019
553
|
key: "messageRemove",
|
|
1020
554
|
value: function messageRemove(n) {
|
|
1021
|
-
|
|
1022
|
-
var sucess = false;
|
|
555
|
+
var success = false;
|
|
1023
556
|
try {
|
|
1024
557
|
this._messagesArea.removeChild(this._messagesArea.querySelector(".quikchat-msgid-".concat(String(n).padStart(10, '0'))));
|
|
1025
|
-
|
|
1026
|
-
} catch (
|
|
1027
|
-
|
|
558
|
+
success = true;
|
|
559
|
+
} catch (_error) {
|
|
560
|
+
// Message ID not found
|
|
1028
561
|
}
|
|
1029
|
-
if (
|
|
1030
|
-
// slow way to remove from history
|
|
1031
|
-
//this._history = this._history.filter((item) => item.msgid !== n); // todo make this more efficient
|
|
1032
|
-
|
|
1033
|
-
// better way to delete this from history
|
|
562
|
+
if (success) {
|
|
1034
563
|
this._history.splice(this._history.findIndex(function (item) {
|
|
1035
564
|
return item.msgid === n;
|
|
1036
565
|
}), 1);
|
|
1037
|
-
|
|
1038
|
-
// Call the onMessageDelete callback if it exists
|
|
1039
566
|
if (this._onMessageDelete) {
|
|
1040
567
|
this._onMessageDelete(this, n);
|
|
1041
568
|
}
|
|
1042
569
|
}
|
|
1043
|
-
return
|
|
570
|
+
return success;
|
|
1044
571
|
}
|
|
1045
572
|
/* returns the message html object from the DOM
|
|
1046
573
|
*/
|
|
1047
|
-
/**
|
|
1048
|
-
* Gets the DOM element for a message by its ID
|
|
1049
|
-
* @param {number} n - Message ID
|
|
1050
|
-
* @returns {HTMLElement|null} The message DOM element or null if not found
|
|
1051
|
-
*/
|
|
1052
574
|
}, {
|
|
1053
575
|
key: "messageGetDOMObject",
|
|
1054
576
|
value: function messageGetDOMObject(n) {
|
|
1055
577
|
var msg = null;
|
|
1056
|
-
// now use css selector to get the message
|
|
1057
578
|
try {
|
|
1058
579
|
msg = this._messagesArea.querySelector(".quikchat-msgid-".concat(String(n).padStart(10, '0')));
|
|
1059
|
-
} catch (
|
|
1060
|
-
|
|
580
|
+
} catch (_error) {
|
|
581
|
+
// Message ID not found
|
|
1061
582
|
}
|
|
1062
583
|
return msg;
|
|
1063
584
|
}
|
|
1064
585
|
/* returns the message content only
|
|
1065
586
|
*/
|
|
1066
|
-
/**
|
|
1067
|
-
* Gets the content of a message by its ID
|
|
1068
|
-
* @param {number} n - Message ID
|
|
1069
|
-
* @returns {string} The message content or empty string if not found
|
|
1070
|
-
*/
|
|
1071
587
|
}, {
|
|
1072
588
|
key: "messageGetContent",
|
|
1073
589
|
value: function messageGetContent(n) {
|
|
1074
590
|
var content = "";
|
|
1075
|
-
// now use css selector to get the message
|
|
1076
591
|
try {
|
|
1077
|
-
// get from history..
|
|
1078
592
|
content = this._history.filter(function (item) {
|
|
1079
593
|
return item.msgid === n;
|
|
1080
594
|
})[0].content;
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
console.log("{String(n)} : Message ID not found");
|
|
595
|
+
} catch (_error) {
|
|
596
|
+
// Message ID not found
|
|
1084
597
|
}
|
|
1085
598
|
return content;
|
|
1086
599
|
}
|
|
1087
|
-
|
|
1088
|
-
/* returns the DOM Content element of a given message
|
|
1089
|
-
*/
|
|
1090
600
|
}, {
|
|
1091
|
-
key: "
|
|
1092
|
-
value: function
|
|
1093
|
-
var
|
|
1094
|
-
|
|
601
|
+
key: "messageSetVisible",
|
|
602
|
+
value: function messageSetVisible(n, visible) {
|
|
603
|
+
var msgEl = this.messageGetDOMObject(n);
|
|
604
|
+
if (!msgEl) return false;
|
|
605
|
+
msgEl.style.display = visible ? '' : 'none';
|
|
606
|
+
var item = this._history.find(function (entry) {
|
|
607
|
+
return entry.msgid === n;
|
|
608
|
+
});
|
|
609
|
+
if (item) item.visible = visible;
|
|
610
|
+
return true;
|
|
611
|
+
}
|
|
612
|
+
}, {
|
|
613
|
+
key: "messageGetVisible",
|
|
614
|
+
value: function messageGetVisible(n) {
|
|
615
|
+
var item = this._history.find(function (entry) {
|
|
616
|
+
return entry.msgid === n;
|
|
617
|
+
});
|
|
618
|
+
return item ? item.visible !== false : false;
|
|
619
|
+
}
|
|
620
|
+
}, {
|
|
621
|
+
key: "messageToggleVisible",
|
|
622
|
+
value: function messageToggleVisible(n) {
|
|
623
|
+
var current = this.messageGetVisible(n);
|
|
624
|
+
return this.messageSetVisible(n, !current);
|
|
625
|
+
}
|
|
626
|
+
}, {
|
|
627
|
+
key: "messageSetVisibleByTag",
|
|
628
|
+
value: function messageSetVisibleByTag(tag, visible) {
|
|
629
|
+
var count = 0;
|
|
630
|
+
var _iterator = _createForOfIteratorHelper(this._history),
|
|
631
|
+
_step;
|
|
1095
632
|
try {
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
633
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
634
|
+
var item = _step.value;
|
|
635
|
+
if (item.tags && item.tags.includes(tag)) {
|
|
636
|
+
this.messageSetVisible(item.msgid, visible);
|
|
637
|
+
count++;
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
} catch (err) {
|
|
641
|
+
_iterator.e(err);
|
|
642
|
+
} finally {
|
|
643
|
+
_iterator.f();
|
|
1102
644
|
}
|
|
1103
|
-
return
|
|
645
|
+
return count;
|
|
646
|
+
}
|
|
647
|
+
}, {
|
|
648
|
+
key: "messageGetTags",
|
|
649
|
+
value: function messageGetTags(n) {
|
|
650
|
+
var item = this._history.find(function (entry) {
|
|
651
|
+
return entry.msgid === n;
|
|
652
|
+
});
|
|
653
|
+
return item && item.tags ? item.tags.slice() : [];
|
|
654
|
+
}
|
|
655
|
+
}, {
|
|
656
|
+
key: "messageSetTags",
|
|
657
|
+
value: function messageSetTags(n, tags) {
|
|
658
|
+
var item = this._history.find(function (entry) {
|
|
659
|
+
return entry.msgid === n;
|
|
660
|
+
});
|
|
661
|
+
if (!item) return false;
|
|
662
|
+
item.tags = Array.isArray(tags) ? tags.slice() : [];
|
|
663
|
+
return true;
|
|
1104
664
|
}
|
|
1105
665
|
|
|
1106
666
|
/* append message to the message content
|
|
@@ -1110,41 +670,23 @@ var quikchat = /*#__PURE__*/function () {
|
|
|
1110
670
|
value: function messageAppendContent(n, content) {
|
|
1111
671
|
var success = false;
|
|
1112
672
|
try {
|
|
1113
|
-
|
|
1114
|
-
var item = this._history.filter(function (
|
|
1115
|
-
return
|
|
673
|
+
var msgEl = this._messagesArea.querySelector(".quikchat-msgid-".concat(String(n).padStart(10, '0')));
|
|
674
|
+
var item = this._history.filter(function (entry) {
|
|
675
|
+
return entry.msgid === n;
|
|
1116
676
|
})[0];
|
|
1117
677
|
item.content += content;
|
|
1118
678
|
item.updatedtime = new Date().toISOString();
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
if (this.virtualScroller) {
|
|
1122
|
-
// Find the item index in virtual scroller
|
|
1123
|
-
var index = this.virtualScroller.items.findIndex(function (item) {
|
|
1124
|
-
return item.msgid === n;
|
|
1125
|
-
});
|
|
1126
|
-
if (index >= 0) {
|
|
1127
|
-
this.virtualScroller.items[index].content += content;
|
|
1128
|
-
// Re-render if the item is currently visible
|
|
1129
|
-
this.virtualScroller.updateItem(index, {
|
|
1130
|
-
content: this.virtualScroller.items[index].content
|
|
1131
|
-
});
|
|
1132
|
-
}
|
|
1133
|
-
} else {
|
|
1134
|
-
// Regular DOM manipulation
|
|
1135
|
-
this._messagesArea.querySelector(".quikchat-msgid-".concat(String(n).padStart(10, '0'))).lastChild.innerHTML += content;
|
|
1136
|
-
}
|
|
679
|
+
msgEl.querySelector('.quikchat-message-content').innerHTML = this._processContent(item.content);
|
|
680
|
+
msgEl.classList.remove('quikchat-typing');
|
|
1137
681
|
success = true;
|
|
1138
|
-
|
|
1139
|
-
|
|
682
|
+
if (!this.userScrolledUp) {
|
|
683
|
+
this._messagesArea.scrollTop = this._messagesArea.scrollHeight;
|
|
684
|
+
}
|
|
1140
685
|
if (this._onMessageAppend) {
|
|
1141
686
|
this._onMessageAppend(this, n, content);
|
|
1142
687
|
}
|
|
1143
|
-
|
|
1144
|
-
//
|
|
1145
|
-
// Users can call messageScrollToBottom() if they want to scroll
|
|
1146
|
-
} catch (error) {
|
|
1147
|
-
console.log("".concat(String(n), " : Message ID not found"));
|
|
688
|
+
} catch (_error) {
|
|
689
|
+
// Message ID not found
|
|
1148
690
|
}
|
|
1149
691
|
return success;
|
|
1150
692
|
}
|
|
@@ -1156,405 +698,80 @@ var quikchat = /*#__PURE__*/function () {
|
|
|
1156
698
|
value: function messageReplaceContent(n, content) {
|
|
1157
699
|
var success = false;
|
|
1158
700
|
try {
|
|
1159
|
-
|
|
1160
|
-
var item = this._history.filter(function (
|
|
1161
|
-
return
|
|
701
|
+
var msgEl = this._messagesArea.querySelector(".quikchat-msgid-".concat(String(n).padStart(10, '0')));
|
|
702
|
+
var item = this._history.filter(function (entry) {
|
|
703
|
+
return entry.msgid === n;
|
|
1162
704
|
})[0];
|
|
1163
705
|
item.content = content;
|
|
1164
706
|
item.updatedtime = new Date().toISOString();
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
if (this.virtualScroller) {
|
|
1168
|
-
// Find the item index in virtual scroller
|
|
1169
|
-
var index = this.virtualScroller.items.findIndex(function (item) {
|
|
1170
|
-
return item.msgid === n;
|
|
1171
|
-
});
|
|
1172
|
-
if (index >= 0) {
|
|
1173
|
-
this.virtualScroller.items[index].content = content;
|
|
1174
|
-
// Re-render if the item is currently visible
|
|
1175
|
-
this.virtualScroller.updateItem(index, {
|
|
1176
|
-
content: content
|
|
1177
|
-
});
|
|
1178
|
-
}
|
|
1179
|
-
} else {
|
|
1180
|
-
// Regular DOM manipulation
|
|
1181
|
-
this._messagesArea.querySelector(".quikchat-msgid-".concat(String(n).padStart(10, '0'))).lastChild.innerHTML = content;
|
|
1182
|
-
}
|
|
707
|
+
msgEl.querySelector('.quikchat-message-content').innerHTML = this._processContent(content);
|
|
708
|
+
msgEl.classList.remove('quikchat-typing');
|
|
1183
709
|
success = true;
|
|
1184
|
-
|
|
1185
|
-
|
|
710
|
+
if (!this.userScrolledUp) {
|
|
711
|
+
this._messagesArea.scrollTop = this._messagesArea.scrollHeight;
|
|
712
|
+
}
|
|
1186
713
|
if (this._onMessageReplace) {
|
|
1187
714
|
this._onMessageReplace(this, n, content);
|
|
1188
715
|
}
|
|
1189
|
-
|
|
1190
|
-
//
|
|
1191
|
-
// Users can call messageScrollToBottom() if they want to scroll
|
|
1192
|
-
} catch (error) {
|
|
1193
|
-
console.log("".concat(String(n), " : Message ID not found"));
|
|
716
|
+
} catch (_error) {
|
|
717
|
+
// Message ID not found
|
|
1194
718
|
}
|
|
1195
719
|
return success;
|
|
1196
720
|
}
|
|
1197
|
-
|
|
1198
|
-
/**
|
|
1199
|
-
* Scrolls the messages area to the bottom.
|
|
1200
|
-
*/
|
|
1201
|
-
}, {
|
|
1202
|
-
key: "messageScrollToBottom",
|
|
1203
|
-
value: function messageScrollToBottom() {
|
|
1204
|
-
if (this._messagesArea.lastElementChild) {
|
|
1205
|
-
this._messagesArea.lastElementChild.scrollIntoView();
|
|
1206
|
-
}
|
|
1207
|
-
}
|
|
1208
|
-
|
|
1209
|
-
/**
|
|
1210
|
-
* Removes the last message from the messages area.
|
|
1211
|
-
*/
|
|
1212
|
-
}, {
|
|
1213
|
-
key: "messageRemoveLast",
|
|
1214
|
-
value: function messageRemoveLast() {
|
|
1215
|
-
// find the last message by id:
|
|
1216
|
-
if (this._history.length >= 0) {
|
|
1217
|
-
var lastMsgId = this._history[this._history.length - 1].msgid;
|
|
1218
|
-
return this.messageRemove(lastMsgId);
|
|
1219
|
-
}
|
|
1220
|
-
return false;
|
|
1221
|
-
}
|
|
1222
721
|
}, {
|
|
1223
|
-
key: "
|
|
1224
|
-
value: function
|
|
1225
|
-
var
|
|
1226
|
-
|
|
722
|
+
key: "messageAddTypingIndicator",
|
|
723
|
+
value: function messageAddTypingIndicator() {
|
|
724
|
+
var userString = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
725
|
+
var align = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'left';
|
|
726
|
+
var msgid = this.messageAddFull({
|
|
727
|
+
content: '',
|
|
728
|
+
userString: userString,
|
|
729
|
+
align: align,
|
|
730
|
+
role: 'assistant'
|
|
1227
731
|
});
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
}
|
|
1234
|
-
return false;
|
|
732
|
+
var msgEl = this.messageGetDOMObject(msgid);
|
|
733
|
+
msgEl.classList.add('quikchat-typing');
|
|
734
|
+
var contentDiv = msgEl.querySelector('.quikchat-message-content');
|
|
735
|
+
contentDiv.innerHTML = '<span class="quikchat-typing-dots"><span>.</span><span>.</span><span>.</span></span>';
|
|
736
|
+
return msgid;
|
|
1235
737
|
}
|
|
1236
738
|
}, {
|
|
1237
|
-
key: "
|
|
1238
|
-
value: function
|
|
1239
|
-
|
|
1240
|
-
return item.msgid === msgid;
|
|
1241
|
-
});
|
|
1242
|
-
if (message && message.messageDiv) {
|
|
1243
|
-
return message.messageDiv.style.display !== 'none';
|
|
1244
|
-
}
|
|
1245
|
-
return false; // Return false if not found or no messageDiv
|
|
739
|
+
key: "setMessageFormatter",
|
|
740
|
+
value: function setMessageFormatter(formatter) {
|
|
741
|
+
this._messageFormatter = formatter;
|
|
1246
742
|
}
|
|
1247
743
|
}, {
|
|
1248
|
-
key: "
|
|
1249
|
-
value: function
|
|
1250
|
-
|
|
1251
|
-
return child.style.display !== 'none';
|
|
1252
|
-
});
|
|
1253
|
-
visibleMessages.forEach(function (messageDiv, index) {
|
|
1254
|
-
messageDiv.classList.remove('quikchat-message-1', 'quikchat-message-2');
|
|
1255
|
-
messageDiv.classList.add(index % 2 === 0 ? 'quikchat-message-1' : 'quikchat-message-2');
|
|
1256
|
-
});
|
|
744
|
+
key: "setSanitize",
|
|
745
|
+
value: function setSanitize(sanitize) {
|
|
746
|
+
this._sanitize = sanitize;
|
|
1257
747
|
}
|
|
1258
748
|
|
|
1259
|
-
/**
|
|
1260
|
-
* For right sided or centered messages, we need to handle the CSS for short and long messages.
|
|
1261
|
-
* for short messages we use simple justifying, for long messages we need to wrap and perform multiline
|
|
1262
|
-
* formatting.
|
|
1263
|
-
*
|
|
1264
|
-
* @param {*} messageElement
|
|
1265
|
-
* @returns nothing
|
|
1266
|
-
*/
|
|
1267
|
-
}, {
|
|
1268
|
-
key: "_handleShortLongMessageCSS",
|
|
1269
|
-
value: function _handleShortLongMessageCSS(messageElement, align) {
|
|
1270
|
-
// console.log(messageElement);
|
|
1271
|
-
// Reset classes
|
|
1272
|
-
messageElement.classList.remove('left-singleline', 'left-multiline', 'center-singleline', 'center-multiline', 'right-singleline', 'right-multiline');
|
|
1273
|
-
var contentDiv = messageElement.lastChild;
|
|
1274
|
-
window.lastDiv = contentDiv; // for debugging
|
|
1275
|
-
// Determine if the message is short or long
|
|
1276
|
-
|
|
1277
|
-
var computedStyle = window.getComputedStyle(contentDiv);
|
|
1278
|
-
|
|
1279
|
-
// Get the element's height
|
|
1280
|
-
var elementHeight = contentDiv.offsetHeight;
|
|
1281
|
-
|
|
1282
|
-
// Calculate or estimate line height
|
|
1283
|
-
var lineHeight;
|
|
1284
|
-
if (computedStyle.lineHeight === "normal") {
|
|
1285
|
-
var fontSize = parseFloat(computedStyle.fontSize);
|
|
1286
|
-
lineHeight = fontSize * 1.2; // approximate "normal" as 1.2 times font-size
|
|
1287
|
-
} else {
|
|
1288
|
-
lineHeight = parseFloat(computedStyle.lineHeight);
|
|
1289
|
-
}
|
|
1290
|
-
|
|
1291
|
-
// Check if the element height is more than one line-height
|
|
1292
|
-
var isMultiLine = elementHeight > lineHeight;
|
|
1293
|
-
|
|
1294
|
-
// Using scrollHeight and clientHeight to check for overflow (multi-line)
|
|
1295
|
-
switch (align) {
|
|
1296
|
-
case 'center':
|
|
1297
|
-
if (isMultiLine) {
|
|
1298
|
-
messageElement.classList.add('center-multiline');
|
|
1299
|
-
} else {
|
|
1300
|
-
messageElement.classList.add('center-singleline');
|
|
1301
|
-
}
|
|
1302
|
-
break;
|
|
1303
|
-
case 'right':
|
|
1304
|
-
if (isMultiLine) {
|
|
1305
|
-
messageElement.classList.add('right-multiline');
|
|
1306
|
-
} else {
|
|
1307
|
-
messageElement.classList.add('right-singleline');
|
|
1308
|
-
}
|
|
1309
|
-
break;
|
|
1310
|
-
case 'left':
|
|
1311
|
-
default:
|
|
1312
|
-
if (isMultiLine) {
|
|
1313
|
-
messageElement.classList.add('left-multiline');
|
|
1314
|
-
} else {
|
|
1315
|
-
messageElement.classList.add('left-singleline');
|
|
1316
|
-
}
|
|
1317
|
-
break;
|
|
1318
|
-
}
|
|
1319
|
-
}
|
|
1320
749
|
// history functions
|
|
1321
750
|
/**
|
|
1322
|
-
*
|
|
1323
|
-
* @param {*} n
|
|
1324
|
-
* @param {*} m
|
|
751
|
+
*
|
|
752
|
+
* @param {*} n
|
|
753
|
+
* @param {*} m
|
|
1325
754
|
* @returns array of history messages
|
|
1326
755
|
*/
|
|
1327
|
-
/**
|
|
1328
|
-
* Gets a slice of message history
|
|
1329
|
-
* @param {number} [n] - Start index (defaults to 0)
|
|
1330
|
-
* @param {number} [m] - End index (defaults to history length)
|
|
1331
|
-
* @returns {Array} Array of message objects
|
|
1332
|
-
* @example
|
|
1333
|
-
* // Get first 10 messages
|
|
1334
|
-
* const messages = chat.historyGet(0, 10);
|
|
1335
|
-
*
|
|
1336
|
-
* // Get all messages
|
|
1337
|
-
* const allMessages = chat.historyGet();
|
|
1338
|
-
*/
|
|
1339
756
|
}, {
|
|
1340
757
|
key: "historyGet",
|
|
1341
758
|
value: function historyGet(n, m) {
|
|
1342
|
-
if (n
|
|
1343
|
-
|
|
1344
|
-
m = this._history.length;
|
|
759
|
+
if (n === undefined) {
|
|
760
|
+
return this._history.slice();
|
|
1345
761
|
}
|
|
1346
762
|
if (m === undefined) {
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
// remember that entries could be deleted. TODO: So we need to return the actual history entries
|
|
1350
|
-
// so now we need to find the array index that correspondes to messageIds n (start) and m (end)
|
|
1351
|
-
|
|
1352
|
-
return this._history.slice(n, m);
|
|
1353
|
-
}
|
|
1354
|
-
|
|
1355
|
-
/**
|
|
1356
|
-
* Gets a copy of the entire message history
|
|
1357
|
-
* @returns {Array} Complete array of all message objects
|
|
1358
|
-
* @example
|
|
1359
|
-
* const history = chat.historyGetAllCopy();
|
|
1360
|
-
* console.log(`Total messages: ${history.length}`);
|
|
1361
|
-
*/
|
|
1362
|
-
}, {
|
|
1363
|
-
key: "historyGetAllCopy",
|
|
1364
|
-
value: function historyGetAllCopy() {
|
|
1365
|
-
return this._history.slice();
|
|
1366
|
-
}
|
|
1367
|
-
|
|
1368
|
-
/**
|
|
1369
|
-
* Get a page of history messages with pagination support
|
|
1370
|
-
* @param {number} page - Page number (1-based)
|
|
1371
|
-
* @param {number} pageSize - Number of messages per page (default 50)
|
|
1372
|
-
* @param {string} order - 'asc' for oldest first, 'desc' for newest first (default 'asc')
|
|
1373
|
-
* @returns {object} Object with messages array, pagination info
|
|
1374
|
-
*/
|
|
1375
|
-
}, {
|
|
1376
|
-
key: "historyGetPage",
|
|
1377
|
-
value: function historyGetPage() {
|
|
1378
|
-
var page = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
|
|
1379
|
-
var pageSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 50;
|
|
1380
|
-
var order = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'asc';
|
|
1381
|
-
var totalMessages = this._history.length;
|
|
1382
|
-
var totalPages = Math.ceil(totalMessages / pageSize);
|
|
1383
|
-
var currentPage = Math.max(1, Math.min(page, totalPages || 1));
|
|
1384
|
-
var start, end;
|
|
1385
|
-
if (order === 'desc') {
|
|
1386
|
-
// For descending order, page 1 shows the newest messages
|
|
1387
|
-
start = Math.max(0, totalMessages - currentPage * pageSize);
|
|
1388
|
-
end = totalMessages - (currentPage - 1) * pageSize;
|
|
1389
|
-
} else {
|
|
1390
|
-
// For ascending order, page 1 shows the oldest messages
|
|
1391
|
-
start = (currentPage - 1) * pageSize;
|
|
1392
|
-
end = Math.min(start + pageSize, totalMessages);
|
|
1393
|
-
}
|
|
1394
|
-
var messages = this._history.slice(start, end);
|
|
1395
|
-
|
|
1396
|
-
// Reverse messages array if descending order requested
|
|
1397
|
-
if (order === 'desc') {
|
|
1398
|
-
messages.reverse();
|
|
1399
|
-
}
|
|
1400
|
-
return {
|
|
1401
|
-
messages: messages,
|
|
1402
|
-
pagination: {
|
|
1403
|
-
currentPage: currentPage,
|
|
1404
|
-
pageSize: pageSize,
|
|
1405
|
-
totalPages: totalPages,
|
|
1406
|
-
totalMessages: totalMessages,
|
|
1407
|
-
hasNext: currentPage < totalPages,
|
|
1408
|
-
hasPrevious: currentPage > 1,
|
|
1409
|
-
order: order
|
|
763
|
+
if (n < 0) {
|
|
764
|
+
return this._history.slice(n);
|
|
1410
765
|
}
|
|
1411
|
-
|
|
1412
|
-
}
|
|
1413
|
-
|
|
1414
|
-
/**
|
|
1415
|
-
* Get information about history size and pagination
|
|
1416
|
-
* @param {number} pageSize - Size to calculate pages for (default 50)
|
|
1417
|
-
* @returns {object} History metadata
|
|
1418
|
-
*/
|
|
1419
|
-
/**
|
|
1420
|
-
* Search history for messages matching criteria
|
|
1421
|
-
* @param {object} criteria - Search criteria object
|
|
1422
|
-
* @param {string} criteria.text - Text to search for in message content
|
|
1423
|
-
* @param {string} criteria.userString - Filter by user name
|
|
1424
|
-
* @param {string} criteria.role - Filter by role
|
|
1425
|
-
* @param {array} criteria.tags - Filter by tags (messages with any of these tags)
|
|
1426
|
-
* @param {number} criteria.limit - Maximum results to return (default 100)
|
|
1427
|
-
* @returns {array} Array of matching messages
|
|
1428
|
-
*/
|
|
1429
|
-
/**
|
|
1430
|
-
* Searches through message history with various filters
|
|
1431
|
-
* @param {Object} [criteria={}] - Search criteria
|
|
1432
|
-
* @param {string} [criteria.text] - Text to search for in message content
|
|
1433
|
-
* @param {string} [criteria.userString] - Filter by specific user
|
|
1434
|
-
* @param {string} [criteria.role] - Filter by role (user, assistant, system)
|
|
1435
|
-
* @param {string[]} [criteria.tags] - Filter by tags (messages must have at least one)
|
|
1436
|
-
* @param {number} [criteria.limit=100] - Maximum number of results
|
|
1437
|
-
* @returns {Array} Array of matching messages
|
|
1438
|
-
* @since 1.1.15
|
|
1439
|
-
* @example
|
|
1440
|
-
* // Search for messages containing 'error'
|
|
1441
|
-
* const errors = chat.historySearch({ text: 'error' });
|
|
1442
|
-
*
|
|
1443
|
-
* // Find all bot messages
|
|
1444
|
-
* const botMessages = chat.historySearch({ role: 'assistant' });
|
|
1445
|
-
*
|
|
1446
|
-
* // Complex search
|
|
1447
|
-
* const results = chat.historySearch({
|
|
1448
|
-
* text: 'help',
|
|
1449
|
-
* userString: 'Support',
|
|
1450
|
-
* tags: ['urgent'],
|
|
1451
|
-
* limit: 20
|
|
1452
|
-
* });
|
|
1453
|
-
*/
|
|
1454
|
-
}, {
|
|
1455
|
-
key: "historySearch",
|
|
1456
|
-
value: function historySearch() {
|
|
1457
|
-
var criteria = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1458
|
-
var results = this._history;
|
|
1459
|
-
|
|
1460
|
-
// Filter by text content (case-insensitive)
|
|
1461
|
-
if (criteria.text) {
|
|
1462
|
-
var searchText = criteria.text.toLowerCase();
|
|
1463
|
-
results = results.filter(function (msg) {
|
|
1464
|
-
return msg.content.toLowerCase().includes(searchText);
|
|
1465
|
-
});
|
|
1466
|
-
}
|
|
1467
|
-
|
|
1468
|
-
// Filter by user
|
|
1469
|
-
if (criteria.userString) {
|
|
1470
|
-
results = results.filter(function (msg) {
|
|
1471
|
-
return msg.userString === criteria.userString;
|
|
1472
|
-
});
|
|
766
|
+
return this._history.slice(n, n + 1);
|
|
1473
767
|
}
|
|
1474
|
-
|
|
1475
|
-
// Filter by role
|
|
1476
|
-
if (criteria.role) {
|
|
1477
|
-
results = results.filter(function (msg) {
|
|
1478
|
-
return msg.role === criteria.role;
|
|
1479
|
-
});
|
|
1480
|
-
}
|
|
1481
|
-
|
|
1482
|
-
// Filter by tags (match any tag)
|
|
1483
|
-
if (criteria.tags && criteria.tags.length > 0) {
|
|
1484
|
-
results = results.filter(function (msg) {
|
|
1485
|
-
return msg.tags && msg.tags.some(function (tag) {
|
|
1486
|
-
return criteria.tags.includes(tag);
|
|
1487
|
-
});
|
|
1488
|
-
});
|
|
1489
|
-
}
|
|
1490
|
-
|
|
1491
|
-
// Limit results
|
|
1492
|
-
var limit = criteria.limit || 100;
|
|
1493
|
-
if (results.length > limit) {
|
|
1494
|
-
results = results.slice(0, limit);
|
|
1495
|
-
}
|
|
1496
|
-
return results;
|
|
1497
|
-
}
|
|
1498
|
-
|
|
1499
|
-
/**
|
|
1500
|
-
* Gets metadata and statistics about the message history
|
|
1501
|
-
* @param {number} [pageSize=50] - Page size for calculating total pages
|
|
1502
|
-
* @returns {Object} History information object
|
|
1503
|
-
* @returns {number} returns.totalMessages - Total number of messages
|
|
1504
|
-
* @returns {number} returns.totalPages - Total pages based on page size
|
|
1505
|
-
* @returns {Object|null} returns.oldestMessage - First message info
|
|
1506
|
-
* @returns {Object|null} returns.newestMessage - Last message info
|
|
1507
|
-
* @returns {Object} returns.memoryUsage - Memory usage statistics
|
|
1508
|
-
* @since 1.1.15
|
|
1509
|
-
* @example
|
|
1510
|
-
* const info = chat.historyGetInfo();
|
|
1511
|
-
* console.log(`Messages: ${info.totalMessages}`);
|
|
1512
|
-
* console.log(`Memory: ${info.memoryUsage.estimatedSize} bytes`);
|
|
1513
|
-
*/
|
|
1514
|
-
}, {
|
|
1515
|
-
key: "historyGetInfo",
|
|
1516
|
-
value: function historyGetInfo() {
|
|
1517
|
-
var pageSize = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 50;
|
|
1518
|
-
var totalMessages = this._history.length;
|
|
1519
|
-
return {
|
|
1520
|
-
totalMessages: totalMessages,
|
|
1521
|
-
totalPages: Math.ceil(totalMessages / pageSize),
|
|
1522
|
-
oldestMessage: totalMessages > 0 ? {
|
|
1523
|
-
msgid: this._history[0].msgid,
|
|
1524
|
-
timestamp: this._history[0].timestamp,
|
|
1525
|
-
userString: this._history[0].userString
|
|
1526
|
-
} : null,
|
|
1527
|
-
newestMessage: totalMessages > 0 ? {
|
|
1528
|
-
msgid: this._history[totalMessages - 1].msgid,
|
|
1529
|
-
timestamp: this._history[totalMessages - 1].timestamp,
|
|
1530
|
-
userString: this._history[totalMessages - 1].userString
|
|
1531
|
-
} : null,
|
|
1532
|
-
memoryUsage: {
|
|
1533
|
-
estimatedSize: JSON.stringify(this._history).length,
|
|
1534
|
-
averageMessageSize: totalMessages > 0 ? Math.round(JSON.stringify(this._history).length / totalMessages) : 0
|
|
1535
|
-
}
|
|
1536
|
-
};
|
|
768
|
+
return this._history.slice(n, m);
|
|
1537
769
|
}
|
|
1538
|
-
|
|
1539
|
-
/**
|
|
1540
|
-
* Clears all messages and resets the chat
|
|
1541
|
-
* @returns {void}
|
|
1542
|
-
* @example
|
|
1543
|
-
* chat.historyClear(); // Removes all messages
|
|
1544
|
-
*/
|
|
1545
770
|
}, {
|
|
1546
771
|
key: "historyClear",
|
|
1547
772
|
value: function historyClear() {
|
|
1548
773
|
this.msgid = 0;
|
|
1549
|
-
|
|
1550
|
-
// Handle virtual scroller
|
|
1551
|
-
if (this.virtualScroller) {
|
|
1552
|
-
this.virtualScroller.clear();
|
|
1553
|
-
} else {
|
|
1554
|
-
this._messagesArea.innerHTML = "";
|
|
1555
|
-
}
|
|
1556
774
|
this._history = [];
|
|
1557
|
-
this._activeTags.clear();
|
|
1558
775
|
}
|
|
1559
776
|
}, {
|
|
1560
777
|
key: "historyGetLength",
|
|
@@ -1572,29 +789,57 @@ var quikchat = /*#__PURE__*/function () {
|
|
|
1572
789
|
}, {
|
|
1573
790
|
key: "historyGetMessageContent",
|
|
1574
791
|
value: function historyGetMessageContent(n) {
|
|
1575
|
-
if (n >= 0 && n < this._history.length)
|
|
792
|
+
if (n >= 0 && n < this._history.length) {
|
|
793
|
+
return this._history[n].content;
|
|
794
|
+
}
|
|
795
|
+
return "";
|
|
1576
796
|
}
|
|
1577
|
-
|
|
1578
|
-
// expects an array of messages to be in the format of the history object
|
|
1579
797
|
}, {
|
|
1580
|
-
key: "
|
|
1581
|
-
value: function
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
798
|
+
key: "historyExport",
|
|
799
|
+
value: function historyExport() {
|
|
800
|
+
return this._history.map(function (item) {
|
|
801
|
+
return {
|
|
802
|
+
msgid: item.msgid,
|
|
803
|
+
content: item.content,
|
|
804
|
+
userString: item.userString,
|
|
805
|
+
align: item.align,
|
|
806
|
+
role: item.role,
|
|
807
|
+
userID: item.userID,
|
|
808
|
+
visible: item.visible,
|
|
809
|
+
tags: item.tags ? item.tags.slice() : [],
|
|
810
|
+
timestamp: item.timestamp,
|
|
811
|
+
updatedtime: item.updatedtime
|
|
812
|
+
};
|
|
1592
813
|
});
|
|
1593
814
|
}
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
815
|
+
}, {
|
|
816
|
+
key: "historyImport",
|
|
817
|
+
value: function historyImport(data) {
|
|
818
|
+
// Clear existing messages from DOM and history
|
|
819
|
+
this._messagesArea.innerHTML = '';
|
|
820
|
+
this._history = [];
|
|
821
|
+
this.msgid = 0;
|
|
822
|
+
var _iterator2 = _createForOfIteratorHelper(data),
|
|
823
|
+
_step2;
|
|
824
|
+
try {
|
|
825
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
826
|
+
var entry = _step2.value;
|
|
827
|
+
this.messageAddFull({
|
|
828
|
+
content: entry.content || '',
|
|
829
|
+
userString: entry.userString || 'user',
|
|
830
|
+
align: entry.align || 'right',
|
|
831
|
+
role: entry.role || 'user',
|
|
832
|
+
userID: entry.userID,
|
|
833
|
+
visible: entry.visible,
|
|
834
|
+
tags: entry.tags
|
|
835
|
+
});
|
|
836
|
+
}
|
|
837
|
+
} catch (err) {
|
|
838
|
+
_iterator2.e(err);
|
|
839
|
+
} finally {
|
|
840
|
+
_iterator2.f();
|
|
841
|
+
}
|
|
842
|
+
}
|
|
1598
843
|
}, {
|
|
1599
844
|
key: "changeTheme",
|
|
1600
845
|
value: function changeTheme(newTheme) {
|
|
@@ -1602,164 +847,38 @@ var quikchat = /*#__PURE__*/function () {
|
|
|
1602
847
|
this._chatWidget.classList.add(newTheme);
|
|
1603
848
|
this._theme = newTheme;
|
|
1604
849
|
}
|
|
1605
|
-
|
|
1606
|
-
/**
|
|
1607
|
-
* Get the current theme
|
|
1608
|
-
* @returns {string} - The current theme
|
|
1609
|
-
*/
|
|
1610
850
|
}, {
|
|
1611
851
|
key: "theme",
|
|
1612
852
|
get: function get() {
|
|
1613
853
|
return this._theme;
|
|
1614
854
|
}
|
|
1615
|
-
|
|
1616
|
-
/**
|
|
1617
|
-
*
|
|
1618
|
-
* @returns {object} - Returns the version and license information for the library.
|
|
1619
|
-
*/
|
|
1620
|
-
/**
|
|
1621
|
-
* Gets the QuikChat version information
|
|
1622
|
-
* @static
|
|
1623
|
-
* @returns {Object} Version information object
|
|
1624
|
-
* @returns {string} returns.version - Version number (e.g., '1.1.15')
|
|
1625
|
-
* @returns {string} returns.license - License type (e.g., 'BSD-2')
|
|
1626
|
-
* @returns {string} returns.url - Project URL
|
|
1627
|
-
* @returns {boolean} returns.fun - Easter egg flag
|
|
1628
|
-
* @example
|
|
1629
|
-
* const version = quikchat.version();
|
|
1630
|
-
* console.log(`QuikChat v${version.version}`);
|
|
1631
|
-
*/
|
|
1632
|
-
}, {
|
|
1633
|
-
key: "setTagVisibility",
|
|
1634
|
-
value:
|
|
1635
|
-
/**
|
|
1636
|
-
* Sets visibility for all messages with a specific tag
|
|
1637
|
-
* @param {string} tagName - Tag name to control
|
|
1638
|
-
* @param {boolean} isVisible - Whether to show or hide messages with this tag
|
|
1639
|
-
* @returns {boolean} True if successful, false if invalid tag name
|
|
1640
|
-
* @since 1.1.14
|
|
1641
|
-
* @example
|
|
1642
|
-
* // Hide all system messages
|
|
1643
|
-
* chat.setTagVisibility('system', false);
|
|
1644
|
-
*
|
|
1645
|
-
* // Show urgent messages
|
|
1646
|
-
* chat.setTagVisibility('urgent', true);
|
|
1647
|
-
*/
|
|
1648
|
-
function setTagVisibility(tagName, isVisible) {
|
|
1649
|
-
if (typeof tagName !== 'string' || !/^[a-zA-Z0-9-]+$/.test(tagName)) {
|
|
1650
|
-
return false;
|
|
1651
|
-
}
|
|
1652
|
-
var className = "quikchat-show-tag-".concat(tagName);
|
|
1653
|
-
if (isVisible) {
|
|
1654
|
-
this._chatWidget.classList.add(className);
|
|
1655
|
-
} else {
|
|
1656
|
-
this._chatWidget.classList.remove(className);
|
|
1657
|
-
}
|
|
1658
|
-
this._updateMessageStyles();
|
|
1659
|
-
return true;
|
|
1660
|
-
}
|
|
1661
|
-
|
|
1662
|
-
/**
|
|
1663
|
-
* Gets the visibility state of a tag
|
|
1664
|
-
* @param {string} tagName - Tag name to check
|
|
1665
|
-
* @returns {boolean} True if tag is visible, false otherwise
|
|
1666
|
-
* @since 1.1.14
|
|
1667
|
-
* @example
|
|
1668
|
-
* const isVisible = chat.getTagVisibility('system');
|
|
1669
|
-
*/
|
|
1670
|
-
}, {
|
|
1671
|
-
key: "getTagVisibility",
|
|
1672
|
-
value: function getTagVisibility(tagName) {
|
|
1673
|
-
if (typeof tagName !== 'string' || !/^[a-zA-Z0-9-]+$/.test(tagName)) {
|
|
1674
|
-
return false;
|
|
1675
|
-
}
|
|
1676
|
-
return this._chatWidget.classList.contains("quikchat-show-tag-".concat(tagName));
|
|
1677
|
-
}
|
|
1678
|
-
|
|
1679
|
-
/**
|
|
1680
|
-
* Gets all active tags in the chat
|
|
1681
|
-
* @returns {string[]} Array of all tags currently in use
|
|
1682
|
-
* @since 1.1.14
|
|
1683
|
-
* @example
|
|
1684
|
-
* const tags = chat.getActiveTags();
|
|
1685
|
-
* console.log('Active tags:', tags);
|
|
1686
|
-
*/
|
|
1687
|
-
}, {
|
|
1688
|
-
key: "getActiveTags",
|
|
1689
|
-
value: function getActiveTags() {
|
|
1690
|
-
return Array.from(this._activeTags);
|
|
1691
|
-
}
|
|
1692
|
-
|
|
1693
|
-
/**
|
|
1694
|
-
* Checks if virtual scrolling is currently enabled
|
|
1695
|
-
* @returns {boolean} True if virtual scrolling is enabled, false otherwise
|
|
1696
|
-
* @since 1.1.16
|
|
1697
|
-
* @example
|
|
1698
|
-
* if (chat.isVirtualScrollingEnabled()) {
|
|
1699
|
-
* console.log('Virtual scrolling is active');
|
|
1700
|
-
* }
|
|
1701
|
-
*/
|
|
1702
|
-
}, {
|
|
1703
|
-
key: "isVirtualScrollingEnabled",
|
|
1704
|
-
value: function isVirtualScrollingEnabled() {
|
|
1705
|
-
return this.virtualScrollingEnabled && this.virtualScroller !== null;
|
|
1706
|
-
}
|
|
1707
|
-
|
|
1708
|
-
/**
|
|
1709
|
-
* Gets the virtual scrolling configuration
|
|
1710
|
-
* @returns {Object} Virtual scrolling configuration with enabled status and threshold
|
|
1711
|
-
* @since 1.1.16
|
|
1712
|
-
* @example
|
|
1713
|
-
* const config = chat.getVirtualScrollingConfig();
|
|
1714
|
-
* console.log(`Virtual scrolling: ${config.enabled}, threshold: ${config.threshold}`);
|
|
1715
|
-
*/
|
|
1716
|
-
}, {
|
|
1717
|
-
key: "getVirtualScrollingConfig",
|
|
1718
|
-
value: function getVirtualScrollingConfig() {
|
|
1719
|
-
return {
|
|
1720
|
-
enabled: this.virtualScrollingEnabled,
|
|
1721
|
-
active: this.virtualScroller !== null,
|
|
1722
|
-
threshold: this.virtualScrollingThreshold
|
|
1723
|
-
};
|
|
1724
|
-
}
|
|
1725
855
|
}], [{
|
|
1726
856
|
key: "version",
|
|
1727
857
|
value: function version() {
|
|
1728
|
-
return
|
|
858
|
+
return {
|
|
859
|
+
"version": "1.2.4",
|
|
860
|
+
"license": "BSD-2",
|
|
861
|
+
"url": "https://github/deftio/quikchat"
|
|
862
|
+
};
|
|
1729
863
|
}
|
|
1730
864
|
|
|
1731
865
|
/**
|
|
1732
866
|
* quikchat.loremIpsum() - Generate a simple string of Lorem Ipsum text (sample typographer's text) of numChars in length.
|
|
1733
867
|
* borrowed from github.com/deftio/bitwrench.js
|
|
1734
|
-
* @param {number} numChars - The number of characters to generate (random btw 25 and 150 if undefined).
|
|
868
|
+
* @param {number} numChars - The number of characters to generate (random btw 25 and 150 if undefined).
|
|
1735
869
|
* @param {number} [startSpot=0] - The starting index in the Lorem Ipsum text. If undefined, a random startSpot will be generated.
|
|
1736
870
|
* @param {boolean} [startWithCapitalLetter=true] - If true, capitalize the first character or inject a capital letter if the first character isn't a capital letter.
|
|
1737
|
-
*
|
|
871
|
+
*
|
|
1738
872
|
* @returns {string} A string of Lorem Ipsum text.
|
|
1739
|
-
*
|
|
1740
|
-
* @example
|
|
873
|
+
*
|
|
874
|
+
* @example
|
|
1741
875
|
* // Returns 200 characters of Lorem Ipsum starting from index 50
|
|
1742
876
|
* loremIpsum(200, 50);
|
|
1743
|
-
*
|
|
1744
|
-
* @example
|
|
877
|
+
*
|
|
878
|
+
* @example
|
|
1745
879
|
* //Returns a 200 Lorem Ipsum characters starting from a random index
|
|
1746
880
|
* loremIpsum(200);
|
|
1747
881
|
*/
|
|
1748
|
-
|
|
1749
|
-
/**
|
|
1750
|
-
* Generates Lorem Ipsum placeholder text
|
|
1751
|
-
* @static
|
|
1752
|
-
* @param {number} [numChars] - Length of text to generate (random if not specified)
|
|
1753
|
-
* @param {number} [startSpot] - Starting offset in Lorem text (random if not specified)
|
|
1754
|
-
* @param {boolean} [startWithCapitalLetter=true] - Whether to capitalize first letter
|
|
1755
|
-
* @returns {string} Generated Lorem Ipsum text
|
|
1756
|
-
* @example
|
|
1757
|
-
* // Generate 100 characters
|
|
1758
|
-
* const text = quikchat.loremIpsum(100);
|
|
1759
|
-
*
|
|
1760
|
-
* // Generate random length
|
|
1761
|
-
* const randomText = quikchat.loremIpsum();
|
|
1762
|
-
*/
|
|
1763
882
|
}, {
|
|
1764
883
|
key: "loremIpsum",
|
|
1765
884
|
value: function loremIpsum(numChars) {
|
|
@@ -1767,7 +886,7 @@ var quikchat = /*#__PURE__*/function () {
|
|
|
1767
886
|
var startWithCapitalLetter = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
1768
887
|
var loremText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. ";
|
|
1769
888
|
if (typeof numChars !== "number") {
|
|
1770
|
-
numChars = Math.floor(Math.random() *
|
|
889
|
+
numChars = Math.floor(Math.random() * 126) + 25;
|
|
1771
890
|
}
|
|
1772
891
|
if (startSpot === undefined) {
|
|
1773
892
|
startSpot = Math.floor(Math.random() * loremText.length);
|
|
@@ -1779,9 +898,6 @@ var quikchat = /*#__PURE__*/function () {
|
|
|
1779
898
|
startSpot = (startSpot + 1) % loremText.length;
|
|
1780
899
|
}
|
|
1781
900
|
var l = loremText.substring(startSpot) + loremText.substring(0, startSpot);
|
|
1782
|
-
if (typeof numChars !== "number") {
|
|
1783
|
-
numChars = l.length;
|
|
1784
|
-
}
|
|
1785
901
|
var s = "";
|
|
1786
902
|
while (numChars > 0) {
|
|
1787
903
|
s += numChars < l.length ? l.substring(0, numChars) : l;
|
|
@@ -1791,98 +907,10 @@ var quikchat = /*#__PURE__*/function () {
|
|
|
1791
907
|
s = s.substring(0, s.length - 1) + "."; // always end on non-whitespace. "." was chosen arbitrarily.
|
|
1792
908
|
}
|
|
1793
909
|
if (startWithCapitalLetter) {
|
|
1794
|
-
|
|
1795
|
-
c = /[A-Z]/.test(c) ? c : "M";
|
|
1796
|
-
s = c + s.substring(1);
|
|
910
|
+
s = s[0].toUpperCase() + s.substring(1);
|
|
1797
911
|
}
|
|
1798
912
|
return s;
|
|
1799
913
|
}
|
|
1800
|
-
}, {
|
|
1801
|
-
key: "tempMessageGenerator",
|
|
1802
|
-
value:
|
|
1803
|
-
/**
|
|
1804
|
-
* Creates a temporary message that updates periodically
|
|
1805
|
-
* @static
|
|
1806
|
-
* @param {string|HTMLElement} domElement - Element selector or DOM element
|
|
1807
|
-
* @param {string} content - Initial message content
|
|
1808
|
-
* @param {number} interval - Update interval in milliseconds (min 100ms)
|
|
1809
|
-
* @param {Function} [cb=null] - Callback to generate new content
|
|
1810
|
-
* @param {string} cb.message - Current message
|
|
1811
|
-
* @param {number} cb.count - Update count
|
|
1812
|
-
* @returns {void}
|
|
1813
|
-
* @example
|
|
1814
|
-
* // Simple loading indicator
|
|
1815
|
-
* quikchat.tempMessageGenerator('#loading', 'Loading', 500);
|
|
1816
|
-
*
|
|
1817
|
-
* // Custom update function
|
|
1818
|
-
* quikchat.tempMessageGenerator('#status', 'Processing', 1000, (msg, count) => {
|
|
1819
|
-
* return `Processing... ${count}%`;
|
|
1820
|
-
* });
|
|
1821
|
-
*/
|
|
1822
|
-
function tempMessageGenerator(domElement, content, interval) {
|
|
1823
|
-
var cb = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
1824
|
-
interval = Math.max(interval, 100); // Ensure at least 100ms interval
|
|
1825
|
-
|
|
1826
|
-
var count = 0;
|
|
1827
|
-
var defaultCB = function defaultCB(msg, count) {
|
|
1828
|
-
msg += ".";
|
|
1829
|
-
return msg;
|
|
1830
|
-
};
|
|
1831
|
-
if (cb && typeof cb !== 'function') {
|
|
1832
|
-
cb = null;
|
|
1833
|
-
}
|
|
1834
|
-
cb = cb || defaultCB;
|
|
1835
|
-
|
|
1836
|
-
// if its a string, then get the element (css sel) or its an DOM element already
|
|
1837
|
-
var el = domElement;
|
|
1838
|
-
if (typeof el === 'string') {
|
|
1839
|
-
el = document.querySelector(el);
|
|
1840
|
-
}
|
|
1841
|
-
var element = el;
|
|
1842
|
-
|
|
1843
|
-
// Ensure the element exists
|
|
1844
|
-
if (!element) return;
|
|
1845
|
-
element.innerHTML = content;
|
|
1846
|
-
var currentMsg = content;
|
|
1847
|
-
var intervalId = setInterval(function () {
|
|
1848
|
-
if (element.innerHTML !== currentMsg) {
|
|
1849
|
-
clearInterval(intervalId); // Stop updating if content is changed externally
|
|
1850
|
-
return;
|
|
1851
|
-
}
|
|
1852
|
-
currentMsg = String(cb(currentMsg, count)); // Use callback return value if provided
|
|
1853
|
-
|
|
1854
|
-
count++;
|
|
1855
|
-
element.innerHTML = currentMsg;
|
|
1856
|
-
}, interval);
|
|
1857
|
-
}
|
|
1858
|
-
}, {
|
|
1859
|
-
key: "createTempMessageDOMStr",
|
|
1860
|
-
value: function createTempMessageDOMStr(initialContent) {
|
|
1861
|
-
var updateInterval = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1000;
|
|
1862
|
-
var callback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
1863
|
-
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
1864
|
-
// Make sure the interval is at least 100ms
|
|
1865
|
-
updateInterval = Math.max(updateInterval, 100);
|
|
1866
|
-
|
|
1867
|
-
// Validate callback; if not a function, ignore it.
|
|
1868
|
-
if (callback && typeof callback !== 'function') {
|
|
1869
|
-
callback = null;
|
|
1870
|
-
}
|
|
1871
|
-
// Default callback simply appends a dot.
|
|
1872
|
-
callback = callback || function (msg, count) {
|
|
1873
|
-
return msg + ".";
|
|
1874
|
-
};
|
|
1875
|
-
|
|
1876
|
-
// Allow an optional CSS class for the container element
|
|
1877
|
-
var containerClass = options.containerClass ? options.containerClass : '';
|
|
1878
|
-
|
|
1879
|
-
// Generate a unique id so that the inline script can reliably find the container.
|
|
1880
|
-
var uniqueId = "tempMsg_" + Date.now() + "_" + Math.floor(Math.random() * 1000000);
|
|
1881
|
-
|
|
1882
|
-
// Build and return the HTML string.
|
|
1883
|
-
// Note the use of <\/script> (with a backslash) so that the inline script is not terminated early.
|
|
1884
|
-
return "\n <span id=\"".concat(uniqueId, "\" ").concat(containerClass ? "class=\"".concat(containerClass, "\"") : '', ">\n ").concat(initialContent, "\n </span>\n <script>\n (function(){\n // Get our container element by its unique id.\n var container = document.getElementById(\"").concat(uniqueId, "\");\n if (!container) return;\n var count = 0;\n var currentMsg = container.innerHTML;\n var interval = ").concat(updateInterval, ";\n // Convert the callback function into its string representation.\n var cb = ").concat(callback.toString(), ";\n var intervalId = setInterval(function(){\n // If the content has been replaced, stop updating.\n if(container.innerHTML !== currentMsg){\n clearInterval(intervalId);\n return;\n }\n // Use the callback to generate the new message.\n currentMsg = String(cb(currentMsg, count));\n count++;\n container.innerHTML = currentMsg;\n }, interval);\n })();\n </script>\n ");
|
|
1885
|
-
}
|
|
1886
914
|
}]);
|
|
1887
915
|
}();
|
|
1888
916
|
|