@financial-times/cp-content-pipeline-ui 7.3.1 → 7.4.0-beta.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.
@@ -11,7 +11,7 @@ declare class CustomCodeComponentClient {
11
11
  */
12
12
  tracking: CustomCodeComponentTracker;
13
13
  constructor(el: Element);
14
- static init(rootEl?: Element): (CustomCodeComponentClient | undefined)[];
14
+ static init(rootEl?: Element): CustomCodeComponentClient[] | void;
15
15
  static destroy(components: CustomCodeComponentClient[]): void;
16
16
  }
17
17
  export default CustomCodeComponentClient;
@@ -20,7 +20,12 @@ class CustomCodeComponentClient {
20
20
  }
21
21
  static init(rootEl) {
22
22
  const root = rootEl instanceof Element ? rootEl : document;
23
- return Array.from(root.querySelectorAll('custom-code-component')).map((el) => new CustomCodeComponentClient(el));
23
+ return Array.from(root.querySelectorAll('custom-code-component')).reduce((acc, el) => {
24
+ if (!el.hasAttribute('data-o-tracking-initialised')) {
25
+ acc.push(new CustomCodeComponentClient(el));
26
+ }
27
+ return acc;
28
+ }, []);
24
29
  }
25
30
  static destroy(components) {
26
31
  components.forEach((component) => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/components/content-tree/CustomCodeComponent/client/index.ts"],"names":[],"mappings":";;AAAA,yCAAuD;AAEvD;;;;;GAKG;AACH,MAAM,yBAAyB;IAM7B,YAAY,EAAW;QACrB,MAAM,YAAY,GAAG;YACnB,SAAS,EAAE;gBACT,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE;gBAC/B,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE;gBACnC,IAAI,EAAE,uBAAuB;aAC9B;SACF,CAAA;QACD,IAAI,CAAC,QAAQ,GAAG,IAAI,qCAA0B,CAAC,EAAa,EAAE,YAAY,CAAC,CAAA;IAC7E,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,MAAgB;QAC1B,MAAM,IAAI,GAAG,MAAM,YAAY,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAA;QAC1D,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,uBAAuB,CAAC,CAAC,CAAC,GAAG,CACnE,CAAC,EAAW,EAAE,EAAE,CAAC,IAAI,yBAAyB,CAAC,EAAE,CAAC,CACnD,CAAA;IACH,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,UAAuC;QACpD,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;YAC/B,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAA;QAC9B,CAAC,CAAC,CAAA;IACJ,CAAC;CACF;AAED,kBAAe,yBAAyB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/components/content-tree/CustomCodeComponent/client/index.ts"],"names":[],"mappings":";;AAAA,yCAAuD;AAEvD;;;;;GAKG;AACH,MAAM,yBAAyB;IAM7B,YAAY,EAAW;QACrB,MAAM,YAAY,GAAG;YACnB,SAAS,EAAE;gBACT,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE;gBAC/B,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE;gBACnC,IAAI,EAAE,uBAAuB;aAC9B;SACF,CAAA;QACD,IAAI,CAAC,QAAQ,GAAG,IAAI,qCAA0B,CAC5C,EAAiB,EACjB,YAAY,CACb,CAAA;IACH,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,MAAgB;QAC1B,MAAM,IAAI,GAAG,MAAM,YAAY,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAA;QAC1D,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,uBAAuB,CAAC,CAAC,CAAC,MAAM,CAEtE,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE;YACZ,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,6BAA6B,CAAC,EAAE,CAAC;gBACpD,GAAG,CAAC,IAAI,CAAC,IAAI,yBAAyB,CAAC,EAAE,CAAC,CAAC,CAAA;YAC7C,CAAC;YACD,OAAO,GAAG,CAAA;QACZ,CAAC,EAAE,EAAE,CAAC,CAAA;IACR,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,UAAuC;QACpD,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;YAC/B,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAA;QAC9B,CAAC,CAAC,CAAA;IACJ,CAAC;CACF;AAED,kBAAe,yBAAyB,CAAA"}
@@ -16,10 +16,12 @@ type TrackingData = {
16
16
  declare class CustomCodeComponentTracker {
17
17
  private component;
18
18
  private trackingData;
19
- private observer?;
19
+ private mutationObserver?;
20
+ private intersectionObserver?;
20
21
  private viewing?;
21
- constructor(component: Element, trackingData: TrackingData);
22
+ constructor(component: HTMLElement, trackingData: TrackingData);
22
23
  private init;
24
+ private mutationCallback;
23
25
  private onCccConnected;
24
26
  private onCccError;
25
27
  private onView;
@@ -12,32 +12,53 @@ class CustomCodeComponentTracker {
12
12
  this.component = component;
13
13
  this.trackingData = trackingData;
14
14
  this.component = component;
15
- if (this.component.hasAttribute('data-o-tracking-initialised')) {
16
- return;
17
- }
18
15
  this.trackingData = trackingData;
19
- // this needs to instantiated here so that it can be accessed correctly in the destroy method
16
+ // we're using a mutation observer to watch for changes to the component rather than event listeners
17
+ // as dynamic imports in the app are run before the tracking client can be instantiated on second
18
+ // and subsequent page visits in a session
19
+ // the observers need to instantiated here so that they can be accessed correctly in the destroy method
20
20
  // called by the app
21
- this.observer = new IntersectionObserver(this.onChange.bind(this), {
21
+ this.mutationObserver = new MutationObserver(this.mutationCallback.bind(this));
22
+ this.mutationObserver.observe(this.component, {
23
+ attributes: true,
24
+ attributeFilter: ['data-ccc-ready', 'data-ccc-error'],
25
+ });
26
+ this.intersectionObserver = new IntersectionObserver(this.onChange.bind(this), {
22
27
  rootMargin: `0px 0px -300px 0px`,
23
28
  threshold: 0,
24
29
  });
25
- this.observer.observe(this.component);
30
+ this.intersectionObserver.observe(this.component);
26
31
  this.viewing = false;
27
32
  this.destroy = this.destroy.bind(this);
28
33
  this.init();
29
34
  }
30
35
  init() {
31
36
  this.dispatchEvent('mount');
32
- this.component.addEventListener('error', this.onCccError.bind(this));
33
- this.component.addEventListener('ccc-connected', this.onCccConnected.bind(this));
37
+ if (this.component.dataset.cccError) {
38
+ this.onCccError();
39
+ }
40
+ if (this.component.dataset.cccReady) {
41
+ this.onCccConnected();
42
+ }
34
43
  this.component.setAttribute('data-o-tracking-initialised', 'true');
35
44
  }
45
+ mutationCallback(mutationsList) {
46
+ for (const mutation of mutationsList) {
47
+ if (mutation.attributeName === 'data-ccc-ready') {
48
+ this.onCccConnected();
49
+ }
50
+ if (mutation.attributeName === 'data-ccc-error') {
51
+ this.onCccError();
52
+ }
53
+ }
54
+ }
36
55
  onCccConnected() {
37
56
  this.dispatchEvent('act', { trigger_action: 'success' });
38
57
  }
39
58
  onCccError() {
40
- this.dispatchEvent('act', { trigger_action: 'error' });
59
+ this.dispatchEvent('act', {
60
+ trigger_action: `error: ${this.component.dataset.cccError}`,
61
+ });
41
62
  }
42
63
  onView() {
43
64
  this.dispatchEvent('view');
@@ -75,15 +96,13 @@ class CustomCodeComponentTracker {
75
96
  });
76
97
  }
77
98
  destroy() {
78
- if (this.observer && this.component) {
79
- this.observer.unobserve(this.component);
80
- this.observer.disconnect();
81
- this.component.removeEventListener('ccc-connected', this.onCccConnected.bind(this));
82
- this.component.removeEventListener('error', this.onCccError.bind(this));
83
- if (this.viewing) {
84
- this.onExitView();
85
- }
86
- }
99
+ if (!this.component)
100
+ return;
101
+ this.component.removeAttribute('data-o-tracking-initialised');
102
+ this.mutationObserver?.disconnect();
103
+ this.intersectionObserver?.unobserve(this.component);
104
+ this.intersectionObserver?.disconnect();
105
+ this.viewing && this.onExitView();
87
106
  }
88
107
  }
89
108
  exports.CustomCodeComponentTracker = CustomCodeComponentTracker;
@@ -1 +1 @@
1
- {"version":3,"file":"tracking.js","sourceRoot":"","sources":["../../../../../src/components/content-tree/CustomCodeComponent/client/tracking.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tracking.js","sourceRoot":"","sources":["../../../../../src/components/content-tree/CustomCodeComponent/client/tracking.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@financial-times/cp-content-pipeline-ui",
3
- "version": "7.3.1",
3
+ "version": "7.4.0-beta.0",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -20,14 +20,22 @@ class CustomCodeComponentClient {
20
20
  type: 'custom-code-component',
21
21
  },
22
22
  }
23
- this.tracking = new CustomCodeComponentTracker(el as Element, trackingData)
23
+ this.tracking = new CustomCodeComponentTracker(
24
+ el as HTMLElement,
25
+ trackingData
26
+ )
24
27
  }
25
28
 
26
- static init(rootEl?: Element): (CustomCodeComponentClient | undefined)[] {
29
+ static init(rootEl?: Element): CustomCodeComponentClient[] | void {
27
30
  const root = rootEl instanceof Element ? rootEl : document
28
- return Array.from(root.querySelectorAll('custom-code-component')).map(
29
- (el: Element) => new CustomCodeComponentClient(el)
30
- )
31
+ return Array.from(root.querySelectorAll('custom-code-component')).reduce<
32
+ CustomCodeComponentClient[]
33
+ >((acc, el) => {
34
+ if (!el.hasAttribute('data-o-tracking-initialised')) {
35
+ acc.push(new CustomCodeComponentClient(el))
36
+ }
37
+ return acc
38
+ }, [])
31
39
  }
32
40
 
33
41
  static destroy(components: CustomCodeComponentClient[]): void {
@@ -16,22 +16,36 @@ type TrackingData = {
16
16
  * @param {TrackingData} trackingData - The specific component data
17
17
  */
18
18
  class CustomCodeComponentTracker {
19
- private observer?: IntersectionObserver
19
+ private mutationObserver?: MutationObserver
20
+ private intersectionObserver?: IntersectionObserver
20
21
  private viewing?: boolean
21
22
 
22
- constructor(private component: Element, private trackingData: TrackingData) {
23
+ constructor(
24
+ private component: HTMLElement,
25
+ private trackingData: TrackingData
26
+ ) {
23
27
  this.component = component
24
- if (this.component.hasAttribute('data-o-tracking-initialised')) {
25
- return
26
- }
27
28
  this.trackingData = trackingData
28
- // this needs to instantiated here so that it can be accessed correctly in the destroy method
29
+ // we're using a mutation observer to watch for changes to the component rather than event listeners
30
+ // as dynamic imports in the app are run before the tracking client can be instantiated on second
31
+ // and subsequent page visits in a session
32
+ // the observers need to instantiated here so that they can be accessed correctly in the destroy method
29
33
  // called by the app
30
- this.observer = new IntersectionObserver(this.onChange.bind(this), {
31
- rootMargin: `0px 0px -300px 0px`,
32
- threshold: 0,
34
+ this.mutationObserver = new MutationObserver(
35
+ this.mutationCallback.bind(this)
36
+ )
37
+ this.mutationObserver.observe(this.component, {
38
+ attributes: true,
39
+ attributeFilter: ['data-ccc-ready', 'data-ccc-error'],
33
40
  })
34
- this.observer.observe(this.component)
41
+ this.intersectionObserver = new IntersectionObserver(
42
+ this.onChange.bind(this),
43
+ {
44
+ rootMargin: `0px 0px -300px 0px`,
45
+ threshold: 0,
46
+ }
47
+ )
48
+ this.intersectionObserver.observe(this.component)
35
49
  this.viewing = false
36
50
  this.destroy = this.destroy.bind(this)
37
51
  this.init()
@@ -39,20 +53,36 @@ class CustomCodeComponentTracker {
39
53
 
40
54
  private init() {
41
55
  this.dispatchEvent('mount')
42
- this.component.addEventListener('error', this.onCccError.bind(this))
43
- this.component.addEventListener(
44
- 'ccc-connected',
45
- this.onCccConnected.bind(this)
46
- )
56
+ if (this.component.dataset.cccError) {
57
+ this.onCccError()
58
+ }
59
+
60
+ if (this.component.dataset.cccReady) {
61
+ this.onCccConnected()
62
+ }
63
+
47
64
  this.component.setAttribute('data-o-tracking-initialised', 'true')
48
65
  }
49
66
 
67
+ private mutationCallback(mutationsList: MutationRecord[]): void {
68
+ for (const mutation of mutationsList) {
69
+ if (mutation.attributeName === 'data-ccc-ready') {
70
+ this.onCccConnected()
71
+ }
72
+ if (mutation.attributeName === 'data-ccc-error') {
73
+ this.onCccError()
74
+ }
75
+ }
76
+ }
77
+
50
78
  private onCccConnected(): void {
51
79
  this.dispatchEvent('act', { trigger_action: 'success' })
52
80
  }
53
81
 
54
82
  private onCccError(): void {
55
- this.dispatchEvent('act', { trigger_action: 'error' })
83
+ this.dispatchEvent('act', {
84
+ trigger_action: `error: ${this.component.dataset.cccError}`,
85
+ })
56
86
  }
57
87
 
58
88
  private onView(): void {
@@ -99,18 +129,14 @@ class CustomCodeComponentTracker {
99
129
  }
100
130
 
101
131
  destroy(): void {
102
- if (this.observer && this.component) {
103
- this.observer.unobserve(this.component)
104
- this.observer.disconnect()
105
- this.component.removeEventListener(
106
- 'ccc-connected',
107
- this.onCccConnected.bind(this)
108
- )
109
- this.component.removeEventListener('error', this.onCccError.bind(this))
110
- if (this.viewing) {
111
- this.onExitView()
112
- }
113
- }
132
+ if (!this.component) return
133
+
134
+ this.component.removeAttribute('data-o-tracking-initialised')
135
+ this.mutationObserver?.disconnect()
136
+ this.intersectionObserver?.unobserve(this.component)
137
+ this.intersectionObserver?.disconnect()
138
+
139
+ this.viewing && this.onExitView()
114
140
  }
115
141
  }
116
142