webmarker-js 0.1.0 → 0.2.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Reid Barber
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -15,7 +15,6 @@ Mark web pages for use with vision-language models.
15
15
 
16
16
  ![Screenshot of marked Google homepage](https://github.com/user-attachments/assets/722e1034-06d4-4ccd-a7d6-f03749435681)
17
17
 
18
-
19
18
  ## How it works
20
19
 
21
20
  **1. Call the `mark()` function**
@@ -24,7 +23,7 @@ This marks the interactive elements on the page, and returns an object containin
24
23
 
25
24
  - `element`: The interactive element that was marked.
26
25
  - `markElement`: The label element that was added to the page.
27
- - `maskElement`: The bounding box element that was added to the page.
26
+ - `boundingBoxElement`: The bounding box element that was added to the page.
28
27
 
29
28
  You can use this information to build your prompt for the vision-language model.
30
29
 
@@ -58,7 +57,7 @@ Example response: click 0
58
57
 
59
58
  In a web browser (i.e. via Playwright), interact with elements as needed.
60
59
 
61
- For prompting or agent ideas, see the [WebVoyager](https://arxiv.org/abs/2401.13919) paper.
60
+ For prompting or agent ideas, see the [WebVoyager](https://github.com/MinorJerry/WebVoyager) paper.
62
61
 
63
62
  ## Playwright example
64
63
 
@@ -71,6 +70,9 @@ await page.addScriptTag({
71
70
  // Mark the page and get the marked elements
72
71
  let markedElements = await page.evaluate(async () => await WebMarker.mark());
73
72
 
73
+ // Click a marked element
74
+ await page.locator('[data-mark-label="0"]').click();
75
+
74
76
  // (Optional) Check if page is marked
75
77
  let isMarked = await page.evaluate(async () => await WebMarker.isMarked());
76
78
 
@@ -92,7 +94,7 @@ A custom CSS selector to specify which elements to mark.
92
94
  A custom attribute to add to the marked elements. This attribute contains the label of the mark.
93
95
 
94
96
  - Type: `string`
95
- - Default: `"data-mark-id"`
97
+ - Default: `"data-mark-label"`
96
98
 
97
99
  ### markStyle
98
100
 
@@ -108,21 +110,21 @@ The placement of the mark relative to the element.
108
110
  - Type: `'top' | 'top-start' | 'top-end' | 'right' | 'right-start' | 'right-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end'`
109
111
  - Default: `'top-start'`
110
112
 
111
- ### maskStyle
113
+ ### boundingBoxStyle
112
114
 
113
- A CSS style to apply to the bounding box element. You can also specify a function that returns a CSS style object. Bounding boxes are only shown if showMasks is true.
115
+ A CSS style to apply to the bounding box element. You can also specify a function that returns a CSS style object. Bounding boxes are only shown if showBoundingBoxes is true.
114
116
 
115
117
  - Type: `Readonly<Partial<CSSStyleDeclaration>> or (element: Element) => Readonly<Partial<CSSStyleDeclaration>>`
116
118
  - Default: `{outline: "2px dashed red", backgroundColor: "transparent"}`
117
119
 
118
- ### showMasks
120
+ ### showBoundingBoxes
119
121
 
120
122
  Whether or not to show bounding boxes around the elements.
121
123
 
122
124
  - Type: `boolean`
123
125
  - Default: `true`
124
126
 
125
- ### labelGenerator
127
+ ### getLabel
126
128
 
127
129
  Provide a function for generating labels. By default, labels are generated as integers starting from 0.
128
130
 
@@ -153,15 +155,15 @@ const markedElements = await mark({
153
155
  markAttribute: "data-test-id",
154
156
  // Use a blue mark with white text
155
157
  markStyle: { color: "white", backgroundColor: "blue", padding: 5 },
156
- // Use a blue dashed outline mask with a transparent and slighly blue background
157
- maskStyle: { outline: "2px dashed blue", backgroundColor: "rgba(0, 0, 255, 0.1)"},
158
+ // Use a blue dashed outline with a transparent and slighly blue background
159
+ boundingBoxStyle: { outline: "2px dashed blue", backgroundColor: "rgba(0, 0, 255, 0.1)"},
158
160
  // Place the mark at the top right corner of the element
159
161
  markPlacement: "top-end";
160
- // Show masks over elements (defaults to true)
161
- showMasks: true,
162
+ // Show bounding boxes over elements (defaults to true)
163
+ showBoundingBoxes: true,
162
164
  // Generate labels as 'Element 0', 'Element 1', 'Element 2'...
163
165
  // Defaults to '0', '1', '2'... if not provided.
164
- labelGenerator: (element, index) => `Element ${index}`,
166
+ getLabel: (element, index) => `Element ${index}`,
165
167
  // A custom container element to query the elements to be marked.
166
168
  // Defaults to the document.body.
167
169
  containerElement: document.body.querySelector("main"),
package/dist/index.d.ts CHANGED
@@ -1,43 +1,45 @@
1
1
  type Placement = "top" | "top-start" | "top-end" | "right" | "right-start" | "right-end" | "bottom" | "bottom-start" | "bottom-end" | "left" | "left-start" | "left-end";
2
+ type StyleFunction = (element: Element) => CSSStyleDeclaration;
3
+ type StyleObject = Readonly<Partial<CSSStyleDeclaration>>;
2
4
  interface MarkOptions {
3
5
  /**
4
- * A CSS selector to specify the elements to be marked.
6
+ * A CSS selector to query the elements to be marked.
5
7
  */
6
8
  selector?: string;
7
9
  /**
8
- * Name for the attribute added to the marked elements. This attribute is used to store the label.
9
- *
10
- * @default 'data-mark-id'
10
+ * Provide a function for generating labels.
11
+ * By default, labels are generated as numbers starting from 0.
11
12
  */
12
- markAttribute?: string;
13
+ getLabel?: (element: Element, index: number) => string;
13
14
  /**
14
- * A CSS style to apply to the label element.
15
- * You can also specify a function that returns a CSS style object.
15
+ * Name for the attribute added to the marked elements to store the mark label.
16
+ *
17
+ * @default 'data-mark-label'
16
18
  */
17
- markStyle?: Readonly<Partial<CSSStyleDeclaration>> | ((element: Element) => Readonly<Partial<CSSStyleDeclaration>>);
19
+ markAttribute?: string;
18
20
  /**
19
21
  * The placement of the mark relative to the element.
20
22
  *
21
23
  * @default 'top-start'
22
24
  */
23
25
  markPlacement?: Placement;
26
+ /**
27
+ * A CSS style to apply to the label element.
28
+ * You can also specify a function that returns a CSS style object.
29
+ */
30
+ markStyle?: StyleObject | StyleFunction;
24
31
  /**
25
32
  * A CSS style to apply to the bounding box element.
26
33
  * You can also specify a function that returns a CSS style object.
27
- * Bounding boxes are only shown if `showMasks` is `true`.
34
+ * Bounding boxes are only shown if `showBoundingBoxes` is `true`.
28
35
  */
29
- maskStyle?: Readonly<Partial<CSSStyleDeclaration>> | ((element: Element) => Readonly<Partial<CSSStyleDeclaration>>);
36
+ boundingBoxStyle?: StyleObject | StyleFunction;
30
37
  /**
31
38
  * Whether or not to show bounding boxes around the elements.
32
39
  *
33
40
  * @default true
34
41
  */
35
- showMasks?: boolean;
36
- /**
37
- * Provide a function for generating labels.
38
- * By default, labels are generated as numbers starting from 0.
39
- */
40
- labelGenerator?: (element: Element, index: number) => string;
42
+ showBoundingBoxes?: boolean;
41
43
  /**
42
44
  * Provide a container element to query the elements to be marked.
43
45
  * By default, the container element is `document.body`.
@@ -53,7 +55,7 @@ interface MarkOptions {
53
55
  interface MarkedElement {
54
56
  element: Element;
55
57
  markElement: HTMLElement;
56
- maskElement?: HTMLElement;
58
+ boundingBoxElement?: HTMLElement;
57
59
  }
58
60
  declare function mark(options?: MarkOptions): Promise<Record<string, MarkedElement>>;
59
61
  declare function unmark(): void;
package/dist/main.js CHANGED
@@ -932,7 +932,9 @@ var WebMarker = (() => {
932
932
  return __async(this, arguments, function* (options = {}) {
933
933
  const {
934
934
  selector = "button, input, a, select, textarea",
935
- markAttribute = "data-mark-id",
935
+ getLabel = (_, index) => index.toString(),
936
+ markAttribute = "data-mark-label",
937
+ markPlacement = "top-start",
936
938
  markStyle = {
937
939
  backgroundColor: "red",
938
940
  color: "white",
@@ -940,13 +942,11 @@ var WebMarker = (() => {
940
942
  fontSize: "12px",
941
943
  fontWeight: "bold"
942
944
  },
943
- markPlacement = "top-start",
944
- maskStyle = {
945
+ boundingBoxStyle = {
945
946
  outline: "2px dashed red",
946
947
  backgroundColor: "transparent"
947
948
  },
948
- showMasks = true,
949
- labelGenerator = (_, index) => index.toString(),
949
+ showBoundingBoxes = true,
950
950
  containerElement = document.body,
951
951
  viewPortOnly = false
952
952
  } = options;
@@ -958,14 +958,14 @@ var WebMarker = (() => {
958
958
  const markedElements = {};
959
959
  yield Promise.all(
960
960
  elements.map((element, index) => __async(this, null, function* () {
961
- const label = labelGenerator(element, index);
961
+ const label = getLabel(element, index);
962
962
  const markElement = createMark(element, markStyle, label, markPlacement);
963
- const maskElement = showMasks ? createMask(element, maskStyle, label) : void 0;
964
- markedElements[label] = { element, markElement, maskElement };
963
+ const boundingBoxElement = showBoundingBoxes ? createBoundingBox(element, boundingBoxStyle, label) : void 0;
964
+ markedElements[label] = { element, markElement, boundingBoxElement };
965
965
  element.setAttribute(markAttribute, label);
966
966
  }))
967
967
  );
968
- document.documentElement.dataset.webmarkered = "true";
968
+ document.documentElement.setAttribute("data-marked", "true");
969
969
  return markedElements;
970
970
  });
971
971
  }
@@ -987,14 +987,14 @@ var WebMarker = (() => {
987
987
  );
988
988
  return markElement;
989
989
  }
990
- function createMask(element, style, label) {
991
- const maskElement = document.createElement("div");
992
- maskElement.className = "webmarker-mask";
993
- maskElement.id = `webmarker-mask-${label}`;
994
- document.body.appendChild(maskElement);
995
- positionMask(maskElement, element);
990
+ function createBoundingBox(element, style, label) {
991
+ const boundingBoxElement = document.createElement("div");
992
+ boundingBoxElement.className = "webmarker-bounding-box";
993
+ boundingBoxElement.id = `webmarker-bounding-box-${label}`;
994
+ document.body.appendChild(boundingBoxElement);
995
+ positionBoundingBox(boundingBoxElement, element);
996
996
  applyStyle(
997
- maskElement,
997
+ boundingBoxElement,
998
998
  {
999
999
  zIndex: "999999999",
1000
1000
  position: "absolute",
@@ -1002,7 +1002,7 @@ var WebMarker = (() => {
1002
1002
  },
1003
1003
  typeof style === "function" ? style(element) : style
1004
1004
  );
1005
- return maskElement;
1005
+ return boundingBoxElement;
1006
1006
  }
1007
1007
  function positionMark(markElement, element, markPlacement) {
1008
1008
  function updatePosition() {
@@ -1018,36 +1018,36 @@ var WebMarker = (() => {
1018
1018
  }
1019
1019
  cleanupFns.push(autoUpdate(element, markElement, updatePosition));
1020
1020
  }
1021
- function positionMask(mask, element) {
1021
+ function positionBoundingBox(boundingBox, element) {
1022
1022
  return __async(this, null, function* () {
1023
1023
  const { width, height } = element.getBoundingClientRect();
1024
1024
  function updatePosition() {
1025
1025
  return __async(this, null, function* () {
1026
- const { x: maskX, y: maskY } = yield computePosition2(element, mask, {
1026
+ const { x, y } = yield computePosition2(element, boundingBox, {
1027
1027
  placement: "top-start"
1028
1028
  });
1029
- Object.assign(mask.style, {
1030
- left: `${maskX}px`,
1031
- top: `${maskY + height}px`,
1029
+ Object.assign(boundingBox.style, {
1030
+ left: `${x}px`,
1031
+ top: `${y + height}px`,
1032
1032
  width: `${width}px`,
1033
1033
  height: `${height}px`
1034
1034
  });
1035
1035
  });
1036
1036
  }
1037
- cleanupFns.push(autoUpdate(element, mask, updatePosition));
1037
+ cleanupFns.push(autoUpdate(element, boundingBox, updatePosition));
1038
1038
  });
1039
1039
  }
1040
1040
  function applyStyle(element, defaultStyle, customStyle) {
1041
1041
  Object.assign(element.style, defaultStyle, customStyle);
1042
1042
  }
1043
1043
  function unmark() {
1044
- document.querySelectorAll(".webmarker, .webmarker-mask").forEach((el) => el.remove());
1045
- document.documentElement.removeAttribute("data-webmarkered");
1044
+ document.querySelectorAll(".webmarker, .webmarker-bounding-box").forEach((el) => el.remove());
1045
+ document.documentElement.removeAttribute("data-marked");
1046
1046
  cleanupFns.forEach((fn) => fn());
1047
1047
  cleanupFns = [];
1048
1048
  }
1049
1049
  function isMarked() {
1050
- return document.documentElement.hasAttribute("data-webmarkered");
1050
+ return document.documentElement.hasAttribute("data-marked");
1051
1051
  }
1052
1052
  if (typeof window !== "undefined") {
1053
1053
  window["mark"] = mark;
package/dist/module.js CHANGED
@@ -908,7 +908,9 @@ function mark() {
908
908
  return __async(this, arguments, function* (options = {}) {
909
909
  const {
910
910
  selector = "button, input, a, select, textarea",
911
- markAttribute = "data-mark-id",
911
+ getLabel = (_, index) => index.toString(),
912
+ markAttribute = "data-mark-label",
913
+ markPlacement = "top-start",
912
914
  markStyle = {
913
915
  backgroundColor: "red",
914
916
  color: "white",
@@ -916,13 +918,11 @@ function mark() {
916
918
  fontSize: "12px",
917
919
  fontWeight: "bold"
918
920
  },
919
- markPlacement = "top-start",
920
- maskStyle = {
921
+ boundingBoxStyle = {
921
922
  outline: "2px dashed red",
922
923
  backgroundColor: "transparent"
923
924
  },
924
- showMasks = true,
925
- labelGenerator = (_, index) => index.toString(),
925
+ showBoundingBoxes = true,
926
926
  containerElement = document.body,
927
927
  viewPortOnly = false
928
928
  } = options;
@@ -934,14 +934,14 @@ function mark() {
934
934
  const markedElements = {};
935
935
  yield Promise.all(
936
936
  elements.map((element, index) => __async(this, null, function* () {
937
- const label = labelGenerator(element, index);
937
+ const label = getLabel(element, index);
938
938
  const markElement = createMark(element, markStyle, label, markPlacement);
939
- const maskElement = showMasks ? createMask(element, maskStyle, label) : void 0;
940
- markedElements[label] = { element, markElement, maskElement };
939
+ const boundingBoxElement = showBoundingBoxes ? createBoundingBox(element, boundingBoxStyle, label) : void 0;
940
+ markedElements[label] = { element, markElement, boundingBoxElement };
941
941
  element.setAttribute(markAttribute, label);
942
942
  }))
943
943
  );
944
- document.documentElement.dataset.webmarkered = "true";
944
+ document.documentElement.setAttribute("data-marked", "true");
945
945
  return markedElements;
946
946
  });
947
947
  }
@@ -963,14 +963,14 @@ function createMark(element, style, label, markPlacement = "top-start") {
963
963
  );
964
964
  return markElement;
965
965
  }
966
- function createMask(element, style, label) {
967
- const maskElement = document.createElement("div");
968
- maskElement.className = "webmarker-mask";
969
- maskElement.id = `webmarker-mask-${label}`;
970
- document.body.appendChild(maskElement);
971
- positionMask(maskElement, element);
966
+ function createBoundingBox(element, style, label) {
967
+ const boundingBoxElement = document.createElement("div");
968
+ boundingBoxElement.className = "webmarker-bounding-box";
969
+ boundingBoxElement.id = `webmarker-bounding-box-${label}`;
970
+ document.body.appendChild(boundingBoxElement);
971
+ positionBoundingBox(boundingBoxElement, element);
972
972
  applyStyle(
973
- maskElement,
973
+ boundingBoxElement,
974
974
  {
975
975
  zIndex: "999999999",
976
976
  position: "absolute",
@@ -978,7 +978,7 @@ function createMask(element, style, label) {
978
978
  },
979
979
  typeof style === "function" ? style(element) : style
980
980
  );
981
- return maskElement;
981
+ return boundingBoxElement;
982
982
  }
983
983
  function positionMark(markElement, element, markPlacement) {
984
984
  function updatePosition() {
@@ -994,36 +994,36 @@ function positionMark(markElement, element, markPlacement) {
994
994
  }
995
995
  cleanupFns.push(autoUpdate(element, markElement, updatePosition));
996
996
  }
997
- function positionMask(mask, element) {
997
+ function positionBoundingBox(boundingBox, element) {
998
998
  return __async(this, null, function* () {
999
999
  const { width, height } = element.getBoundingClientRect();
1000
1000
  function updatePosition() {
1001
1001
  return __async(this, null, function* () {
1002
- const { x: maskX, y: maskY } = yield computePosition2(element, mask, {
1002
+ const { x, y } = yield computePosition2(element, boundingBox, {
1003
1003
  placement: "top-start"
1004
1004
  });
1005
- Object.assign(mask.style, {
1006
- left: `${maskX}px`,
1007
- top: `${maskY + height}px`,
1005
+ Object.assign(boundingBox.style, {
1006
+ left: `${x}px`,
1007
+ top: `${y + height}px`,
1008
1008
  width: `${width}px`,
1009
1009
  height: `${height}px`
1010
1010
  });
1011
1011
  });
1012
1012
  }
1013
- cleanupFns.push(autoUpdate(element, mask, updatePosition));
1013
+ cleanupFns.push(autoUpdate(element, boundingBox, updatePosition));
1014
1014
  });
1015
1015
  }
1016
1016
  function applyStyle(element, defaultStyle, customStyle) {
1017
1017
  Object.assign(element.style, defaultStyle, customStyle);
1018
1018
  }
1019
1019
  function unmark() {
1020
- document.querySelectorAll(".webmarker, .webmarker-mask").forEach((el) => el.remove());
1021
- document.documentElement.removeAttribute("data-webmarkered");
1020
+ document.querySelectorAll(".webmarker, .webmarker-bounding-box").forEach((el) => el.remove());
1021
+ document.documentElement.removeAttribute("data-marked");
1022
1022
  cleanupFns.forEach((fn) => fn());
1023
1023
  cleanupFns = [];
1024
1024
  }
1025
1025
  function isMarked() {
1026
- return document.documentElement.hasAttribute("data-webmarkered");
1026
+ return document.documentElement.hasAttribute("data-marked");
1027
1027
  }
1028
1028
  if (typeof window !== "undefined") {
1029
1029
  window["mark"] = mark;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webmarker-js",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "A library for marking web pages for Set-of-Mark (SoM) prompting with vision-language models.",
5
5
  "source": "src/index.ts",
6
6
  "main": "dist/main.js",
package/src/index.ts CHANGED
@@ -14,49 +14,48 @@ type Placement =
14
14
  | "left-start"
15
15
  | "left-end";
16
16
 
17
+ type StyleFunction = (element: Element) => CSSStyleDeclaration;
18
+ type StyleObject = Readonly<Partial<CSSStyleDeclaration>>;
19
+
17
20
  interface MarkOptions {
18
21
  /**
19
- * A CSS selector to specify the elements to be marked.
22
+ * A CSS selector to query the elements to be marked.
20
23
  */
21
24
  selector?: string;
22
25
  /**
23
- * Name for the attribute added to the marked elements. This attribute is used to store the label.
24
- *
25
- * @default 'data-mark-id'
26
+ * Provide a function for generating labels.
27
+ * By default, labels are generated as numbers starting from 0.
26
28
  */
27
- markAttribute?: string;
29
+ getLabel?: (element: Element, index: number) => string;
28
30
  /**
29
- * A CSS style to apply to the label element.
30
- * You can also specify a function that returns a CSS style object.
31
+ * Name for the attribute added to the marked elements to store the mark label.
32
+ *
33
+ * @default 'data-mark-label'
31
34
  */
32
- markStyle?:
33
- | Readonly<Partial<CSSStyleDeclaration>>
34
- | ((element: Element) => Readonly<Partial<CSSStyleDeclaration>>);
35
+ markAttribute?: string;
35
36
  /**
36
37
  * The placement of the mark relative to the element.
37
38
  *
38
39
  * @default 'top-start'
39
40
  */
40
41
  markPlacement?: Placement;
42
+ /**
43
+ * A CSS style to apply to the label element.
44
+ * You can also specify a function that returns a CSS style object.
45
+ */
46
+ markStyle?: StyleObject | StyleFunction;
41
47
  /**
42
48
  * A CSS style to apply to the bounding box element.
43
49
  * You can also specify a function that returns a CSS style object.
44
- * Bounding boxes are only shown if `showMasks` is `true`.
50
+ * Bounding boxes are only shown if `showBoundingBoxes` is `true`.
45
51
  */
46
- maskStyle?:
47
- | Readonly<Partial<CSSStyleDeclaration>>
48
- | ((element: Element) => Readonly<Partial<CSSStyleDeclaration>>);
52
+ boundingBoxStyle?: StyleObject | StyleFunction;
49
53
  /**
50
54
  * Whether or not to show bounding boxes around the elements.
51
55
  *
52
56
  * @default true
53
57
  */
54
- showMasks?: boolean;
55
- /**
56
- * Provide a function for generating labels.
57
- * By default, labels are generated as numbers starting from 0.
58
- */
59
- labelGenerator?: (element: Element, index: number) => string;
58
+ showBoundingBoxes?: boolean;
60
59
  /**
61
60
  * Provide a container element to query the elements to be marked.
62
61
  * By default, the container element is `document.body`.
@@ -73,7 +72,7 @@ interface MarkOptions {
73
72
  interface MarkedElement {
74
73
  element: Element;
75
74
  markElement: HTMLElement;
76
- maskElement?: HTMLElement;
75
+ boundingBoxElement?: HTMLElement;
77
76
  }
78
77
 
79
78
  let cleanupFns: (() => void)[] = [];
@@ -83,7 +82,9 @@ async function mark(
83
82
  ): Promise<Record<string, MarkedElement>> {
84
83
  const {
85
84
  selector = "button, input, a, select, textarea",
86
- markAttribute = "data-mark-id",
85
+ getLabel = (_, index) => index.toString(),
86
+ markAttribute = "data-mark-label",
87
+ markPlacement = "top-start",
87
88
  markStyle = {
88
89
  backgroundColor: "red",
89
90
  color: "white",
@@ -91,13 +92,11 @@ async function mark(
91
92
  fontSize: "12px",
92
93
  fontWeight: "bold",
93
94
  },
94
- markPlacement = "top-start",
95
- maskStyle = {
95
+ boundingBoxStyle = {
96
96
  outline: "2px dashed red",
97
97
  backgroundColor: "transparent",
98
98
  },
99
- showMasks = true,
100
- labelGenerator = (_, index) => index.toString(),
99
+ showBoundingBoxes = true,
101
100
  containerElement = document.body,
102
101
  viewPortOnly = false,
103
102
  } = options;
@@ -112,27 +111,25 @@ async function mark(
112
111
 
113
112
  await Promise.all(
114
113
  elements.map(async (element, index) => {
115
- const label = labelGenerator(element, index);
114
+ const label = getLabel(element, index);
116
115
  const markElement = createMark(element, markStyle, label, markPlacement);
117
116
 
118
- const maskElement = showMasks
119
- ? createMask(element, maskStyle, label)
117
+ const boundingBoxElement = showBoundingBoxes
118
+ ? createBoundingBox(element, boundingBoxStyle, label)
120
119
  : undefined;
121
120
 
122
- markedElements[label] = { element, markElement, maskElement };
121
+ markedElements[label] = { element, markElement, boundingBoxElement };
123
122
  element.setAttribute(markAttribute, label);
124
123
  })
125
124
  );
126
125
 
127
- document.documentElement.dataset.webmarkered = "true";
126
+ document.documentElement.setAttribute("data-marked", "true");
128
127
  return markedElements;
129
128
  }
130
129
 
131
130
  function createMark(
132
131
  element: Element,
133
- style:
134
- | Readonly<Partial<CSSStyleDeclaration>>
135
- | ((element: Element) => Readonly<Partial<CSSStyleDeclaration>>),
132
+ style: StyleObject | StyleFunction,
136
133
  label: string,
137
134
  markPlacement: Placement = "top-start"
138
135
  ): HTMLElement {
@@ -154,20 +151,18 @@ function createMark(
154
151
  return markElement;
155
152
  }
156
153
 
157
- function createMask(
154
+ function createBoundingBox(
158
155
  element: Element,
159
- style:
160
- | Readonly<Partial<CSSStyleDeclaration>>
161
- | ((element: Element) => Readonly<Partial<CSSStyleDeclaration>>),
156
+ style: StyleObject | StyleFunction,
162
157
  label: string
163
158
  ): HTMLElement {
164
- const maskElement = document.createElement("div");
165
- maskElement.className = "webmarker-mask";
166
- maskElement.id = `webmarker-mask-${label}`;
167
- document.body.appendChild(maskElement);
168
- positionMask(maskElement, element);
159
+ const boundingBoxElement = document.createElement("div");
160
+ boundingBoxElement.className = "webmarker-bounding-box";
161
+ boundingBoxElement.id = `webmarker-bounding-box-${label}`;
162
+ document.body.appendChild(boundingBoxElement);
163
+ positionBoundingBox(boundingBoxElement, element);
169
164
  applyStyle(
170
- maskElement,
165
+ boundingBoxElement,
171
166
  {
172
167
  zIndex: "999999999",
173
168
  position: "absolute",
@@ -175,7 +170,7 @@ function createMask(
175
170
  },
176
171
  typeof style === "function" ? style(element) : style
177
172
  );
178
- return maskElement;
173
+ return boundingBoxElement;
179
174
  }
180
175
 
181
176
  function positionMark(
@@ -196,41 +191,41 @@ function positionMark(
196
191
  cleanupFns.push(autoUpdate(element, markElement, updatePosition));
197
192
  }
198
193
 
199
- async function positionMask(mask: HTMLElement, element: Element) {
194
+ async function positionBoundingBox(boundingBox: HTMLElement, element: Element) {
200
195
  const { width, height } = element.getBoundingClientRect();
201
196
  async function updatePosition() {
202
- const { x: maskX, y: maskY } = await computePosition(element, mask, {
197
+ const { x, y } = await computePosition(element, boundingBox, {
203
198
  placement: "top-start",
204
199
  });
205
- Object.assign(mask.style, {
206
- left: `${maskX}px`,
207
- top: `${maskY + height}px`,
200
+ Object.assign(boundingBox.style, {
201
+ left: `${x}px`,
202
+ top: `${y + height}px`,
208
203
  width: `${width}px`,
209
204
  height: `${height}px`,
210
205
  });
211
206
  }
212
- cleanupFns.push(autoUpdate(element, mask, updatePosition));
207
+ cleanupFns.push(autoUpdate(element, boundingBox, updatePosition));
213
208
  }
214
209
 
215
210
  function applyStyle(
216
211
  element: HTMLElement,
217
- defaultStyle: Readonly<Partial<CSSStyleDeclaration>>,
218
- customStyle: Readonly<Partial<CSSStyleDeclaration>>
212
+ defaultStyle: Partial<CSSStyleDeclaration>,
213
+ customStyle: Partial<CSSStyleDeclaration>
219
214
  ): void {
220
215
  Object.assign(element.style, defaultStyle, customStyle);
221
216
  }
222
217
 
223
218
  function unmark(): void {
224
219
  document
225
- .querySelectorAll(".webmarker, .webmarker-mask")
220
+ .querySelectorAll(".webmarker, .webmarker-bounding-box")
226
221
  .forEach((el) => el.remove());
227
- document.documentElement.removeAttribute("data-webmarkered");
222
+ document.documentElement.removeAttribute("data-marked");
228
223
  cleanupFns.forEach((fn) => fn());
229
224
  cleanupFns = [];
230
225
  }
231
226
 
232
227
  function isMarked(): boolean {
233
- return document.documentElement.hasAttribute("data-webmarkered");
228
+ return document.documentElement.hasAttribute("data-marked");
234
229
  }
235
230
 
236
231
  if (typeof window !== "undefined") {
@@ -1,6 +1,4 @@
1
1
  {
2
- "status": "failed",
3
- "failedTests": [
4
- "bcbd25456d68a5d49fac-61d7a7d69e576e88625b"
5
- ]
2
+ "status": "passed",
3
+ "failedTests": []
6
4
  }