I want to develop an extension that runs in the background and listens to keystrokes and stores them as a string in a variable. For example, if I have 5 tabs in a chrome browser window and I press a,b,c,d,e on each tab of the window; the final string should be abcde.
Could any please provide a sample code for this?
Help will be greatly appreciated.
You could add code like this to a content script:
var bodyElement = document.getElementsByTagName("body")[0];
bodyElement.addEventListener("keypress", function(e){
console.log(e);
console.log(String.fromCharCode(e.keyCode));
});
The body element must be loaded for this code to work, so use jQuery's $(document).ready(), or similar, or in the extension manifest set the run_at value for the script to document_end.
Related
I am trying to fix a bug in a Chrome extension. When the extension is installed an alert dialog containing the message "undefined" will be displayed seemingly at random. This does not happen when the extension is not installed.
There is not one call to alert, confirm, or prompt in the extension source code. How do I find out why the alert dialog is being displayed?
I have attempted adding the following code to one of the background scripts and to one of the content scripts.
var originalWindowAlert = window.alert;
window.alert = function() {
console.trace();
return originalWindowAlert.apply(window, arguments);
}
I have confirmed that this technique works when used in a webpage, but it is not working for the extension.
I have also built Chromium from source code and I am able to reproduce it but so far I have not been able to figure out how to determine the origin of the alert dialog. I have set a breakpoint in the RenderFrameHostImpl::RunModalAlertDialog function but I see no way to determine what caused the breakpoint to be hit.
I am getting desperate.
I asked this question on the Chromium Extensions Google Group. I got the following very useful response from Scott Fortmann-Roe.
If you do the following in a content script:
var originalWindowAlert = window.alert;
window.alert = function() {
console.trace();
return originalWindowAlert.apply(window, arguments);
}
I don't believe it will actually intercept alerts triggered by the page as you are overriding the content script's window.alert method which is different from the page's method (content script JS is isolated from page JS).
To modify the page's alert method you'll probably need to inject a script tag into the page. E.g. something along these lines in the content script:
let script = document.createElement('script');
script.textContent = `
var originalWindowAlert = window.alert;
window.alert = function() {
console.trace()
return originalWindowAlert.apply(window, arguments);
} `;
document.body.appendChild(script);
I have a requirement that we should be able to copy an image displayed in our application, to Clipboard and paste it outside (Like on Excel).
I was trying the below code snippet (Inside a button Click).
Clipboard.generalClipboard.clear();
var dataLoaded:Boolean = Clipboard.generalClipboard.setData(ClipboardFormats.RICH_TEXT_FORMAT,
byteArray, false);
The dataLoaded object is true, however it does not paste anything when tried on Excel or MsPaint.
Do we have any way to achieve this?
Thanks.
The code you are showing is not enough in itself to get a successful transfer. Like many other operations within the security sandbox of a FP app (web) this code can only respond to a direct user interaction. So your code without any valid context cannot work of course but if called within a mouse down listener for example (a true user generated mouse event, creating a fake mouseevent would still not work) it should respond correctly:
private function handleMouseClick(event:MouseEvent):void
{
Clipboard.generalClipboard.clear();
var dataLoaded:Boolean = Clipboard.generalClipboard.setData(ClipboardFormats.RICH_TEXT_FORMAT, byteArray, false);
}
I created a simple chrome app which has only one text div element by id "sample". I'm testing on chromebook. The problem is this:
I typed few keys in text input.
I pressed the full screen button in Chromebook.
The focus on the text input element is lost.
This is the function i'm using to create the chrome app window
chrome.app.runtime.onLaunched.addListener(function() {
chrome.app.window.create('index.html',
{'bounds': {'width': 500, 'height': 309}});
});
I wrote a small javascript code to handle the full screen issue. But this is not working:
chrome.app.window.current().onFullscreened.addListener(function(){
var textbox = document.getElementById("sample");
textbox.focus();
});
Please help.
Put a call to console.log in your onFullscreened handler to verify that it's being called. The current() method returns an AppWindow object, which is certainly not what you want to attach the event handler to. Perhaps the contentWindow property of the AppWindow is what you want. Try that.
Is there a simple way where I can access a global javascript variable through content-scripts in chrome extensions?
Accessing global object from content script in chrome extension
I followed the steps mentioned in the above link, but it did not work out for me. Any help would be much appreciated.
Thanks,
Shankar
I managed to complete it. Thanks for the help. I used simple message passing to retrieve the value from the extension script to the content script. The place where I had missed was, the listener at the extension script needs to be at the background page (I think so). Once I changed that, it worked.
For those from the future looking for an answer to this question, here's how I do it:
function getVariable(v) {
var c = document.createElement("div");
c.id = 'var-data';
c.style.display = 'none';
document.body.appendChild(c);
var s = document.createElement('script');
s.innerHTML = 'document.getElementById("var-data").innerText=JSON.stringify('+v+');';
document.head.appendChild(s);
var data = JSON.parse(c.innerText);
c.remove();
s.remove();
return data;
}
And basic usage:
getVariable('globalVarIWantToAccess');
All this script goes in the content-script, not the code for the main webpage, which means that no co-operation is needed from the webpage itself. Basically, the getVariable function creates a script element which is injected into the main page. This script tag retrieves the requested global variable and puts the data into a new div. The function then gets this data from the new div, deletes the new div, deletes the new script element and returns the data.
In Google Chrome's extension developer section, it says
The HTML pages inside an extension
have complete access to each other's
DOMs, and they can invoke functions on
each other. ... The popup's contents
are a web page defined by an HTML file
(popup.html). The popup doesn't need
to duplicate code that's in the
background page (background.html)
because the popup can invoke functions
on the background page
I've loaded and tested jQuery, and can access DOM elements in background.html with jQuery, but I cannot figure out how to get access to DOM elements in popup.html from background.html.
can you discuss why you would want to do that? A background page is a page that lives forever for the life time of your extension. While the popup page only lives when you click on the popup.
In my opinion, it should be refactored the other way around, your popup should request something from the background page. You just do this in the popup to access the background page:
chrome.extension.getBackgroundPage()
But if you insist, you can use simple communication with extension pages with sendRequest() and onRequest. Perhaps you can use chrome.extension.getViews
I understand why you want to do this as I have run into the problem myself.
The easiest thing I could think of was using Google's method of a callback - the sendRequest and onRequest methods work as well, but I find them to be clunky and less straightforward.
Popup.js
chrome.extension.getBackgroundPage().doMethod(function(params)
{
// Work with modified params
// Use local variables
});
Background.html
function doMethod(callback)
{
if(callback)
{
// Create/modify params if needed
var params;
// Invoke the callback
callback(params);
}
}
As other answers mention, you can call background.js functions from popup.js like so:
var _background = chrome.extension.getBackgroundPage();
_background.backgroundJsFunction();
But to access popup.js or popup.html from background.js, you're supposed to use the messages architecture like so:
// in background.js
chrome.runtime.sendMessage( { property: value } );
// in popup.js
chrome.runtime.onMessage.addListener(handleBackgroundMessages);
function handleBackgroundMessages(message)
{
if (message.property === value)
// do stuff
}
However, it seems that you can synchronously access popup.js from background.js, just like you can synchronously access the other way around. chrome.extension.getViews can get you the popup window object, and you can use that to call functions, access variables, and access the DOM.
var _popup = chrome.extension.getViews( { type: 'popup' } )[0];
_popup.popupJsFunction();
_popup.document.getElementById('element');
_popup.document.title = 'poop'
Note that getViews() will return [] if the popup is not open, so you have to handle that.
I'm not sure why no one else mentioned this. Perhaps there's some pitfalls or bad practices to this that I've overlooked? But in my limited testing in my own extension, it seems to work.