From 2b97d44a4f27d12f99faf62455e55dba84a4ee8d Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 1 Feb 2024 20:31:47 +0000 Subject: [PATCH 1/3] Added support for paste with hidden elements Added support for no parent form node found Refactored --- background.js | 10 ++-- content.js | 125 +++++++++++++++++++++++++++++++++++--------------- manifest.json | 2 +- 3 files changed, 95 insertions(+), 42 deletions(-) diff --git a/background.js b/background.js index 73ccbf7..06754e0 100644 --- a/background.js +++ b/background.js @@ -1,6 +1,7 @@ chrome.runtime.onInstalled.addListener(function() { chrome.contextMenus.create({ "id": "copy_form", "title": "Copy Form", "contexts": ["editable"] }); chrome.contextMenus.create({ "id": "paste_form", "title": "Paste Form", "contexts": ["editable"], enabled: false }); + chrome.contextMenus.create({ "id": "paste_form2", "title": "Paste Form (with Hidden)", "contexts": ["editable"], enabled: false }); }); chrome.contextMenus.onClicked.addListener(function(msg, tab) { @@ -9,7 +10,10 @@ chrome.contextMenus.onClicked.addListener(function(msg, tab) { copyFormContextMenu(tab); break; case "paste_form": - pastFormContextMenu(tab); + pasteFormContextMenu(tab, false); + break; + case "paste_form2": + pasteFormContextMenu(tab, true); break; default: break; } @@ -30,11 +34,11 @@ function copyFormContextMenu(tab) { }); } -function pastFormContextMenu(tab) { +function pasteFormContextMenu(tab, includeHiddenEl) { chrome.storage.local.get('clipboard', function(response) { try { let msgData = JSON.parse(response.clipboard); - msgData.action = "paste"; + msgData.action = (includeHiddenEl === true ? "paste2" : "paste"); chrome.tabs.sendMessage(tab.id, msgData); } catch (err) { diff --git a/content.js b/content.js index 55662a7..3e9b97c 100644 --- a/content.js +++ b/content.js @@ -1,14 +1,13 @@ chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { - - const parentForm = getParentFormNode(document.activeElement); - if (parentForm == null) { - console.log("Form not found"); + let formContainer = getContainer(document.activeElement); + if (formContainer == null) { + writeLog("Form container not found"); return; } switch (request.action) { case "copy": - const result = buildFormValueSet(parentForm, "input", "select", "textarea"); + const result = getFormElementValueSet(formContainer, "input", "select", "textarea"); console.log(result); @@ -16,30 +15,31 @@ chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { break; case "paste": - delete request.pasteForm; + case "paste2": + const includeHidden = (request.action == "paste2"); - // console.log(request); + delete request.action; for (let key in request) { if (String.isNullOrWhitespace(key)) { continue; } - const dataType = checkDataType(request[key]); + const dataType = Object.getDataType(request[key]); if (dataType == "object") { continue; } - const foundElements = parentForm.querySelectorAll("[name='" + key + "']"); - if (foundElements.length <= 0) { + const foundEls = formContainer.querySelectorAll("[name='" + key + "']"); + if (foundEls.length <= 0) { continue; } if (dataType == "array") { - setFormElementValues(foundElements, request[key]); + setFormElementValues(foundEls, request[key], includeHidden); } else { - for (let x=0; x 0) { - return foundForms[0]; - } + return null; } while (true) { @@ -103,9 +105,25 @@ function getParentFormNode(node) { } /** - * Push form element value to array. + * Get form node in iframe. */ -function buildFormValueSet(form, ...tagNames){ +function getIFrameFormNode(node) { + if (node.nodeName.toLocaleLowerCase() != "iframe") { + return null; + } + + const foundEls = (node.contentDocument || node.contentWindow).getElementsByTagName("form"); + if (foundEls.length <= 0) { + return null; + } + + return foundEls[0]; +} + +/** + * Get form element values. + */ +function getFormElementValueSet(form, ...tagNames){ let result = { }; for (let x=0; x " + message); +} + + + + +Object.getDataType = function(value) { + if (String.isNullOrUndefined(value)) { + return "null"; + } + + if (typeof(value) == "object") { + if (Array.isArray(value)) { + return "array"; + } else { + return "object"; + } + } + + return typeof(value); +}; + String.isNullOrUndefined = function(value) { if (typeof (value) == "undefined") { return true; diff --git a/manifest.json b/manifest.json index 06bc7e4..3feb213 100644 --- a/manifest.json +++ b/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 3, "name": "Form Copypasta", "description": "Copy and paste form element values. Not for distribution. Internal use only. Based on Copy Form (0.0.1.2) by Sam Larison.", - "version": "0.1.0.028", + "version": "0.1.0.035", "content_scripts": [ { "js": [ -- 2.45.2 From a39229690cdc84ef431b019117902aae77f89cec Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 1 Feb 2024 22:03:49 +0000 Subject: [PATCH 2/3] Refactor to separate form-data fro message action --- background.js | 14 ++++--- content.js | 101 +++++++++++++++++++++++++++++--------------------- 2 files changed, 66 insertions(+), 49 deletions(-) diff --git a/background.js b/background.js index 06754e0..81f1627 100644 --- a/background.js +++ b/background.js @@ -24,12 +24,12 @@ chrome.contextMenus.onClicked.addListener(function(msg, tab) { function copyFormContextMenu(tab) { chrome.tabs.sendMessage(tab.id, { action: "copy" }, function(response) { - if (response) { + try { chrome.storage.local.set({ 'clipboard': JSON.stringify(response) },function() { chrome.contextMenus.update("paste_form", { enabled: true }); }); - } else { - // Reload required + } catch (err) { + // Do nothing } }); } @@ -37,10 +37,12 @@ function copyFormContextMenu(tab) { function pasteFormContextMenu(tab, includeHiddenEl) { chrome.storage.local.get('clipboard', function(response) { try { - let msgData = JSON.parse(response.clipboard); - msgData.action = (includeHiddenEl === true ? "paste2" : "paste"); + const payload = { + action: (includeHiddenEl === true ? "paste2" : "paste"), + formData: JSON.parse(response.clipboard) + }; - chrome.tabs.sendMessage(tab.id, msgData); + chrome.tabs.sendMessage(tab.id, payload); } catch (err) { // Do nothing } diff --git a/content.js b/content.js index 3e9b97c..1eddf6c 100644 --- a/content.js +++ b/content.js @@ -1,56 +1,71 @@ chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { - let formContainer = getContainer(document.activeElement); - if (formContainer == null) { + switch (request.action) { + case "copy": + const result = copyFormElementValues(document.activeElement); + sendResponse(result); + break; + case "paste": + pasteFormElementValues(document.activeElement, request.formData, false); + break; + case "paste2": + pasteFormElementValues(document.activeElement, request.formData, true); + break; + default: break; + } +}); + + + + +function copyFormElementValues(el) { + const container = getContainer(el); + if (container == null) { + writeLog("Form container not found"); + return null; + } + + const result = getFormElementValueSet(container, "input", "select", "textarea"); + + console.log(result); + + return result; +} + +function pasteFormElementValues(el, formData, includeHidden) { + if (String.isNullOrUndefined(formData)) { + return; + } + + let container = getContainer(el); + if (container == null) { writeLog("Form container not found"); return; } - switch (request.action) { - case "copy": - const result = getFormElementValueSet(formContainer, "input", "select", "textarea"); + for (let key in formData) { + if (String.isNullOrWhitespace(key)) { + continue; + } - console.log(result); + const dataType = Object.getDataType(formData[key]); + if (dataType == "object") { + continue; + } - sendResponse(result); + const foundEls = container.querySelectorAll("[name='" + key + "']"); + if (foundEls.length <= 0) { + continue; + } - break; - case "paste": - case "paste2": - const includeHidden = (request.action == "paste2"); - - delete request.action; - - for (let key in request) { - if (String.isNullOrWhitespace(key)) { - continue; - } - - const dataType = Object.getDataType(request[key]); - if (dataType == "object") { - continue; - } - - const foundEls = formContainer.querySelectorAll("[name='" + key + "']"); - if (foundEls.length <= 0) { - continue; - } - - if (dataType == "array") { - setFormElementValues(foundEls, request[key], includeHidden); - } else { - for (let x=0; x Date: Thu, 1 Feb 2024 23:07:51 +0000 Subject: [PATCH 3/3] Added hotkey support on Ctrl+Shift+2 and Ctrl+Shift+3 --- background.js | 33 ++++++++++++++++++++++++++------- content.js | 14 ++++++++++---- manifest.json | 46 ++++++++++++++++++++++++++++++++-------------- 3 files changed, 68 insertions(+), 25 deletions(-) diff --git a/background.js b/background.js index 81f1627..0ff560f 100644 --- a/background.js +++ b/background.js @@ -1,24 +1,42 @@ chrome.runtime.onInstalled.addListener(function() { - chrome.contextMenus.create({ "id": "copy_form", "title": "Copy Form", "contexts": ["editable"] }); - chrome.contextMenus.create({ "id": "paste_form", "title": "Paste Form", "contexts": ["editable"], enabled: false }); - chrome.contextMenus.create({ "id": "paste_form2", "title": "Paste Form (with Hidden)", "contexts": ["editable"], enabled: false }); + chrome.contextMenus.create({ "id": "copy-form", "title": "Copy Form", "contexts": ["editable"] }); + chrome.contextMenus.create({ "id": "paste-form", "title": "Paste Form", "contexts": ["editable"], enabled: false }); + chrome.contextMenus.create({ "id": "paste-form2", "title": "Paste Form (with Hidden)", "contexts": ["editable"], enabled: false }); }); chrome.contextMenus.onClicked.addListener(function(msg, tab) { switch (msg.menuItemId) { - case "copy_form": + case "copy-form": copyFormContextMenu(tab); break; - case "paste_form": + case "paste-form": pasteFormContextMenu(tab, false); break; - case "paste_form2": + case "paste-form2": pasteFormContextMenu(tab, true); break; default: break; } }); +chrome.commands.onCommand.addListener(function (command) { + switch (command) { + case 'copy-form': + chrome.tabs.query({ currentWindow: true, active: true }, function (tabs) { + copyFormContextMenu(tabs[0]); + }); + + break; + case 'paste-form': + chrome.tabs.query({ currentWindow: true, active: true }, function (tabs) { + pasteFormContextMenu(tabs[0], false); + }); + + break; + default: break; + } +}); + @@ -26,7 +44,8 @@ function copyFormContextMenu(tab) { chrome.tabs.sendMessage(tab.id, { action: "copy" }, function(response) { try { chrome.storage.local.set({ 'clipboard': JSON.stringify(response) },function() { - chrome.contextMenus.update("paste_form", { enabled: true }); + chrome.contextMenus.update("paste-form", { enabled: true }); + chrome.contextMenus.update("paste-form2", { enabled: true }); }); } catch (err) { // Do nothing diff --git a/content.js b/content.js index 1eddf6c..cafb489 100644 --- a/content.js +++ b/content.js @@ -1,14 +1,14 @@ -chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { - switch (request.action) { +chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) { + switch (message.action) { case "copy": const result = copyFormElementValues(document.activeElement); sendResponse(result); break; case "paste": - pasteFormElementValues(document.activeElement, request.formData, false); + pasteFormElementValues(document.activeElement, message.formData, false); break; case "paste2": - pasteFormElementValues(document.activeElement, request.formData, true); + pasteFormElementValues(document.activeElement, message.formData, true); break; default: break; } @@ -65,6 +65,8 @@ function pasteFormElementValues(el, formData, includeHidden) { } } } + + writeLog("Pasted"); } @@ -147,6 +149,10 @@ function getFormElementValueSet(form, ...tagNames){ for (let i=0; i