calling Greasemonkey functions from web page [duplicate] - greasemonkey

This question already has an answer here:
How to call Greasemonkey's GM_ functions from code that must run in the target page scope?
(1 answer)
Closed 8 years ago.
Can I call function() of my custom Greasemonkey from my page?
For example,
I created a GM script that contains do_this() function.
I want my-web-site.com call the do_this() function.
But I can't.
I know, I can by doing unsafeWindow.do_this() but doing so prevents
me from calling GM_xmlhttpRequest().
Any ideas?

here the example that working, first create element then addEventListener
// ==UserScript==
// #name GM addEventListener Function Test
// #namespace ewwink.com
// #description GM addEventListener Function Test
// #include http://*
// ==/UserScript==
document.body.innerHTML+='<input type="image" id="alertMeID" onclick="do_this()" style="position:fixed;top:0;left:0" src="http://i55.tinypic.com/2nly5wz.gif" />';
document.getElementById('alertMeID').addEventListener('click', do_this, false);
function do_this(){
alert('hello World!, today is: '+new Date())
}

I just had the same Problem. You can find good information here in the wiki. I would suggest to use script injection to insert the needed code into the document. That way it will run like its in the sourcecode of the page. You can't use GM_ functions there either but you can use a combination of script injection (to retrieve a variable for example) and classic greasemonkey scripting with all the GM_ functions (For example you could use the variables you read and POST them with GM_xmlhttpRequest()).
Furthermore, techniques like script injection have several security-related advantages over unsafeWindow.
I hope that helps.

Never used this myself but here is the workaround http://wiki.greasespot.net/0.7.20080121.0%2B_compatibility.
unsafeWindow.someObject.registerCallback(function() {
var value = "bar";
setTimeout(function() {
GM_setValue("foo", value);
}, 0);
});

No, GM_* functions are not accessible from webpage.

Related

How do I add button in NetSuite client script and use it as trigger for script function?

