quikchat 1.1.13 → 1.1.15

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.
@@ -86,11 +86,55 @@
86
86
  }
87
87
  }
88
88
 
89
+ // Auto-generated version file - DO NOT EDIT MANUALLY
90
+ // This file is automatically updated by tools/updateVersion.js
91
+
92
+ var quikchatVersion = {
93
+ version: "1.1.15",
94
+ license: "BSD-2",
95
+ url: "https://github/deftio/quikchat",
96
+ fun: true
97
+ };
98
+
99
+ /**
100
+ * QuikChat - A zero-dependency JavaScript chat widget for modern web applications
101
+ * @class quikchat
102
+ * @version 1.1.15
103
+ */
89
104
  var quikchat = /*#__PURE__*/function () {
90
105
  /**
106
+ * Creates a new QuikChat instance
107
+ * @constructor
108
+ * @param {string|HTMLElement} parentElement - CSS selector or DOM element to attach the chat widget to
109
+ * @param {Function} [onSend] - Callback function triggered when user sends a message
110
+ * @param {Object} [options] - Configuration options
111
+ * @param {string} [options.theme='quikchat-theme-light'] - CSS theme class name
112
+ * @param {boolean} [options.trackHistory=true] - Whether to track message history
113
+ * @param {Object} [options.titleArea] - Title area configuration
114
+ * @param {string} [options.titleArea.title='Chat'] - Title text/HTML
115
+ * @param {boolean} [options.titleArea.show=false] - Whether to show title area initially
116
+ * @param {'left'|'center'|'right'} [options.titleArea.align='center'] - Title alignment
117
+ * @param {Object} [options.messagesArea] - Messages area configuration
118
+ * @param {boolean} [options.messagesArea.alternating=true] - Alternate message colors
119
+ * @param {Object} [options.inputArea] - Input area configuration
120
+ * @param {boolean} [options.inputArea.show=true] - Whether to show input area initially
121
+ * @param {boolean} [options.sendOnEnter=true] - Send message on Enter key
122
+ * @param {boolean} [options.sendOnShiftEnter=false] - Send message on Shift+Enter
123
+ * @param {string} [options.instanceClass=''] - Additional CSS class for the widget instance
124
+ * @example
125
+ * // Basic usage
126
+ * const chat = new quikchat('#chat-container', (instance, message) => {
127
+ * console.log('User sent:', message);
128
+ * });
91
129
  *
92
- * @param string or DOM element parentElement
93
- * @param {*} meta
130
+ * @example
131
+ * // With options
132
+ * const chat = new quikchat('#chat', handleMessage, {
133
+ * theme: 'quikchat-theme-dark',
134
+ * titleArea: { title: 'Support Chat', show: true },
135
+ * sendOnEnter: false,
136
+ * sendOnShiftEnter: true
137
+ * });
94
138
  */
95
139
  function quikchat(parentElement) {
96
140
  var onSend = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
@@ -111,7 +155,8 @@
111
155
  show: true
112
156
  },
113
157
  sendOnEnter: true,
114
- sendOnShiftEnter: false
158
+ sendOnShiftEnter: false,
159
+ instanceClass: ''
115
160
  };
116
161
  var meta = _objectSpread2(_objectSpread2({}, defaultOpts), options); // merge options with defaults
117
162
 
@@ -123,6 +168,10 @@
123
168
  this._theme = meta.theme;
124
169
  this._onSend = onSend ? onSend : function () {}; // call back function for onSend
125
170
  this._createWidget();
171
+ if (meta.instanceClass) {
172
+ this._chatWidget.classList.add(meta.instanceClass);
173
+ }
174
+
126
175
  // title area
127
176
  if (meta.titleArea) {
128
177
  this.titleAreaSetContents(meta.titleArea.title, meta.titleArea.align);
@@ -146,6 +195,7 @@
146
195
  this.trackHistory = meta.trackHistory || true;
147
196
  this._historyLimit = 10000000;
148
197
  this._history = [];
198
+ this._activeTags = new Set();
149
199
 
150
200
  // send on enter / shift enter
151
201
  this.sendOnEnter = meta.sendOnEnter;
@@ -220,24 +270,100 @@
220
270
  this._onMessageAdded = callback;
221
271
  }
222
272
 
273
+ /**
274
+ * Sets the callback function for when content is appended to a message
275
+ * @param {Function} callback - Function to call when content is appended
276
+ * @param {quikchat} callback.instance - The QuikChat instance
277
+ * @param {number} callback.msgId - The ID of the message being appended to
278
+ * @param {string} callback.content - The content being appended
279
+ * @since 1.1.15
280
+ * @example
281
+ * chat.setCallbackonMessageAppend((instance, msgId, content) => {
282
+ * console.log(`Appended "${content}" to message ${msgId}`);
283
+ * });
284
+ */
285
+ }, {
286
+ key: "setCallbackonMessageAppend",
287
+ value: function setCallbackonMessageAppend(callback) {
288
+ this._onMessageAppend = callback;
289
+ }
290
+
291
+ /**
292
+ * Sets the callback function for when a message's content is replaced
293
+ * @param {Function} callback - Function to call when content is replaced
294
+ * @param {quikchat} callback.instance - The QuikChat instance
295
+ * @param {number} callback.msgId - The ID of the message being replaced
296
+ * @param {string} callback.content - The new content
297
+ * @since 1.1.15
298
+ * @example
299
+ * chat.setCallbackonMessageReplace((instance, msgId, content) => {
300
+ * console.log(`Message ${msgId} replaced with: ${content}`);
301
+ * });
302
+ */
303
+ }, {
304
+ key: "setCallbackonMessageReplace",
305
+ value: function setCallbackonMessageReplace(callback) {
306
+ this._onMessageReplace = callback;
307
+ }
308
+
309
+ /**
310
+ * Sets the callback function for when a message is deleted
311
+ * @param {Function} callback - Function to call when a message is deleted
312
+ * @param {quikchat} callback.instance - The QuikChat instance
313
+ * @param {number} callback.msgId - The ID of the deleted message
314
+ * @since 1.1.15
315
+ * @example
316
+ * chat.setCallbackonMessageDelete((instance, msgId) => {
317
+ * console.log(`Message ${msgId} was deleted`);
318
+ * });
319
+ */
320
+ }, {
321
+ key: "setCallbackonMessageDelete",
322
+ value: function setCallbackonMessageDelete(callback) {
323
+ this._onMessageDelete = callback;
324
+ }
325
+
223
326
  // Public methods
327
+ /**
328
+ * Toggles the visibility of the title area
329
+ * @returns {void}
330
+ */
224
331
  }, {
225
332
  key: "titleAreaToggle",
226
333
  value: function titleAreaToggle() {
227
334
  this._titleArea.style.display === 'none' ? this.titleAreaShow() : this.titleAreaHide();
228
335
  }
336
+
337
+ /**
338
+ * Shows the title area
339
+ * @returns {void}
340
+ */
229
341
  }, {
230
342
  key: "titleAreaShow",
231
343
  value: function titleAreaShow() {
232
344
  this._titleArea.style.display = '';
233
345
  this._adjustMessagesAreaHeight();
234
346
  }
347
+
348
+ /**
349
+ * Hides the title area
350
+ * @returns {void}
351
+ */
235
352
  }, {
236
353
  key: "titleAreaHide",
237
354
  value: function titleAreaHide() {
238
355
  this._titleArea.style.display = 'none';
239
356
  this._adjustMessagesAreaHeight();
240
357
  }
358
+
359
+ /**
360
+ * Sets the contents of the title area
361
+ * @param {string} title - HTML content to display in the title area
362
+ * @param {'left'|'center'|'right'} [align='center'] - Text alignment
363
+ * @returns {void}
364
+ * @example
365
+ * chat.titleAreaSetContents('<h2>Support Chat</h2>', 'center');
366
+ */
241
367
  }, {
242
368
  key: "titleAreaSetContents",
243
369
  value: function titleAreaSetContents(title) {
@@ -245,6 +371,11 @@
245
371
  this._titleArea.innerHTML = title;
246
372
  this._titleArea.style.textAlign = align;
247
373
  }
374
+
375
+ /**
376
+ * Gets the current contents of the title area
377
+ * @returns {string} The HTML content of the title area
378
+ */
248
379
  }, {
249
380
  key: "titleAreaGetContents",
250
381
  value: function titleAreaGetContents() {
@@ -319,10 +450,33 @@
319
450
  value: function messagesAreaAlternateColorsGet() {
320
451
  return this._messagesArea.classList.contains('quikchat-messages-area-alt');
321
452
  }
322
- // message functions
453
+ /**
454
+ * Adds a new message to the chat with full configuration options
455
+ * @param {Object} input - Message configuration object
456
+ * @param {string} [input.content=''] - Message content (HTML allowed)
457
+ * @param {string} [input.userString='user'] - Display name for the message sender
458
+ * @param {'left'|'right'|'center'} [input.align='right'] - Message alignment
459
+ * @param {string} [input.role='user'] - Role identifier (user, assistant, system)
460
+ * @param {number} [input.userID=-1] - User ID for the message
461
+ * @param {string|false} [input.timestamp=false] - ISO timestamp or false for auto
462
+ * @param {string|false} [input.updatedtime=false] - Last updated timestamp
463
+ * @param {boolean|'smart'} [input.scrollIntoView=true] - Scroll behavior (true/false/'smart')
464
+ * @param {boolean} [input.visible=true] - Whether message is initially visible
465
+ * @param {string[]} [input.tags=[]] - Tags for message categorization
466
+ * @returns {number} Message ID for the newly added message
467
+ * @example
468
+ * const msgId = chat.messageAddFull({
469
+ * content: 'Hello!',
470
+ * userString: 'Bot',
471
+ * align: 'left',
472
+ * scrollIntoView: 'smart',
473
+ * tags: ['greeting']
474
+ * });
475
+ */
323
476
  }, {
324
477
  key: "messageAddFull",
325
478
  value: function messageAddFull() {
479
+ var _this2 = this;
326
480
  var input = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
327
481
  content: "",
328
482
  userString: "user",
@@ -332,13 +486,22 @@
332
486
  timestamp: false,
333
487
  updatedtime: false,
334
488
  scrollIntoView: true,
335
- visible: true
489
+ visible: true,
490
+ tags: []
336
491
  };
337
492
  var msgid = this.msgid;
338
493
  var messageDiv = document.createElement('div');
339
494
  var msgidClass = 'quikchat-msgid-' + String(msgid).padStart(10, '0');
340
495
  'quikchat-userid-' + String(input.userString).padStart(10, '0'); // hash this..
341
496
  messageDiv.classList.add('quikchat-message', msgidClass, 'quikchat-structure');
497
+ if (Array.isArray(input.tags)) {
498
+ input.tags.forEach(function (tag) {
499
+ if (typeof tag === 'string' && /^[a-zA-Z0-9-]+$/.test(tag)) {
500
+ messageDiv.classList.add("quikchat-tag-".concat(tag));
501
+ _this2._activeTags.add(tag);
502
+ }
503
+ });
504
+ }
342
505
  this.msgid++;
343
506
  var userDiv = document.createElement('div');
344
507
  userDiv.innerHTML = input.userString;
@@ -367,10 +530,15 @@
367
530
  messageDiv.style.display = 'none';
368
531
  }
369
532
 
370
- // Scroll to the last message only if the user is not actively scrolling up
371
- if (!this.userScrolledUp || input.scrollIntoView) {
533
+ // Handle scroll behavior based on scrollIntoView parameter
534
+ // 'smart' = only scroll if near bottom, true = always scroll, false = never scroll
535
+ if (input.scrollIntoView === true) {
536
+ this.messageScrollToBottom();
537
+ } else if (input.scrollIntoView === 'smart' && !this.userScrolledUp) {
372
538
  this.messageScrollToBottom();
373
539
  }
540
+ // If scrollIntoView is false, don't scroll at all
541
+
374
542
  this._textEntry.value = '';
375
543
  this._adjustMessagesAreaHeight();
376
544
  this._handleShortLongMessageCSS(messageDiv, input.align); // Handle CSS for short/long messages
@@ -397,6 +565,24 @@
397
565
  }
398
566
  return msgid;
399
567
  }
