I want to open webpage and automatically fill in login information. My main.js addon code is given below. I have uname and upass variable. I want to fill in the login form using those when addon opens the tab.
var uname="username";
var upass="password";
tabs.open({
url: "https://www.facebook.com",
onReady:runScript
});
function runScript(tab) {
tab.attach({
contentScriptFile: data.url("mody.js")
});
I put this code in my mody.js file:
document.getElementById("email").value=uname; // uname undefined
document.getElementById("pass").value=upass; // upass undefined
But I can't access these variables from mody.js. Is there any way to pass this variable to the login page?
Use the contentScriptOptions for this.
The contentScriptOptions is a JSON object that is exposed to content
scripts as a read-only value under the self.options property:
Related
I am trying to use PhantomJS on a page with basic always auth, for example, this page
http://alexturpin.net/auth (test:rosebud)
Using the following code
var webpage = require('webpage');
page = webpage.create();
page.settings = {
userName: "test",
password: "rosebud"
};
page.open("http://alexturpin.net/auth/", function(status) {
console.log(status);
var retval = page.evaluate(function() {
return "test";
});
console.log(retval);
});
I get this output
$ phantomjs test.js
success
null
Whatever I try, evaluate will keep returning null, even though the page seems to have been opened fine because status contains "success".
If I decide to open a page with no basic auth, like http://alexturpin.net/noauth, I still get the same results. Only when I finally remove the authentication settings altogether before opening the page does it work.
The use of authentication settings seem to be conflicting with the evaluate. Is this a bug in PhantomJS, or did I miss something?
With that syntax you are wiping out the settings object, replacing it with only userName and password. Use that code to set them:
page.settings.userName = "test";
page.settings.password = "rosebud";
Probably PhantomJS should handle that better, i.e. not rely on the settings object for defaults.
This is a closure issue, try to put your console.log in a callback
I wrote an chrome extension, which saves user input to the local storage via chrome.storage.sync.set/get... and sends this data via chrome.tabs.sendMessage to a content script, which listens via chrome.runtime.onMessage.addListener. This whole load and send process is triggered, when the user opens the extension per mouse click and presses a button. Before this happens the content script has not the needed data to do its task and is waiting.
Concrete requirements / questions:
I want, that the local storage data gets loaded (and sent to the content script) automatically on every page load without any user interaction needed.
Which callback do I have to implement or where do I have to put my code in order to achieve this?
The whole code looks like this (Tag and Pass are the mentioned user data):
function clickHandler(e) {
var tag = document.getElementById(DOM_TAG).value, pass = document.getElementById(DOM_PASS).value;
// ...query for the active tab...
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {
from: 'popup',
subject: 'init',
tag: tag,
pass: pass
});
});
// Save data to local storage.
chrome.storage.sync.set({DOM_TAG: tag, DOM_PASS: pass}, function() {
// Notify that we saved.
});
}
// Once the DOM is ready...
window.addEventListener('DOMContentLoaded', function() {
// Load data from local storage.
chrome.storage.sync.get({DOM_TAG: 'defaultTag', DOM_PASS: 'defaultPass'}, function(items) {
document.getElementById(DOM_TAG).value = items.DOM_TAG;
document.getElementById(DOM_PASS).value = items.DOM_PASS;
});
document.querySelector('button').addEventListener('click', clickHandler);
});
What I already tried:
Of course I tried to start the process inside the callback function for DOMContentLoaded, but that is not working since this event only gets fired when the user manually opens the extensions by clicking on it. Thats not what I want.
I also tried to put the specific lines of code into a BackgroundScript, with no success.
You do not need to pass data from extension to content script. You can access it directly in content script. i.e: chrome.storage.local and chrome.storage.sync are available to content scripts.
Your extension's content scripts can directly access user data without the need for a background page.
storage docs
I'm currently writing a Chrome Extension that takes user selected data and passes it to another window. Aside from the manifest.json files, I have a background.js and index.php file.
The background.js file successfully grabs the user selected data, opens a new broswer window, and then passes the user selected data to the index.php file located on a server via $_GET. This works great until you exceed a certain character limit in which case you get an error saying the url is too long. I was wondering if there was anyway to send the data from the background.js file to the new window using $_POST or any other method that would allow larger data selections? Or could I just pass the user selected data to the new window first, and then have that window access the server?
background.js
function getClickHandler() {
return function(info, tab) {
var tx = info.selectionText;
tx = encodeURIComponent(tx);
// Create a new window to the info page.
var url = 'http://192.168.0.22?tx=' + tx;
chrome.windows.create({url: url, width: 500, height: 760 });
};
};
chrome.contextMenus.create({
"title" : "Store",
"type" : "normal",
"contexts" : ["selection"],
"onclick" : getClickHandler()
});
index.php
<?php
$text = $_GET['tx'];
print ($text);
?>
Potentially you could create a form dynamically and then set an input to the value you're trying to send as a query-string-parameter.
Something like:
var $form = $('<form action="' + url + '" method="POST" target="_blank" />'),
$input = $('<input name="tx" type="text" />').val(tx);
$form.append($input).trigger("submit");
Without running the code I'm not sure if the submit will function without adding the form to the DOM, if not then you'll need to append the form to the DOM and then trigger submit, after which you probably want to remove the form from the DOM.
I say potentially because I'm not familiar with writing Chrome Extensions but I've done this as part of a normal web-app before and it worked.
I already created an extension that does the following:
When I run Thinderbird with the command line thunderbird -MyCustomParam1 "12345" my extension will open a compose window and add the parameter "12345" to the window.
Some code that I use:
// In the calling code
var args = {
param1: 12345,
};
args.wrappedJSObject = args;
var watcher = Components.classes["#mozilla.org/embedcomp/window-watcher;1"]
.getService(Components.interfaces.nsIWindowWatcher);
watcher.openWindow(null, url, windowName, features, args);
// In the window code
var args = window.arguments[0].wrappedJSObject;
Of course using the correct url and features.
Now I want to do the same, but for the message window and with am eml file that is choose.
You can open an eml file from the command line like this: Thunderbird test.eml (this will open the mail in a new window).
What I want is the following:
Thunderbird test.eml -MycustomParam1 "1234" should open the mail, and add the param "1234" to screen, so I can access it in the document window, just like example 1.
So basically I want something like watcher.openWindow, but with a given eml file.
Any ideas?
You can see how this is done in the MsgOpenFromFile function, it is being called for the File / Open Saved Message menu item. You basically have to take the eml file (get an nsIFile instance from file path), turn it into a URI and then change the query string before opening a message window:
uri.QueryInterface(Components.interfaces.nsIURL);
uri.query = "type=application/x-message-display";
watcher.openWindow(null, "chrome://messenger/content/messageWindow.xul", "_blank",
"all,chrome,dialog=no,status,toolbar", uri);
Using the Google Javascript API I am trying to authenticate myself (locally) to create a new event in my calendar. However, I get an error (see below) stating that my "next" parameter is bad or missing when I execute the log-in portion of the script. I am following the data api interactive samples for "Create a single event".
Update 1: From the address bar I see "next" set the following way:
next=file:///C:/calext/sending_data.html
Does Google not like local files? Workaround?
Update 2: I tried running the file on my web host. The page ran (threw a few errors) but the event ended up on my calendar. So the bug lies somewhere with not liking local files. Thoughts?
Error Message:
The page you have requested cannot be
displayed. Another site was requesting
access to your Google Account, but
sent a malformed request. Please
contact the site that you were trying
to use when you received this message
to inform them of the error. A
detailed error message follows:
The "next" parameter was bad or
missing.
My page's code:
<html>
<head>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
</head>
<body>
<img src="128.png">
<script type="text/javascript">
var myService;
var feedUrl = "https://www.google.com/calendar/feeds/default/private/full";
google.load("gdata", "1");
google.setOnLoadCallback(getMyFeed); // starts process
// Create a single event example
function doExample()
{
var calendarService = myService;
// The default "private/full" feed is used to insert event to the
// primary calendar of the authenticated user
var feedUri = 'http://www.google.com/calendar/feeds/default/private/full';
// Create an instance of CalendarEventEntry representing the new event
var entry = new google.gdata.calendar.CalendarEventEntry();
// Set the title of the event
entry.setTitle(google.gdata.Text.create('JS-Client: insert event'));
// Create a When object that will be attached to the event
var when = new google.gdata.When();
// Set the start and end time of the When object
var startTime = google.gdata.DateTime.fromIso8601("2010-10-24T09:00:00.000-05:00");
var endTime = google.gdata.DateTime.fromIso8601("2010-10-24T10:00:00.000-05:00");
when.setStartTime(startTime);
when.setEndTime(endTime);
// Add the When object to the event
entry.addTime(when);
// Submit the request using the calendar service object
calendarService.insertEntry(feedUri, entry, handleMyFeed, handleError, google.gdata.calendar.CalendarEventEntry);
}
function handleMyFeed(myResultsFeedRoot)
{
alert("This feed's title is: " + myResultsFeedRoot.feed.getTitle().getText());
}
function handleError(e)
{
alert("There was an error!");
alert(e.cause ? e.cause.statusText : e.message);
}
function getMyFeed()
{
// Set up my service
myService = new google.gdata.calendar.CalendarService('GoogleInc-jsguide-1.0');
// Log me in
var scope = "https://www.google.com/calendar/feeds/";
var token = google.accounts.user.login(scope);
// Create a single event example
doExample();
// Get my feed
myService.getEventsFeed(feedUrl, handleMyFeed, handleError);
}
</script>
</body>
</html>
I assume your opening a local file which requires a local file. By default, file:// URIs cannot read other file:// URIs. Try adding this command line parameter, it is specifically made to help developers test:
chrome --allow-file-access-from-files