diff --git a/chrome-extension/background.js b/chrome-extension/background.js new file mode 100644 index 0000000..174ec31 --- /dev/null +++ b/chrome-extension/background.js @@ -0,0 +1,24 @@ +chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { + if (message.action === "injectWebMarker") { + const { code } = message; + chrome.scripting.executeScript( + { + target: { tabId: sender.tab.id }, + world: "MAIN", + func: new Function(code), + }, + () => { + if (chrome.runtime.lastError) { + console.error(chrome.runtime.lastError); + sendResponse({ + success: false, + error: chrome.runtime.lastError.message, + }); + } else { + sendResponse({ success: true }); + } + } + ); + return true; + } +}); diff --git a/chrome-extension/contentScript.js b/chrome-extension/contentScript.js new file mode 100644 index 0000000..7ad803f --- /dev/null +++ b/chrome-extension/contentScript.js @@ -0,0 +1,38 @@ +chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { + const { action, options } = message; + + if (action === "injectWebMarker") { + sendResponse({ success: true }); + return; + } + + const executeAction = () => { + if (action === "markPage") { + const markedElements = WebMarker.mark(options); + sendResponse({ markedElements }); + } else if (action === "unmarkPage") { + WebMarker.unmark(); + sendResponse({ success: true }); + } else if (action === "refresh") { + if (WebMarker.isMarked()) { + WebMarker.unmark(); + } + const markedElements = WebMarker.mark(options); + sendResponse({ markedElements }); + } + }; + + if (WebMarker && WebMarker.mark) { + executeAction(); + } else { + // Wait for WebMarker to load + const interval = setInterval(() => { + if (WebMarker && WebMarker.mark) { + clearInterval(interval); + executeAction(); + } + }, 50); + } + + return true; +}); diff --git a/chrome-extension/devtools.html b/chrome-extension/devtools.html new file mode 100644 index 0000000..07db577 --- /dev/null +++ b/chrome-extension/devtools.html @@ -0,0 +1,7 @@ + + + + + + + diff --git a/chrome-extension/devtools.js b/chrome-extension/devtools.js new file mode 100644 index 0000000..c5a6ace --- /dev/null +++ b/chrome-extension/devtools.js @@ -0,0 +1,8 @@ +chrome.devtools.panels.create( + "WebMarker", + "icon.png", + "panel.html", + function (panel) { + // Panel created + } +); diff --git a/chrome-extension/icon.png b/chrome-extension/icon.png new file mode 100644 index 0000000..e1cbb17 Binary files /dev/null and b/chrome-extension/icon.png differ diff --git a/chrome-extension/manifest.json b/chrome-extension/manifest.json new file mode 100644 index 0000000..caf848e --- /dev/null +++ b/chrome-extension/manifest.json @@ -0,0 +1,28 @@ +{ + "manifest_version": 3, + "name": "WebMarker Extension", + "version": "1.0", + "description": "Adds visual markings to web pages using WebMarker.", + "permissions": ["scripting", "activeTab"], + "host_permissions": [""], + "devtools_page": "devtools.html", + "content_scripts": [ + { + "matches": [""], + "js": ["contentScript.js", "dist/main.js"], + "run_at": "document_end" + } + ], + "web_accessible_resources": [ + { + "resources": ["dist/main.js"], + "matches": [""] + } + ], + "icons": { + "128": "icon.png" + }, + "background": { + "service_worker": "background.js" + } +} diff --git a/chrome-extension/panel.html b/chrome-extension/panel.html new file mode 100644 index 0000000..b089999 --- /dev/null +++ b/chrome-extension/panel.html @@ -0,0 +1,86 @@ + + + + + + +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ + + + diff --git a/chrome-extension/panel.js b/chrome-extension/panel.js new file mode 100644 index 0000000..d2b2bcc --- /dev/null +++ b/chrome-extension/panel.js @@ -0,0 +1,59 @@ +document.addEventListener("DOMContentLoaded", () => { + const markPageCheckbox = document.getElementById("markPage"); + const selectorInput = document.getElementById("selector"); + const markPlacementSelect = document.getElementById("markPlacement"); + const showBoundingBoxesCheckbox = + document.getElementById("showBoundingBoxes"); + const viewPortOnlyCheckbox = document.getElementById("viewPortOnly"); + const copyOptionsButton = document.getElementById("copyOptions"); + const refreshButton = document.getElementById("refresh"); + const outputDiv = document.getElementById("output"); + + const getCurrentOptions = () => { + return { + selector: selectorInput.value, + markPlacement: markPlacementSelect.value, + showBoundingBoxes: showBoundingBoxesCheckbox.checked, + viewPortOnly: viewPortOnlyCheckbox.checked, + // TODO: Add new options + }; + }; + + const sendMessageToContentScript = (action) => { + const options = getCurrentOptions(); + chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { + if (tabs.length === 0) return; + chrome.tabs.sendMessage(tabs[0].id, { action, options }, (response) => { + if (chrome.runtime.lastError) { + outputDiv.textContent = "Error: " + chrome.runtime.lastError.message; + return; + } + if (response && response.markedElements) { + outputDiv.textContent = JSON.stringify( + response.markedElements, + null, + 2 + ); + } else if (response && response.success) { + outputDiv.textContent = "Unmarked successfully."; + } + }); + }); + }; + + markPageCheckbox.addEventListener("change", () => { + const action = markPageCheckbox.checked ? "markPage" : "unmarkPage"; + sendMessageToContentScript(action); + }); + + copyOptionsButton.addEventListener("click", () => { + const options = getCurrentOptions(); + navigator.clipboard.writeText(JSON.stringify(options, null, 2)).then(() => { + alert("Options copied to clipboard!"); + }); + }); + + refreshButton.addEventListener("click", () => { + sendMessageToContentScript("refresh"); + }); +});