fck-honey 0.1.2 → 0.1.4

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
@@ -7,7 +7,7 @@ Open source lib for Merchants to detect if an end user has Honey browser extensi
7
7
  ## Usage (Browser Global)
8
8
 
9
9
  ```html
10
- <script src="https://cdn.jsdelivr.net/npm/fck-honey@0.1/dist/honey-detect.min.js"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/fck-honey"></script>
11
11
  <script>
12
12
  window.fckHoney.listen((el) => {
13
13
  // Decide how you want to handle this.
package/dist/esm/index.js CHANGED
@@ -11,69 +11,99 @@ var __assign = (this && this.__assign) || function () {
11
11
  };
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
- function parseZIndex(cs) {
15
- var z = parseInt(cs.zIndex, 10);
16
- return isFinite(z) ? z : null;
14
+ var TARGET_SELECTOR = "div[id]";
15
+ function parseZIndex(cs, el) {
16
+ var computed = parseInt(cs.zIndex, 10);
17
+ if (isFinite(computed))
18
+ return computed;
19
+ var inline = parseInt(el.style.zIndex, 10);
20
+ return isFinite(inline) ? inline : null;
17
21
  }
18
- function looksLikeTargetDiv(el, zNearMax, uuidGate) {
19
- if (!el.id)
22
+ function looksLikeTargetDiv(el, zNearMax, uuidGate, debug) {
23
+ if (!el.id) {
24
+ if (debug)
25
+ console.log("+++ reject: no id", el);
20
26
  return false;
21
- if (uuidGate && !UUIDISH_RE.test(el.id))
27
+ }
28
+ if (uuidGate && !UUIDISH_RE.test(el.id)) {
29
+ if (debug)
30
+ console.log("+++ reject: uuid", el.id);
22
31
  return false;
32
+ }
23
33
  var cs = getComputedStyle(el);
24
- var z = parseZIndex(cs);
25
- if (z === null || z < zNearMax)
34
+ var z = parseZIndex(cs, el);
35
+ if (z === null || z < zNearMax) {
36
+ if (debug)
37
+ console.log("+++ reject: z-index", z, cs.zIndex, el.style.zIndex, el);
26
38
  return false;
27
- if (cs.display === "none")
39
+ }
40
+ if (cs.display === "none") {
41
+ if (debug)
42
+ console.log("+++ reject: display none", el);
28
43
  return false;
29
- if (el.shadowRoot)
44
+ }
45
+ if (el.shadowRoot) {
46
+ if (debug)
47
+ console.log("+++ reject: shadowRoot", el);
30
48
  return false;
49
+ }
50
+ if (debug)
51
+ console.log("+++ match", el);
31
52
  return true;
32
53
  }
33
- function checkNode(node, seen, zNearMax, uuidGate, onMatch) {
54
+ function scanElement(el, seen, zNearMax, uuidGate, debug, onMatch) {
34
55
  var _a;
35
- if (!(node instanceof Element))
36
- return;
37
- if (node instanceof HTMLDivElement &&
38
- seen.indexOf(node) === -1 &&
39
- looksLikeTargetDiv(node, zNearMax, uuidGate)) {
40
- seen.push(node);
41
- onMatch(node);
56
+ if (el instanceof HTMLDivElement && el.matches(TARGET_SELECTOR)) {
57
+ if (seen.indexOf(el) === -1 && looksLikeTargetDiv(el, zNearMax, uuidGate, debug)) {
58
+ seen.push(el);
59
+ onMatch(el);
60
+ }
42
61
  }
43
- var divs = (_a = node.querySelectorAll) === null || _a === void 0 ? void 0 : _a.call(node, "div[id]");
62
+ var divs = (_a = el.querySelectorAll) === null || _a === void 0 ? void 0 : _a.call(el, TARGET_SELECTOR);
44
63
  if (!divs)
45
64
  return;
46
65
  for (var i = 0; i < divs.length; i += 1) {
47
66
  var d = divs[i];
48
- if (seen.indexOf(d) === -1 && looksLikeTargetDiv(d, zNearMax, uuidGate)) {
67
+ if (seen.indexOf(d) === -1 && looksLikeTargetDiv(d, zNearMax, uuidGate, debug)) {
49
68
  seen.push(d);
50
69
  onMatch(d);
51
70
  }
52
71
  }
53
72
  }
54
73
  export function startHoneyOverlayObserver(options) {
55
- var _a, _b, _c;
74
+ var _a, _b, _c, _d;
56
75
  if (options === void 0) { options = {}; }
57
76
  var seen = [];
58
77
  var zNearMax = (_a = options.zNearMax) !== null && _a !== void 0 ? _a : DEFAULT_Z_NEAR_MAX;
59
78
  var uuidGate = (_b = options.uuidGate) !== null && _b !== void 0 ? _b : true;
60
- var onMatch = (_c = options.onMatch) !== null && _c !== void 0 ? _c : (function () { });
79
+ var debug = (_c = options.debug) !== null && _c !== void 0 ? _c : false;
80
+ var onMatch = (_d = options.onMatch) !== null && _d !== void 0 ? _d : (function () { });
61
81
  var mo = new MutationObserver(function (mutations) {
62
82
  for (var _i = 0, mutations_1 = mutations; _i < mutations_1.length; _i++) {
63
83
  var m = mutations_1[_i];
84
+ if (debug &&
85
+ (m.target === document.body || (m.target instanceof Node && document.body.contains(m.target)))) {
86
+ console.log("+++ body mutation", m.type, m.target);
87
+ }
88
+ }
89
+ for (var _a = 0, mutations_2 = mutations; _a < mutations_2.length; _a++) {
90
+ var m = mutations_2[_a];
64
91
  if (m.type === "childList") {
65
- for (var i = 0; i < m.addedNodes.length; i += 1) {
66
- checkNode(m.addedNodes[i], seen, zNearMax, uuidGate, onMatch);
92
+ if (m.addedNodes.length) {
93
+ for (var i = 0; i < m.addedNodes.length; i += 1) {
94
+ var node = m.addedNodes[i];
95
+ if (node.nodeType === Node.ELEMENT_NODE) {
96
+ scanElement(node, seen, zNearMax, uuidGate, debug, onMatch);
97
+ }
98
+ }
99
+ }
100
+ if (m.target instanceof Element) {
101
+ scanElement(m.target, seen, zNearMax, uuidGate, debug, onMatch);
67
102
  }
68
103
  }
69
104
  else if (m.type === "attributes") {
70
- var el = m.target;
71
- if (el instanceof HTMLDivElement &&
72
- el.id &&
73
- seen.indexOf(el) === -1 &&
74
- looksLikeTargetDiv(el, zNearMax, uuidGate)) {
75
- seen.push(el);
76
- onMatch(el);
105
+ if (m.target instanceof Element) {
106
+ scanElement(m.target, seen, zNearMax, uuidGate, debug, onMatch);
77
107
  }
78
108
  }
79
109
  }
@@ -84,7 +114,7 @@ export function startHoneyOverlayObserver(options) {
84
114
  attributes: true,
85
115
  attributeFilter: ["style", "class", "id"]
86
116
  });
87
- checkNode(document.documentElement, seen, zNearMax, uuidGate, onMatch);
117
+ scanElement(document.documentElement, seen, zNearMax, uuidGate, debug, onMatch);
88
118
  return {
89
119
  stop: function () { return mo.disconnect(); }
90
120
  };
@@ -12,69 +12,99 @@ var __assign = (this && this.__assign) || function () {
12
12
  };
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
- function parseZIndex(cs) {
16
- var z = parseInt(cs.zIndex, 10);
17
- return isFinite(z) ? z : null;
15
+ var TARGET_SELECTOR = "div[id]";
16
+ function parseZIndex(cs, el) {
17
+ var computed = parseInt(cs.zIndex, 10);
18
+ if (isFinite(computed))
19
+ return computed;
20
+ var inline = parseInt(el.style.zIndex, 10);
21
+ return isFinite(inline) ? inline : null;
18
22
  }
19
- function looksLikeTargetDiv(el, zNearMax, uuidGate) {
20
- if (!el.id)
23
+ function looksLikeTargetDiv(el, zNearMax, uuidGate, debug) {
24
+ if (!el.id) {
25
+ if (debug)
26
+ console.log("+++ reject: no id", el);
21
27
  return false;
22
- if (uuidGate && !UUIDISH_RE.test(el.id))
28
+ }
29
+ if (uuidGate && !UUIDISH_RE.test(el.id)) {
30
+ if (debug)
31
+ console.log("+++ reject: uuid", el.id);
23
32
  return false;
33
+ }
24
34
  var cs = getComputedStyle(el);
25
- var z = parseZIndex(cs);
26
- if (z === null || z < zNearMax)
35
+ var z = parseZIndex(cs, el);
36
+ if (z === null || z < zNearMax) {
37
+ if (debug)
38
+ console.log("+++ reject: z-index", z, cs.zIndex, el.style.zIndex, el);
27
39
  return false;
28
- if (cs.display === "none")
40
+ }
41
+ if (cs.display === "none") {
42
+ if (debug)
43
+ console.log("+++ reject: display none", el);
29
44
  return false;
30
- if (el.shadowRoot)
45
+ }
46
+ if (el.shadowRoot) {
47
+ if (debug)
48
+ console.log("+++ reject: shadowRoot", el);
31
49
  return false;
50
+ }
51
+ if (debug)
52
+ console.log("+++ match", el);
32
53
  return true;
33
54
  }
34
- function checkNode(node, seen, zNearMax, uuidGate, onMatch) {
55
+ function scanElement(el, seen, zNearMax, uuidGate, debug, onMatch) {
35
56
  var _a;
36
- if (!(node instanceof Element))
37
- return;
38
- if (node instanceof HTMLDivElement &&
39
- seen.indexOf(node) === -1 &&
40
- looksLikeTargetDiv(node, zNearMax, uuidGate)) {
41
- seen.push(node);
42
- onMatch(node);
57
+ if (el instanceof HTMLDivElement && el.matches(TARGET_SELECTOR)) {
58
+ if (seen.indexOf(el) === -1 && looksLikeTargetDiv(el, zNearMax, uuidGate, debug)) {
59
+ seen.push(el);
60
+ onMatch(el);
61
+ }
43
62
  }
44
- var divs = (_a = node.querySelectorAll) === null || _a === void 0 ? void 0 : _a.call(node, "div[id]");
63
+ var divs = (_a = el.querySelectorAll) === null || _a === void 0 ? void 0 : _a.call(el, TARGET_SELECTOR);
45
64
  if (!divs)
46
65
  return;
47
66
  for (var i = 0; i < divs.length; i += 1) {
48
67
  var d = divs[i];
49
- if (seen.indexOf(d) === -1 && looksLikeTargetDiv(d, zNearMax, uuidGate)) {
68
+ if (seen.indexOf(d) === -1 && looksLikeTargetDiv(d, zNearMax, uuidGate, debug)) {
50
69
  seen.push(d);
51
70
  onMatch(d);
52
71
  }
53
72
  }
54
73
  }
55
74
  function startHoneyOverlayObserver(options) {
56
- var _a, _b, _c;
75
+ var _a, _b, _c, _d;
57
76
  if (options === void 0) { options = {}; }
58
77
  var seen = [];
59
78
  var zNearMax = (_a = options.zNearMax) !== null && _a !== void 0 ? _a : DEFAULT_Z_NEAR_MAX;
60
79
  var uuidGate = (_b = options.uuidGate) !== null && _b !== void 0 ? _b : true;
61
- var onMatch = (_c = options.onMatch) !== null && _c !== void 0 ? _c : (function () { });
80
+ var debug = (_c = options.debug) !== null && _c !== void 0 ? _c : false;
81
+ var onMatch = (_d = options.onMatch) !== null && _d !== void 0 ? _d : (function () { });
62
82
  var mo = new MutationObserver(function (mutations) {
63
83
  for (var _i = 0, mutations_1 = mutations; _i < mutations_1.length; _i++) {
64
84
  var m = mutations_1[_i];
85
+ if (debug &&
86
+ (m.target === document.body || (m.target instanceof Node && document.body.contains(m.target)))) {
87
+ console.log("+++ body mutation", m.type, m.target);
88
+ }
89
+ }
90
+ for (var _a = 0, mutations_2 = mutations; _a < mutations_2.length; _a++) {
91
+ var m = mutations_2[_a];
65
92
  if (m.type === "childList") {
66
- for (var i = 0; i < m.addedNodes.length; i += 1) {
67
- checkNode(m.addedNodes[i], seen, zNearMax, uuidGate, onMatch);
93
+ if (m.addedNodes.length) {
94
+ for (var i = 0; i < m.addedNodes.length; i += 1) {
95
+ var node = m.addedNodes[i];
96
+ if (node.nodeType === Node.ELEMENT_NODE) {
97
+ scanElement(node, seen, zNearMax, uuidGate, debug, onMatch);
98
+ }
99
+ }
100
+ }
101
+ if (m.target instanceof Element) {
102
+ scanElement(m.target, seen, zNearMax, uuidGate, debug, onMatch);
68
103
  }
69
104
  }
70
105
  else if (m.type === "attributes") {
71
- var el = m.target;
72
- if (el instanceof HTMLDivElement &&
73
- el.id &&
74
- seen.indexOf(el) === -1 &&
75
- looksLikeTargetDiv(el, zNearMax, uuidGate)) {
76
- seen.push(el);
77
- onMatch(el);
106
+ if (m.target instanceof Element) {
107
+ scanElement(m.target, seen, zNearMax, uuidGate, debug, onMatch);
78
108
  }
79
109
  }
80
110
  }
@@ -85,7 +115,7 @@ function startHoneyOverlayObserver(options) {
85
115
  attributes: true,
86
116
  attributeFilter: ["style", "class", "id"]
87
117
  });
88
- checkNode(document.documentElement, seen, zNearMax, uuidGate, onMatch);
118
+ scanElement(document.documentElement, seen, zNearMax, uuidGate, debug, onMatch);
89
119
  return {
90
120
  stop: function () { return mo.disconnect(); }
91
121
  };
@@ -3,6 +3,7 @@ export interface ObserverOptions {
3
3
  onMatch?: MatchCallback;
4
4
  uuidGate?: boolean;
5
5
  zNearMax?: number;
6
+ debug?: boolean;
6
7
  }
7
8
  export interface ObserverHandle {
8
9
  stop: () => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fck-honey",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Detects Honey browser extension overlays for merchants.",
5
5
  "license": "MIT",
6
6
  "main": "dist/honey-detect.js",