mirror of
https://github.com/keepassxreboot/keepassxc-browser.git
synced 2026-03-11 08:54:43 +00:00
Merge pull request #719 from keepassxreboot/feature/shadow_dom
Move DOM elements to Shadow DOM
This commit is contained in:
commit
90fb5ad9e9
8 changed files with 165 additions and 80 deletions
|
|
@ -6,6 +6,8 @@ kpxcAutocomplete.elements = [];
|
||||||
kpxcAutocomplete.started = false;
|
kpxcAutocomplete.started = false;
|
||||||
kpxcAutocomplete.index = -1;
|
kpxcAutocomplete.index = -1;
|
||||||
kpxcAutocomplete.input = undefined;
|
kpxcAutocomplete.input = undefined;
|
||||||
|
kpxcAutocomplete.shadowRoot = undefined;
|
||||||
|
kpxcAutocomplete.wrapper = undefined;
|
||||||
|
|
||||||
kpxcAutocomplete.create = function(input, showListInstantly = false, autoSubmit = false) {
|
kpxcAutocomplete.create = function(input, showListInstantly = false, autoSubmit = false) {
|
||||||
kpxcAutocomplete.autoSubmit = autoSubmit;
|
kpxcAutocomplete.autoSubmit = autoSubmit;
|
||||||
|
|
@ -36,10 +38,21 @@ kpxcAutocomplete.showList = function(inputField) {
|
||||||
kpxcAutocomplete.input = inputField;
|
kpxcAutocomplete.input = inputField;
|
||||||
|
|
||||||
const div = kpxcUI.createElement('div', 'kpxcAutocomplete-items', { 'id': 'kpxcAutocomplete-list' });
|
const div = kpxcUI.createElement('div', 'kpxcAutocomplete-items', { 'id': 'kpxcAutocomplete-list' });
|
||||||
|
initColorTheme(div);
|
||||||
|
|
||||||
kpxcAutocomplete.updatePosition(inputField, div);
|
kpxcAutocomplete.updatePosition(inputField, div);
|
||||||
div.style.zIndex = '2147483646';
|
div.style.zIndex = '2147483646';
|
||||||
initColorTheme(div);
|
|
||||||
document.body.append(div);
|
const styleSheet = createStylesheet('css/autocomplete.css');
|
||||||
|
const colorStyleSheet = createStylesheet('css/colors.css');
|
||||||
|
const wrapper = kpxcUI.createElement('div');
|
||||||
|
|
||||||
|
kpxcAutocomplete.shadowRoot = wrapper.attachShadow({ mode: 'closed' });
|
||||||
|
kpxcAutocomplete.shadowRoot.append(colorStyleSheet);
|
||||||
|
kpxcAutocomplete.shadowRoot.append(styleSheet);
|
||||||
|
kpxcAutocomplete.shadowRoot.append(div);
|
||||||
|
kpxcAutocomplete.wrapper = wrapper;
|
||||||
|
document.body.append(wrapper);
|
||||||
|
|
||||||
for (const c of kpxcAutocomplete.elements) {
|
for (const c of kpxcAutocomplete.elements) {
|
||||||
const item = document.createElement('div');
|
const item = document.createElement('div');
|
||||||
|
|
@ -61,6 +74,7 @@ kpxcAutocomplete.showList = function(inputField) {
|
||||||
kpxcAutocomplete.fillPassword(inputField.value, index);
|
kpxcAutocomplete.fillPassword(inputField.value, index);
|
||||||
kpxcAutocomplete.closeList();
|
kpxcAutocomplete.closeList();
|
||||||
inputField.focus();
|
inputField.focus();
|
||||||
|
document.body.removeChild(wrapper);
|
||||||
});
|
});
|
||||||
|
|
||||||
// These events prevent the double hover effect if both keyboard and mouse are used
|
// These events prevent the double hover effect if both keyboard and mouse are used
|
||||||
|
|
@ -114,7 +128,15 @@ kpxcAutocomplete.removeItem = function(items) {
|
||||||
};
|
};
|
||||||
|
|
||||||
kpxcAutocomplete.closeList = function(elem) {
|
kpxcAutocomplete.closeList = function(elem) {
|
||||||
const items = document.getElementsByClassName('kpxcAutocomplete-items');
|
if (!kpxcAutocomplete.shadowRoot) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const items = kpxcAutocomplete.shadowSelectorAll('.kpxcAutocomplete-items');
|
||||||
|
if (!items) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
if (elem !== item && kpxcAutocomplete.input) {
|
if (elem !== item && kpxcAutocomplete.input) {
|
||||||
item.parentNode.removeChild(item);
|
item.parentNode.removeChild(item);
|
||||||
|
|
@ -123,7 +145,7 @@ kpxcAutocomplete.closeList = function(elem) {
|
||||||
};
|
};
|
||||||
|
|
||||||
kpxcAutocomplete.getAllItems = function() {
|
kpxcAutocomplete.getAllItems = function() {
|
||||||
const list = document.getElementById('kpxcAutocomplete-list');
|
const list = kpxcAutocomplete.shadowSelector('#kpxcAutocomplete-list');
|
||||||
if (!list) {
|
if (!list) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
@ -199,7 +221,7 @@ kpxcAutocomplete.fillPassword = function(value, index) {
|
||||||
};
|
};
|
||||||
|
|
||||||
kpxcAutocomplete.updatePosition = function(inputField, elem) {
|
kpxcAutocomplete.updatePosition = function(inputField, elem) {
|
||||||
const div = elem || $('.kpxcAutocomplete-items');
|
const div = elem || kpxcAutocomplete.shadowSelector('.kpxcAutocomplete-items');
|
||||||
if (!div) {
|
if (!div) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -216,7 +238,7 @@ document.addEventListener('click', function(e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const list = document.getElementById('kpxcAutocomplete-list');
|
const list = kpxcAutocomplete.shadowRoot ? kpxcAutocomplete.shadowSelector('#kpxcAutocomplete-list') : undefined;
|
||||||
if (!list) {
|
if (!list) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -225,6 +247,10 @@ document.addEventListener('click', function(e) {
|
||||||
!e.target.classList.contains('kpxc-username-icon') &&
|
!e.target.classList.contains('kpxc-username-icon') &&
|
||||||
e.target.nodeName !== kpxcAutocomplete.input.nodeName) {
|
e.target.nodeName !== kpxcAutocomplete.input.nodeName) {
|
||||||
kpxcAutocomplete.closeList(e.target);
|
kpxcAutocomplete.closeList(e.target);
|
||||||
|
|
||||||
|
if (kpxcAutocomplete.wrapper) {
|
||||||
|
document.body.removeChild(kpxcAutocomplete.wrapper);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,29 +6,26 @@ const kpxcBanner = {};
|
||||||
kpxcBanner.banner = undefined;
|
kpxcBanner.banner = undefined;
|
||||||
kpxcBanner.created = false;
|
kpxcBanner.created = false;
|
||||||
kpxcBanner.credentials = {};
|
kpxcBanner.credentials = {};
|
||||||
|
kpxcBanner.wrapper = undefined;
|
||||||
|
|
||||||
kpxcBanner.destroy = function() {
|
kpxcBanner.destroy = function() {
|
||||||
kpxcBanner.created = false;
|
kpxcBanner.created = false;
|
||||||
kpxcBanner.credentials = {};
|
kpxcBanner.credentials = {};
|
||||||
|
|
||||||
const dialog = $('.kpxc-banner-dialog');
|
const dialog = kpxcBanner.shadowSelector('.kpxc-banner-dialog');
|
||||||
if (dialog) {
|
if (dialog) {
|
||||||
document.body.removeChild(dialog);
|
kpxcBanner.banner.removeChild(dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
browser.runtime.sendMessage({
|
browser.runtime.sendMessage({
|
||||||
action: 'remove_credentials_from_tab_information'
|
action: 'remove_credentials_from_tab_information'
|
||||||
});
|
});
|
||||||
|
|
||||||
const banners = document.querySelectorAll('.kpxc-banner');
|
if (kpxcBanner.wrapper && window.parent.document.body.contains(kpxcBanner.wrapper)) {
|
||||||
if (banners.length > 0) {
|
window.parent.document.body.removeChild(kpxcBanner.wrapper);
|
||||||
for (const b of banners) {
|
} else {
|
||||||
document.body.removeChild(b);
|
window.parent.document.body.removeChild(window.parent.document.body.querySelector('#kpxc-banner'));
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
document.body.removeChild(kpxcBanner.banner);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
kpxcBanner.create = async function(credentials = {}) {
|
kpxcBanner.create = async function(credentials = {}) {
|
||||||
|
|
@ -48,10 +45,10 @@ kpxcBanner.create = async function(credentials = {}) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
kpxcBanner.created = true;
|
|
||||||
kpxcBanner.credentials = credentials;
|
kpxcBanner.credentials = credentials;
|
||||||
|
|
||||||
const banner = kpxcUI.createElement('div', 'kpxc-banner', { 'id': 'container' });
|
const banner = kpxcUI.createElement('div', 'kpxc-banner', { 'id': 'container' });
|
||||||
|
initColorTheme(banner);
|
||||||
banner.style.zIndex = '2147483646';
|
banner.style.zIndex = '2147483646';
|
||||||
|
|
||||||
const bannerInfo = kpxcUI.createElement('div', 'banner-info');
|
const bannerInfo = kpxcUI.createElement('div', 'banner-info');
|
||||||
|
|
@ -98,12 +95,12 @@ kpxcBanner.create = async function(credentials = {}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a banner dialog is shown, display the main banner
|
// If a banner dialog is shown, display the main banner
|
||||||
const dialog = $('.kpxc-banner-dialog');
|
const dialog = kpxcBanner.shadowSelector('.kpxc-banner-dialog');
|
||||||
if (dialog) {
|
if (dialog) {
|
||||||
$('#kpxc-banner-btn-new').hidden = false;
|
kpxcBanner.shadowSelector('#kpxc-banner-btn-new').hidden = false;
|
||||||
$('#kpxc-banner-btn-update').hidden = false;
|
kpxcBanner.shadowSelector('#kpxc-banner-btn-update').hidden = false;
|
||||||
$('.kpxc-checkbox').disabled = false;
|
kpxcBanner.shadowSelector('.kpxc-checkbox').disabled = false;
|
||||||
document.body.removeChild(dialog);
|
kpxcBanner.banner.removeChild(dialog);
|
||||||
} else {
|
} else {
|
||||||
if (ignoreCheckbox.checked) {
|
if (ignoreCheckbox.checked) {
|
||||||
kpxc.ignoreSite([ window.top.location.href ]);
|
kpxc.ignoreSite([ window.top.location.href ]);
|
||||||
|
|
@ -119,9 +116,23 @@ kpxcBanner.create = async function(credentials = {}) {
|
||||||
|
|
||||||
initColorTheme(banner);
|
initColorTheme(banner);
|
||||||
|
|
||||||
const existingBanner = window.parent.document.body.querySelector('.kpxc-banner');
|
|
||||||
if (existingBanner === null) {
|
const styleSheet = createStylesheet('css/banner.css');
|
||||||
window.parent.document.body.appendChild(banner);
|
const buttonStyleSheet = createStylesheet('css/button.css');
|
||||||
|
const colorStyleSheet = createStylesheet('css/colors.css');
|
||||||
|
|
||||||
|
const wrapper = document.createElement('div');
|
||||||
|
wrapper.setAttribute('id', 'kpxc-banner');
|
||||||
|
this.shadowRoot = wrapper.attachShadow({ mode: 'closed' });
|
||||||
|
this.shadowRoot.append(colorStyleSheet);
|
||||||
|
this.shadowRoot.append(styleSheet);
|
||||||
|
this.shadowRoot.append(buttonStyleSheet);
|
||||||
|
this.shadowRoot.append(banner);
|
||||||
|
kpxcBanner.wrapper = wrapper;
|
||||||
|
|
||||||
|
if (window.self === window.top && !kpxcBanner.created) {
|
||||||
|
window.parent.document.body.appendChild(wrapper);
|
||||||
|
kpxcBanner.created = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -195,7 +206,7 @@ kpxcBanner.saveNewCredentials = async function(credentials = {}) {
|
||||||
a.setAttribute('id', 'root-child');
|
a.setAttribute('id', 'root-child');
|
||||||
}
|
}
|
||||||
|
|
||||||
$('ul#list').appendChild(a);
|
kpxcBanner.shadowSelector('ul#list').appendChild(a);
|
||||||
addChildren(child, a, depth);
|
addChildren(child, a, depth);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -230,11 +241,11 @@ kpxcBanner.saveNewCredentials = async function(credentials = {}) {
|
||||||
const a = createLink(g.name, g.uuid, g.children.length > 0);
|
const a = createLink(g.name, g.uuid, g.children.length > 0);
|
||||||
a.setAttribute('id', 'root');
|
a.setAttribute('id', 'root');
|
||||||
|
|
||||||
$('ul#list').appendChild(a);
|
kpxcBanner.shadowSelector('ul#list').appendChild(a);
|
||||||
addChildren(g, a, depth);
|
addChildren(g, a, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
$('.kpxc-banner-dialog').style.display = 'block';
|
kpxcBanner.shadowSelector('.kpxc-banner-dialog').style.display = 'block';
|
||||||
};
|
};
|
||||||
|
|
||||||
kpxcBanner.updateCredentials = async function(credentials = {}) {
|
kpxcBanner.updateCredentials = async function(credentials = {}) {
|
||||||
|
|
@ -252,15 +263,15 @@ kpxcBanner.updateCredentials = async function(credentials = {}) {
|
||||||
kpxcBanner.verifyResult(res);
|
kpxcBanner.verifyResult(res);
|
||||||
} else {
|
} else {
|
||||||
await kpxcBanner.createCredentialDialog();
|
await kpxcBanner.createCredentialDialog();
|
||||||
$('.kpxc-banner-dialog .username-new .strong').textContent = credentials.username;
|
kpxcBanner.shadowSelector('.kpxc-banner-dialog .username-new .strong').textContent = credentials.username;
|
||||||
$('.kpxc-banner-dialog .username-exists .strong').textContent = credentials.username;
|
kpxcBanner.shadowSelector('.kpxc-banner-dialog .username-exists .strong').textContent = credentials.username;
|
||||||
|
|
||||||
if (credentials.usernameExists) {
|
if (credentials.usernameExists) {
|
||||||
$('.kpxc-banner-dialog .username-new').style.display = 'none';
|
kpxcBanner.shadowSelector('.kpxc-banner-dialog .username-new').style.display = 'none';
|
||||||
$('.kpxc-banner-dialog .username-exists').style.display = 'block';
|
kpxcBanner.shadowSelector('.kpxc-banner-dialog .username-exists').style.display = 'block';
|
||||||
} else {
|
} else {
|
||||||
$('.kpxc-banner-dialog .username-new').style.display = 'block';
|
kpxcBanner.shadowSelector('.kpxc-banner-dialog .username-new').style.display = 'block';
|
||||||
$('.kpxc-banner-dialog .username-exists').style.display = 'none';
|
kpxcBanner.shadowSelector('.kpxc-banner-dialog .username-exists').style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < credentials.list.length; i++) {
|
for (let i = 0; i < credentials.list.length; i++) {
|
||||||
|
|
@ -303,10 +314,10 @@ kpxcBanner.updateCredentials = async function(credentials = {}) {
|
||||||
a.style.fontWeight = 'bold';
|
a.style.fontWeight = 'bold';
|
||||||
}
|
}
|
||||||
|
|
||||||
$('ul#list').appendChild(a);
|
kpxcBanner.shadowSelector('ul#list').appendChild(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
$('.kpxc-banner-dialog').style.display = 'block';
|
kpxcBanner.shadowSelector('.kpxc-banner-dialog').style.display = 'block';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -346,9 +357,9 @@ kpxcBanner.getDefaultGroup = function(groups, defaultGroup) {
|
||||||
};
|
};
|
||||||
|
|
||||||
kpxcBanner.createCredentialDialog = async function() {
|
kpxcBanner.createCredentialDialog = async function() {
|
||||||
$('#kpxc-banner-btn-new').hidden = true;
|
kpxcBanner.shadowSelector('#kpxc-banner-btn-new').hidden = true;
|
||||||
$('#kpxc-banner-btn-update').hidden = true;
|
kpxcBanner.shadowSelector('#kpxc-banner-btn-update').hidden = true;
|
||||||
$('.kpxc-checkbox').disabled = true;
|
kpxcBanner.shadowSelector('.kpxc-checkbox').disabled = true;
|
||||||
|
|
||||||
const connectedDatabase = await browser.runtime.sendMessage({
|
const connectedDatabase = await browser.runtime.sendMessage({
|
||||||
action: 'get_connected_database'
|
action: 'get_connected_database'
|
||||||
|
|
@ -379,13 +390,13 @@ kpxcBanner.createCredentialDialog = async function() {
|
||||||
usernameExists.append(kpxcUI.createElement('span', 'strong'));
|
usernameExists.append(kpxcUI.createElement('span', 'strong'));
|
||||||
dialog.appendMultiple(databaseText, usernameNew, usernameExists, chooseCreds, list);
|
dialog.appendMultiple(databaseText, usernameNew, usernameExists, chooseCreds, list);
|
||||||
initColorTheme(dialog);
|
initColorTheme(dialog);
|
||||||
document.body.appendChild(dialog);
|
kpxcBanner.banner.appendChild(dialog);
|
||||||
};
|
};
|
||||||
|
|
||||||
kpxcBanner.createGroupDialog = function() {
|
kpxcBanner.createGroupDialog = function() {
|
||||||
$('#kpxc-banner-btn-new').hidden = true;
|
kpxcBanner.shadowSelector('#kpxc-banner-btn-new').hidden = true;
|
||||||
$('#kpxc-banner-btn-update').hidden = true;
|
kpxcBanner.shadowSelector('#kpxc-banner-btn-update').hidden = true;
|
||||||
$('.kpxc-checkbox').disabled = true;
|
kpxcBanner.shadowSelector('.kpxc-checkbox').disabled = true;
|
||||||
|
|
||||||
const dialog = kpxcUI.createElement('div', 'kpxc-banner-dialog');
|
const dialog = kpxcUI.createElement('div', 'kpxc-banner-dialog');
|
||||||
const chooseGroup = kpxcUI.createElement('p', '', {}, tr('rememberChooseGroup'));
|
const chooseGroup = kpxcUI.createElement('p', '', {}, tr('rememberChooseGroup'));
|
||||||
|
|
@ -396,5 +407,5 @@ kpxcBanner.createGroupDialog = function() {
|
||||||
dialog.style.right = Pixels(0);
|
dialog.style.right = Pixels(0);
|
||||||
|
|
||||||
dialog.appendMultiple(chooseGroup, list);
|
dialog.appendMultiple(chooseGroup, list);
|
||||||
document.body.appendChild(dialog);
|
kpxcBanner.banner.appendChild(dialog);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,16 @@ PasswordIcon.prototype.createIcon = function(field) {
|
||||||
|
|
||||||
kpxcUI.setIconPosition(icon, field);
|
kpxcUI.setIconPosition(icon, field);
|
||||||
this.icon = icon;
|
this.icon = icon;
|
||||||
document.body.appendChild(icon);
|
|
||||||
|
const styleSheet = document.createElement('link');
|
||||||
|
styleSheet.setAttribute('rel', 'stylesheet');
|
||||||
|
styleSheet.setAttribute('href', browser.runtime.getURL('css/pwgen.css'));
|
||||||
|
|
||||||
|
const wrapper = document.createElement('div');
|
||||||
|
this.shadowRoot = wrapper.attachShadow({ mode: 'closed' });
|
||||||
|
this.shadowRoot.append(styleSheet);
|
||||||
|
this.shadowRoot.append(icon);
|
||||||
|
document.body.append(wrapper);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -121,7 +130,7 @@ kpxcPasswordDialog.removeIcon = function(field) {
|
||||||
kpxcPasswordDialog.createDialog = function() {
|
kpxcPasswordDialog.createDialog = function() {
|
||||||
if (kpxcPasswordDialog.created) {
|
if (kpxcPasswordDialog.created) {
|
||||||
// If database is open again, generate a new password right away
|
// If database is open again, generate a new password right away
|
||||||
const input = $('.kpxc-pwgen-input');
|
const input = kpxcPasswordDialog.shadowSelector('.kpxc-pwgen-input');
|
||||||
if (input.style.display === 'none') {
|
if (input.style.display === 'none') {
|
||||||
kpxcPasswordDialog.generate();
|
kpxcPasswordDialog.generate();
|
||||||
}
|
}
|
||||||
|
|
@ -129,7 +138,9 @@ kpxcPasswordDialog.createDialog = function() {
|
||||||
}
|
}
|
||||||
kpxcPasswordDialog.created = true;
|
kpxcPasswordDialog.created = true;
|
||||||
|
|
||||||
const wrapper = kpxcUI.createElement('div', 'kpxc');
|
const wrapper = kpxcUI.createElement('div');
|
||||||
|
kpxcPasswordDialog.shadowRoot = wrapper.attachShadow({ mode: 'closed' });
|
||||||
|
|
||||||
const dialog = kpxcUI.createElement('div', 'kpxc kpxc-pwgen-dialog');
|
const dialog = kpxcUI.createElement('div', 'kpxc kpxc-pwgen-dialog');
|
||||||
const titleBar = kpxcUI.createElement('div', 'kpxc-pwgen-titlebar', {}, tr('passwordGeneratorTitle'));
|
const titleBar = kpxcUI.createElement('div', 'kpxc-pwgen-titlebar', {}, tr('passwordGeneratorTitle'));
|
||||||
const closeButton = kpxcUI.createElement('div', 'kpxc-pwgen-close', {}, '×');
|
const closeButton = kpxcUI.createElement('div', 'kpxc-pwgen-close', {}, '×');
|
||||||
|
|
@ -167,7 +178,15 @@ kpxcPasswordDialog.createDialog = function() {
|
||||||
|
|
||||||
buttonsRow.appendMultiple(generateButton, copyButton, fillButton);
|
buttonsRow.appendMultiple(generateButton, copyButton, fillButton);
|
||||||
dialog.appendMultiple(titleBar, passwordRow, buttonsRow);
|
dialog.appendMultiple(titleBar, passwordRow, buttonsRow);
|
||||||
wrapper.append(dialog);
|
|
||||||
|
const styleSheet = createStylesheet('css/pwgen.css');
|
||||||
|
const buttonStyle = createStylesheet('css/button.css');
|
||||||
|
const colorStyleSheet = createStylesheet('css/colors.css');
|
||||||
|
|
||||||
|
kpxcPasswordDialog.shadowRoot.append(colorStyleSheet);
|
||||||
|
kpxcPasswordDialog.shadowRoot.append(styleSheet);
|
||||||
|
kpxcPasswordDialog.shadowRoot.append(buttonStyle);
|
||||||
|
kpxcPasswordDialog.shadowRoot.append(dialog);
|
||||||
|
|
||||||
const icon = $('.kpxc-pwgen-icon');
|
const icon = $('.kpxc-pwgen-icon');
|
||||||
if (icon) {
|
if (icon) {
|
||||||
|
|
@ -236,17 +255,6 @@ kpxcPasswordDialog.showDialog = function(field, icon) {
|
||||||
kpxcPasswordDialog.dialog.setAttribute('kpxc-pwgen-field-id', field.getAttribute('data-kpxc-id'));
|
kpxcPasswordDialog.dialog.setAttribute('kpxc-pwgen-field-id', field.getAttribute('data-kpxc-id'));
|
||||||
kpxcPasswordDialog.dialog.setAttribute('kpxc-pwgen-next-field-id', field.getAttribute('kpxc-pwgen-next-field-id'));
|
kpxcPasswordDialog.dialog.setAttribute('kpxc-pwgen-next-field-id', field.getAttribute('kpxc-pwgen-next-field-id'));
|
||||||
kpxcPasswordDialog.dialog.setAttribute('kpxc-pwgen-next-is-password-field', field.getAttribute('kpxc-pwgen-next-is-password-field'));
|
kpxcPasswordDialog.dialog.setAttribute('kpxc-pwgen-next-is-password-field', field.getAttribute('kpxc-pwgen-next-is-password-field'));
|
||||||
|
|
||||||
const fieldExists = Boolean(field.getAttribute('kpxc-pwgen-next-field-exists'));
|
|
||||||
const checkbox = $('.kpxc-pwgen-checkbox');
|
|
||||||
if (checkbox) {
|
|
||||||
checkbox.setAttribute('checked', fieldExists);
|
|
||||||
if (fieldExists) {
|
|
||||||
checkbox.removeAttribute('disabled');
|
|
||||||
} else {
|
|
||||||
checkbox.setAttribute('disabled', '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -283,7 +291,7 @@ kpxcPasswordDialog.fill = function(e) {
|
||||||
// Use the active input field
|
// Use the active input field
|
||||||
const field = _f(kpxcPasswordDialog.dialog.getAttribute('kpxc-pwgen-field-id'));
|
const field = _f(kpxcPasswordDialog.dialog.getAttribute('kpxc-pwgen-field-id'));
|
||||||
if (field) {
|
if (field) {
|
||||||
const password = $('.kpxc-pwgen-input');
|
const password = kpxcPasswordDialog.shadowSelector('.kpxc-pwgen-input');
|
||||||
if (field.getAttribute('maxlength')) {
|
if (field.getAttribute('maxlength')) {
|
||||||
if (password.value.length > field.getAttribute('maxlength')) {
|
if (password.value.length > field.getAttribute('maxlength')) {
|
||||||
const message = tr('passwordGeneratorErrorTooLong') + '\r\n' +
|
const message = tr('passwordGeneratorErrorTooLong') + '\r\n' +
|
||||||
|
|
@ -307,7 +315,7 @@ kpxcPasswordDialog.fill = function(e) {
|
||||||
};
|
};
|
||||||
|
|
||||||
kpxcPasswordDialog.copyPasswordToClipboard = function() {
|
kpxcPasswordDialog.copyPasswordToClipboard = function() {
|
||||||
$('.kpxc-pwgen-input').select();
|
kpxcPasswordDialog.shadowSelector('.kpxc-pwgen-input').select();
|
||||||
try {
|
try {
|
||||||
return document.execCommand('copy');
|
return document.execCommand('copy');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
@ -318,19 +326,19 @@ kpxcPasswordDialog.copyPasswordToClipboard = function() {
|
||||||
|
|
||||||
const callbackGeneratedPassword = function(entries) {
|
const callbackGeneratedPassword = function(entries) {
|
||||||
if (entries && entries.length >= 1) {
|
if (entries && entries.length >= 1) {
|
||||||
const errorMessage = $('#kpxc-pwgen-error');
|
const errorMessage = kpxcPasswordDialog.shadowSelector('#kpxc-pwgen-error');
|
||||||
if (errorMessage) {
|
if (errorMessage) {
|
||||||
enableButtons();
|
enableButtons();
|
||||||
|
|
||||||
const input = $('.kpxc-pwgen-input');
|
const input = kpxcPasswordDialog.shadowSelector('.kpxc-pwgen-input');
|
||||||
input.style.display = 'block';
|
input.style.display = 'block';
|
||||||
errorMessage.remove();
|
errorMessage.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
$('.kpxc-pwgen-input').value = entries[0].password;
|
kpxcPasswordDialog.shadowSelector('.kpxc-pwgen-input').value = entries[0].password;
|
||||||
} else {
|
} else {
|
||||||
if (document.querySelectorAll('div#kpxc-pwgen-error').length === 0) {
|
if (kpxcPasswordDialog.shadowSelectorAll('div#kpxc-pwgen-error').length === 0) {
|
||||||
const input = $('.kpxc-pwgen-input');
|
const input = kpxcPasswordDialog.shadowSelector('.kpxc-pwgen-input');
|
||||||
input.style.display = 'none';
|
input.style.display = 'none';
|
||||||
|
|
||||||
const errorMessage = kpxcUI.createElement('div', '', { 'id': 'kpxc-pwgen-error' },
|
const errorMessage = kpxcUI.createElement('div', '', { 'id': 'kpxc-pwgen-error' },
|
||||||
|
|
@ -344,13 +352,13 @@ const callbackGeneratedPassword = function(entries) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const enableButtons = function() {
|
const enableButtons = function() {
|
||||||
$('#kpxc-pwgen-btn-generate').textContent = tr('passwordGeneratorGenerate');
|
kpxcPasswordDialog.shadowSelector('#kpxc-pwgen-btn-generate').textContent = tr('passwordGeneratorGenerate');
|
||||||
$('#kpxc-pwgen-btn-copy').style.display = 'inline-block';
|
kpxcPasswordDialog.shadowSelector('#kpxc-pwgen-btn-copy').style.display = 'inline-block';
|
||||||
$('#kpxc-pwgen-btn-fill').style.display = 'inline-block';
|
kpxcPasswordDialog.shadowSelector('#kpxc-pwgen-btn-fill').style.display = 'inline-block';
|
||||||
};
|
};
|
||||||
|
|
||||||
const disableButtons = function() {
|
const disableButtons = function() {
|
||||||
$('#kpxc-pwgen-btn-generate').textContent = tr('passwordGeneratorTryAgain');
|
kpxcPasswordDialog.shadowSelector('#kpxc-pwgen-btn-generate').textContent = tr('passwordGeneratorTryAgain');
|
||||||
$('#kpxc-pwgen-btn-copy').style.display = 'none';
|
kpxcPasswordDialog.shadowSelector('#kpxc-pwgen-btn-copy').style.display = 'none';
|
||||||
$('#kpxc-pwgen-btn-fill').style.display = 'none';
|
kpxcPasswordDialog.shadowSelector('#kpxc-pwgen-btn-fill').style.display = 'none';
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -81,5 +81,14 @@ TOTPFieldIcon.prototype.createIcon = function(field) {
|
||||||
|
|
||||||
kpxcUI.setIconPosition(icon, field);
|
kpxcUI.setIconPosition(icon, field);
|
||||||
this.icon = icon;
|
this.icon = icon;
|
||||||
document.body.appendChild(icon);
|
|
||||||
|
const styleSheet = document.createElement('link');
|
||||||
|
styleSheet.setAttribute('rel', 'stylesheet');
|
||||||
|
styleSheet.setAttribute('href', browser.runtime.getURL('css/totp.css'));
|
||||||
|
|
||||||
|
const wrapper = document.createElement('div');
|
||||||
|
this.shadowRoot = wrapper.attachShadow({ mode: 'closed' });
|
||||||
|
this.shadowRoot.append(styleSheet);
|
||||||
|
this.shadowRoot.append(icon);
|
||||||
|
document.body.append(wrapper);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -166,6 +166,13 @@ const initColorTheme = function(elem) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const createStylesheet = function(file) {
|
||||||
|
const stylesheet = document.createElement('link');
|
||||||
|
stylesheet.setAttribute('rel', 'stylesheet');
|
||||||
|
stylesheet.setAttribute('href', browser.runtime.getURL(file));
|
||||||
|
return stylesheet;
|
||||||
|
};
|
||||||
|
|
||||||
// Enables dragging
|
// Enables dragging
|
||||||
document.addEventListener('mousemove', function(e) {
|
document.addEventListener('mousemove', function(e) {
|
||||||
if (!kpxcUI.mouseDown) {
|
if (!kpxcUI.mouseDown) {
|
||||||
|
|
@ -212,3 +219,16 @@ HTMLDivElement.prototype.appendMultiple = function(...args) {
|
||||||
Element.prototype.getLowerCaseAttribute = function(attr) {
|
Element.prototype.getLowerCaseAttribute = function(attr) {
|
||||||
return this.getAttribute(attr) ? this.getAttribute(attr).toLowerCase() : undefined;
|
return this.getAttribute(attr) ? this.getAttribute(attr).toLowerCase() : undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Element.prototype._attachShadow = Element.prototype.attachShadow;
|
||||||
|
Element.prototype.attachShadow = function () {
|
||||||
|
return this._attachShadow( { mode: 'closed' } );
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.prototype.shadowSelector = function(value) {
|
||||||
|
return this.shadowRoot ? this.shadowRoot.querySelector(value) : undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.prototype.shadowSelectorAll = function(value) {
|
||||||
|
return this.shadowRoot ? this.shadowRoot.querySelectorAll(value) : undefined;
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,16 @@ UsernameFieldIcon.prototype.createIcon = function(target) {
|
||||||
|
|
||||||
kpxcUI.setIconPosition(icon, field);
|
kpxcUI.setIconPosition(icon, field);
|
||||||
this.icon = icon;
|
this.icon = icon;
|
||||||
document.body.appendChild(icon);
|
|
||||||
|
const styleSheet = document.createElement('link');
|
||||||
|
styleSheet.setAttribute('rel', 'stylesheet');
|
||||||
|
styleSheet.setAttribute('href', browser.runtime.getURL('css/username.css'));
|
||||||
|
|
||||||
|
const wrapper = document.createElement('div');
|
||||||
|
this.shadowRoot = wrapper.attachShadow({ mode: 'closed' });
|
||||||
|
this.shadowRoot.append(styleSheet);
|
||||||
|
this.shadowRoot.append(icon);
|
||||||
|
document.body.append(wrapper);
|
||||||
};
|
};
|
||||||
|
|
||||||
const iconClicked = async function(field, icon) {
|
const iconClicked = async function(field, icon) {
|
||||||
|
|
|
||||||
|
|
@ -65,11 +65,6 @@
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.kpxc-pwgen-checkbox-label {
|
|
||||||
font-style: normal !important;
|
|
||||||
font-weight: normal !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.kpxc #kpxc-pwgen-error {
|
.kpxc #kpxc-pwgen-error {
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
font-size: 12px !important;
|
font-size: 12px !important;
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,14 @@
|
||||||
"icons/keepassxc.svg",
|
"icons/keepassxc.svg",
|
||||||
"icons/key.svg",
|
"icons/key.svg",
|
||||||
"icons/locked.svg",
|
"icons/locked.svg",
|
||||||
"icons/otp.svg"
|
"icons/otp.svg",
|
||||||
|
"css/autocomplete.css",
|
||||||
|
"css/banner.css",
|
||||||
|
"css/button.css",
|
||||||
|
"css/colors.css",
|
||||||
|
"css/pwgen.css",
|
||||||
|
"css/username.css",
|
||||||
|
"css/totp.css"
|
||||||
],
|
],
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"activeTab",
|
"activeTab",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue