@playpilot/tpi 5.32.2 → 5.32.3

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": "5.32.2",
3
+ "version": "5.32.3",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
@@ -9,4 +9,9 @@ export const SplitTest = {
9
9
  numberOfVariants: 2,
10
10
  variantNames: ['Image', 'Label'] as string[],
11
11
  },
12
+ UserTimeSpent: {
13
+ key: 'user_time_spent',
14
+ numberOfVariants: 10,
15
+ variantNames: ['No Links', 'Default', 'Default', 'Default', 'Default', 'Default', 'Default', 'Default', 'Default', 'Default'] as string[],
16
+ }
12
17
  } as const
@@ -12,7 +12,7 @@
12
12
  // If the fallback value is not given at all we assume it's meant to be a variable straight up without fallback.
13
13
  @if $fallback == "" {
14
14
  @return var(--playpilot-#{$scope});
15
- } @if meta.type-of($fallback) == "string" {
15
+ } @if meta.type-of($fallback) == "string" and $fallback != currentColor {
16
16
  @return var(--playpilot-#{$scope}, var(--playpilot-#{$fallback}));
17
17
  } @else {
18
18
  @return var(--playpilot-#{$scope}, $fallback);
@@ -9,6 +9,8 @@
9
9
  import { fetchAds } from '$lib/api/ads'
10
10
  import { fetchConfig } from '$lib/api/config'
11
11
  import { authorize, getAuthToken, isEditorialModeEnabled, removeAuthCookie, setEditorialParamInUrl } from '$lib/api/auth'
12
+ import { getSplitTestVariantName } from '$lib/splitTest'
13
+ import { SplitTest } from '$lib/enums/SplitTest'
12
14
  import type { LinkInjectionResponse, LinkInjection, LinkInjectionTypes } from '$lib/types/injection'
13
15
  import Editor from './components/Editorial/Editor.svelte'
14
16
  import EditorTrigger from './components/Editorial/EditorTrigger.svelte'
@@ -129,9 +131,15 @@
129
131
  }
130
132
 
131
133
  function inject(injections: LinkInjectionTypes = { aiInjections, manualInjections }): void {
134
+ // This is part of a split test were we are not injecting for 10% of users.
135
+ // The action is tracked as part of the UserLeft event in /components/UserJourney.svelte.
136
+ const hasAnyInjections = aiInjections?.length || manualInjections?.length
137
+ if (process.env.NODE_ENV !== 'test' && hasAnyInjections && getSplitTestVariantName(SplitTest.UserTimeSpent) === 'No Links') return
138
+
132
139
  // Get filtered injections as they are shown on the page.
133
140
  // Only update state if it they are different from current injections.
134
141
  const filteredInjections = injectLinksInDocument(elements, injections)
142
+
135
143
  if (JSON.stringify(filteredInjections) !== JSON.stringify(linkInjections)) {
136
144
  linkInjections = filteredInjections
137
145
 
@@ -88,6 +88,12 @@
88
88
  onclose()
89
89
  destroyAllModals()
90
90
  }
91
+
92
+ function closeOnBackdropClick(event: MouseEvent): void {
93
+ if (event.target !== modalElement) return
94
+
95
+ close()
96
+ }
91
97
  </script>
92
98
 
93
99
  <svelte:window
@@ -95,7 +101,17 @@
95
101
  onhashchange={close}
96
102
  bind:innerWidth={windowWidth} />
97
103
 
98
- <div class="modal" style:--dialog-offset="{dialogOffset}px" transition:fade|global={{ duration: 150 }} bind:this={modalElement} use:focustrap class:has-bubble={!!bubble && inlineBubble} class:has-prepend={!!prepend}>
104
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
105
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
106
+ <div
107
+ class="modal"
108
+ class:has-bubble={!!bubble && inlineBubble}
109
+ class:has-prepend={!!prepend}
110
+ style:--dialog-offset="{dialogOffset}px"
111
+ onclick={closeOnBackdropClick}
112
+ transition:fade|global={{ duration: 150 }}
113
+ bind:this={modalElement}
114
+ use:focustrap>
99
115
  {#if prepend}
100
116
  <div class="prepend" transition:scaleOrFly|global={{ y: window.innerHeight }} data-view-transition-new="playpilot-title-extra">
101
117
  {@render prepend()}
@@ -131,10 +147,6 @@
131
147
 
132
148
  {@render children()}
133
149
  </div>
134
-
135
- <!-- svelte-ignore a11y_click_events_have_key_events -->
136
- <!-- svelte-ignore a11y_no_static_element_interactions -->
137
- <div class="backdrop" onclick={close}></div>
138
150
  </div>
139
151
 
140
152
  <style lang="scss">
@@ -211,15 +223,6 @@
211
223
  }
212
224
  }
213
225
 
214
- .backdrop {
215
- z-index: 0;
216
- position: fixed;
217
- top: 0;
218
- right: 0;
219
- bottom: 0;
220
- left: 0;
221
- }
222
-
223
226
  .swipe-handle {
224
227
  z-index: 5;
225
228
  position: absolute;
@@ -1,7 +1,9 @@
1
1
  <script lang="ts">
2
2
  import { isEditorialModeEnabled } from '$lib/api/auth'
3
+ import { SplitTest } from '$lib/enums/SplitTest'
3
4
  import { TrackingEvent } from '$lib/enums/TrackingEvent'
4
5
  import { keyDataAttribute, keySelector } from '$lib/injection'
6
+ import { getSplitTestVariantName } from '$lib/splitTest'
5
7
  import { track } from '$lib/tracking'
6
8
  import { onMount } from 'svelte'
7
9
 
@@ -70,6 +72,7 @@
70
72
  existing_injections_count: totalInjectionElements.length,
71
73
  shown_injections_count: shownInjections.length,
72
74
  fired_events: window.PlayPilotLinkInjections?.tracked_events?.map(event => event.event) || [],
75
+ split_test_variant: getSplitTestVariantName(SplitTest.UserTimeSpent),
73
76
  })
74
77
  }
75
78
  </script>
@@ -19,15 +19,24 @@ describe('Modal.svelte', () => {
19
19
  const onclose = vi.fn()
20
20
  const children = createRawSnippet(() => ({ render: () => '<div></div>' }))
21
21
 
22
- it('Should fire given onclose and destroyAllModals functions when backdrop is clicked', async () => {
22
+ it('Should fire given onclose and destroyAllModals functions when modal is clicked', async () => {
23
23
  const { container } = render(Modal, { children, onclose })
24
24
 
25
- await fireEvent.click(/** @type {Node} */ (container.querySelector('.backdrop')))
25
+ await fireEvent.click(/** @type {Node} */ (container.querySelector('.modal')))
26
26
 
27
27
  expect(onclose).toHaveBeenCalled()
28
28
  expect(destroyAllModals).toHaveBeenCalled()
29
29
  })
30
30
 
31
+ it('Should not fire given onclose and destroyAllModals functions when dialog is clicked', async () => {
32
+ const { container } = render(Modal, { children, onclose })
33
+
34
+ await fireEvent.click(/** @type {Node} */ (container.querySelector('.dialog')))
35
+
36
+ expect(onclose).not.toHaveBeenCalled()
37
+ expect(destroyAllModals).not.toHaveBeenCalled()
38
+ })
39
+
31
40
  it('Should fire given onclose and destroyAllModals functions when close button is clicked', async () => {
32
41
  const { container } = render(Modal, { children, onclose })
33
42