fck-honey 0.2.0 → 0.2.2

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.
package/README.md CHANGED
@@ -9,10 +9,9 @@ Open source lib for Merchants to detect if an end user has Honey browser extensi
9
9
  ```html
10
10
  <script src="https://cdn.jsdelivr.net/npm/fck-honey/dist/honey-detect.min.js"></script>
11
11
  <script>
12
- window.fckHoney.listen((el) => {
13
- // Decide how you want to handle this.
14
- // Example: pause checkout and notify the user.
15
- console.log("Honey overlay detected:", el);
12
+ window.fckHoney.listen((warn) => {
13
+ // Decide how you want to handle this. Native warn function allows you to tell the user to disable Honey.
14
+ warn("You must disable the Honey extension to continue.");
16
15
  });
17
16
  </script>
18
17
  ```
@@ -26,9 +25,17 @@ npm install fck-honey
26
25
  ```js
27
26
  import { listen } from "fck-honey";
28
27
 
29
- listen((el) => {
30
- // Decide how you want to handle this.
31
- // Example: pause checkout and notify the user.
32
- console.log("Honey overlay detected:", el);
28
+ listen((warn) => {
29
+ // Decide how you want to handle this. Native warn function allows you to tell the user to disable Honey.
30
+ warn("You must disable the Honey extension to continue.");
33
31
  });
34
32
  ```
