shimmer 0.0.17 → 0.0.20
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.
- checksums.yaml +4 -4
- data/.vscode/settings.json +1 -0
- data/lib/shimmer/utils/consent_settings.rb +41 -0
- data/lib/shimmer/utils/file_helper.rb +2 -2
- data/lib/shimmer/version.rb +1 -1
- data/src/consent.ts +64 -0
- data/src/controllers/analytics.ts +42 -0
- data/src/controllers/consent.ts +52 -0
- data/src/index.ts +14 -4
- data/src/util.ts +19 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8819816445402b9ba5fc3a8ffcd9e273f85b34018cd29d0e0c99b5a338e6c37
|
4
|
+
data.tar.gz: 91786fdab270afb2c5cd89c3874284dd1701263eacbd309043ba35b87ae49ad5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f0abe61b9c8a001df68bfd019cee02d5de58c2c582ab58ed0f6899dcad78409f9136e62cd5892be9dc5167708f19b04df66afbdaccf0f925e5b986f1e9de97b
|
7
|
+
data.tar.gz: 2f8031509918cd09d64dd87158b9b119fc90f3e594c2fbdc068898bdffe29b5687cb7f6161af7d7d98061fe17ad72747388c8a01e2c381f082801d02ace39193
|
data/.vscode/settings.json
CHANGED
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shimmer
|
4
|
+
class ConsentSettings
|
5
|
+
SETTINGS = [:essential, :targeting, :statistic].freeze
|
6
|
+
DEFAULT = [:essential].freeze
|
7
|
+
|
8
|
+
SETTINGS.each do |setting|
|
9
|
+
attr_accessor setting
|
10
|
+
alias_method "#{setting}?", setting
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(cookies)
|
14
|
+
@cookies = cookies
|
15
|
+
allowed = @cookies[:consent].to_s.split(",").map(&:strip)
|
16
|
+
SETTINGS.each do |setting|
|
17
|
+
instance_variable_set "@#{setting}", DEFAULT.include?(setting) || allowed.include?(setting.to_s)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def save
|
22
|
+
value = SETTINGS.map { |e| e.to_s if instance_variable_get("@#{e}") }.compact.join(",")
|
23
|
+
@cookies.permanent[:consent] = {value: value, expires: 2.years.from_now}
|
24
|
+
end
|
25
|
+
|
26
|
+
def given?
|
27
|
+
@cookies[:consent].present?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module Consent
|
32
|
+
extend ActiveSupport::Concern
|
33
|
+
|
34
|
+
included do
|
35
|
+
helper_method :consent_settings
|
36
|
+
def consent_settings
|
37
|
+
@consent_settings ||= ConsentSettings.new(cookies)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -27,11 +27,11 @@ module Shimmer
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def image_file_path(source, width: nil, height: nil)
|
30
|
-
image_file_proxy(source, width: width, height: height)
|
30
|
+
image_file_proxy(source, width: width, height: height)&.path
|
31
31
|
end
|
32
32
|
|
33
33
|
def image_file_url(source, width: nil, height: nil)
|
34
|
-
image_file_proxy(source, width: width, height: height)
|
34
|
+
image_file_proxy(source, width: width, height: height)&.url
|
35
35
|
end
|
36
36
|
|
37
37
|
def image_file_proxy(source, width: nil, height: nil)
|
data/lib/shimmer/version.rb
CHANGED
data/src/consent.ts
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
import { getCookie, setCookie } from "./util";
|
2
|
+
|
3
|
+
const consentCategories = ["essential", "targeting", "statistic"] as const;
|
4
|
+
export type ConsentCategory = typeof consentCategories[number];
|
5
|
+
|
6
|
+
export class Consent {
|
7
|
+
#consentListeners: Record<ConsentCategory, Array<() => void>> = {
|
8
|
+
essential: [],
|
9
|
+
targeting: [],
|
10
|
+
statistic: [],
|
11
|
+
};
|
12
|
+
|
13
|
+
get permitted(): ConsentCategory[] {
|
14
|
+
return (getCookie("consent") ?? "").split(",") as ConsentCategory[];
|
15
|
+
}
|
16
|
+
|
17
|
+
set permitted(settings: ConsentCategory[]) {
|
18
|
+
setCookie("consent", settings.join(","));
|
19
|
+
settings.forEach((category) => {
|
20
|
+
this.#consentListeners[category].forEach((e) => e());
|
21
|
+
});
|
22
|
+
}
|
23
|
+
|
24
|
+
get given(): boolean {
|
25
|
+
return getCookie("consent") !== undefined;
|
26
|
+
}
|
27
|
+
|
28
|
+
permitAll(): void {
|
29
|
+
this.permitted = consentCategories.slice();
|
30
|
+
}
|
31
|
+
|
32
|
+
denyAll(): void {
|
33
|
+
this.permitted = ["essential"];
|
34
|
+
}
|
35
|
+
|
36
|
+
showSettings(): void {
|
37
|
+
const element = document.getElementById("personalization-settings");
|
38
|
+
if (element) element.hidden = false;
|
39
|
+
}
|
40
|
+
|
41
|
+
consentFor(category: ConsentCategory): Promise<void> {
|
42
|
+
return new Promise((res) => {
|
43
|
+
if (this.permitted.includes(category)) {
|
44
|
+
res();
|
45
|
+
} else {
|
46
|
+
this.#consentListeners[category].push(res);
|
47
|
+
}
|
48
|
+
});
|
49
|
+
}
|
50
|
+
|
51
|
+
async enableGoogleAnalytics(
|
52
|
+
id: string,
|
53
|
+
role: ConsentCategory = "statistic"
|
54
|
+
): Promise<void> {
|
55
|
+
await this.consentFor(role);
|
56
|
+
window.gtag("config", id);
|
57
|
+
const script = document.createElement("script");
|
58
|
+
script.setAttribute(
|
59
|
+
"src",
|
60
|
+
`https://www.googletagmanager.com/gtag/js?id=${id}`
|
61
|
+
);
|
62
|
+
document.head.appendChild(script);
|
63
|
+
}
|
64
|
+
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
|
+
|
3
|
+
interface DataEvent {
|
4
|
+
event: string;
|
5
|
+
}
|
6
|
+
|
7
|
+
declare global {
|
8
|
+
interface Window {
|
9
|
+
dataLayer?: DataEvent[];
|
10
|
+
gtag(...arg): void;
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
const dataLayer = (window.dataLayer = window.dataLayer ?? []);
|
15
|
+
|
16
|
+
window.gtag = (...arg) => {
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
18
|
+
dataLayer.push(arg as any);
|
19
|
+
};
|
20
|
+
window.gtag("js", new Date());
|
21
|
+
|
22
|
+
export default class extends Controller {
|
23
|
+
connect(): void {
|
24
|
+
this.recordPage();
|
25
|
+
}
|
26
|
+
|
27
|
+
recordAction(event: MouseEvent): void {
|
28
|
+
const data = JSON.parse(
|
29
|
+
(event.target as HTMLElement).dataset.analytics ?? "{}"
|
30
|
+
);
|
31
|
+
dataLayer.push(data);
|
32
|
+
}
|
33
|
+
|
34
|
+
recordPage(): void {
|
35
|
+
const event = {
|
36
|
+
event: "Pageview",
|
37
|
+
path: location.pathname + location.search,
|
38
|
+
host: location.host,
|
39
|
+
};
|
40
|
+
dataLayer.push(event);
|
41
|
+
}
|
42
|
+
}
|
@@ -0,0 +1,52 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
|
+
import { ConsentCategory } from "../consent";
|
3
|
+
|
4
|
+
export default class extends Controller {
|
5
|
+
static targets = ["check"];
|
6
|
+
declare checkTargets: HTMLInputElement[];
|
7
|
+
|
8
|
+
connect(): void {
|
9
|
+
this.checkTargets.forEach((input) => {
|
10
|
+
input.checked =
|
11
|
+
window.ui?.consent.permitted.includes(input.name as ConsentCategory) ||
|
12
|
+
input.name === "essential";
|
13
|
+
});
|
14
|
+
}
|
15
|
+
|
16
|
+
permitAll(event: Event): void {
|
17
|
+
event.preventDefault();
|
18
|
+
window.ui?.consent.permitAll();
|
19
|
+
this.closeAll();
|
20
|
+
}
|
21
|
+
|
22
|
+
denyAll(event: Event): void {
|
23
|
+
event.preventDefault();
|
24
|
+
window.ui?.consent.denyAll();
|
25
|
+
this.closeAll();
|
26
|
+
}
|
27
|
+
|
28
|
+
save(event: Event): void {
|
29
|
+
event.preventDefault();
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
31
|
+
window.ui!.consent.permitted = this.checkTargets
|
32
|
+
.filter((e) => e.checked)
|
33
|
+
.map((e) => e.name) as ConsentCategory[];
|
34
|
+
this.closeAll();
|
35
|
+
}
|
36
|
+
|
37
|
+
manage(event: Event): void {
|
38
|
+
event.preventDefault();
|
39
|
+
const div = document.body.querySelector(
|
40
|
+
"#personalization-settings"
|
41
|
+
) as HTMLDivElement;
|
42
|
+
if (!div) return;
|
43
|
+
(this.element as HTMLElement).hidden = true;
|
44
|
+
div.hidden = false;
|
45
|
+
}
|
46
|
+
|
47
|
+
closeAll(): void {
|
48
|
+
document
|
49
|
+
.querySelectorAll("[data-controller='consent']")
|
50
|
+
.forEach((e: HTMLElement) => (e.hidden = true));
|
51
|
+
}
|
52
|
+
}
|
data/src/index.ts
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
import type { Application } from "@hotwired/stimulus";
|
2
2
|
import { ModalPresenter } from "./modal";
|
3
3
|
import { PopoverPresenter } from "./popover";
|
4
|
+
import { Consent } from "./consent";
|
4
5
|
import RemoteNavigationController from "./controllers/remote-navigation";
|
6
|
+
import ConsentController from "./controllers/consent";
|
7
|
+
import AnalyticsController from "./controllers/analytics";
|
5
8
|
import "./touch";
|
6
9
|
|
7
10
|
export { registerServiceWorker } from "./serviceworker";
|
@@ -12,10 +15,17 @@ declare global {
|
|
12
15
|
ui?: {
|
13
16
|
modal: ModalPresenter;
|
14
17
|
popover: PopoverPresenter;
|
18
|
+
consent: Consent;
|
15
19
|
};
|
16
20
|
}
|
17
21
|
}
|
18
22
|
|
23
|
+
window.ui = {
|
24
|
+
modal: new ModalPresenter(),
|
25
|
+
popover: new PopoverPresenter(),
|
26
|
+
consent: new Consent(),
|
27
|
+
};
|
28
|
+
|
19
29
|
function createRemoteDestination(): void {
|
20
30
|
if (document.getElementById("shimmer")) {
|
21
31
|
return;
|
@@ -33,8 +43,8 @@ export async function start({
|
|
33
43
|
window.addEventListener("turbo:load", createRemoteDestination);
|
34
44
|
createRemoteDestination();
|
35
45
|
application.register("remote-navigation", RemoteNavigationController);
|
36
|
-
|
37
|
-
|
38
|
-
popover: new PopoverPresenter(),
|
39
|
-
};
|
46
|
+
application.register("consent", ConsentController);
|
47
|
+
application.register("analytics", AnalyticsController);
|
40
48
|
}
|
49
|
+
|
50
|
+
export const ui = window.ui;
|
data/src/util.ts
CHANGED
@@ -44,3 +44,22 @@ export function wait(seconds: number): Promise<void> {
|
|
44
44
|
setTimeout(res, seconds * 1000);
|
45
45
|
});
|
46
46
|
}
|
47
|
+
|
48
|
+
export function getCookie(key: string): string | null {
|
49
|
+
if (!document.cookie) return null;
|
50
|
+
return (
|
51
|
+
document.cookie
|
52
|
+
.split(";")
|
53
|
+
.map((v) => v.split("="))
|
54
|
+
.reduce((acc, v) => {
|
55
|
+
acc[decodeURIComponent(v[0].trim())] = decodeURIComponent(v[1].trim());
|
56
|
+
return acc;
|
57
|
+
}, {})[key] ?? null
|
58
|
+
);
|
59
|
+
}
|
60
|
+
|
61
|
+
export function setCookie(key: string, value: string): void {
|
62
|
+
const date = new Date();
|
63
|
+
date.setTime(date.getTime() + 365 * 24 * 60 * 60 * 1000);
|
64
|
+
document.cookie = `${key}=${value}; expires=${date.toUTCString()}`;
|
65
|
+
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shimmer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jens Ravens
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-07-
|
11
|
+
date: 2022-07-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -154,6 +154,7 @@ files:
|
|
154
154
|
- lib/shimmer/tasks/lint.rake
|
155
155
|
- lib/shimmer/tasks/s3.rake
|
156
156
|
- lib/shimmer/utils/config.rb
|
157
|
+
- lib/shimmer/utils/consent_settings.rb
|
157
158
|
- lib/shimmer/utils/file_helper.rb
|
158
159
|
- lib/shimmer/utils/file_proxy.rb
|
159
160
|
- lib/shimmer/utils/localizable.rb
|
@@ -163,6 +164,9 @@ files:
|
|
163
164
|
- lib/shimmer/version.rb
|
164
165
|
- package.json
|
165
166
|
- rollup.config.js
|
167
|
+
- src/consent.ts
|
168
|
+
- src/controllers/analytics.ts
|
169
|
+
- src/controllers/consent.ts
|
166
170
|
- src/controllers/remote-navigation.ts
|
167
171
|
- src/index.ts
|
168
172
|
- src/locale.ts
|