Initial commit

This commit is contained in:
Ray 2024-02-01 00:53:14 +00:00
commit ec4daf2268
8 changed files with 282 additions and 0 deletions

44
background.js Normal file
View File

@ -0,0 +1,44 @@
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.onClicked.addListener(function(msg, tab) {
switch (msg.menuItemId) {
case "copy_form":
copyFormContextMenu(tab);
break;
case "paste_form":
pastFormContextMenu(tab);
break;
default: break;
}
});
function copyFormContextMenu(tab) {
chrome.tabs.sendMessage(tab.id, { action: "copy" }, function(response) {
if (response) {
chrome.storage.local.set({ 'clipboard': JSON.stringify(response) },function() {
chrome.contextMenus.update("paste_form", { enabled: true });
});
} else {
// Reload required
}
});
}
function pastFormContextMenu(tab) {
chrome.storage.local.get('clipboard', function(response) {
try {
let msgData = JSON.parse(response.clipboard);
msgData.action = "paste";
chrome.tabs.sendMessage(tab.id, msgData);
} catch (err) {
// Do nothing
}
});
}

203
content.js Normal file
View File

@ -0,0 +1,203 @@
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
const parentForm = getParentFormNode(document.activeElement);
if (parentForm == null) {
console.log("Form not found");
return;
}
switch (request.action) {
case "copy":
const result = buildFormValueSet(parentForm, "input", "select", "textarea");
console.log(result);
sendResponse(result);
break;
case "paste":
delete request.pasteForm;
// console.log(request);
for (let key in request) {
if (String.isNullOrWhitespace(key)) {
continue;
}
const dataType = checkDataType(request[key]);
if (dataType == "object") {
continue;
}
const foundElements = parentForm.querySelectorAll("[name='" + key + "']");
if (foundElements.length <= 0) {
continue;
}
if (dataType == "array") {
setFormElementValues(foundElements, request[key]);
} else {
for (let x=0; x<foundElements.length; x++) {
setFormElementValue(foundElements[x], request[key]);
}
}
}
break;
default: break;
}
});
/**
* Check the data type of the value (string, number, array, object).
*/
function checkDataType(value) {
if (String.isNullOrUndefined(value)) {
return "null";
}
if (typeof(value) == "object") {
if (Array.isArray(value)) {
return "array";
} else {
return "object";
}
}
return typeof(value);
}
/**
* Get parent form node.
*/
function getParentFormNode(node) {
let result = node;
// Special case, look inside iframe.
if (result.nodeName.toLocaleLowerCase() == "iframe") {
const foundForms = (result.contentDocument || result.contentWindow).getElementsByTagName("form");
if (foundForms.length > 0) {
return foundForms[0];
}
}
while (true) {
if (String.isNullOrUndefined(result)) {
result = null;
break;
}
if (result.nodeName.toLocaleLowerCase() == "form") {
break;
}
result = result.parentNode;
}
return result;
}
/**
* Push form element value to array.
*/
function buildFormValueSet(form, ...tagNames){
let result = { };
for (let x=0; x<tagNames.length; x++) {
let els = form.getElementsByTagName(tagNames[x]);
for (let i=0; i<els.length; i++) {
let newValue = null;
switch (els[i].type)
{
case "hidden":
// Do nothing
break;
case "checkbox":
newValue = els[i].checked;
break;
case "radio":
newValue = els[i].checked;
break;
default:
newValue = els[i].value;
break;
}
if (newValue === null) {
continue;
}
if (result[els[i].name]) {
// Convert single to array
if (checkDataType(result[els[i].name]) != "array") {
result[els[i].name] = [result[els[i].name]];
}
result[els[i].name].push(newValue);
} else {
result[els[i].name] = newValue;
}
}
}
return result;
}
/**
* Set single form element value.
*/
function setFormElementValue(el, value) {
switch (el.type) {
case "hidden":
break;
case "checkbox":
case "radio":
el.checked = value;
break;
default:
el.value = value;
break;
}
}
/**
* Set form element value from an array of values.
*/
function setFormElementValues(els, values) {
for (let i=0; i<Math.min(els.length, values.length); i++) {
setFormElementValue(els[i], values[i]);
}
}
String.isNullOrUndefined = function(value) {
if (typeof (value) == "undefined") {
return true;
}
if (value == null) {
return true;
}
return false;
};
String.isNullOrWhitespace = function(value) {
const a = this;
if (String.isNullOrUndefined(value)) {
return true;
}
if (typeof(value) == "string") {
return (value.trim().length <= 0);
} else {
return (value.toString().trim().length <= 0);
}
};

BIN
icon128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

BIN
icon16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 873 B

BIN
icon32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
icon48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
icon64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

35
manifest.json Normal file
View File

@ -0,0 +1,35 @@
{
"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",
"content_scripts": [
{
"js": [
"content.js"
],
"run_at": "document_idle",
"all_frames": true,
"matches": [
"<all_urls>"
]
}
],
"background": {
"service_worker": "background.js",
"type": "module"
},
"icons": {
"16": "icon16.png",
"32": "icon32.png",
"48": "icon48.png",
"64": "icon64.png",
"128": "icon128.png"
},
"permissions": [
"activeTab",
"contextMenus",
"storage",
"tabs"
]
}