form detection w/site configs and ajax

This commit is contained in:
Chris Karlof 2013-01-04 15:15:41 -08:00
Родитель 5df0ec63cf
Коммит 3736e850e2
14 изменённых файлов: 5876 добавлений и 35 удалений

Просмотреть файл

@ -9,3 +9,5 @@ Setup
-----
Make sure to check out submodules (` git submodule update --init `) before running.
Building the site configuration file requires running `build_site_configs.rb`. This is only needed when site_configs.yml is updated. This script uses the js-yaml commmand line tool [https://github.com/nodeca/js-yaml], which must be in your PATH.

Просмотреть файл

@ -1,6 +1,8 @@
<!doctype html>
<script src="../lib/jquery.js"></script>
<script src="../lib/jsuri.js"></script>
<script src="../lib/tldjs.js"></script>
<script src="../lib/js-yaml.js"></script>
<script src="../infobar/manager.js"></script>
<script src="util.js"></script>
<script src="browser_action_interface.js"></script>
@ -10,8 +12,8 @@
<script src="chrome_messaging.js"></script>
<script src="command_handler.js"></script>
<script src="storage.js"></script>
<script src="tld_service.js"></script>
<script src="captured_credential_storage.js"></script>
<script src="site_configs.js"></script>
<script src="main.js"></script>
<body>
<!-- Invisible <textarea> used to copy data onto the clipboard -->

Просмотреть файл

@ -14,12 +14,9 @@ var CapturedCredentialStorage = function(TldService) {
// id: identifier for the credential's source
// url: url of the credential's source
function setCredentials(credentials, source) {
var callback = function(tld) {
credentials.domain = tld;
credentials.domain = TldService.getDomain((new Uri(source.url)).host());
storage[source.id] = credentials;
console.log("Storing credentials", credentials);
};
TldService.tldForDomain((new Uri(source.url)).host(), callback);
}
function getCrendentials(credentials, source, callback) {

Просмотреть файл

@ -124,7 +124,7 @@ var CommandHandler = function(Messaging, CapturedCredentialStorage) {
}
function getSavedCredentials(message, sender, callback) {
var hostname = (new Uri(sender.tab.url)).host();
var hostname = Gombot.TldService.getDomain((new Uri(sender.tab.url)).host());
getLoginsForSite(hostname, function(logins) {
callback(logins);
});
@ -148,6 +148,10 @@ var CommandHandler = function(Messaging, CapturedCredentialStorage) {
return true;
}
function getSiteConfig(message, sender, callback) {
callback(Gombot.SiteConfigs[Gombot.TldService.getDomain(new Uri(sender.tab.url).host())] || {});
}
var commandHandlers = {
'add_login': addLogin,
'observing_page': observingPage,
@ -156,7 +160,8 @@ var CommandHandler = function(Messaging, CapturedCredentialStorage) {
'set_captured_credentials': setCapturedCredentials,
'get_captured_credentials': getCapturedCredentials,
'delete_captured_credentials': deleteCapturedCredentials,
'get_saved_credentials': getSavedCredentials
'get_saved_credentials': getSavedCredentials,
'get_site_config': getSiteConfig
};
//

Просмотреть файл

@ -10,7 +10,8 @@ initGombot();
var Gombot = {};
Gombot.Messaging = ChromeMessaging();
Gombot.TldService = TldService();
Gombot.TldService = Tld;
Gombot.SiteConfigs = SiteConfigs;
Gombot.CapturedCredentialStorage = CapturedCredentialStorage(Gombot.TldService);
Gombot.CommandHandler = CommandHandler(Gombot.Messaging, Gombot.CapturedCredentialStorage);

Просмотреть файл

@ -0,0 +1,2 @@
// AUTOGENERATED FILE: EDIT 'site_configs.yml' instead and run 'build_site_configs.rb'
var SiteConfigs = { "hulu.com": { "clickOn": "input.inactive.dummy.user" }};

Просмотреть файл

@ -0,0 +1,2 @@
hulu.com:
clickOn: "input.inactive.dummy.user"

Просмотреть файл

@ -1,11 +0,0 @@
var TldService = function() {
// TODO: flesh this out
function tldForDomain(domain, callback) {
callback(domain);
}
return {
tldForDomain: tldForDomain
};
};

5
build_site_configs.rb Executable file
Просмотреть файл

@ -0,0 +1,5 @@
#!/usr/bin/ruby
output = "// AUTOGENERATED FILE: edit 'site_configs.yml' instead and run 'build_site_configs.rb'\n"
output += "var SiteConfigs = "+`js-yaml -j #{Dir.pwd+"/background/site_configs.yml"}`.gsub(/\n/,"")+";"
File.open(Dir.pwd+"/background/site_configs.js", 'w') {|f| f.write(output) }

Просмотреть файл

@ -3,8 +3,8 @@ var Gombot = {};
Gombot.Messaging = ContentMessaging();
Gombot.MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
Gombot.DomMonitor = DomMonitor(jQuery, Gombot.MutationObserver);
Gombot.PasswordForm = PasswordForm(jQuery, Gombot.DomMonitor);
//Gombot.InputMonitor = InputMonitor(Gombot.MutationObserver); not used, replaced by DomMonitor
Gombot.SiteConfig = {};
Gombot.PasswordForm = PasswordForm(jQuery, Gombot.DomMonitor, Gombot.SiteConfig);
Gombot.Linker = {};
Gombot.PasswordFormInspector = PasswordFormInspector(jQuery, Gombot.PasswordForm, Gombot.DomMonitor);
@ -58,7 +58,8 @@ function formsFound(formInspector) {
var formInspectorObserver = {
formsFound: formsFound,
credentialsCaptured: credentialsCaptured
credentialsCaptured: credentialsCaptured,
link: maybePromptToSaveCapturedCredentials
};
function start() {
@ -68,4 +69,7 @@ function start() {
Gombot.PasswordFormInspector.observe(formInspectorObserver);
}
start();
Gombot.Messaging.messageToChrome({type: "get_site_config"}, function(config) {
Gombot.SiteConfig.config = config;
start();
});

Просмотреть файл

@ -1,22 +1,33 @@
var PasswordForm = function($, DomMonitor) {
var PasswordForm = function($, DomMonitor, SiteConfig) {
function notifyObserver(fn) {
var args;
if (this.observer[fn]) {
args = Array.prototype.slice.call(arguments,1);
// Add self as first argument
args.unshift(this);
this.observer[fn].apply(this.observer, args);
}
}
function passwordFieldRemovedCallback(domMonitor) {
//console.log("PasswordForm.passwordFieldRemovedCallback username=",this.getUsername(),"password=",this.getPassword());
// Stop listening for the password field to be removed
DomMonitor.off("isRemoved.pwdEl"+this.id);
if (this.getPassword()) { // if we have a password in the form
// Notify observer of credentials in the form
notifyObserver.call(this, "credentialsCaptured");
}
// Notify observers they should link if they have captured creds
// TODO: maybe should qualify this a bit, e.g., only notify if user
// actually entered credentials into this form
// Note: this should be called even if the password field is empty because
// the page may have deleted the password field contents before removing it.
notifyObserver.call(this, "link");
}
function capturedCredentialsCallback(event) {
notifyObserver.call(this, "credentialsCaptured");
}
var PasswordForm = function(id, usernameField, passwordField, containingEl) {
this.id = id;
this.usernameField = usernameField;
@ -38,11 +49,8 @@ var PasswordForm = function($, DomMonitor) {
// becomes visible, invisible, or removed.
PasswordForm.prototype.observe = function(observer) {
this.observer = observer;
var capturedCredentialsNotify = function(event) {
notifyObserver.call(this, "credentialsCaptured");
};
this.$containingEl.on(this.inputEvents, "input", capturedCredentialsNotify.bind(this));
this.$containingEl.on(this.submitEvents, capturedCredentialsNotify.bind(this));
this.$containingEl.on(this.inputEvents, "input", capturedCredentialsCallback.bind(this));
this.$containingEl.on(this.submitEvents, capturedCredentialsCallback.bind(this));
return this;
};
@ -54,6 +62,10 @@ var PasswordForm = function($, DomMonitor) {
};
PasswordForm.prototype.fill = function(credentials) {
var clickOn = SiteConfig.config.clickOn;
if (clickOn) {
$(clickOn).click();
}
this.usernameField.el.value = credentials.username;
this.passwordField.el.value = credentials.password;
return this;

Просмотреть файл

@ -71,9 +71,13 @@ var PasswordFormInspector = function($, PasswordForm, DomMonitor) {
visitObservers("credentialsCaptured", creds);
}
function link(passwordForm) {
visitObservers("link");
}
var passwordFormObserver = {
credentialsCaptured: credentialsCaptured,
link: function() { visitObservers("link"); }
link: link
};
// internal function to start observing the form collection

5162
lib/js-yaml.js Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

654
lib/tldjs.js Normal file

Различия файлов скрыты, потому что одна или несколько строк слишком длинны