568
+
569
+ /**
570
+ * Adds a new message to the chat (simplified version of messageAddFull)
571
+ * @param {string} [content=''] - Message content (HTML allowed)
572
+ * @param {string} [userString='user'] - Display name for the message sender
573
+ * @param {'left'|'right'|'center'} [align='right'] - Message alignment
574
+ * @param {string} [role='user'] - Role identifier (user, assistant, system)
575
+ * @param {boolean|'smart'} [scrollIntoView=true] - Scroll behavior
576
+ * @param {boolean} [visible=true] - Whether message is initially visible
577
+ * @param {string[]} [tags=[]] - Tags for message categorization
578
+ * @returns {number} Message ID for the newly added message
579
+ * @example
580
+ * // Simple message
581
+ * chat.messageAddNew('Hello!', 'User', 'right');
582
+ *
583
+ * // Bot message with smart scroll
584
+ * chat.messageAddNew('Hi there!', 'Bot', 'left', 'assistant', 'smart');
585
+ */
400
586
  }, {
401
587
  key: "messageAddNew",
402
588
  value: function messageAddNew() {
@@ -406,17 +592,27 @@
406
592
  var role = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : "user";
407
593
  var scrollIntoView = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
408
594
  var visible = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;
595
+ var tags = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : [];
409
596
  var retvalue = this.messageAddFull({
410
597
  content: content,
411
598
  userString: userString,
412
599
  align: align,
413
600
  role: role,
414
601
  scrollIntoView: scrollIntoView,
415
- visible: visible
602
+ visible: visible,
603
+ tags: tags
416
604
  });
417
605
  // this.messageScrollToBottom();
418
606
  return retvalue;
419
607
  }
608
+
609
+ /**
610
+ * Removes a message from the chat by its ID
611
+ * @param {number} n - Message ID to remove
612
+ * @returns {boolean} True if message was removed, false if not found
613
+ * @example
614
+ * const success = chat.messageRemove(5);
615
+ */
420
616
  }, {
421
617
  key: "messageRemove",
422
618
  value: function messageRemove(n) {
@@ -436,11 +632,21 @@
436
632
  this._history.splice(this._history.findIndex(function (item) {
437
633
  return item.msgid === n;
438
634
  }), 1);
635
+
636
+ // Call the onMessageDelete callback if it exists
637
+ if (this._onMessageDelete) {
638
+ this._onMessageDelete(this, n);
639
+ }
439
640
  }
440
641
  return sucess;
441
642
  }