33
+
34
+ ## Advanced Options
35
+
36
+ ```js
37
+ window.fckHoney.listen((warn, el) => {
38
+ // removeHoney defaults to true (element is auto-removed).
39
+ // Set removeHoney to false if you want to keep the Honey element for some reason.
40
+ }, { removeHoney: false });
41
+ ```
package/dist/esm/index.js CHANGED
@@ -12,6 +12,36 @@ var __assign = (this && this.__assign) || function () {
12
12
  var DEFAULT_Z_NEAR_MAX = 2147480000;
13
13
  var UUIDISH_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
14
14
  var TARGET_SELECTOR = "div[id]";
15
+ var OVERLAY_STYLE_ID = "simple-overlay-styles";
16
+ function showOverlay(message) {
17
+ if (typeof document === "undefined")
18
+ return function () { };
19
+ if (!document.getElementById(OVERLAY_STYLE_ID)) {
20
+ var style = document.createElement("style");
21
+ style.id = OVERLAY_STYLE_ID;
22
+ style.textContent =
23
+ ".simple-overlay{position:fixed;inset:0;background:rgba(0,0,0,0.6);z-index:999999;display:flex;align-items:center;justify-content:center;pointer-events:all;}" +
24
+ ".simple-overlay-message{background:#ffffff;padding:16px 20px;border-radius:8px;font-size:14px;max-width:80%;text-align:center;box-shadow:0 10px 30px rgba(0,0,0,0.3);}";
25
+ document.head.appendChild(style);
26
+ }
27
+ var overlay = document.createElement("div");
28
+ overlay.className = "simple-overlay";
29
+ var messageEl = document.createElement("div");
30
+ messageEl.className = "simple-overlay-message";
31
+ messageEl.innerHTML = message;
32
+ overlay.appendChild(messageEl);
33
+ if (document.body) {
34
+ document.body.appendChild(overlay);
35
+ }
36
+ var prevOverflow = document.body ? document.body.style.overflow : "";
37
+ if (document.body)
38
+ document.body.style.overflow = "hidden";
39
+ return function hideOverlay() {
40
+ overlay.remove();
41
+ if (document.body)
42
+ document.body.style.overflow = prevOverflow;
43
+ };
44
+ }
15
45
  function parseZIndex(cs, el) {
16
46
  var computed = parseInt(cs.zIndex, 10);
17
47
  if (isFinite(computed))
@@ -51,12 +81,19 @@ function looksLikeTargetDiv(el, zNearMax, uuidGate, debug) {
51
81
  console.log("+++ match", el);
52
82
  return true;
53
83
  }
54
- function scanElement(el, seen, zNearMax, uuidGate, debug, onMatch) {
84
+ function scanElement(el, seen, zNearMax, uuidGate, debug, removeHoney, onMatch, warn) {
55
85
  var _a;
56
86
  if (el instanceof HTMLDivElement && el.matches(TARGET_SELECTOR)) {
57
87
  if (seen.indexOf(el) === -1 && looksLikeTargetDiv(el, zNearMax, uuidGate, debug)) {
58
88
  seen.push(el);
59
- onMatch(el);
89
+ if (removeHoney && el.parentNode)
90
+ el.parentNode.removeChild(el);
91
+ if (removeHoney) {
92
+ onMatch(warn);
93
+ }
94
+ else {
95
+ onMatch(warn, el);
96
+ }
60
97
  }
61
98
  }
62
99
  var divs = (_a = el.querySelectorAll) === null || _a === void 0 ? void 0 : _a.call(el, TARGET_SELECTOR);
@@ -66,18 +103,27 @@ function scanElement(el, seen, zNearMax, uuidGate, debug, onMatch) {
66
103
  var d = divs[i];
67
104
  if (seen.indexOf(d) === -1 && looksLikeTargetDiv(d, zNearMax, uuidGate, debug)) {
68
105
  seen.push(d);
69
- onMatch(d);
106
+ if (removeHoney && d.parentNode)
107
+ d.parentNode.removeChild(d);
108
+ if (removeHoney) {
109
+ onMatch(warn);
110
+ }
111
+ else {
112
+ onMatch(warn, d);
113
+ }
70
114
  }
71
115
  }
72
116
  }
73
117
  export function startHoneyOverlayObserver(options) {
74
- var _a, _b, _c, _d;
118
+ var _a, _b, _c, _d, _e;
75
119
  if (options === void 0) { options = {}; }
76
120
  var seen = [];
77
121
  var zNearMax = (_a = options.zNearMax) !== null && _a !== void 0 ? _a : DEFAULT_Z_NEAR_MAX;
78
122
  var uuidGate = (_b = options.uuidGate) !== null && _b !== void 0 ? _b : true;
79
123
  var debug = (_c = options.debug) !== null && _c !== void 0 ? _c : false;
80
- var onMatch = (_d = options.onMatch) !== null && _d !== void 0 ? _d : (function () { });
124
+ var removeHoney = (_d = options.removeHoney) !== null && _d !== void 0 ? _d : true;
125
+ var warn = function (message) { return showOverlay(message); };
126
+ var onMatch = (_e = options.onMatch) !== null && _e !== void 0 ? _e : (function () { });
81
127
  var mo = new MutationObserver(function (mutations) {
82
128
  for (var _i = 0, mutations_1 = mutations; _i < mutations_1.length; _i++) {
83
129
  var m = mutations_1[_i];
@@ -94,17 +140,17 @@ export function startHoneyOverlayObserver(options) {
94
140
  for (var i = 0; i < m.addedNodes.length; i += 1) {
95
141
  var node = m.addedNodes[i];
96
142
  if (node.nodeType === Node.ELEMENT_NODE) {
97
- scanElement(node, seen, zNearMax, uuidGate, debug, onMatch);
143
+ scanElement(node, seen, zNearMax, uuidGate, debug, removeHoney, onMatch, warn);
98
144
  }
99
145
  }
100
146
  }
101
147
  if (m.target instanceof Element) {
102
- scanElement(m.target, seen, zNearMax, uuidGate, debug, onMatch);
148
+ scanElement(m.target, seen, zNearMax, uuidGate, debug, removeHoney, onMatch, warn);
103
149
  }
104
150
  }
105
151
  else if (m.type === "attributes") {
106
152
  if (m.target instanceof Element) {
107
- scanElement(m.target, seen, zNearMax, uuidGate, debug, onMatch);
153
+ scanElement(m.target, seen, zNearMax, uuidGate, debug, removeHoney, onMatch, warn);
108
154
  }
109
155
  }
110
156
  }
@@ -115,7 +161,7 @@ export function startHoneyOverlayObserver(options) {
115
161
  attributes: true,
116
162
  attributeFilter: ["style", "class", "id"]
117
163
  });
118
- scanElement(document.documentElement, seen, zNearMax, uuidGate, debug, onMatch);
164
+ scanElement(document.documentElement, seen, zNearMax, uuidGate, debug, removeHoney, onMatch, warn);
119
165
  return {
120
166
  stop: function () { return mo.disconnect(); }
121
167
  };
@@ -13,6 +13,36 @@ var __assign = (this && this.__assign) || function () {
13
13
  var DEFAULT_Z_NEAR_MAX = 2147480000;
14
14
  var UUIDISH_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
15
15
  var TARGET_SELECTOR = "div[id]";
16
+ var OVERLAY_STYLE_ID = "simple-overlay-styles";
17
+ function showOverlay(message) {
18
+ if (typeof document === "undefined")
19
+ return function () { };
20
+ if (!document.getElementById(OVERLAY_STYLE_ID)) {
21
+ var style = document.createElement("style");
22
+ style.id = OVERLAY_STYLE_ID;
23
+ style.textContent =
24
+ ".simple-overlay{position:fixed;inset:0;background:rgba(0,0,0,0.6);z-index:999999;display:flex;align-items:center;justify-content:center;pointer-events:all;}" +
25
+ ".simple-overlay-message{background:#ffffff;padding:16px 20px;border-radius:8px;font-size:14px;max-width:80%;text-align:center;box-shadow:0 10px 30px rgba(0,0,0,0.3);}";
26
+ document.head.appendChild(style);
27
+ }
28
+ var overlay = document.createElement("div");
29
+ overlay.className = "simple-overlay";
30
+ var messageEl = document.createElement("div");
31
+ messageEl.className = "simple-overlay-message";
32
+ messageEl.innerHTML = message;
33
+ overlay.appendChild(messageEl);
34
+ if (document.body) {
35
+ document.body.appendChild(overlay);
36
+ }
37
+ var prevOverflow = document.body ? document.body.style.overflow : "";
38
+ if (document.body)
39
+ document.body.style.overflow = "hidden";
40
+ return function hideOverlay() {
41
+ overlay.remove();
42
+ if (document.body)
43
+ document.body.style.overflow = prevOverflow;
44
+ };
45
+ }
16
46
  function parseZIndex(cs, el) {
17
47
  var computed = parseInt(cs.zIndex, 10);
18
48
  if (isFinite(computed))
@@ -52,12 +82,19 @@ function looksLikeTargetDiv(el, zNearMax, uuidGate, debug) {
52
82
  console.log("+++ match", el);
53
83
  return true;
54
84
  }
55
- function scanElement(el, seen, zNearMax, uuidGate, debug, onMatch) {
85
+ function scanElement(el, seen, zNearMax, uuidGate, debug, removeHoney, onMatch, warn) {
56
86
  var _a;
57
87
  if (el instanceof HTMLDivElement && el.matches(TARGET_SELECTOR)) {
58
88
  if (seen.indexOf(el) === -1 && looksLikeTargetDiv(el, zNearMax, uuidGate, debug)) {
59
89
  seen.push(el);
60
- onMatch(el);
90
+ if (removeHoney && el.parentNode)
91
+ el.parentNode.removeChild(el);
92
+ if (removeHoney) {
93
+ onMatch(warn);
94
+ }
95
+ else {
96
+ onMatch(warn, el);
97
+ }
61
98
  }
62
99
  }
63
100
  var divs = (_a = el.querySelectorAll) === null || _a === void 0 ? void 0 : _a.call(el, TARGET_SELECTOR);
@@ -67,18 +104,27 @@ function scanElement(el, seen, zNearMax, uuidGate, debug, onMatch) {
67
104
  var d = divs[i];
68
105
  if (seen.indexOf(d) === -1 && looksLikeTargetDiv(d, zNearMax, uuidGate, debug)) {
69
106
  seen.push(d);
70
- onMatch(d);
107
+ if (removeHoney && d.parentNode)
108
+ d.parentNode.removeChild(d);
109
+ if (removeHoney) {
110
+ onMatch(warn);
111
+ }
112
+ else {
113
+ onMatch(warn, d);
114
+ }
71
115
  }
72
116
  }
73
117
  }
74
118
  function startHoneyOverlayObserver(options) {
75
- var _a, _b, _c, _d;
119
+ var _a, _b, _c, _d, _e;
76
120
  if (options === void 0) { options = {}; }
77
121
  var seen = [];
78
122
  var zNearMax = (_a = options.zNearMax) !== null && _a !== void 0 ? _a : DEFAULT_Z_NEAR_MAX;
79
123
  var uuidGate = (_b = options.uuidGate) !== null && _b !== void 0 ? _b : true;
80
124
  var debug = (_c = options.debug) !== null && _c !== void 0 ? _c : false;
81
- var onMatch = (_d = options.onMatch) !== null && _d !== void 0 ? _d : (function () { });
125
+ var removeHoney = (_d = options.removeHoney) !== null && _d !== void 0 ? _d : true;
126
+ var warn = function (message) { return showOverlay(message); };
127
+ var onMatch = (_e = options.onMatch) !== null && _e !== void 0 ? _e : (function () { });
82
128
  var mo = new MutationObserver(function (mutations) {
83
129
  for (var _i = 0, mutations_1 = mutations; _i < mutations_1.length; _i++) {
84
130
  var m = mutations_1[_i];
@@ -95,17 +141,17 @@ function startHoneyOverlayObserver(options) {
95
141
  for (var i = 0; i < m.addedNodes.length; i += 1) {
96
142
  var node = m.addedNodes[i];
97
143
  if (node.nodeType === Node.ELEMENT_NODE) {
98
- scanElement(node, seen, zNearMax, uuidGate, debug, onMatch);
144
+ scanElement(node, seen, zNearMax, uuidGate, debug, removeHoney, onMatch, warn);
99
145
  }
100
146
  }
101
147
  }
102
148
  if (m.target instanceof Element) {
103
- scanElement(m.target, seen, zNearMax, uuidGate, debug, onMatch);
149
+ scanElement(m.target, seen, zNearMax, uuidGate, debug, removeHoney, onMatch, warn);
104
150
  }
105
151
  }
106
152
  else if (m.type === "attributes") {
107
153
  if (m.target instanceof Element) {
108
- scanElement(m.target, seen, zNearMax, uuidGate, debug, onMatch);
154
+ scanElement(m.target, seen, zNearMax, uuidGate, debug, removeHoney, onMatch, warn);
109
155
  }
110
156
  }
111
157
  }
@@ -116,7 +162,7 @@ function startHoneyOverlayObserver(options) {
116
162
  attributes: true,
117
163
  attributeFilter: ["style", "class", "id"]
118
164
  });
119
- scanElement(document.documentElement, seen, zNearMax, uuidGate, debug, onMatch);
165
+ scanElement(document.documentElement, seen, zNearMax, uuidGate, debug, removeHoney, onMatch, warn);
120
166
  return {
121
167
  stop: function () { return mo.disconnect(); }
122
168
  };
@@ -1,9 +1,11 @@
1
- export type MatchCallback = (el: HTMLDivElement) => void;
1
+ export type WarnCallback = (message: string) => () => void;
2
+ export type MatchCallback = (warn: WarnCallback, el?: HTMLDivElement) => void;
2
3
  export interface ObserverOptions {
3
4
  onMatch?: MatchCallback;
4
5
  uuidGate?: boolean;
5
6
  zNearMax?: number;
6
7
  debug?: boolean;
8
+ removeHoney?: boolean;
7
9
  }
8
10
  export interface ObserverHandle {
9
11
  stop: () => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fck-honey",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Detects Honey browser extension overlays for merchants.",
5
5
  "license": "MIT",
6
6
  "main": "dist/honey-detect.js",