Skip to content

Commit

Permalink
start new react cookie popup setup
Browse files Browse the repository at this point in the history
  • Loading branch information
martinbroos committed Mar 31, 2023
1 parent 1063a07 commit d3eee59
Show file tree
Hide file tree
Showing 13 changed files with 4,203 additions and 196 deletions.
26 changes: 23 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,24 @@
/node_modules
/lib
/build
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
4,005 changes: 3,973 additions & 32 deletions package-lock.json

Large diffs are not rendered by default.

35 changes: 25 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,28 @@
"name": "@freshheads/cookie-guard",
"version": "3.0.0",
"description": "Let user manage cookie usage",
"main": "build/index.js",
"types": "build/index.d.ts",
"scripts": {
"dev": "vite",
"build": "tsup src/js/index.ts --format esm,cjs --dts --external react",
"prepare": "npm run build"
},
"files": [
"build",
"dist",
"styles"
],
"scripts": {
"build": "tsc",
"build:watch": "tsc --watch",
"prepare": "npm run build"
"types": "./dist/index.d.ts",
"exports": {
".": {
"require": "./dist/index.js",
"import": "./dist/index.mjs"
}
},
"repository": {
"type": "git",
"url": "git+https://github.com/freshheads/cookie-guard.git"
},
"engines": {
"node": ">= 6.9.0 || >= 8.9.0"
"node": ">=14.0.0"
},
"author": "Freshheads",
"license": "MIT",
Expand All @@ -28,15 +33,25 @@
"devDependencies": {
"@types/js-cookie": "^2.2.2",
"@types/lodash": "^4.14.134",
"typescript": "^3.4.3"
"@types/react": "^18.0.31",
"tsup": "^6.7.0",
"typescript": "^4.9.5",
"react": "18.2.0",
"react-dom": "18.2.0",
"@vitejs/plugin-react": "^3.1.0",
"vite": "^4.2.0"
},
"dependencies": {
"js-cookie": "^2.2.0",
"lodash": "^4.17.11"
},
"peerDependencies": {
"react": ">=17",
"react-dom": ">=17"
},
"homepage": "https://github.com/freshheads/cookie-guard#readme",
"directories": {
"doc": "doc",
"lib": "build"
"lib": "dist"
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
141 changes: 141 additions & 0 deletions src/js.old/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import { merge } from 'lodash';
import CookieConsentStore from './CookieConsentStore';
import CookieConsentNotification from './CookieConsentNotification';
import AutoAcceptRequestWatcher from './AutoAcceptRequestWatcher';
import { isCurrentPageExcluded } from './helpers';
import { OptionsType, UserOptionsType } from './types';

class FHCookieGuard {
public cookieConsentNotificationElement: HTMLElement | null;
public cookieConsentNotification ?: CookieConsentNotification;
public cookieConsentStore: CookieConsentStore;
private options: OptionsType;

constructor(notificationElementSelector = '.js-cookie-alert', options: UserOptionsType = {}) {
this.cookieConsentNotificationElement = document.querySelector(notificationElementSelector);

const defaultOptions: OptionsType = {
selectors: {
accept: '.js-cookie-alert-accept',
refuse: '.js-cookie-alert-refuse',
cookieGuard: '.js-cookie-guarded',
parentContainer: 'body'
},
cookieName: 'cookies-accepted',
cookieAttributes: {
expires: 90,
domain: window.location.hostname,
path: '/',
},
autoAcceptCookieConsentAfterRequestCount: null,
activeClass: 'cookie-alert-is-active',
excludedPageUrls: [],
callbacks: {
onOpenCookieAlert: null,
onCloseCookieAlert: null,
}
};

// merge default options with user options coming from initialisation and data attributes on notification element
this.options = merge<OptionsType, Partial<OptionsType>, Partial<OptionsType>>(
defaultOptions,
options,
this.cookieConsentNotificationElement ? this.cookieConsentNotificationElement.dataset : {}
);

this.cookieConsentStore = new CookieConsentStore(
this.options.cookieName,
this.options.cookieAttributes,
);

this.init();
}

public init() {
this.initCookieConsentNotificationIfNeeded();
this.initAutoAcceptCookieConsentIfNeeded();
}

private initCookieConsentNotificationIfNeeded() {
if (!this.cookieConsentNotificationElement || this.cookieConsentStore.hasBeenSet() || isCurrentPageExcluded(this.options.excludedPageUrls)) {
return;
}

this.cookieConsentNotification = new CookieConsentNotification(
this.cookieConsentNotificationElement,
this.cookieConsentStore,
this.options,
this.enableCookieGuardedContent
);

if (this.cookieConsentNotification) {
this.cookieConsentNotification.show();
}
}

private initAutoAcceptCookieConsentIfNeeded() {
const { autoAcceptCookieConsentAfterRequestCount, cookieAttributes } = this.options;

if (autoAcceptCookieConsentAfterRequestCount === null || this.cookieConsentStore.hasBeenSet() || isCurrentPageExcluded(this.options.excludedPageUrls)) {
return;
}

new AutoAcceptRequestWatcher(
this.cookieConsentStore,
autoAcceptCookieConsentAfterRequestCount,
cookieAttributes,
() => {
this.enableCookieGuardedContent();

if (this.cookieConsentNotification) {
this.cookieConsentNotification.close();
}
}
);
}

public enableCookieGuardedContent() {
const { selectors } = this.options;

const cookieGuardedElements: NodeList = document.querySelectorAll(selectors.cookieGuard);
const parser = new DOMParser();

if (!cookieGuardedElements.length) {
return;
}

Array.prototype.forEach.call(cookieGuardedElements, (element: HTMLElement) => {
// element must have a content data attribute
if (!element.dataset.content) {
return;
}

// Get script from content attribute
let content = parser.parseFromString(element.dataset.content, 'text/html');
let guardedScript = content.querySelector('script');

if (!guardedScript) {
return;
}

// Create a new script element so DOM can execute
let newScriptElement = document.createElement('script');

// Check if the new script tag has a external src
if (guardedScript.src) {
newScriptElement.src = guardedScript.src;
} else {
newScriptElement.innerHTML = guardedScript.innerHTML;
}

// Replace the meta tag with the new script element
let parentNode = element.parentNode;

if (parentNode) {
parentNode.replaceChild(newScriptElement, element);
}
});
}
}

export default FHCookieGuard;
File renamed without changes.
11 changes: 11 additions & 0 deletions src/js/components/CookiePopup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';

const CookiePopup = () => {
return (
<div>
Test fsdfds
</div>
);
};

export default CookiePopup;
142 changes: 1 addition & 141 deletions src/js/index.ts
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,141 +1 @@
import { merge } from 'lodash';
import CookieConsentStore from './CookieConsentStore';
import CookieConsentNotification from './CookieConsentNotification';
import AutoAcceptRequestWatcher from './AutoAcceptRequestWatcher';
import { isCurrentPageExcluded } from './helpers';
import { OptionsType, UserOptionsType } from './types';

class FHCookieGuard {
public cookieConsentNotificationElement: HTMLElement | null;
public cookieConsentNotification ?: CookieConsentNotification;
public cookieConsentStore: CookieConsentStore;
private options: OptionsType;

constructor(notificationElementSelector = '.js-cookie-alert', options: UserOptionsType = {}) {
this.cookieConsentNotificationElement = document.querySelector(notificationElementSelector);

const defaultOptions: OptionsType = {
selectors: {
accept: '.js-cookie-alert-accept',
refuse: '.js-cookie-alert-refuse',
cookieGuard: '.js-cookie-guarded',
parentContainer: 'body'
},
cookieName: 'cookies-accepted',
cookieAttributes: {
expires: 90,
domain: window.location.hostname,
path: '/',
},
autoAcceptCookieConsentAfterRequestCount: null,
activeClass: 'cookie-alert-is-active',
excludedPageUrls: [],
callbacks: {
onOpenCookieAlert: null,
onCloseCookieAlert: null,
}
};

// merge default options with user options coming from initialisation and data attributes on notification element
this.options = merge<OptionsType, Partial<OptionsType>, Partial<OptionsType>>(
defaultOptions,
options,
this.cookieConsentNotificationElement ? this.cookieConsentNotificationElement.dataset : {}
);

this.cookieConsentStore = new CookieConsentStore(
this.options.cookieName,
this.options.cookieAttributes,
);

this.init();
}

public init() {
this.initCookieConsentNotificationIfNeeded();
this.initAutoAcceptCookieConsentIfNeeded();
}

private initCookieConsentNotificationIfNeeded() {
if (!this.cookieConsentNotificationElement || this.cookieConsentStore.hasBeenSet() || isCurrentPageExcluded(this.options.excludedPageUrls)) {
return;
}

this.cookieConsentNotification = new CookieConsentNotification(
this.cookieConsentNotificationElement,
this.cookieConsentStore,
this.options,
this.enableCookieGuardedContent
);

if (this.cookieConsentNotification) {
this.cookieConsentNotification.show();
}
}

private initAutoAcceptCookieConsentIfNeeded() {
const { autoAcceptCookieConsentAfterRequestCount, cookieAttributes } = this.options;

if (autoAcceptCookieConsentAfterRequestCount === null || this.cookieConsentStore.hasBeenSet() || isCurrentPageExcluded(this.options.excludedPageUrls)) {
return;
}

new AutoAcceptRequestWatcher(
this.cookieConsentStore,
autoAcceptCookieConsentAfterRequestCount,
cookieAttributes,
() => {
this.enableCookieGuardedContent();

if (this.cookieConsentNotification) {
this.cookieConsentNotification.close();
}
}
);
}

public enableCookieGuardedContent() {
const { selectors } = this.options;

const cookieGuardedElements: NodeList = document.querySelectorAll(selectors.cookieGuard);
const parser = new DOMParser();

if (!cookieGuardedElements.length) {
return;
}

Array.prototype.forEach.call(cookieGuardedElements, (element: HTMLElement) => {
// element must have a content data attribute
if (!element.dataset.content) {
return;
}

// Get script from content attribute
let content = parser.parseFromString(element.dataset.content, 'text/html');
let guardedScript = content.querySelector('script');

if (!guardedScript) {
return;
}

// Create a new script element so DOM can execute
let newScriptElement = document.createElement('script');

// Check if the new script tag has a external src
if (guardedScript.src) {
newScriptElement.src = guardedScript.src;
} else {
newScriptElement.innerHTML = guardedScript.innerHTML;
}

// Replace the meta tag with the new script element
let parentNode = element.parentNode;

if (parentNode) {
parentNode.replaceChild(newScriptElement, element);
}
});
}
}

export default FHCookieGuard;
export * from './components/CookiePopup';
Loading

0 comments on commit d3eee59

Please sign in to comment.