@duckduckgo/autoconsent 16.15.0 → 16.17.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,6 +1,10 @@
1
1
  import AutoConsentCMPBase from './base';
2
2
  export default class Admiral extends AutoConsentCMPBase {
3
3
  name: string;
4
+ private readonly consentCardSelector;
5
+ private getVrmNotice;
6
+ private isVisibleElement;
7
+ private getVrmCloseButton;
4
8
  get hasSelfTest(): boolean;
5
9
  get isIntermediate(): boolean;
6
10
  get isCosmetic(): boolean;
@@ -3,6 +3,40 @@ import AutoConsentCMPBase from './base';
3
3
  export default class Admiral extends AutoConsentCMPBase {
4
4
  name = 'Admiral';
5
5
 
6
+ private readonly consentCardSelector =
7
+ 'div > div[class*=Card] > div[class*=Frame] > div[class*=Pills] > button[class*=Pills__StyledPill]';
8
+
9
+ private getVrmNotice() {
10
+ return Array.from(document.querySelectorAll<HTMLElement>('body > div')).find((element) => {
11
+ const text = element.innerText || '';
12
+ const rect = element.getBoundingClientRect();
13
+ const style = getComputedStyle(element);
14
+
15
+ return (
16
+ style.position === 'fixed' &&
17
+ rect.width > 0 &&
18
+ rect.height > 0 &&
19
+ text.includes('Your Privacy') &&
20
+ text.includes('VRM') &&
21
+ text.includes('Admiral')
22
+ );
23
+ });
24
+ }
25
+
26
+ private isVisibleElement(element: HTMLElement) {
27
+ const rect = element.getBoundingClientRect();
28
+ const style = getComputedStyle(element);
29
+
30
+ return rect.width > 0 && rect.height > 0 && style.display !== 'none' && style.visibility !== 'hidden';
31
+ }
32
+
33
+ private getVrmCloseButton() {
34
+ const notice = this.getVrmNotice();
35
+ const closeButton = notice?.querySelector<HTMLElement>('button[aria-label="Close"]');
36
+
37
+ return closeButton && this.isVisibleElement(closeButton) ? closeButton : null;
38
+ }
39
+
6
40
  get hasSelfTest(): boolean {
7
41
  return false;
8
42
  }
@@ -16,14 +50,11 @@ export default class Admiral extends AutoConsentCMPBase {
16
50
  }
17
51
 
18
52
  async detectCmp() {
19
- return this.elementExists('div > div[class*=Card] > div[class*=Frame] > div[class*=Pills] > button[class*=Pills__StyledPill]');
53
+ return (await this.elementExists(this.consentCardSelector)) || Boolean(this.getVrmNotice());
20
54
  }
21
55
 
22
56
  async detectPopup() {
23
- return this.elementVisible(
24
- 'div > div[class*=Card] > div[class*=Frame] > div[class*=Pills] > button[class*=Pills__StyledPill]',
25
- 'any',
26
- );
57
+ return (await this.elementVisible(this.consentCardSelector, 'any')) || Boolean(this.getVrmNotice());
27
58
  }
28
59
 
29
60
  async optOut() {
@@ -34,6 +65,11 @@ export default class Admiral extends AutoConsentCMPBase {
34
65
  return await this.click(rejectAllSelector);
35
66
  }
36
67
 
68
+ const vrmCloseButton = this.getVrmCloseButton();
69
+ if (vrmCloseButton) {
70
+ return await this.clickElement(vrmCloseButton);
71
+ }
72
+
37
73
  const purposesButtonSelector =
38
74
  "xpath///button[contains(., 'Zwecke') or contains(., 'Σκοποί') or contains(., 'Purposes') or contains(., 'Цели') or contains(., 'Eesmärgid') or contains(., 'Tikslai') or contains(., 'Svrhe') or contains(., 'Cele') or contains(., 'Účely') or contains(., 'Finalidades') or contains(., 'Mērķi') or contains(., 'Scopuri') or contains(., 'Fines') or contains(., 'Ändamål') or contains(., 'Finalités') or contains(., 'Doeleinden') or contains(., 'Tarkoitukset') or contains(., 'Scopi') or contains(., 'Amaçlar') or contains(., 'Nameni') or contains(., 'Célok') or contains(., 'Formål')]";
39
75
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duckduckgo/autoconsent",
3
- "version": "16.15.0",
3
+ "version": "16.17.0",
4
4
  "description": "",
5
5
  "types": "./dist/types/web.d.ts",
6
6
  "exports": {
@@ -20,10 +20,12 @@
20
20
  "optOut": [
21
21
  {
22
22
  "if": { "visible": "#pandectes-banner .cc-deny" },
23
- "then": [{ "click": "#pandectes-banner .cc-deny" }],
23
+ "then": [{ "waitForThenClick": "#pandectes-banner .cc-deny" }],
24
24
  "else": [
25
- { "click": "#pandectes-banner .cc-settings" },
26
- { "waitForThenClick": ".pd-cp-ui-rejectAll" },
25
+ { "waitForThenClick": "#pandectes-banner .cc-settings" },
26
+ { "waitForVisible": ".pd-cp-ui-rejectAll" },
27
+ { "click": ".pd-cp-ui-rejectAll" },
28
+ { "waitForVisible": ".pd-cp-ui-save" },
27
29
  { "click": ".pd-cp-ui-save" }
28
30
  ]
29
31
  }
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "theguardian.com",
3
+ "vendorUrl": "https://www.theguardian.com/",
4
+ "comment": "Sourcepoint 'consent or pay' wall shown in the EU/EEA (message 1482251) and UK (message 1482252), where the only reject option requires a paid subscription. The container id embeds the Sourcepoint message id, so we target the pay-wall variants specifically to avoid clashing with the free-reject Sourcepoint popup used in other regions (handled by Sourcepoint-frame). Brittle: message ids may change if the campaign is reconfigured.",
5
+ "cosmetic": true,
6
+ "minimumRuleStepVersion": 2,
7
+ "runContext": {
8
+ "urlPattern": "^https?://(\\w+\\.)?theguardian\\.com/",
9
+ "main": true,
10
+ "frame": false
11
+ },
12
+ "prehideSelectors": ["div[id='sp_message_container_1482251'],div[id='sp_message_container_1482252']"],
13
+ "detectCmp": [{ "exists": "div[id='sp_message_container_1482251'],div[id='sp_message_container_1482252']" }],
14
+ "detectPopup": [{ "visible": "div[id='sp_message_container_1482251'],div[id='sp_message_container_1482252']" }],
15
+ "optIn": [],
16
+ "optOut": [
17
+ { "hide": "div[id='sp_message_container_1482251'],div[id='sp_message_container_1482252']" },
18
+ { "removeClass": "sp-message-open", "selector": "html", "optional": true }
19
+ ],
20
+ "test": [{ "visible": "div[id='sp_message_container_1482251'],div[id='sp_message_container_1482252']", "check": "none" }]
21
+ }
@@ -10,6 +10,7 @@
10
10
  { "wait": 500 }
11
11
  ],
12
12
  "optOut": [
13
+ { "wait": 500 },
13
14
  {
14
15
  "waitForThenClick": "ytm-consent-bump-v2-renderer .privacy-terms + .one-col-dialog-buttons c3-material-button:nth-child(2) button, ytm-consent-bump-v2-renderer .privacy-terms + .one-col-dialog-buttons ytm-button-renderer:nth-child(2) button"
15
16
  },