442
643
  /* returns the message html object from the DOM
443
644
  */
645
+ /**
646
+ * Gets the DOM element for a message by its ID
647
+ * @param {number} n - Message ID
648
+ * @returns {HTMLElement|null} The message DOM element or null if not found
649
+ */
444
650
  }, {
445
651
  key: "messageGetDOMObject",
446
652
  value: function messageGetDOMObject(n) {
@@ -455,6 +661,11 @@
455
661
  }
456
662
  /* returns the message content only
457
663
  */
664
+ /**
665
+ * Gets the content of a message by its ID
666
+ * @param {number} n - Message ID
667
+ * @returns {string} The message content or empty string if not found
668
+ */
458
669
  }, {
459
670
  key: "messageGetContent",
460
671
  value: function messageGetContent(n) {
@@ -506,10 +717,13 @@
506
717
  item.updatedtime = new Date().toISOString();
507
718
  success = true;
508
719
 
509
- // Scroll to the last message only if the user is not actively scrolling up
510
- if (!this.userScrolledUp) {
511
- this._messagesArea.lastElementChild.scrollIntoView();
720
+ // Call the onMessageAppend callback if it exists
721
+ if (this._onMessageAppend) {
722
+ this._onMessageAppend(this, n, content);
512
723
  }
724
+
725
+ // Don't auto-scroll on append - let user control this
726
+ // Users can call messageScrollToBottom() if they want to scroll
513
727
  } catch (error) {
514
728
  console.log("".concat(String(n), " : Message ID not found"));
515
729
  }
@@ -532,10 +746,13 @@
532
746
  item.updatedtime = new Date().toISOString();
533
747
  success = true;
534
748
 
535
- // Scroll to the last message only if the user is not actively scrolling up
536
- if (!this.userScrolledUp) {
537
- this._messagesArea.lastElementChild.scrollIntoView();
749
+ // Call the onMessageReplace callback if it exists
750
+ if (this._onMessageReplace) {
751
+ this._onMessageReplace(this, n, content);
538
752
  }
753
+
754
+ // Don't auto-scroll on append - let user control this
755
+ // Users can call messageScrollToBottom() if they want to scroll
539
756
  } catch (error) {
540
757
  console.log("".concat(String(n), " : Message ID not found"));
541
758
  }
@@ -671,6 +888,18 @@
671
888
  * @param {*} m
672
889
  * @returns array of history messages
673
890
  */
891
+ /**
892
+ * Gets a slice of message history
893
+ * @param {number} [n] - Start index (defaults to 0)
894
+ * @param {number} [m] - End index (defaults to history length)
895
+ * @returns {Array} Array of message objects
896
+ * @example
897
+ * // Get first 10 messages
898
+ * const messages = chat.historyGet(0, 10);
899
+ *
900
+ * // Get all messages
901
+ * const allMessages = chat.historyGet();
902
+ */
674
903
  }, {
675
904
  key: "historyGet",
676
905
  value: function historyGet(n, m) {
@@ -686,17 +915,204 @@
686
915
 
687
916
  return this._history.slice(n, m);
688
917
  }
918
+
919
+ /**
920
+ * Gets a copy of the entire message history
921
+ * @returns {Array} Complete array of all message objects
922
+ * @example
923
+ * const history = chat.historyGetAllCopy();
924
+ * console.log(`Total messages: ${history.length}`);
925
+ */
689
926
  }, {
690
927
  key: "historyGetAllCopy",
691
928
  value: function historyGetAllCopy() {
692
929
  return this._history.slice();
693
930
  }
931
+
932
+ /**
933
+ * Get a page of history messages with pagination support
934
+ * @param {number} page - Page number (1-based)
935
+ * @param {number} pageSize - Number of messages per page (default 50)
936
+ * @param {string} order - 'asc' for oldest first, 'desc' for newest first (default 'asc')
937
+ * @returns {object} Object with messages array, pagination info
938
+ */
939
+ }, {
940
+ key: "historyGetPage",
941
+ value: function historyGetPage() {
942
+ var page = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
943
+ var pageSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 50;
944
+ var order = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'asc';
945
+ var totalMessages = this._history.length;
946
+ var totalPages = Math.ceil(totalMessages / pageSize);
947
+ var currentPage = Math.max(1, Math.min(page, totalPages || 1));
948
+ var start, end;
949
+ if (order === 'desc') {
950
+ // For descending order, page 1 shows the newest messages
951
+ start = Math.max(0, totalMessages - currentPage * pageSize);
952
+ end = totalMessages - (currentPage - 1) * pageSize;
953
+ } else {
954
+ // For ascending order, page 1 shows the oldest messages
955
+ start = (currentPage - 1) * pageSize;
956
+ end = Math.min(start + pageSize, totalMessages);
957
+ }
958
+ var messages = this._history.slice(start, end);
959
+
960
+ // Reverse messages array if descending order requested
961
+ if (order === 'desc') {
962
+ messages.reverse();
963
+ }
964
+ return {
965
+ messages: messages,
966
+ pagination: {
967
+ currentPage: currentPage,
968
+ pageSize: pageSize,
969
+ totalPages: totalPages,
970
+ totalMessages: totalMessages,
971
+ hasNext: currentPage < totalPages,
972
+ hasPrevious: currentPage > 1,
973
+ order: order
974
+ }
975
+ };
976
+ }
977
+
978
+ /**
979
+ * Get information about history size and pagination
980
+ * @param {number} pageSize - Size to calculate pages for (default 50)
981
+ * @returns {object} History metadata
982
+ */
983
+ /**
984
+ * Search history for messages matching criteria
985
+ * @param {object} criteria - Search criteria object
986
+ * @param {string} criteria.text - Text to search for in message content
987
+ * @param {string} criteria.userString - Filter by user name
988
+ * @param {string} criteria.role - Filter by role
989
+ * @param {array} criteria.tags - Filter by tags (messages with any of these tags)
990
+ * @param {number} criteria.limit - Maximum results to return (default 100)
991
+ * @returns {array} Array of matching messages
992
+ */
993
+ /**
994
+ * Searches through message history with various filters
995
+ * @param {Object} [criteria={}] - Search criteria
996
+ * @param {string} [criteria.text] - Text to search for in message content
997
+ * @param {string} [criteria.userString] - Filter by specific user
998
+ * @param {string} [criteria.role] - Filter by role (user, assistant, system)
999
+ * @param {string[]} [criteria.tags] - Filter by tags (messages must have at least one)
1000
+ * @param {number} [criteria.limit=100] - Maximum number of results
1001
+ * @returns {Array} Array of matching messages
1002
+ * @since 1.1.15
1003
+ * @example
1004
+ * // Search for messages containing 'error'
1005
+ * const errors = chat.historySearch({ text: 'error' });
1006
+ *
1007
+ * // Find all bot messages
1008
+ * const botMessages = chat.historySearch({ role: 'assistant' });
1009
+ *
1010
+ * // Complex search
1011
+ * const results = chat.historySearch({
1012
+ * text: 'help',
1013
+ * userString: 'Support',
1014
+ * tags: ['urgent'],
1015
+ * limit: 20
1016
+ * });
1017
+ */
1018
+ }, {
1019
+ key: "historySearch",
1020
+ value: function historySearch() {
1021
+ var criteria = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1022
+ var results = this._history;
1023
+
1024
+ // Filter by text content (case-insensitive)
1025
+ if (criteria.text) {
1026
+ var searchText = criteria.text.toLowerCase();
1027
+ results = results.filter(function (msg) {
1028
+ return msg.content.toLowerCase().includes(searchText);
1029
+ });
1030
+ }
1031
+
1032
+ // Filter by user
1033
+ if (criteria.userString) {
1034
+ results = results.filter(function (msg) {
1035
+ return msg.userString === criteria.userString;
1036
+ });
1037
+ }
1038
+
1039
+ // Filter by role
1040
+ if (criteria.role) {
1041
+ results = results.filter(function (msg) {
1042
+ return msg.role === criteria.role;
1043
+ });
1044
+ }
1045
+
1046
+ // Filter by tags (match any tag)
1047
+ if (criteria.tags && criteria.tags.length > 0) {
1048
+ results = results.filter(function (msg) {
1049
+ return msg.tags && msg.tags.some(function (tag) {
1050
+ return criteria.tags.includes(tag);
1051
+ });
1052
+ });
1053
+ }
1054
+
1055
+ // Limit results
1056
+ var limit = criteria.limit || 100;
1057
+ if (results.length > limit) {
1058
+ results = results.slice(0, limit);
1059
+ }
1060
+ return results;
1061
+ }
1062
+
1063
+ /**
1064
+ * Gets metadata and statistics about the message history
1065
+ * @param {number} [pageSize=50] - Page size for calculating total pages
1066
+ * @returns {Object} History information object
1067
+ * @returns {number} returns.totalMessages - Total number of messages
1068
+ * @returns {number} returns.totalPages - Total pages based on page size
1069
+ * @returns {Object|null} returns.oldestMessage - First message info
1070
+ * @returns {Object|null} returns.newestMessage - Last message info
1071
+ * @returns {Object} returns.memoryUsage - Memory usage statistics
1072
+ * @since 1.1.15
1073
+ * @example
1074
+ * const info = chat.historyGetInfo();
1075
+ * console.log(`Messages: ${info.totalMessages}`);
1076
+ * console.log(`Memory: ${info.memoryUsage.estimatedSize} bytes`);
1077
+ */
1078
+ }, {
1079
+ key: "historyGetInfo",
1080
+ value: function historyGetInfo() {
1081
+ var pageSize = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 50;
1082
+ var totalMessages = this._history.length;
1083
+ return {
1084
+ totalMessages: totalMessages,
1085
+ totalPages: Math.ceil(totalMessages / pageSize),
1086
+ oldestMessage: totalMessages > 0 ? {
1087
+ msgid: this._history[0].msgid,
1088
+ timestamp: this._history[0].timestamp,
1089
+ userString: this._history[0].userString
1090
+ } : null,
1091
+ newestMessage: totalMessages > 0 ? {
1092
+ msgid: this._history[totalMessages - 1].msgid,
1093
+ timestamp: this._history[totalMessages - 1].timestamp,
1094
+ userString: this._history[totalMessages - 1].userString
1095
+ } : null,
1096
+ memoryUsage: {
1097
+ estimatedSize: JSON.stringify(this._history).length,
1098
+ averageMessageSize: totalMessages > 0 ? Math.round(JSON.stringify(this._history).length / totalMessages) : 0
1099
+ }
1100
+ };
1101
+ }
1102
+
1103
+ /**
1104
+ * Clears all messages and resets the chat
1105
+ * @returns {void}
1106
+ * @example
1107
+ * chat.historyClear(); // Removes all messages
1108
+ */
694
1109
  }, {
695
1110
  key: "historyClear",
696
1111
  value: function historyClear() {
697
1112
  this.msgid = 0;
698
1113
  this._messagesArea.innerHTML = "";
699
1114
  this._history = [];
1115
+ this._activeTags.clear();
700
1116
  }
701
1117
  }, {
702
1118
  key: "historyGetLength",
@@ -721,7 +1137,7 @@
721
1137
  }, {
722
1138
  key: "historyRestoreAll",
723
1139
  value: function historyRestoreAll(messageList) {
724
- var _this2 = this;
1140
+ var _this3 = this;
725
1141
  // clear all messages and history
726
1142
  this.historyClear();
727
1143
 
@@ -730,7 +1146,7 @@
730
1146
 
731
1147
  // add all messages
732
1148
  messageList.forEach(function (message) {
733
- _this2.messageAddFull(message);
1149
+ _this3.messageAddFull(message);
734
1150
  });
735
1151
  }
736
1152
  /**
@@ -759,15 +1175,82 @@
759
1175
  *
760
1176
  * @returns {object} - Returns the version and license information for the library.
761
1177
  */
1178
+ /**
1179
+ * Gets the QuikChat version information
1180
+ * @static
1181
+ * @returns {Object} Version information object
1182
+ * @returns {string} returns.version - Version number (e.g., '1.1.15')
1183
+ * @returns {string} returns.license - License type (e.g., 'BSD-2')
1184
+ * @returns {string} returns.url - Project URL
1185
+ * @returns {boolean} returns.fun - Easter egg flag
1186
+ * @example
1187
+ * const version = quikchat.version();
1188
+ * console.log(`QuikChat v${version.version}`);
1189
+ */
1190
+ }, {
1191
+ key: "setTagVisibility",
1192
+ value:
1193
+ /**
1194
+ * Sets visibility for all messages with a specific tag
1195
+ * @param {string} tagName - Tag name to control
1196
+ * @param {boolean} isVisible - Whether to show or hide messages with this tag
1197
+ * @returns {boolean} True if successful, false if invalid tag name
1198
+ * @since 1.1.14
1199
+ * @example
1200
+ * // Hide all system messages
1201
+ * chat.setTagVisibility('system', false);
1202
+ *
1203
+ * // Show urgent messages
1204
+ * chat.setTagVisibility('urgent', true);
1205
+ */
1206
+ function setTagVisibility(tagName, isVisible) {
1207
+ if (typeof tagName !== 'string' || !/^[a-zA-Z0-9-]+$/.test(tagName)) {
1208
+ return false;
1209
+ }
1210
+ var className = "quikchat-show-tag-".concat(tagName);
1211
+ if (isVisible) {
1212
+ this._chatWidget.classList.add(className);
1213
+ } else {
1214
+ this._chatWidget.classList.remove(className);
1215
+ }
1216
+ this._updateMessageStyles();
1217
+ return true;
1218
+ }
1219
+
1220
+ /**
1221
+ * Gets the visibility state of a tag
1222
+ * @param {string} tagName - Tag name to check
1223
+ * @returns {boolean} True if tag is visible, false otherwise
1224
+ * @since 1.1.14
1225
+ * @example
1226
+ * const isVisible = chat.getTagVisibility('system');
1227
+ */
1228
+ }, {
1229
+ key: "getTagVisibility",
1230
+ value: function getTagVisibility(tagName) {
1231
+ if (typeof tagName !== 'string' || !/^[a-zA-Z0-9-]+$/.test(tagName)) {
1232
+ return false;
1233
+ }
1234
+ return this._chatWidget.classList.contains("quikchat-show-tag-".concat(tagName));
1235
+ }
1236
+
1237
+ /**
1238
+ * Gets all active tags in the chat
1239
+ * @returns {string[]} Array of all tags currently in use
1240
+ * @since 1.1.14
1241
+ * @example
1242
+ * const tags = chat.getActiveTags();
1243
+ * console.log('Active tags:', tags);
1244
+ */
1245
+ }, {
1246
+ key: "getActiveTags",
1247
+ value: function getActiveTags() {
1248
+ return Array.from(this._activeTags);
1249
+ }
762
1250
  }], [{
763
1251
  key: "version",
764
1252
  value: function version() {
765
- return {
766
- "version": "1.1.13",
767
- "license": "BSD-2",
768
- "url": "https://github/deftio/quikchat",
769
- "fun": true
770
- };
1253
+ return quikchatVersion;
771
1254
  }
772
1255
 
773
1256
  /**
@@ -787,6 +1270,21 @@
787
1270
  * //Returns a 200 Lorem Ipsum characters starting from a random index
788
1271
  * loremIpsum(200);
789
1272
  */
1273
+
1274
+ /**
1275
+ * Generates Lorem Ipsum placeholder text
1276
+ * @static
1277
+ * @param {number} [numChars] - Length of text to generate (random if not specified)
1278
+ * @param {number} [startSpot] - Starting offset in Lorem text (random if not specified)
1279
+ * @param {boolean} [startWithCapitalLetter=true] - Whether to capitalize first letter
1280
+ * @returns {string} Generated Lorem Ipsum text
1281
+ * @example
1282
+ * // Generate 100 characters
1283
+ * const text = quikchat.loremIpsum(100);
1284
+ *
1285
+ * // Generate random length
1286
+ * const randomText = quikchat.loremIpsum();
1287
+ */
790
1288
  }, {
791
1289
  key: "loremIpsum",
792
1290
  value: function loremIpsum(numChars) {
@@ -826,7 +1324,27 @@
826
1324
  }
827
1325
  }, {
828
1326
  key: "tempMessageGenerator",
829
- value: function tempMessageGenerator(domElement, content, interval) {
1327
+ value:
1328
+ /**
1329
+ * Creates a temporary message that updates periodically
1330
+ * @static
1331
+ * @param {string|HTMLElement} domElement - Element selector or DOM element
1332
+ * @param {string} content - Initial message content
1333
+ * @param {number} interval - Update interval in milliseconds (min 100ms)
1334
+ * @param {Function} [cb=null] - Callback to generate new content
1335
+ * @param {string} cb.message - Current message
1336
+ * @param {number} cb.count - Update count
1337
+ * @returns {void}
1338
+ * @example
1339
+ * // Simple loading indicator
1340
+ * quikchat.tempMessageGenerator('#loading', 'Loading', 500);
1341
+ *
1342
+ * // Custom update function
1343
+ * quikchat.tempMessageGenerator('#status', 'Processing', 1000, (msg, count) => {
1344
+ * return `Processing... ${count}%`;
1345
+ * });
1346
+ */
1347
+ function tempMessageGenerator(domElement, content, interval) {
830
1348
  var cb = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
831
1349
  interval = Math.max(interval, 100); // Ensure at least 100ms interval
832
1350