I'm trying to add a button to the current record with the Client Script button definition on a script record, but for some reason it's not finding my function. I'm returning my function tryThisand there is a button on the page which I created on the script record with the function tryThis defined in the appropriate field, but the code doesn't run. Here's my script:
define (['N/currentRecord','N/search','N/record'] ,
function(currentRecord,search,record) {
function tryThis(context){
log.debug({
title: 'try this',
details: 'try this'
});
}
function pageInit(context) {
}
return {
pageInit: pageInit,
tryThis: tryThis
};
});
Nothing happens :(
Yes, the script is deployed.
How can I use this button on a client script??
This doesn't exactly answer your question directly, but I hope it may help. I tested this, and there appears to be nothing wrong with the way you've set it up - the only thing that seems to be not working is the log module, which I've come across before in client scripts.
Try running your function using a console.log() or alert() instead (both work for me).
Hopefully someone with more detailed knowledge of the N/log module's design and behavior will chip in, as the documentation seems to indicate that this should work.
At the bottom of your Client Script record in Edit mode you will find where you can easily set the button and function to call.

Access content script by injected script

I have a content script where I define a small task api, I would like to access this api (namespace) through the script injected by browser.tabs; executeScript (). for example:
//contentScript.js
const api = new (function () {
     this.doSomething()
})();
// injectedScript
console.log (api.doSomething ())
It is possible? If yes, how?
I'm trying to do this, and am getting a RefereceError.
Being the content script and the script injected, considered by the content scripts documentation, why do not they see each other?
Thanks
The symbol api in your content script is a const, which is not visible outside that specific script. The two scripts run in the same global so var api = ... or simply function api() { ... } should work.

Callback to content script breaks after using captureVisibleTab in Extension [duplicate]

This question already has answers here:
Chrome Extension Message passing: response not sent
(3 answers)
Chrome Extension Message Passing [duplicate]
(1 answer)
Closed 8 years ago.
I've got a very odd problem. I have an extension that takes a screenshot of webpages. I created it using this extension as a reference. It works perfectly and the world is happy.
The extension communicates back and forth with a content script and it uses deprecated APIs to do so. In an effort to keep the extension from using outdated code, I went ahead and made the following replacements:
chrome.tabs.sendRequest(...) -> chrome.tabs.sendMessage(...)
chrome.extension.onRequest(...) -> chrome.runtime.onMessage(...)
chrome.extension.sendRequest(...) -> chrome.runtime.sendMessage(...)
Doing that breaks the extension and it no longer works. If I use the deprecated code, it all works fine again.
I did some tracking and discovered that the extension breaks at the following code:
CONTENT SCRIPT
chrome.runtime.sendMessage(sender.id, data, function(captured) {
window.clearTimeout(cleanUpTimeout);
console.log("came back from extension...");
if (captured) {
// Move on to capture next arrangement.
processArrangements(); //function defined elsewhere
} else {
// If there's an error in popup.js, the response value can be
// undefined, so cleanup
cleanUp(); // function defined elsewhere
}
});
EXTENSION
chrome.runtime.onMessage.addListener(function(message, sender, cb){
appendLog("received message from content script. callback is " + cb);
if (message.msg === 'capturePage') {
capturePage(message, sender, cb);
} else {
console.error('Unknown message received from content script: ' + message.msg);
}
});
function capturePage(data, sender, cb) {
... // some code omitted for clarity
chrome.tabs.captureVisibleTab(
null, {format: 'png', quality: 100}, function(dataURI) {
if (dataURI) {
var image = new Image();
image.onload = function() {
screenshot.ctx.drawImage(image, data.x, data.y);
//appendLog("calling callback function. callback is: " + cb);
cb(true); // **callback isn't called on content script**
};
image.src = dataURI;
}
});
}
I've omitted some code for clarity and the missing code is irrelevant. Let me explain what you see up there:
On the extension, inside the capturePage function, the line cb(true) executes. I can confirm it does because I'm able to see the "calling callback function" that comes right before it. However, the callback code on the content script does NOT run. Again, I can confirm this because I don't see the "came back from extension" message.
Here's the bizarre part: if I call cb(true) BEFORE I call chrome.tabs.captureVisibleTab(), the callback code on the content script DOES execute normally. That means chrome.tabs.captureVisibleTab() is interfering with the execution of cb(true) on the content script somehow. Maybe a port is closed when I call captureVisibleTab() - I'm not sure. The fact of the matter is that cb(true) will not execute on the content script after calling captureVisibleTab() but it will execute if I call it before.
On the extension, I tried storing the callback function, cb, in a variable outside capturePage() and then calling another function which would then call cb... but that doesn't work either.
I added the "" permission to my extension thinking maybe that would change things, but no. That changes nothing.
Again, if I replace the 4 lines of code where the deprecated APIs are, my extension works as expected. Thus, the problem is a combination of sendMessage() and captureVisibleTab(). There is no syntax error and I'm not leaving anything out. If I omit the call to captureVisibleTab(), the cb call will execute normally on the content script. What on earth???
How bizarre is that? I don't want to leave those deprecated API calls there. But then again, what could possibly be preventing the call back code to execute on the content script? I'm set on thinking the port is closed/replaced when we call captureVisibleTab(), but I'm not really sure and I've investigating it further.
I came across this online but I'm not sure if it's related to my issue. I also couldn't find anything similar here on stackoverflow and hence I created this question. Can anyone shed some light on this?
Thanks

How can I disable javascript for the page that's being opened?

I was up till 1 am last night trying to find an example of how to do this. My theory is that I'd write a function that would comment out all javascript.
The second option would be to add the url to the list of javascript settings.
Right now my extension is very simple:
function linkOnClick(info, tab) {
window.open(info.linkUrl)
}
chrome.contextMenus.create(
{title: "Load with no Javascript", contexts:["link"], onclick: linkOnClick});
This is my first extension and I'm kind of lost.
edit: let me know if I should also post the manifest.json.
edit: I can't mark this as solved for 2 days (why? who knows.), so I'll probably not remember to mark this as solved. So accept this as the official making: SOLVED.
chrome.contentSettings.javascript.set is the thing that disables javascript.
Here's the part that disables javascript.
(Google, here's what an actual example should look like):
chrome.contentSettings.javascript.set(
{'primaryPattern':AnyDomainName, /*this is a string with the domain*/
'setting': "block", /* block the domain. Can be switched to "allow" */
'scope':'regular'}, /*it's either regular or incognito*/
function(){
/*optional action you want to
take place AFTER something's been blocked'*/
});
Here's the script I used to import into my json script for my chrome extension.
var link=""
var pattern=""
function linkOnClick(info, tab) {
r = /:\/\/(.[^/]+)/;
link=info.linkUrl
pattern="http://"+link.match(r)[1]+"/*"
chrome.contentSettings.javascript.set(
{'primaryPattern':pattern,
'setting': "block",
'scope':'regular'},
function(){
window.open(link)
});
}
chrome.contextMenus.create({title: "Load with no Javascript", contexts:["link"], onclick: linkOnClick});
I couldn't tell how any of this worked by reading the developer.chrome.com page! They really need add complete working examples or allow a way for users to add examples. I can't even use it. The git hub link is what saved me.

How to use the experimental offscreenTab API?

I've been searching for examples and reference and have come up with nothing. I found a note in offscreenTab source code mentioning it cannot be instantiated from a background page (it doesn't have a tab for the offscreenTab to relate to). Elsewhere I found mention that popup also has no tie to a tab.
How do you successfully create an offscreenTab in a Chrome extension?
According to the documentation, offscreenTabs.create won't function in a background page. Although not explicitly mentioned, the API cannot be used in a Content script either. Through a simple test, it seems that the popup has the same limitation as a background page.
The only leftover option is a tab which runs in the context of a Chrome extension. The easiest way to do that is by using the following code in the background/popup:
chrome.tabs.create({url: chrome.extension.getURL('ost.htm'), active:false});
// active:false, so that the window do not jump to the front
ost.htm is a helper page, which creates the tab:
chrome.experimental.offscreenTabs.create({url: '...'}, function(offscreenTab) {
// Do something with offscreenTab.id !
});
To change the URL, use chrome.experimental.offscreenTabs.update.
offscreenTab.id is a tabId, which ought to be used with the chrome.tabs API. However, at least in Chrome 20.0.1130.1, this is not the case. All methods of the tabs API do not recognise the returned tabID.
A work-around is to inject a content script using a manifest file, eg:
{"content_scripts": {"js":["contentscript.js"], "matches":["<all_urls>"]}}
// contentscript.js:
chrome.extension.sendMessage({ .. any request .. }, function(response) {
// Do something with response.
});
Appendum to the background page:
chrome.extension.onMessage.addListener(function(message, sender, sendResponse) {
// Instead of checking for index == -1, you can also see if the ID matches
// the ID of a previously created offscreenTab
if (sender.tab && sender.tab.index === -1) {
// index is negative if the tab is invisible
// ... do something (logic) ...
sendResponse( /* .. some response .. */ );
}
});
With content scripts, you've got full access to a page's DOM. But not to the global object. You'll have to inject scripts (see this answer) if you want to run code in the context of the page.
Another API which might be useful is the chrome.webRequest API. It can be used to modify headers/abort/redirect requests. Note: It cannot be used to read or modify the response.
Currently, the offscreenTabs API is experimental. To play with it, you have to enable the experimental APIs via chrome://flags, and add "permissions":["experimental"] to your manifest file. Once it's not experimental any more, use "permissions":["offscreenTabs"].

Resources