@financial-times/cp-content-pipeline-ui 6.13.0-beta.0 → 6.13.0

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.
@@ -1,14 +0,0 @@
1
- declare class FlourishTopperTracker {
2
- private startTime;
3
- private totalVisibleTime;
4
- private timeElapsedSeconds;
5
- private component;
6
- private id;
7
- private observer;
8
- constructor();
9
- init(): void;
10
- private dispatchEvent;
11
- private onChange;
12
- disconnect(): void;
13
- }
14
- export { FlourishTopperTracker };
@@ -1,69 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FlourishTopperTracker = void 0;
4
- class FlourishTopperTracker {
5
- constructor() {
6
- this.startTime = 0;
7
- this.totalVisibleTime = 0;
8
- this.timeElapsedSeconds = null;
9
- this.component = document.querySelector('[data-component-type="flourish-topper"]');
10
- this.id = this.component?.getAttribute('data-component-id') || null;
11
- this.observer = null;
12
- }
13
- init() {
14
- if (!window.IntersectionObserver || !this.component) {
15
- return;
16
- }
17
- if (this.component) {
18
- this.dispatchEvent('mount');
19
- }
20
- this.observer = new IntersectionObserver(this.onChange.bind(this), {
21
- threshold: [1.0],
22
- });
23
- this.observer.observe(this.component);
24
- }
25
- dispatchEvent(action) {
26
- let component = {
27
- name: 'flourish-topper',
28
- id: this.id,
29
- };
30
- if (this.timeElapsedSeconds) {
31
- component = { ...component, timeElapsedSeconds: this.timeElapsedSeconds };
32
- }
33
- const event = new CustomEvent('oTracking.event', {
34
- detail: {
35
- category: 'component',
36
- action: action,
37
- component,
38
- },
39
- bubbles: true,
40
- });
41
- document.body.dispatchEvent(event);
42
- }
43
- onChange(changes) {
44
- changes.forEach((change) => {
45
- if (change.target !== this.component) {
46
- return;
47
- }
48
- if (change.isIntersecting || change.intersectionRatio >= 1) {
49
- this.dispatchEvent('view');
50
- this.startTime = performance.now();
51
- }
52
- if (!change.isIntersecting || change.intersectionRatio === 0) {
53
- this.totalVisibleTime = performance.now() - this.startTime;
54
- this.timeElapsedSeconds = parseFloat((this.totalVisibleTime / 1000).toFixed(2));
55
- this.dispatchEvent('stop-view');
56
- this.totalVisibleTime = 0;
57
- this.timeElapsedSeconds = null;
58
- }
59
- });
60
- }
61
- disconnect() {
62
- if (this.observer && this.component) {
63
- this.observer.unobserve(this.component);
64
- this.observer.disconnect();
65
- }
66
- }
67
- }
68
- exports.FlourishTopperTracker = FlourishTopperTracker;
69
- //# sourceMappingURL=flourish-tracking.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"flourish-tracking.js","sourceRoot":"","sources":["../../../../src/components/Topper/client/flourish-tracking.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import { FlourishTopperTracker } from './flourish-tracking';
2
- export { FlourishTopperTracker };
@@ -1,6 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FlourishTopperTracker = void 0;
4
- const flourish_tracking_1 = require("./flourish-tracking");
5
- Object.defineProperty(exports, "FlourishTopperTracker", { enumerable: true, get: function () { return flourish_tracking_1.FlourishTopperTracker; } });
6
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/Topper/client/index.ts"],"names":[],"mappings":";;;AAAA,2DAA2D;AAElD,sGAFA,yCAAqB,OAEA"}
@@ -1,117 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const client_1 = require("../../client");
4
- // const CustomEventMock = jest.fn()
5
- // global.CustomEvent = CustomEventMock
6
- describe('FlourishTopperTracker', () => {
7
- let mockIntersectionObserver;
8
- let mockObserve;
9
- let mockUnobserve;
10
- let mockDisconnect;
11
- let mockComponent;
12
- let dispatchEventSpy;
13
- beforeEach(() => {
14
- mockObserve = jest.fn();
15
- mockUnobserve = jest.fn();
16
- mockDisconnect = jest.fn();
17
- mockIntersectionObserver = jest.fn(() => {
18
- return {
19
- observe: mockObserve,
20
- unobserve: mockUnobserve,
21
- disconnect: mockDisconnect,
22
- };
23
- });
24
- window.IntersectionObserver = mockIntersectionObserver;
25
- mockComponent = document.createElement('div');
26
- mockComponent.setAttribute('data-component-type', 'flourish-topper');
27
- mockComponent.setAttribute('data-component-id', 'test-id');
28
- document.body.appendChild(mockComponent);
29
- jest.spyOn(document, 'querySelector').mockReturnValue(mockComponent);
30
- jest
31
- .spyOn(performance, 'now')
32
- .mockImplementationOnce(() => 1)
33
- .mockImplementationOnce(() => 12344);
34
- dispatchEventSpy = jest.spyOn(document.body, 'dispatchEvent');
35
- });
36
- afterEach(() => {
37
- jest.clearAllMocks();
38
- document.body.removeChild(mockComponent);
39
- });
40
- it('should initialise and observe the component', () => {
41
- const tracker = new client_1.FlourishTopperTracker();
42
- tracker.init();
43
- expect(mockIntersectionObserver).toHaveBeenCalled();
44
- expect(mockObserve).toHaveBeenCalledWith(mockComponent);
45
- });
46
- it('should dispatch a mount event on intialisation', () => {
47
- const tracker = new client_1.FlourishTopperTracker();
48
- tracker.init();
49
- const mountEvent = dispatchEventSpy.mock.calls[0][0];
50
- expect(mountEvent.type).toBe('oTracking.event');
51
- expect(mountEvent.detail).toEqual({
52
- category: 'component',
53
- action: 'mount',
54
- component: {
55
- name: 'flourish-topper',
56
- id: 'test-id',
57
- },
58
- });
59
- });
60
- it('should handle component visibility changes', () => {
61
- const tracker = new client_1.FlourishTopperTracker();
62
- tracker.init();
63
- const mockChanges = [
64
- {
65
- target: mockComponent,
66
- isIntersecting: true,
67
- intersectionRatio: 1.0,
68
- boundingClientRect: {},
69
- intersectionRect: {},
70
- rootBounds: null,
71
- time: 1,
72
- },
73
- ];
74
- tracker['onChange'](mockChanges);
75
- const viewEvent = dispatchEventSpy.mock.calls[1][0];
76
- expect(viewEvent.type).toBe('oTracking.event');
77
- expect(viewEvent.detail).toEqual({
78
- category: 'component',
79
- action: 'view',
80
- component: {
81
- name: 'flourish-topper',
82
- id: 'test-id',
83
- },
84
- });
85
- const mockChangesAfter = [
86
- {
87
- target: mockComponent,
88
- isIntersecting: false,
89
- intersectionRatio: 0.0,
90
- boundingClientRect: {},
91
- intersectionRect: {},
92
- rootBounds: null,
93
- time: 12.3444,
94
- },
95
- ];
96
- tracker['onChange'](mockChangesAfter);
97
- const stopViewEvent = dispatchEventSpy.mock.calls[2][0];
98
- expect(stopViewEvent.type).toBe('oTracking.event');
99
- expect(stopViewEvent.detail).toEqual({
100
- category: 'component',
101
- action: 'stop-view',
102
- component: {
103
- name: 'flourish-topper',
104
- id: 'test-id',
105
- timeElapsedSeconds: 12.34,
106
- },
107
- });
108
- });
109
- it('should disconnect the observer', () => {
110
- const tracker = new client_1.FlourishTopperTracker();
111
- tracker.init();
112
- tracker.disconnect();
113
- expect(mockUnobserve).toHaveBeenCalledWith(mockComponent);
114
- expect(mockDisconnect).toHaveBeenCalled();
115
- });
116
- });
117
- //# sourceMappingURL=flourish-tracking.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"flourish-tracking.spec.js","sourceRoot":"","sources":["../../../../../src/components/Topper/test/client/flourish-tracking.spec.ts"],"names":[],"mappings":"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"}
@@ -1,83 +0,0 @@
1
- class FlourishTopperTracker {
2
- private startTime: number
3
- private totalVisibleTime: number
4
- private timeElapsedSeconds: number | null
5
- private component: Element | null
6
- private id: string | null
7
- private observer: IntersectionObserver | null
8
-
9
- constructor() {
10
- this.startTime = 0
11
- this.totalVisibleTime = 0
12
- this.timeElapsedSeconds = null
13
- this.component = document.querySelector(
14
- '[data-component-type="flourish-topper"]'
15
- )
16
- this.id = this.component?.getAttribute('data-component-id') || null
17
- this.observer = null
18
- }
19
-
20
- init(): void {
21
- if (!window.IntersectionObserver || !this.component) {
22
- return
23
- }
24
-
25
- if (this.component) {
26
- this.dispatchEvent('mount')
27
- }
28
-
29
- this.observer = new IntersectionObserver(this.onChange.bind(this), {
30
- threshold: [1.0],
31
- })
32
- this.observer.observe(this.component)
33
- }
34
-
35
- private dispatchEvent(action: string): void {
36
- let component: object = {
37
- name: 'flourish-topper',
38
- id: this.id,
39
- }
40
- if (this.timeElapsedSeconds) {
41
- component = { ...component, timeElapsedSeconds: this.timeElapsedSeconds }
42
- }
43
- const event = new CustomEvent('oTracking.event', {
44
- detail: {
45
- category: 'component',
46
- action: action,
47
- component,
48
- },
49
- bubbles: true,
50
- })
51
- document.body.dispatchEvent(event)
52
- }
53
-
54
- private onChange(changes: IntersectionObserverEntry[]): void {
55
- changes.forEach((change) => {
56
- if (change.target !== this.component) {
57
- return
58
- }
59
- if (change.isIntersecting || change.intersectionRatio >= 1) {
60
- this.dispatchEvent('view')
61
- this.startTime = performance.now()
62
- }
63
- if (!change.isIntersecting || change.intersectionRatio === 0) {
64
- this.totalVisibleTime = performance.now() - this.startTime
65
- this.timeElapsedSeconds = parseFloat(
66
- (this.totalVisibleTime / 1000).toFixed(2)
67
- )
68
- this.dispatchEvent('stop-view')
69
- this.totalVisibleTime = 0
70
- this.timeElapsedSeconds = null
71
- }
72
- })
73
- }
74
-
75
- disconnect(): void {
76
- if (this.observer && this.component) {
77
- this.observer.unobserve(this.component)
78
- this.observer.disconnect()
79
- }
80
- }
81
- }
82
-
83
- export { FlourishTopperTracker }
@@ -1,3 +0,0 @@
1
- import { FlourishTopperTracker } from './flourish-tracking'
2
-
3
- export { FlourishTopperTracker }
@@ -1,135 +0,0 @@
1
- import { FlourishTopperTracker } from '../../client'
2
-
3
- // const CustomEventMock = jest.fn()
4
- // global.CustomEvent = CustomEventMock
5
-
6
- describe('FlourishTopperTracker', () => {
7
- let mockIntersectionObserver: jest.Mock
8
- let mockObserve: jest.Mock
9
- let mockUnobserve: jest.Mock
10
- let mockDisconnect: jest.Mock
11
- let mockComponent: HTMLElement
12
- let dispatchEventSpy: jest.SpyInstance
13
-
14
- beforeEach(() => {
15
- mockObserve = jest.fn()
16
- mockUnobserve = jest.fn()
17
- mockDisconnect = jest.fn()
18
-
19
- mockIntersectionObserver = jest.fn(() => {
20
- return {
21
- observe: mockObserve,
22
- unobserve: mockUnobserve,
23
- disconnect: mockDisconnect,
24
- }
25
- })
26
-
27
- window.IntersectionObserver = mockIntersectionObserver
28
-
29
- mockComponent = document.createElement('div')
30
- mockComponent.setAttribute('data-component-type', 'flourish-topper')
31
- mockComponent.setAttribute('data-component-id', 'test-id')
32
- document.body.appendChild(mockComponent)
33
-
34
- jest.spyOn(document, 'querySelector').mockReturnValue(mockComponent)
35
- jest
36
- .spyOn(performance, 'now')
37
- .mockImplementationOnce(() => 1)
38
- .mockImplementationOnce(() => 12344)
39
- dispatchEventSpy = jest.spyOn(document.body, 'dispatchEvent')
40
- })
41
-
42
- afterEach(() => {
43
- jest.clearAllMocks()
44
- document.body.removeChild(mockComponent)
45
- })
46
-
47
- it('should initialise and observe the component', () => {
48
- const tracker = new FlourishTopperTracker()
49
- tracker.init()
50
-
51
- expect(mockIntersectionObserver).toHaveBeenCalled()
52
- expect(mockObserve).toHaveBeenCalledWith(mockComponent)
53
- })
54
-
55
- it('should dispatch a mount event on intialisation', () => {
56
- const tracker = new FlourishTopperTracker()
57
- tracker.init()
58
-
59
- const mountEvent = dispatchEventSpy.mock.calls[0][0] as CustomEvent
60
- expect(mountEvent.type).toBe('oTracking.event')
61
- expect(mountEvent.detail).toEqual({
62
- category: 'component',
63
- action: 'mount',
64
- component: {
65
- name: 'flourish-topper',
66
- id: 'test-id',
67
- },
68
- })
69
- })
70
-
71
- it('should handle component visibility changes', () => {
72
- const tracker = new FlourishTopperTracker()
73
- tracker.init()
74
-
75
- const mockChanges: IntersectionObserverEntry[] = [
76
- {
77
- target: mockComponent,
78
- isIntersecting: true,
79
- intersectionRatio: 1.0,
80
- boundingClientRect: {} as DOMRectReadOnly,
81
- intersectionRect: {} as DOMRectReadOnly,
82
- rootBounds: null,
83
- time: 1,
84
- },
85
- ]
86
-
87
- tracker['onChange'](mockChanges)
88
-
89
- const viewEvent = dispatchEventSpy.mock.calls[1][0] as CustomEvent
90
- expect(viewEvent.type).toBe('oTracking.event')
91
- expect(viewEvent.detail).toEqual({
92
- category: 'component',
93
- action: 'view',
94
- component: {
95
- name: 'flourish-topper',
96
- id: 'test-id',
97
- },
98
- })
99
-
100
- const mockChangesAfter: IntersectionObserverEntry[] = [
101
- {
102
- target: mockComponent,
103
- isIntersecting: false,
104
- intersectionRatio: 0.0,
105
- boundingClientRect: {} as DOMRectReadOnly,
106
- intersectionRect: {} as DOMRectReadOnly,
107
- rootBounds: null,
108
- time: 12.3444,
109
- },
110
- ]
111
-
112
- tracker['onChange'](mockChangesAfter)
113
-
114
- const stopViewEvent = dispatchEventSpy.mock.calls[2][0] as CustomEvent
115
- expect(stopViewEvent.type).toBe('oTracking.event')
116
- expect(stopViewEvent.detail).toEqual({
117
- category: 'component',
118
- action: 'stop-view',
119
- component: {
120
- name: 'flourish-topper',
121
- id: 'test-id',
122
- timeElapsedSeconds: 12.34,
123
- },
124
- })
125
- })
126
-
127
- it('should disconnect the observer', () => {
128
- const tracker = new FlourishTopperTracker()
129
- tracker.init()
130
- tracker.disconnect()
131
-
132
- expect(mockUnobserve).toHaveBeenCalledWith(mockComponent)
133
- expect(mockDisconnect).toHaveBeenCalled()
134
- })
135
- })