├── README.md
├── extension
├── background.js
├── icon.png
├── manifest.json
└── visualTagger.js
├── logo.svg
└── visualTagger.js
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Visual Tagger for AI Interaction
4 |
5 | ## Description
6 |
7 | The **Visual Tagger** is a JavaScript script designed to provide visual guidance for artificial intelligences capable of image recognition. This code allows AIs to quickly identify which elements to interact with on a web page, facilitating the generation of JavaScript code to perform actions.
8 |
9 | ## Functionality
10 |
11 | The script applies visual tagging to HTML elements that have defined colors, providing a clear visual representation. Each tagged element is highlighted with a colored border, and a corresponding label is inserted above it, displaying its tag name, ID, and classes. This allows AIs to understand the page structure and interact with the elements effectively.
12 |
13 | ## Chrome Extension
14 |
15 | We now offer a Chrome Extension version of the Visual Tagger! This extension makes it even easier to inject the Visual Tagger into web pages with just one click.
16 |
17 | ### Loading the Extension in Chrome
18 |
19 | To load the Visual Tagger Chrome extension:
20 |
21 | 1. **Clone or download the repository** to your local machine.
22 | 2. Go to `chrome://extensions` in your Chrome browser.
23 | 3. Enable **Developer mode** (toggle found in the upper-right corner).
24 | 4. Click **"Load unpacked"** and select the folder containing the extension files.
25 | 5. The Visual Tagger icon will appear in your extensions bar, ready to inject the visual tagging.
26 |
27 | Now, simply click the icon to toggle the Visual Tagger on any page!
28 |
29 | ## How to Use Without Extension
30 |
31 | To use the Visual Tagger script directly:
32 |
33 | 1. **Open the web page** where you want to run the Visual Tagger.
34 | 2. **Open the browser console** (usually by pressing `F12` or `Ctrl + Shift + I`).
35 | 3. **Paste the Visual Tagger code** directly into the console and press `Enter`.
36 |
37 | - Make sure the code is accessible for copying and pasting.
38 |
39 | 4. The Visual Tagger will execute, and the visual tagging will appear on the relevant elements of the page.
40 |
41 | ## Note
42 |
43 | This code is still experimental and may miss some elements. Contributions are welcome! If you have any ideas or improvements for the Visual Tagger, feel free to open an issue or submit a pull request.
44 |
45 | ## License
46 |
47 | This project is licensed under the [MIT License](LICENSE).
48 |
--------------------------------------------------------------------------------
/extension/background.js:
--------------------------------------------------------------------------------
1 | chrome.action.onClicked.addListener((tab) => {
2 | chrome.scripting.executeScript({
3 | target: { tabId: tab.id },
4 | files: ["visualTagger.js"]
5 | });
6 | });
--------------------------------------------------------------------------------
/extension/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calmstate/VisualTagger/3a59c5bb9ffa1c4b10b015c02a43d79c50287007/extension/icon.png
--------------------------------------------------------------------------------
/extension/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "manifest_version": 3,
3 | "name": "Visual Tagger",
4 | "version": "1.0",
5 | "description": "Runs the visualTagger.js script on the active page.",
6 | "permissions": ["scripting", "activeTab"],
7 | "background": {
8 | "service_worker": "background.js"
9 | },
10 | "action": {
11 | "default_icon": {
12 | "16": "icon.png",
13 | "48": "icon.png",
14 | "128": "icon.png"
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/extension/visualTagger.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | const tagColors = {
3 | a: { background: "blue", text: "white" },
4 | button: { background: "dodgerblue", text: "white" },
5 | details: { background: "peru", text: "black" },
6 | dialog: { background: "steelblue", text: "white" },
7 | form: { background: "lavender", text: "black" },
8 | input: { background: "peachpuff", text: "black" },
9 | label: { background: "palegreen", text: "black" },
10 | menu: { background: "mediumturquoise", text: "black" },
11 | select: { background: "darkslategray", text: "white" },
12 | textarea: { background: "plum", text: "black" },
13 | option: { background: "mediumpurple", text: "white" },
14 | optgroup: { background: "darkkhaki", text: "black" },
15 | fieldset: { background: "cyan", text: "black" },
16 | legend: { background: "powderblue", text: "black" },
17 | output: { background: "moccasin", text: "black" },
18 | progress: { background: "plum", text: "black" },
19 | meter: { background: "palegoldenrod", text: "black" },
20 | summary: { background: "azure", text: "black" }
21 | };
22 |
23 | function createTagInfo(tagName, id, classList, colors) {
24 | const tagInfo = document.createElement('div');
25 | tagInfo.innerHTML = `${tagName}${id}${classList}`;
26 | Object.assign(tagInfo.style, {
27 | position: "absolute",
28 | top: "-20px",
29 | left: "0",
30 | color: colors.text,
31 | backgroundColor: colors.background,
32 | fontSize: "12px",
33 | padding: "5px",
34 | zIndex: "1000",
35 | border: "1px solid white"
36 | });
37 | tagInfo.classList.add('visual-tagger-info');
38 | return tagInfo;
39 | }
40 |
41 | function styleElement(element, colors) {
42 | element.dataset.originalBorder = element.style.border;
43 | element.dataset.originalMarginTop = element.style.marginTop;
44 | Object.assign(element.style, {
45 | position: "relative",
46 | border: `2px solid ${colors.background}`,
47 | marginTop: "15px"
48 | });
49 | }
50 |
51 | function restoreElementStyle(element) {
52 | element.style.border = element.dataset.originalBorder || "";
53 | element.style.marginTop = element.dataset.originalMarginTop || "";
54 | delete element.dataset.originalBorder;
55 | delete element.dataset.originalMarginTop;
56 | }
57 |
58 | function VisualTagger() {
59 | const relevantElements = Array.from(document.querySelectorAll(Object.keys(tagColors).join(',')));
60 |
61 | if (document.querySelector('.visual-tagger-info')) {
62 | const taggedElements = document.querySelectorAll('.visual-tagger-info');
63 | taggedElements.forEach(e=>e.remove());
64 | relevantElements.forEach(element => restoreElementStyle(element));
65 | } else {
66 | relevantElements.forEach(element => {
67 | const tagName = element.tagName.toLowerCase();
68 | const colors = tagColors[tagName];
69 | if (colors) {
70 | const id = element.id ? `#${element.id}` : '';
71 | const classList = Array.from(element.classList).map(cls => `.${cls}`).join('') || '';
72 |
73 | const tagInfo = createTagInfo(tagName, id, classList, colors);
74 | styleElement(element, colors);
75 |
76 | const rect = element.getBoundingClientRect();
77 | tagInfo.style.top = `${rect.top - 30}px`;
78 | tagInfo.style.left = `${rect.left}px`;
79 | document.body.appendChild(tagInfo);
80 |
81 | }
82 | });
83 | }
84 | }
85 |
86 | VisualTagger();
87 | })();
88 |
--------------------------------------------------------------------------------
/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/visualTagger.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | const tagColors = {
3 | a: { background: "blue", text: "white" },
4 | button: { background: "dodgerblue", text: "white" },
5 | details: { background: "peru", text: "black" },
6 | dialog: { background: "steelblue", text: "white" },
7 | form: { background: "lavender", text: "black" },
8 | input: { background: "peachpuff", text: "black" },
9 | label: { background: "palegreen", text: "black" },
10 | menu: { background: "mediumturquoise", text: "black" },
11 | select: { background: "darkslategray", text: "white" },
12 | textarea: { background: "plum", text: "black" },
13 | option: { background: "mediumpurple", text: "white" },
14 | optgroup: { background: "darkkhaki", text: "black" },
15 | fieldset: { background: "cyan", text: "black" },
16 | legend: { background: "powderblue", text: "black" },
17 | output: { background: "moccasin", text: "black" },
18 | progress: { background: "plum", text: "black" },
19 | meter: { background: "palegoldenrod", text: "black" },
20 | summary: { background: "azure", text: "black" }
21 | };
22 |
23 | function createTagInfo(tagName, id, classList, colors) {
24 | const tagInfo = document.createElement('div');
25 | tagInfo.innerHTML = `${tagName}${id}${classList}`;
26 | Object.assign(tagInfo.style, {
27 | position: "absolute",
28 | top: "-20px",
29 | left: "0",
30 | color: colors.text,
31 | backgroundColor: colors.background,
32 | fontSize: "12px",
33 | padding: "5px",
34 | zIndex: "1000",
35 | border: "1px solid white"
36 | });
37 | tagInfo.classList.add('visual-tagger-info');
38 | return tagInfo;
39 | }
40 |
41 | function styleElement(element, colors) {
42 | element.dataset.originalBorder = element.style.border;
43 | element.dataset.originalMarginTop = element.style.marginTop;
44 | Object.assign(element.style, {
45 | position: "relative",
46 | border: `2px solid ${colors.background}`,
47 | marginTop: "15px"
48 | });
49 | }
50 |
51 | function restoreElementStyle(element) {
52 | element.style.border = element.dataset.originalBorder || "";
53 | element.style.marginTop = element.dataset.originalMarginTop || "";
54 | delete element.dataset.originalBorder;
55 | delete element.dataset.originalMarginTop;
56 | }
57 |
58 | function VisualTagger() {
59 | const relevantElements = Array.from(document.querySelectorAll(Object.keys(tagColors).join(',')));
60 |
61 | if (document.querySelector('.visual-tagger-info')) {
62 | const taggedElements = document.querySelectorAll('.visual-tagger-info');
63 | taggedElements.forEach(e=>e.remove());
64 | relevantElements.forEach(element => restoreElementStyle(element));
65 | } else {
66 | relevantElements.forEach(element => {
67 | const tagName = element.tagName.toLowerCase();
68 | const colors = tagColors[tagName];
69 | if (colors) {
70 | const id = element.id ? `#${element.id}` : '';
71 | const classList = Array.from(element.classList).map(cls => `.${cls}`).join('') || '';
72 |
73 | const tagInfo = createTagInfo(tagName, id, classList, colors);
74 | styleElement(element, colors);
75 |
76 | const rect = element.getBoundingClientRect();
77 | tagInfo.style.top = `${rect.top - 30}px`;
78 | tagInfo.style.left = `${rect.left}px`;
79 | document.body.appendChild(tagInfo);
80 |
81 | }
82 | });
83 | }
84 | }
85 |
86 | VisualTagger();
87 | })();
88 |
--------------------------------------------------------------------------------