tagger.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /**
  2. * wait until element is loaded and returns
  3. * @param {string} selector
  4. * @param {number} timeout
  5. * @param {Element} $rootElement
  6. * @returns {Promise<HTMLElement>}
  7. */
  8. function waitQuerySelector(selector, timeout = 5000, $rootElement = gradioApp()) {
  9. return new Promise((resolve, reject) => {
  10. const element = $rootElement.querySelector(selector)
  11. if (document.querySelector(element)) {
  12. return resolve(element)
  13. }
  14. let timeoutId
  15. const observer = new MutationObserver(() => {
  16. const element = $rootElement.querySelector(selector)
  17. if (!element) {
  18. return
  19. }
  20. if (timeoutId) {
  21. clearInterval(timeoutId)
  22. }
  23. observer.disconnect()
  24. resolve(element)
  25. })
  26. timeoutId = setTimeout(() => {
  27. observer.disconnect()
  28. reject(new Error(`timeout, cannot find element by '${selector}'`))
  29. }, timeout)
  30. observer.observe($rootElement, {
  31. childList: true,
  32. subtree: true
  33. })
  34. })
  35. }
  36. document.addEventListener('DOMContentLoaded', () => {
  37. Promise.all([
  38. // option texts
  39. waitQuerySelector('#additioanl-tags'),
  40. waitQuerySelector('#exclude-tags'),
  41. // tag-confident labels
  42. waitQuerySelector('#rating-confidents'),
  43. waitQuerySelector('#tag-confidents')
  44. ]).then(elements => {
  45. const $additionalTags = elements[0].querySelector('textarea')
  46. const $excludeTags = elements[1].querySelector('textarea')
  47. const $ratingConfidents = elements[2]
  48. const $tagConfidents = elements[3]
  49. let $selectedTextarea = $additionalTags
  50. /**
  51. * @this {HTMLElement}
  52. * @param {MouseEvent} e
  53. * @listens document#click
  54. */
  55. function onClickTextarea(e) {
  56. $selectedTextarea = this
  57. }
  58. $additionalTags.addEventListener('click', onClickTextarea)
  59. $excludeTags.addEventListener('click', onClickTextarea)
  60. /**
  61. * @this {HTMLElement}
  62. * @param {MouseEvent} e
  63. * @listens document#click
  64. */
  65. function onClickLabels(e) {
  66. // find clicked label item's wrapper element
  67. const $tag = e.target.closest('.output-label > div:not(:first-child)')
  68. if (!$tag) {
  69. return
  70. }
  71. /** @type {string} */
  72. const tag = $tag.querySelector('.leading-snug').textContent
  73. // ignore if tag is already exist in textbox
  74. const escapedTag = tag.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  75. const pattern = new RegExp(`(^|,)\\s{0,}${escapedTag}\\s{0,}($|,)`)
  76. if (pattern.test($selectedTextarea.value)) {
  77. return
  78. }
  79. if ($selectedTextarea.value !== '') {
  80. $selectedTextarea.value += ', '
  81. }
  82. $selectedTextarea.value += tag
  83. }
  84. $ratingConfidents.addEventListener('click', onClickLabels)
  85. $tagConfidents.addEventListener('click', onClickLabels)
  86. }).catch(err => {
  87. console.error(err)
  88. })
  89. })