WebExtensions - how to get the field value in a web page


#1

Hello,

I just try to migrate my terminated colleague’s addon to Webextension from SDK.
However, I do not know how to realize it. just want to do the followings by addon.

1.Use Context menu
2.Get the values from 2 or more fields which have id in a web page
3.Set these values to clipboard
4.Open specific page as new tab

Previously, SDK get the values as follows.


var f1 = document.getElementById(“filed1”);
var f1value = f1.value;
var f2 = document.getElementById(“field2”);
var f2value = f2.value;

and pack them as follows.


var packdata = “F1:” + f1 + “,F2:” + f2;

Please provide the sample one or similar addons.

Regards.


(erosman) #2

ContextMenu is in background script.
Webpage can be accessed from content script.

An example:

  • ContextMenu to get the data
  • After clicking, browser injects the content code using tabs.executeScript()
  • If the result is needed in the page, then handle it
  • If the result is needed in the background script, then get the result from tabs.executeScript() and handle it



#3

Thanks.

umm it’s difficult for me…
This is my rough design. concept is good?

background.js


// 1
browser.contextMenus.create({
id:

// 2
browser.contextMenus.onClicked.addListener((info, tab) => {

// 3
browser.tabs.executeScript(tab.id, { file: “/content_script/datacopy.js”, });

// 6 recieve filed values from content script and set them to clipboard, and open new tab

content_script/datacopy.js


// 4 how to get the values in field1 and field2?

// 5
chrome.runtime.onMessage.addListener();


(erosman) #4

No need for message send/receive listener. You can pass the result of f1 + f2 to a value that will be retuned by tabs.executeScript()

Check the return value of tabs.executeScript()


#5

Thanks.

But, I still can not find how to get the values which are in specific fields.

Does anyone know how to convert the following content to WebExtension?

var f1 = document.getElementById(“filed1”);
var f1value = f1.value;

Thanks.


(erosman) #6

Plain JavaScript (like above) is the same in WebExtension and other extensions.

What type of node is “filed1”?

Check if the node was found…


#7

Hi,

The filed1 is written as follows in html and has the value e.g. “abcd”. Sorry I do not understand what you need.

<input id=“field1” class=… name=“field1” … type=“text”>

I’d like to do:
1.Use Context menu without selecting any fields
2.Get the values from 2 or more specific fields which have id in a web page
3.Set these values to clipboard
4.Open specific page as new tab

I write the followings and just try to add it using FF developer edition, but did not work.
No error occurs, but I do not know how to debug it…

background.js

browser.contextMenus.create({
id: “CopyData”,
title: “Coyp Data”,
contexts: [“all”],
});

browser.contextMenus.onClicked.addListener((info, tab) => {

return browser.tabs.executeScript(tab.id, {
   	  	file: "/content_script/copy.js",

	}).catch((error) => {
		console.error("Failed to copy data: " + error);
		});

});

/// Need to add the command for opening new tab

copy.js

function copyheader(text) {

var filed1_info = document.getElementById("field1");
var filed1_value = filed1_info.value;

// Not work console in context script?
console.log("filed1_value = " + filed1_value);

function copydata(event) {
	event.clipboardData.setData(filed1_value);
}

document.addEventListener("copy", copydata, true);

document.execCommand("copy");

}


(erosman) #8

That is the problem … browser.tabs.executeScript is asynchronous and doesn’t return anything. You need to wait for it to resolve and then() use the data.


#9

Thank you for your kindly help.

I changed the code as follows, but clipboard does not have any data although I believe I passed the test text data.
“browser.tabs.executeScript was executed!” is shown in Console output and open new tab. So, no error occurs.

backgroud.js

browser.contextMenus.create({
id: “CopyData”,
title: “Coyp Data”,
contexts: [“all”],
});

browser.contextMenus.onClicked.addListener((info, tab) => {

browser.tabs.executeScript(tab.id, {
   	  	file: "/content_script/copy.js",
	}).then(() => {
		console.log('browser.tabs.executeScript was executed!');
	}).catch((error) => {
		console.error("Failed to copy data: " + error);
		});

browser.tabs.create({
	"url": "sample URL" 
     });

});

copy.js
function copyheader(text) {

var filed1_info = document.getElementById(“field1”);
var filed1_value = filed1_info.value;

function copydata(event) {
	document.removeEventListener("copy", copydata, true);
	event.preventDefault();

// event.clipboardData.setData(‘text/plain’, filed1_value);
event.clipboardData.setData(‘text/plain’,‘Copied??’);

}

document.addEventListener("copy", copydata, true);

document.execCommand("copy");

}


(erosman) #10

In your code, it doesnt look like function copyheader(text) {..} is called.


#11

Hi,

Thanks for good point.
I confirmed it works fine as following code.

chrome.contextMenus.onClicked.addListener((info, tab) => {

const text = info.text;
const code = "copyheader(" + JSON.stringify(text) + ");";

    browser.tabs.executeScript({
        code: "typeof copyheader === 'function';",

    }).then(() => {
		return browser.tabs.executeScript(tab.id, {
		code,
		});

	}).catch((error) => {
		console.error("Failed to copy data: " + error);
		});

browser.tabs.create({
	"url": "https://xxxxxxxxxxxxxxxxxxxxxxxxx" ,
	index: tab.index + 1
});

});


(erosman) #12

Can you paste the code somewhere that can be seen easily?


#13

Hi,
This is full code of our extension.

content_script/copy.js

function copyheader(text) {

var filed1_value =  document.getElementById(“field1”).value;

function copydata(event) {
	document.removeEventListener("copy", copydata, true);
	event.preventDefault();
	event.clipboardData.setData(‘text/plain’, filed1_value);

}

document.addEventListener("copy", copydata, true);

document.execCommand("copy");
}

=====

background.js

// Create context menu - right click

chrome.contextMenus.create({
    id: "xxxxx",
    title: "xxxxx",
    contexts: ["all"],
});

// Fire when click context menu
chrome.contextMenus.onClicked.addListener((info, tab) => {

	const text = info.text;
	const code = "copyheader(" + JSON.stringify(text) + ");";

// Call content script and get result

        browser.tabs.executeScript({
            code: "typeof copyheader === 'function';",

        }).then(() => {
		return browser.tabs.executeScript(tab.id, {
		code,
		});

	}).catch((error) => {
		console.error("Failed to copy data: " + error);
		});

// Open Apex page as new tab at next position
	browser.tabs.create({
		"url": "https://xxxxxxxxxxxxxxxxxxxxx" ,
		index: tab.index + 1
	});
	
});

=====


(erosman) #14

That code has problems… try

content_script/copy.js

function copydata(event) {
  document.removeEventListener("copy", copydata, true);
  let filed1_value =  document.getElementById(“field1”).value;
  event.preventDefault();
  event.clipboardData.setData(‘text/plain’, filed1_value);
}

document.addEventListener("copy", copydata, true);
document.execCommand("copy");

background.js

// Create context menu - right click
chrome.contextMenus.create({
    id: "xxxxx",
    title: "xxxxx",
    contexts: ["all"],
});

// Fire when click context menu
chrome.contextMenus.onClicked.addListener((info, tab) => {

  // Call content script and get result
  browser.tabs.executeScript({ file: "content_script/copy.js"})
  .then(
    // succesfull copy from filed1_value
  )
  .catch((error) => {
    console.error("Failed to copy data: " + error);
  });


  // Open Apex page as new tab at next position
  // when is this supposed to happen? Does it have anything to do with the copy?
  browser.tabs.create({
    "url": "https://xxxxxxxxxxxxxxxxxxxxx" ,
    index: tab.index + 1
  });
  
});

Thai is a quick try and I have not tested it.


#15

Hi,

I can not understand which code is problem…
But, your code works! It’s simple one so will use it.