@playpilot/tpi 8.10.0 → 8.10.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playpilot/tpi",
3
- "version": "8.10.0",
3
+ "version": "8.10.1",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
@@ -18,8 +18,17 @@
18
18
  const targetSelector = `${target?.nodeName.toLowerCase()}${getClasslistAsString(target)}`
19
19
  const selector = `${parentSelector} > ${targetSelector}`
20
20
 
21
- const hasDirectTextContent = Array.from(target.childNodes).some(node => node.nodeName === '#text' && !!node.nodeValue?.trim())
22
- const text = hasDirectTextContent ? target.textContent.slice(0, 30) : ''
21
+ const closestButtonOrLink = target.closest('a, button')
22
+ const directTextNode =
23
+ elementHasDirectTextContent(target) ||
24
+ elementHasDirectTextContent(parent) ||
25
+ (closestButtonOrLink && elementHasDirectTextContent(closestButtonOrLink))
26
+
27
+ const textContent = directTextNode ? directTextNode.textContent?.slice(0, 30) : ''
28
+ const label = target.getAttribute('aria-label') || closestButtonOrLink?.getAttribute('aria-label') || parent?.getAttribute('aria-label')
29
+ const placeholder = (target as HTMLInputElement).placeholder
30
+ const alt = (target as HTMLImageElement).alt
31
+ const text = (textContent || label || placeholder || alt || '').trim()
23
32
 
24
33
  track(trackingEvent, null, { selector, text })
25
34
  }
@@ -33,6 +42,10 @@
33
42
 
34
43
  return '.' + classnames.join('.')
35
44
  }
45
+
46
+ function elementHasDirectTextContent(element: Element): Node | undefined {
47
+ return Array.from(element.childNodes).find(node => node.nodeName === '#text' && !!node.textContent?.trim())
48
+ }
36
49
  </script>
37
50
 
38
51
  <svelte:window {onclick} />
@@ -38,7 +38,7 @@
38
38
  </iframe>
39
39
 
40
40
  {#if showMuteControls}
41
- <button class="mute" onclick={() => toggleMute()}>
41
+ <button class="mute" onclick={() => toggleMute()} aria-label="Mute">
42
42
  <IconMute muted={isMuted} />
43
43
  </button>
44
44
  {/if}
@@ -42,7 +42,7 @@ describe('TrackAnyClick.svelte', () => {
42
42
  TrackingEvent.ExploreAnyClick,
43
43
  null,
44
44
  expect.objectContaining({
45
- text: 'This is a very long text that ',
45
+ text: 'This is a very long text that',
46
46
  }),
47
47
  )
48
48
  })
@@ -104,4 +104,140 @@ describe('TrackAnyClick.svelte', () => {
104
104
 
105
105
  expect(track).toHaveBeenCalledWith(TrackingEvent.ExploreAnyClick, null, expect.objectContaining({ selector: 'section > p' }))
106
106
  })
107
+
108
+ it('Should select text of closest button', async () => {
109
+ document.body.innerHTML = '<button>Some text <span><em></em></span></button>'
110
+
111
+ render(ClickTracking)
112
+
113
+ // @ts-ignore
114
+ await fireEvent.click(document.querySelector('em'))
115
+
116
+ expect(track).toHaveBeenCalledWith(
117
+ TrackingEvent.ExploreAnyClick,
118
+ null,
119
+ expect.objectContaining({
120
+ text: 'Some text',
121
+ }),
122
+ )
123
+ })
124
+
125
+ it('Should select text of closest link', async () => {
126
+ document.body.innerHTML = '<a href="/">Some text <span><em></em></span></a>'
127
+
128
+ render(ClickTracking)
129
+
130
+ // @ts-ignore
131
+ await fireEvent.click(document.querySelector('em'))
132
+
133
+ expect(track).toHaveBeenCalledWith(
134
+ TrackingEvent.ExploreAnyClick,
135
+ null,
136
+ expect.objectContaining({
137
+ text: 'Some text',
138
+ }),
139
+ )
140
+ })
141
+
142
+ it('Should use placeholder text', async () => {
143
+ document.body.innerHTML = '<input placeholder="Some placeholder" />'
144
+
145
+ render(ClickTracking)
146
+
147
+ // @ts-ignore
148
+ await fireEvent.click(document.querySelector('input'))
149
+
150
+ expect(track).toHaveBeenCalledWith(
151
+ TrackingEvent.ExploreAnyClick,
152
+ null,
153
+ expect.objectContaining({
154
+ text: 'Some placeholder',
155
+ }),
156
+ )
157
+ })
158
+
159
+ it('Should use alt text', async () => {
160
+ document.body.innerHTML = '<img alt="Some alt text" />'
161
+
162
+ render(ClickTracking)
163
+
164
+ // @ts-ignore
165
+ await fireEvent.click(document.querySelector('img'))
166
+
167
+ expect(track).toHaveBeenCalledWith(
168
+ TrackingEvent.ExploreAnyClick,
169
+ null,
170
+ expect.objectContaining({
171
+ text: 'Some alt text',
172
+ }),
173
+ )
174
+ })
175
+
176
+ it('Should use aria label', async () => {
177
+ document.body.innerHTML = '<button aria-label="Some aria label"></button>'
178
+
179
+ render(ClickTracking)
180
+
181
+ // @ts-ignore
182
+ await fireEvent.click(document.querySelector('button'))
183
+
184
+ expect(track).toHaveBeenCalledWith(
185
+ TrackingEvent.ExploreAnyClick,
186
+ null,
187
+ expect.objectContaining({
188
+ text: 'Some aria label',
189
+ }),
190
+ )
191
+ })
192
+
193
+ it('Should use parent aria label', async () => {
194
+ document.body.innerHTML = '<button aria-label="Some aria label"><img /></button>'
195
+
196
+ render(ClickTracking)
197
+
198
+ // @ts-ignore
199
+ await fireEvent.click(document.querySelector('img'))
200
+
201
+ expect(track).toHaveBeenCalledWith(
202
+ TrackingEvent.ExploreAnyClick,
203
+ null,
204
+ expect.objectContaining({
205
+ text: 'Some aria label',
206
+ }),
207
+ )
208
+ })
209
+
210
+ it('Should prefer aria label over placeholder and alt text', async () => {
211
+ document.body.innerHTML = '<button aria-label="Some aria label"><img placeholder="Some placeholder" alt="Some alt text" /></button>'
212
+
213
+ render(ClickTracking)
214
+
215
+ // @ts-ignore
216
+ await fireEvent.click(document.querySelector('img'))
217
+
218
+ expect(track).toHaveBeenCalledWith(
219
+ TrackingEvent.ExploreAnyClick,
220
+ null,
221
+ expect.objectContaining({
222
+ text: 'Some aria label',
223
+ }),
224
+ )
225
+ })
226
+
227
+ it('Should prefer text content over aria label, placeholder and alt text', async () => {
228
+ document.body.innerHTML = '<button aria-label="Some aria label">Some text <img placeholder="Some placeholder" alt="Some alt text" /></button>'
229
+
230
+ render(ClickTracking)
231
+
232
+ // @ts-ignore
233
+ await fireEvent.click(document.querySelector('img'))
234
+
235
+ expect(track).toHaveBeenCalledWith(
236
+ TrackingEvent.ExploreAnyClick,
237
+ null,
238
+ expect.objectContaining({
239
+ text: 'Some text',
240
+ }),
241
+ )
242
+ })
107
243
  })