detect login form submitted and show notification
This commit is contained in:
parent
54e8867ce7
commit
4bd34598b1
|
@ -1,4 +1,5 @@
|
|||
var isBackground = true;
|
||||
var loginsToAdd = [];
|
||||
var i18nService = new i18nService();
|
||||
var constantsService = new ConstantsService();
|
||||
var utilsService = new UtilsService();
|
||||
|
@ -56,15 +57,28 @@ chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
|
|||
messageCurrentTab('closeOverlayPopup');
|
||||
}
|
||||
else if (msg.command === 'bgOpenNotificationBar') {
|
||||
messageCurrentTab('openNotificationBar');
|
||||
messageCurrentTab('openNotificationBar', msg.data);
|
||||
}
|
||||
else if (msg.command === 'bgCloseNotificationBar') {
|
||||
messageCurrentTab('closeNotificationBar');
|
||||
}
|
||||
else if (msg.command === 'bgCollectPageDetails') {
|
||||
collectPageDetailsForContentScript(sender.tab);
|
||||
}
|
||||
else if (msg.command === 'bgAddLogin') {
|
||||
addLogin(msg.login, sender.tab);
|
||||
}
|
||||
else if (msg.command === 'collectPageDetailsResponse') {
|
||||
clearTimeout(autofillTimeout);
|
||||
pageDetailsToAutoFill.push({ frameId: sender.frameId, tabId: msg.tabId, details: msg.details });
|
||||
autofillTimeout = setTimeout(autofillPage, 300);
|
||||
// messageCurrentTab('openNotificationBar', { type: 'add', typeData: null });
|
||||
if (msg.contentScript) {
|
||||
var forms = autofillService.getFormsWithPasswordFields(msg.details);
|
||||
messageTab(msg.tabId, 'pageDetails', { details: msg.details, forms: forms });
|
||||
}
|
||||
else {
|
||||
clearTimeout(autofillTimeout);
|
||||
pageDetailsToAutoFill.push({ frameId: sender.frameId, tabId: msg.tabId, details: msg.details });
|
||||
autofillTimeout = setTimeout(autofillPage, 300);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -156,6 +170,7 @@ function buildContextMenu(callback) {
|
|||
}
|
||||
|
||||
chrome.tabs.onActivated.addListener(function (activeInfo) {
|
||||
checkLoginsToAdd();
|
||||
refreshBadgeAndMenu();
|
||||
});
|
||||
|
||||
|
@ -165,6 +180,7 @@ chrome.tabs.onReplaced.addListener(function (addedTabId, removedTabId) {
|
|||
return;
|
||||
}
|
||||
onReplacedRan = true;
|
||||
checkLoginsToAdd();
|
||||
refreshBadgeAndMenu();
|
||||
});
|
||||
|
||||
|
@ -174,6 +190,7 @@ chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
|
|||
return;
|
||||
}
|
||||
onUpdatedRan = true;
|
||||
checkLoginsToAdd();
|
||||
refreshBadgeAndMenu();
|
||||
});
|
||||
|
||||
|
@ -300,6 +317,60 @@ chrome.contextMenus.onClicked.addListener(function (info, tab) {
|
|||
});
|
||||
|
||||
function messageCurrentTab(command, data) {
|
||||
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
|
||||
var tabId = null;
|
||||
if (tabs.length > 0) {
|
||||
tabId = tabs[0].id;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
messageTab(tabId, command, data);
|
||||
});
|
||||
}
|
||||
|
||||
function messageTab(tabId, command, data) {
|
||||
if (!tabId) {
|
||||
return;
|
||||
}
|
||||
|
||||
var obj = {
|
||||
command: command
|
||||
};
|
||||
|
||||
if (data) {
|
||||
obj['data'] = data;
|
||||
}
|
||||
|
||||
chrome.tabs.sendMessage(tabId, obj);
|
||||
}
|
||||
|
||||
function collectPageDetailsForContentScript(tab) {
|
||||
chrome.tabs.sendMessage(tab.id, { command: 'collectPageDetails', tabId: tab.id, contentScript: true }, function () { });
|
||||
}
|
||||
|
||||
function addLogin(login, tab) {
|
||||
var loginDomain = tldjs.getDomain(login.url);
|
||||
if (!loginDomain) {
|
||||
return;
|
||||
}
|
||||
|
||||
loginsToAdd.push({
|
||||
username: login.username,
|
||||
password: login.password,
|
||||
name: loginDomain,
|
||||
uri: login.url,
|
||||
tabId: tab.id
|
||||
});
|
||||
checkLoginsToAdd();
|
||||
}
|
||||
|
||||
function checkLoginsToAdd() {
|
||||
if (!loginsToAdd.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
|
||||
var tabId = null;
|
||||
if (tabs.length > 0) {
|
||||
|
@ -313,15 +384,17 @@ function messageCurrentTab(command, data) {
|
|||
return;
|
||||
}
|
||||
|
||||
var obj = {
|
||||
command: command
|
||||
};
|
||||
|
||||
if (data) {
|
||||
obj['data'] = data;
|
||||
var tabDomain = tldjs.getDomain(tabs[0].url);
|
||||
if (!tabDomain) {
|
||||
return;
|
||||
}
|
||||
|
||||
chrome.tabs.sendMessage(tabId, obj);
|
||||
for (var i = 0; i < loginsToAdd.length; i++) {
|
||||
if (loginsToAdd[i].tabId === tabId && loginsToAdd[i].name === tabDomain) {
|
||||
messageTab(tabId, 'openNotificationBar', { type: 'add' });
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -90,7 +90,8 @@
|
|||
chrome.runtime.sendMessage({
|
||||
command: 'collectPageDetailsResponse',
|
||||
tabId: msg.tabId,
|
||||
details: pageDetailsObj
|
||||
details: pageDetailsObj,
|
||||
contentScript: msg.contentScript ? true : false
|
||||
});
|
||||
sendResponse();
|
||||
return true;
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
!(function () {
|
||||
var pageDetails = [],
|
||||
formData = [];
|
||||
chrome.runtime.sendMessage({
|
||||
command: 'bgCollectPageDetails'
|
||||
});
|
||||
|
||||
chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
|
||||
if (msg.command === 'openNotificationBar') {
|
||||
closeBar();
|
||||
openBar();
|
||||
openBar(msg.data.type, msg.data.typeData);
|
||||
sendResponse();
|
||||
return true;
|
||||
}
|
||||
|
@ -11,11 +17,103 @@
|
|||
sendResponse();
|
||||
return true;
|
||||
}
|
||||
else if (msg.command === 'pageDetails') {
|
||||
console.log(msg.data);
|
||||
pageDetails.push(msg.data.details);
|
||||
watchForms(msg.data.forms);
|
||||
sendResponse();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
function openBar() {
|
||||
function watchForms(forms) {
|
||||
if (!forms || !forms.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < forms.length; i++) {
|
||||
var form = null,
|
||||
formId = forms[i].form ? forms[i].form.htmlID : null;
|
||||
|
||||
if (formId && formId !== '') {
|
||||
form = document.getElementById(formId);
|
||||
}
|
||||
|
||||
if (!form) {
|
||||
var index = parseInt(forms[i].form.opid.split('__')[2]);
|
||||
form = document.getElementsByTagName('form')[index];
|
||||
}
|
||||
|
||||
if (form) {
|
||||
forms[i].formElement = form;
|
||||
formData.push(forms[i]);
|
||||
form.addEventListener('submit', formSubmitted, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function formSubmitted(e) {
|
||||
for (var i = 0; i < formData.length; i++) {
|
||||
if (formData[i].formElement === e.target) {
|
||||
var password = null,
|
||||
username = null,
|
||||
passwordId = formData[i].password ? formData[i].password.htmlID : null,
|
||||
usernameId = formData[i].username ? formData[i].username.htmlID : null;
|
||||
|
||||
if (passwordId && passwordId !== '') {
|
||||
password = document.getElementById(passwordId);
|
||||
}
|
||||
else if (formData[i].password) {
|
||||
password = document.getElementsByTagName('input')[formData[i].password.elementNumber];
|
||||
}
|
||||
|
||||
if (usernameId && usernameId !== '') {
|
||||
username = document.getElementById(usernameId);
|
||||
}
|
||||
else if (formData[i].username) {
|
||||
username = document.getElementsByTagName('input')[formData[i].username.elementNumber];
|
||||
}
|
||||
|
||||
var login = {
|
||||
username: username.value,
|
||||
password: password.value,
|
||||
url: document.URL
|
||||
};
|
||||
|
||||
if (login.password && login.password !== '') {
|
||||
chrome.runtime.sendMessage({
|
||||
command: 'bgAddLogin',
|
||||
login: login
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function openBar(type, typeData) {
|
||||
var barPage = 'notification/bar.html';
|
||||
switch (type) {
|
||||
case 'info':
|
||||
barPage = barPage + '?info=' + typeData.text;
|
||||
break;
|
||||
case 'warning':
|
||||
barPage = barPage + '?warning=' + typeData.text;
|
||||
break;
|
||||
case 'error':
|
||||
barPage = barPage + '?error=' + typeData.text;
|
||||
break;
|
||||
case 'success':
|
||||
barPage = barPage + '?success=' + typeData.text;
|
||||
break;
|
||||
case 'add':
|
||||
barPage = barPage + '?add=1';
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.src = chrome.extension.getURL('notification/bar.html');
|
||||
iframe.src = chrome.extension.getURL(barPage);
|
||||
iframe.style.cssText = 'height: 41px; width: 100%; border: 0;';
|
||||
|
||||
var frameDiv = document.createElement('div');
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
body {
|
||||
background-color: #ffffff;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
color: #333333;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.outter-table > tbody > tr > td {
|
||||
padding: 0 0 0 10px;
|
||||
border-bottom: 1px solid #333333;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.outter-table > tbody > tr > td:last-child {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.inner-table td {
|
||||
padding: 0 10px 0 0;
|
||||
}
|
||||
|
||||
.inner-table td:last-child {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.inner-table td button {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#logo {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#close {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: block;
|
||||
}
|
|
@ -3,74 +3,41 @@
|
|||
<head>
|
||||
<title></title>
|
||||
<meta charset="utf-8" />
|
||||
<style>
|
||||
body {
|
||||
background-color: #ffffff;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
color: #333333;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table td {
|
||||
height: 40px;
|
||||
padding: 0 0 0 10px;
|
||||
border-bottom: 1px solid #333333;
|
||||
}
|
||||
|
||||
table td:last-child {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#logo {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#content {
|
||||
}
|
||||
|
||||
#close {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
!(function () {
|
||||
|
||||
});
|
||||
</script>
|
||||
<link rel="stylesheet" type="text/css" href="bar.css" />
|
||||
</head>
|
||||
<body>
|
||||
<table cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td width="24">
|
||||
<img id="logo" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAclBMVEUAAAAzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzOkbymMAAAAJXRSTlMAAQIICQsMGBkaKkJYWWl0dXeMjpWXm6WmtcXM0dPr7fH3+fv9KIjKuwAAAIRJREFUKM/dzUkCgkAMBdHfCArOIypBW4S6/xVdNCqDJ7BWSd4iknKG5ZIkMW4AdzMzs+cI1mG3f4N6ADfqMJR9cFAG2PVhDtsAWQ8igyyAzl3Yw6W9K/YfcAfw8RuUVS1MrlCl+pZ6gM3iAX6mbknR/ikS9XOrBmiWTqOmR05T/SzqLi/Z3CbrA3nnNwAAAABJRU5ErkJggg==" />
|
||||
</td>
|
||||
<td id="content">
|
||||
This is the notification bar
|
||||
</td>
|
||||
<td align="right" width="18">
|
||||
<a href="#" title="Close">
|
||||
<img id="close" alt="X" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAWlBMVEUAAAAzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMHgWvyAAAAHXRSTlMAAgMFCA4RLTE0NVlrbG97naCotbe5z+Lk5ujr/TBmF6UAAAB+SURBVBhXXc7JEsJQCETRm3l2ikZj0v//my7ol0rJBjhFAUB+X2oimnUEyF/SFtZKugKzZGslSSOlZAvRCpNtiKwGuLiOaOHPQs6WBB6W4ZA+Dfm/kxx2Elvnxvu2mmKPsk93F7K3Jf1yg+prCXtmQPXZO9+eNGcAZIUFSuAHidYU7gWlVOAAAAAASUVORK5CYII=" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<table class="outter-table" cellpadding="0" cellspacing="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="24">
|
||||
<img id="logo" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAclBMVEUAAAAzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzOkbymMAAAAJXRSTlMAAQIICQsMGBkaKkJYWWl0dXeMjpWXm6WmtcXM0dPr7fH3+fv9KIjKuwAAAIRJREFUKM/dzUkCgkAMBdHfCArOIypBW4S6/xVdNCqDJ7BWSd4iknKG5ZIkMW4AdzMzs+cI1mG3f4N6ADfqMJR9cFAG2PVhDtsAWQ8igyyAzl3Yw6W9K/YfcAfw8RuUVS1MrlCl+pZ6gM3iAX6mbknR/ikS9XOrBmiWTqOmR05T/SzqLi/Z3CbrA3nnNwAAAABJRU5ErkJggg==" />
|
||||
</td>
|
||||
<td id="content"></td>
|
||||
<td align="right" width="18">
|
||||
<a href="#" title="Close" id="close-button">
|
||||
<img id="close" alt="X" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAAWlBMVEUAAAAzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMHgWvyAAAAHXRSTlMAAgMFCA4RLTE0NVlrbG97naCotbe5z+Lk5ujr/TBmF6UAAAB+SURBVBhXXc7JEsJQCETRm3l2ikZj0v//my7ol0rJBjhFAUB+X2oimnUEyF/SFtZKugKzZGslSSOlZAvRCpNtiKwGuLiOaOHPQs6WBB6W4ZA+Dfm/kxx2Elvnxvu2mmKPsk93F7K3Jf1yg+prCXtmQPXZO9+eNGcAZIUFSuAHidYU7gWlVOAAAAAASUVORK5CYII=" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="templates" style="display: none;">
|
||||
<table class="inner-table" cellpadding="0" cellspacing="0" id="template-add">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Should bitwarden remember this password for you?</td>
|
||||
<td align="right" width="200">
|
||||
<button class="add-save">Save Site</button>
|
||||
<button class="add-never">Never</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="template-alert">
|
||||
This is an alert.
|
||||
</div>
|
||||
</div>
|
||||
<script src="../lib/jquery/jquery.js"></script>
|
||||
<script src="bar.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
$(function () {
|
||||
var content = document.getElementById('content'),
|
||||
template_add = document.getElementById('template-add'),
|
||||
template_alert = document.getElementById('template-alert');
|
||||
|
||||
if (getQueryVariable('add')) {
|
||||
setContent(template_add);
|
||||
|
||||
var add = $('#template-add-clone'),
|
||||
addButton = $('#template-add-clone.add-save'),
|
||||
neverButton = $('#template-add-clone.add-never');
|
||||
}
|
||||
else if (getQueryVariable('info')) {
|
||||
setContent(template_alert);
|
||||
$('#template-alert-clone').text(getQueryVariable('info'));
|
||||
}
|
||||
|
||||
$('#close-button').click(function (e) {
|
||||
e.preventDefault();
|
||||
chrome.runtime.sendMessage({
|
||||
command: 'bgCloseNotificationBar'
|
||||
});
|
||||
});
|
||||
|
||||
function getQueryVariable(variable) {
|
||||
var query = window.location.search.substring(1);
|
||||
var vars = query.split('&');
|
||||
|
||||
for (var i = 0; i < vars.length; i++) {
|
||||
var pair = vars[i].split('=');
|
||||
if (pair[0] == variable) {
|
||||
return pair[1];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function setContent(element) {
|
||||
while (content.firstChild) {
|
||||
content.removeChild(content.firstChild);
|
||||
}
|
||||
|
||||
var newElement = element.cloneNode(true);
|
||||
newElement.id = newElement.id + '-clone';
|
||||
content.appendChild(newElement);
|
||||
}
|
||||
});
|
|
@ -23,31 +23,10 @@ function initAutofill() {
|
|||
pf = null,
|
||||
username = null;
|
||||
|
||||
function loadPasswordFields(canBeHidden) {
|
||||
for (var i = 0; i < pageDetails.fields.length; i++) {
|
||||
if (pageDetails.fields[i].type === 'password' && (canBeHidden || pageDetails.fields[i].viewable)) {
|
||||
passwordFields.push(pageDetails.fields[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loadPasswordFields(false);
|
||||
passwordFields = loadPasswordFields(pageDetails, false);
|
||||
if (!passwordFields.length) {
|
||||
// not able to find any viewable password fields. maybe there are some "hidden" ones?
|
||||
loadPasswordFields(true);
|
||||
}
|
||||
|
||||
function findUsernameField(passwordField, canBeHidden) {
|
||||
for (var i = 0; i < pageDetails.fields.length; i++) {
|
||||
var f = pageDetails.fields[i];
|
||||
if (f.form === passwordField.form && (canBeHidden || f.viewable)
|
||||
&& (f.type === 'text' || f.type === 'email' || f.type === 'tel')
|
||||
&& f.elementNumber < passwordField.elementNumber) {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
passwordFields = loadPasswordFields(pageDetails, true);
|
||||
}
|
||||
|
||||
for (var formKey in pageDetails.forms) {
|
||||
|
@ -63,11 +42,11 @@ function initAutofill() {
|
|||
passwords.push(pf);
|
||||
|
||||
if (fillUsername) {
|
||||
username = findUsernameField(pf, false);
|
||||
username = findUsernameField(pageDetails, pf, false);
|
||||
|
||||
if (!username) {
|
||||
// not able to find any viewable username fields. maybe there are some "hidden" ones?
|
||||
username = findUsernameField(pf, true);
|
||||
username = findUsernameField(pageDetails, pf, true);
|
||||
}
|
||||
|
||||
if (username) {
|
||||
|
@ -77,22 +56,6 @@ function initAutofill() {
|
|||
}
|
||||
}
|
||||
|
||||
function findUsernameFieldWithoutForm(passwordField, canBeHidden) {
|
||||
var usernameField = null;
|
||||
for (var i = 0; i < pageDetails.fields.length; i++) {
|
||||
var f = pageDetails.fields[i];
|
||||
if (f.elementNumber > passwordField.elementNumber) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((canBeHidden || f.viewable) && (f.type === 'text' || f.type === 'email' || f.type === 'tel')) {
|
||||
usernameField = f;
|
||||
}
|
||||
}
|
||||
|
||||
return usernameField;
|
||||
}
|
||||
|
||||
if (passwordFields.length && !passwords.length) {
|
||||
// The page does not have any forms with password fields. Use the first password field on the page and the
|
||||
// input field just before it as the username.
|
||||
|
@ -101,11 +64,11 @@ function initAutofill() {
|
|||
passwords.push(pf);
|
||||
|
||||
if (fillUsername && pf.elementNumber > 0) {
|
||||
username = findUsernameFieldWithoutForm(pf, false);
|
||||
username = findUsernameFieldWithoutForm(pageDetails, pf, false);
|
||||
|
||||
if (!username) {
|
||||
// not able to find any viewable username fields. maybe there are some "hidden" ones?
|
||||
username = findUsernameFieldWithoutForm(pf, true);
|
||||
username = findUsernameFieldWithoutForm(pageDetails, pf, true);
|
||||
}
|
||||
|
||||
if (username) {
|
||||
|
@ -130,4 +93,79 @@ function initAutofill() {
|
|||
|
||||
return fillScript;
|
||||
};
|
||||
|
||||
AutofillService.prototype.getFormsWithPasswordFields = function (pageDetails) {
|
||||
var passwordFields = [],
|
||||
formData = [];
|
||||
|
||||
passwordFields = loadPasswordFields(pageDetails, false);
|
||||
if (!passwordFields.length) {
|
||||
// not able to find any viewable password fields. maybe there are some "hidden" ones?
|
||||
passwordFields = loadPasswordFields(pageDetails, true);
|
||||
}
|
||||
|
||||
if (passwordFields.length) {
|
||||
for (var formKey in pageDetails.forms) {
|
||||
for (var i = 0; i < passwordFields.length; i++) {
|
||||
var pf = passwordFields[i];
|
||||
if (formKey === pf.form) {
|
||||
var uf = findUsernameField(pageDetails, pf, false);
|
||||
if (!uf) {
|
||||
// not able to find any viewable username fields. maybe there are some "hidden" ones?
|
||||
uf = findUsernameField(pageDetails, pf, true);
|
||||
}
|
||||
|
||||
formData.push({
|
||||
form: pageDetails.forms[formKey],
|
||||
password: pf,
|
||||
username: uf
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return formData;
|
||||
};
|
||||
|
||||
function loadPasswordFields(pageDetails, canBeHidden) {
|
||||
var arr = [];
|
||||
for (var i = 0; i < pageDetails.fields.length; i++) {
|
||||
if (pageDetails.fields[i].type === 'password' && (canBeHidden || pageDetails.fields[i].viewable)) {
|
||||
arr.push(pageDetails.fields[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
function findUsernameField(pageDetails, passwordField, canBeHidden) {
|
||||
for (var i = 0; i < pageDetails.fields.length; i++) {
|
||||
var f = pageDetails.fields[i];
|
||||
if (f.form === passwordField.form && (canBeHidden || f.viewable)
|
||||
&& (f.type === 'text' || f.type === 'email' || f.type === 'tel')
|
||||
&& f.elementNumber < passwordField.elementNumber) {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function findUsernameFieldWithoutForm(pageDetails, passwordField, canBeHidden) {
|
||||
var usernameField = null;
|
||||
for (var i = 0; i < pageDetails.fields.length; i++) {
|
||||
var f = pageDetails.fields[i];
|
||||
if (f.elementNumber > passwordField.elementNumber) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((canBeHidden || f.viewable) && (f.type === 'text' || f.type === 'email' || f.type === 'tel')) {
|
||||
usernameField = f;
|
||||
}
|
||||
}
|
||||
|
||||
return usernameField;
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue