diff --git a/src/content/autofiller.js b/src/content/autofiller.ts similarity index 79% rename from src/content/autofiller.js rename to src/content/autofiller.ts index 37d49d39d9..465c69a937 100644 --- a/src/content/autofiller.js +++ b/src/content/autofiller.ts @@ -1,5 +1,5 @@ document.addEventListener('DOMContentLoaded', (event) => { - let pageHref = null; + let pageHref: string = null; const isSafari = (typeof safari !== 'undefined') && navigator.userAgent.indexOf(' Safari/') !== -1 && navigator.userAgent.indexOf('Chrome') === -1; @@ -7,9 +7,9 @@ document.addEventListener('DOMContentLoaded', (event) => { const responseCommand = 'autofillerAutofillOnPageLoadEnabledResponse'; safari.self.tab.dispatchMessage('bitwarden', { command: 'bgGetDataForTab', - responseCommand: responseCommand + responseCommand: responseCommand, }); - safari.self.addEventListener('message', (msgEvent) => { + safari.self.addEventListener('message', (msgEvent: any) => { const msg = msgEvent.message; if (msg.command === responseCommand && msg.data.autofillEnabled === true) { setInterval(doFillIfNeeded, 500); @@ -18,8 +18,8 @@ document.addEventListener('DOMContentLoaded', (event) => { return; } else { const enabledKey = 'enableAutoFillOnPageLoad'; - chrome.storage.local.get(enabledKey, (obj) => { - if (obj && obj[enabledKey] === true) { + chrome.storage.local.get(enabledKey, (obj: any) => { + if (obj != null && obj[enabledKey] === true) { setInterval(doFillIfNeeded, 500); } }); @@ -30,7 +30,7 @@ document.addEventListener('DOMContentLoaded', (event) => { pageHref = window.location.href; const msg = { command: 'bgCollectPageDetails', - sender: 'autofiller' + sender: 'autofiller', }; if (isSafari) { diff --git a/src/content/notificationBar.js b/src/content/notificationBar.js deleted file mode 100644 index 9badba08a4..0000000000 --- a/src/content/notificationBar.js +++ /dev/null @@ -1,450 +0,0 @@ -document.addEventListener('DOMContentLoaded', (event) => { - if (window.location.hostname.indexOf('vault.bitwarden.com') > -1) { - return; - } - - var pageDetails = [], - formData = [], - barType = null, - pageHref = null, - observer = null, - domObservationCollectTimeout = null, - collectIfNeededTimeout = null, - observeDomTimeout = null, - iframed = isIframed(), - submitButtonNames = ['log in', 'sign in', 'login', 'go', 'submit', 'continue', 'next'], - notificationBarData = null, - isSafari = (typeof safari !== 'undefined') && navigator.userAgent.indexOf(' Safari/') !== -1 && - navigator.userAgent.indexOf('Chrome') === -1; - - if (isSafari) { - const responseCommand = 'notificationBarDataResponse'; - safari.self.tab.dispatchMessage('bitwarden', { - command: 'bgGetDataForTab', - responseCommand: responseCommand - }); - safari.self.addEventListener('message', (msgEvent) => { - const msg = msgEvent.message; - if (msg.command === responseCommand && msg.data) { - notificationBarData = msg.data; - if (notificationBarData.neverDomains && - notificationBarData.neverDomains.hasOwnProperty(window.location.hostname)) { - return; - } - - if (notificationBarData.disabledNotification === true) { - return; - } - - collectIfNeededWithTimeout(); - return; - } - - processMessages(msg, () => { /* do nothing on send response for Safari */ }); - }, false); - return; - } else { - chrome.storage.local.get('neverDomains', (obj) => { - var domains = obj.neverDomains; - if (domains && domains.hasOwnProperty(window.location.hostname)) { - return; - } - - chrome.storage.local.get('disableAddLoginNotification', (obj) => { - if (!obj || !obj.disableAddLoginNotification) { - collectIfNeededWithTimeout(); - } - }); - }); - - chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { - processMessages(msg, sendResponse); - }); - } - - function processMessages(msg, sendResponse) { - if (msg.command === 'openNotificationBar') { - if (iframed) { - return; - } - closeExistingAndOpenBar(msg.data.type, msg.data.typeData); - sendResponse(); - return true; - } else if (msg.command === 'closeNotificationBar') { - if (iframed) { - return; - } - closeBar(true); - sendResponse(); - return true; - } else if (msg.command === 'adjustNotificationBar') { - if (iframed) { - return; - } - adjustBar(msg.data); - sendResponse(); - return true; - } else if (msg.command === 'notificationBarPageDetails') { - pageDetails.push(msg.data.details); - watchForms(msg.data.forms); - sendResponse(); - return true; - } - } - - function isIframed() { - try { - return window.self !== window.top; - } catch (e) { - return true; - } - } - - function observeDom() { - var bodies = document.querySelectorAll('body'); - if (bodies && bodies.length > 0) { - observer = new window.MutationObserver((mutations) => { - if (!mutations || !mutations.length || pageHref !== window.location.href) { - return; - } - - var doCollect = false; - for (var i = 0; i < mutations.length; i++) { - if (!mutations[i].addedNodes || !mutations[i].addedNodes.length) { - continue; - } - - for (var j = 0; j < mutations[i].addedNodes.length; j++) { - var addedNode = mutations[i].addedNodes[j]; - if (!addedNode) { - continue; - } - - if (addedNode.tagName && addedNode.tagName.toLowerCase() == 'form' && - (!addedNode.dataset || !addedNode.dataset.bitwardenWatching)) { - doCollect = true; - break; - } - - if (!addedNode.querySelectorAll) { - continue; - } - - var forms = mutations[i].addedNodes[j].querySelectorAll('form:not([data-bitwarden-watching])'); - if (forms && forms.length) { - doCollect = true; - break; - } - } - - if (doCollect) { - break; - } - } - - if (doCollect) { - if (domObservationCollectTimeout) { - clearTimeout(domObservationCollectTimeout); - } - - domObservationCollectTimeout = setTimeout(collect, 1000); - } - }); - - observer.observe(bodies[0], { childList: true, subtree: true }); - } - } - - function collectIfNeededWithTimeout() { - if (collectIfNeededTimeout) { - clearTimeout(collectIfNeededTimeout); - } - collectIfNeededTimeout = setTimeout(collectIfNeeded, 1000); - } - - function collectIfNeeded() { - if (pageHref !== window.location.href) { - pageHref = window.location.href; - if (observer) { - observer.disconnect(); - observer = null; - } - - collect(); - - if (observeDomTimeout) { - clearTimeout(observeDomTimeout); - } - observeDomTimeout = setTimeout(observeDom, 1000); - } - - if (collectIfNeededTimeout) { - clearTimeout(collectIfNeededTimeout); - } - collectIfNeededTimeout = setTimeout(collectIfNeeded, 1000); - } - - function collect() { - sendPlatformMessage({ - command: 'bgCollectPageDetails', - sender: 'notificationBar' - }); - } - - 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 && form.dataset.bitwardenWatching !== '1') { - var formDataObj = { - data: forms[i], - formEl: form, - usernameEl: null, - passwordEl: null - }; - locateFields(formDataObj); - formData.push(formDataObj); - listen(form); - form.dataset.bitwardenWatching = '1'; - } - } - } - - function listen(form) { - form.removeEventListener('submit', formSubmitted, false); - form.addEventListener('submit', formSubmitted, false); - var submitButton = form.querySelector( - 'input[type="submit"], input[type="image"], button[type="submit"], button:not([type])'); - if (submitButton) { - submitButton.removeEventListener('click', formSubmitted, false); - submitButton.addEventListener('click', formSubmitted, false); - } else { - var possibleSubmitButtons = form.querySelectorAll('a, span, button[type="button"], input[type="button"]'); - for (var i = 0; i < possibleSubmitButtons.length; i++) { - var button = possibleSubmitButtons[i]; - if (!button || !button.tagName) { - continue; - } - - var buttonText; - if (button.tagName.toLowerCase() === 'input') { - buttonText = button.value; - } else { - buttonText = button.innerText; - } - - if (!buttonText) { - continue; - } - - buttonText = buttonText.trim().toLowerCase(); - if (submitButtonNames.indexOf(buttonText) > -1) { - button.removeEventListener('click', formSubmitted, false); - button.addEventListener('click', formSubmitted, false); - } - } - } - } - - function locateFields(formDataObj) { - var passwordId = formDataObj.data.password ? formDataObj.data.password.htmlID : null, - usernameId = formDataObj.data.username ? formDataObj.data.username.htmlID : null, - passwordName = formDataObj.data.password ? formDataObj.data.password.htmlName : null, - usernameName = formDataObj.data.username ? formDataObj.data.username.htmlName : null, - inputs = document.getElementsByTagName('input'); - - if (passwordId && passwordId !== '') { - try { - formDataObj.passwordEl = formDataObj.formEl.querySelector('#' + passwordId); - } - catch (e) { } - } - if (!formDataObj.passwordEl && passwordName !== '') { - formDataObj.passwordEl = formDataObj.formEl.querySelector('input[name="' + passwordName + '"]'); - } - if (!formDataObj.passwordEl && formDataObj.passwordEl) { - formDataObj.passwordEl = inputs[formDataObj.data.password.elementNumber]; - if (formDataObj.passwordEl && formDataObj.passwordEl.type !== 'password') { - formDataObj.passwordEl = null; - } - } - if (!formDataObj.passwordEl) { - formDataObj.passwordEl = formDataObj.formEl.querySelector('input[type="password"]'); - } - - if (usernameId && usernameId !== '') { - try { - formDataObj.usernameEl = formDataObj.formEl.querySelector('#' + usernameId); - } - catch (e) { } - } - if (!formDataObj.usernameEl && usernameName !== '') { - formDataObj.usernameEl = formDataObj.formEl.querySelector('input[name="' + usernameName + '"]'); - } - if (!formDataObj.usernameEl && formDataObj.data.username) { - formDataObj.usernameEl = inputs[formDataObj.data.username.elementNumber]; - } - } - - function formSubmitted(e) { - var form = null; - if (e.type === 'click') { - form = e.target.closest('form'); - } else { - form = e.target; - } - - if (!form || form.dataset.bitwardenProcessed === '1') { - return; - } - - for (var i = 0; i < formData.length; i++) { - if (formData[i].formEl === form) { - if (!formData[i].usernameEl || !formData[i].passwordEl) { - break; - } - - var login = { - username: formData[i].usernameEl.value, - password: formData[i].passwordEl.value, - url: document.URL - }; - - if (login.username && login.username !== '' && login.password && login.password !== '') { - form.dataset.bitwardenProcessed = '1'; - setTimeout(() => { - form.dataset.bitwardenProcessed = '0'; - }, 500); - - sendPlatformMessage({ - command: 'bgAddLogin', - login: login - }); - break; - } - } - } - } - - function closeExistingAndOpenBar(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'; - break; - default: - break; - } - - var frame = document.getElementById('bit-notification-bar-iframe'); - if (frame && frame.src.indexOf(barPage) >= 0) { - return; - } - - closeBar(false); - openBar(type, barPage); - } - - function openBar(type, barPage) { - barType = type; - - if (!document.body) { - return; - } - - var barPageUrl = isSafari ? (safari.extension.baseURI + barPage) : chrome.extension.getURL(barPage); - - var iframe = document.createElement('iframe'); - iframe.style.cssText = 'height: 42px; width: 100%; border: 0;'; - iframe.id = 'bit-notification-bar-iframe'; - - var frameDiv = document.createElement('div'); - frameDiv.id = 'bit-notification-bar'; - frameDiv.style.cssText = 'height: 42px; width: 100%; top: 0; left: 0; padding: 0; position: fixed; z-index: 2147483647; visibility: visible;'; - frameDiv.appendChild(iframe); - document.body.appendChild(frameDiv); - - iframe.contentWindow.location = barPageUrl; - - var spacer = document.createElement('div'); - spacer.id = 'bit-notification-bar-spacer'; - spacer.style.cssText = 'height: 42px;'; - document.body.insertBefore(spacer, document.body.firstChild); - } - - function closeBar(explicitClose) { - var el = document.getElementById('bit-notification-bar'); - if (el) { - el.parentElement.removeChild(el); - } - - el = document.getElementById('bit-notification-bar-spacer'); - if (el) { - el.parentElement.removeChild(el); - } - - if (!explicitClose) { - return; - } - - switch (barType) { - case 'add': - sendPlatformMessage({ - command: 'bgAddClose' - }); - break; - default: - break; - } - } - - function adjustBar(data) { - if (data.height !== 42) { - var newHeight = data.height + 'px'; - doHeightAdjustment('bit-notification-bar-iframe', newHeight); - doHeightAdjustment('bit-notification-bar', newHeight); - doHeightAdjustment('bit-notification-bar-spacer', newHeight); - } - } - - function doHeightAdjustment(elId, heightStyle) { - var el = document.getElementById(elId); - if (el) { - el.style.height = heightStyle; - } - } - - function sendPlatformMessage(msg) { - if (isSafari) { - safari.self.tab.dispatchMessage('bitwarden', msg); - } else { - chrome.runtime.sendMessage(msg); - } - } -}); diff --git a/src/content/notificationBar.ts b/src/content/notificationBar.ts new file mode 100644 index 0000000000..4299c23788 --- /dev/null +++ b/src/content/notificationBar.ts @@ -0,0 +1,450 @@ +document.addEventListener('DOMContentLoaded', (event) => { + if (window.location.hostname.indexOf('vault.bitwarden.com') > -1) { + return; + } + + const pageDetails: any[] = []; + const formData: any[] = []; + let barType: string = null; + let pageHref: string = null; + let observer: MutationObserver = null; + let domObservationCollectTimeout: number = null; + let collectIfNeededTimeout: number = null; + let observeDomTimeout: number = null; + const inIframe = isInIframe(); + const submitButtonNames = new Set(['log in', 'sign in', 'login', 'go', 'submit', 'continue', 'next']); + let notificationBarData = null; + const isSafari = (typeof safari !== 'undefined') && navigator.userAgent.indexOf(' Safari/') !== -1 && + navigator.userAgent.indexOf('Chrome') === -1; + + if (isSafari) { + const responseCommand = 'notificationBarDataResponse'; + safari.self.tab.dispatchMessage('bitwarden', { + command: 'bgGetDataForTab', + responseCommand: responseCommand, + }); + safari.self.addEventListener('message', (msgEvent: any) => { + const msg = msgEvent.message; + if (msg.command === responseCommand && msg.data) { + notificationBarData = msg.data; + if (notificationBarData.neverDomains && + notificationBarData.neverDomains.hasOwnProperty(window.location.hostname)) { + return; + } + + if (notificationBarData.disabledNotification === true) { + return; + } + + collectIfNeededWithTimeout(); + return; + } + + processMessages(msg, () => { /* do nothing on send response for Safari */ }); + }, false); + return; + } else { + chrome.storage.local.get('neverDomains', (ndObj: any) => { + const domains = ndObj.neverDomains; + if (domains != null && domains.hasOwnProperty(window.location.hostname)) { + return; + } + + chrome.storage.local.get('disableAddLoginNotification', (disObj: any) => { + if (disObj == null || !disObj.disableAddLoginNotification) { + collectIfNeededWithTimeout(); + } + }); + }); + + chrome.runtime.onMessage.addListener((msg: any, sender: any, sendResponse: Function) => { + processMessages(msg, sendResponse); + }); + } + + function processMessages(msg: any, sendResponse: Function) { + if (msg.command === 'openNotificationBar') { + if (inIframe) { + return; + } + closeExistingAndOpenBar(msg.data.type, msg.data.typeData); + sendResponse(); + return true; + } else if (msg.command === 'closeNotificationBar') { + if (inIframe) { + return; + } + closeBar(true); + sendResponse(); + return true; + } else if (msg.command === 'adjustNotificationBar') { + if (inIframe) { + return; + } + adjustBar(msg.data); + sendResponse(); + return true; + } else if (msg.command === 'notificationBarPageDetails') { + pageDetails.push(msg.data.details); + watchForms(msg.data.forms); + sendResponse(); + return true; + } + } + + function isInIframe() { + try { + return window.self !== window.top; + } catch { + return true; + } + } + + function observeDom() { + const bodies = document.querySelectorAll('body'); + if (bodies && bodies.length > 0) { + observer = new MutationObserver((mutations) => { + if (mutations == null || mutations.length === 0 || pageHref !== window.location.href) { + return; + } + + let doCollect = false; + for (let i = 0; i < mutations.length; i++) { + const mutation = mutations[i]; + if (mutation.addedNodes == null || mutation.addedNodes.length === 0) { + continue; + } + + for (let j = 0; j < mutation.addedNodes.length; j++) { + const addedNode: any = mutation.addedNodes[j]; + if (addedNode == null) { + continue; + } + + if (addedNode.tagName != null && addedNode.tagName.toLowerCase() === 'form' && + (addedNode.dataset == null || !addedNode.dataset.bitwardenWatching)) { + doCollect = true; + break; + } + + if (!addedNode.querySelectorAll) { + continue; + } + + const forms = addedNode.querySelectorAll('form:not([data-bitwarden-watching])'); + if (forms != null && forms.length > 0) { + doCollect = true; + break; + } + } + + if (doCollect) { + break; + } + } + + if (doCollect) { + if (domObservationCollectTimeout != null) { + window.clearTimeout(domObservationCollectTimeout); + } + + domObservationCollectTimeout = window.setTimeout(collect, 1000); + } + }); + + observer.observe(bodies[0], { childList: true, subtree: true }); + } + } + + function collectIfNeededWithTimeout() { + if (collectIfNeededTimeout != null) { + window.clearTimeout(collectIfNeededTimeout); + } + collectIfNeededTimeout = window.setTimeout(collectIfNeeded, 1000); + } + + function collectIfNeeded() { + if (pageHref !== window.location.href) { + pageHref = window.location.href; + if (observer) { + observer.disconnect(); + observer = null; + } + + collect(); + + if (observeDomTimeout != null) { + window.clearTimeout(observeDomTimeout); + } + observeDomTimeout = window.setTimeout(observeDom, 1000); + } + + if (collectIfNeededTimeout != null) { + window.clearTimeout(collectIfNeededTimeout); + } + collectIfNeededTimeout = window.setTimeout(collectIfNeeded, 1000); + } + + function collect() { + sendPlatformMessage({ + command: 'bgCollectPageDetails', + sender: 'notificationBar', + }); + } + + function watchForms(forms: any[]) { + if (forms == null || forms.length === 0) { + return; + } + + forms.forEach((f: any) => { + const formId: string = f.form != null ? f.form.htmlID : null; + let formEl: HTMLElement = null; + if (formId != null && formId !== '') { + formEl = document.getElementById(formId); + } + + if (formEl == null) { + const index = parseInt(f.form.opid.split('__')[2], null); + formEl = document.getElementsByTagName('form')[index]; + } + + if (formEl != null && formEl.dataset.bitwardenWatching !== '1') { + const formDataObj: any = { + data: f, + formEl: formEl, + usernameEl: null, + passwordEl: null, + }; + locateFields(formDataObj); + formData.push(formDataObj); + listen(formEl); + formEl.dataset.bitwardenWatching = '1'; + } + }); + } + + function listen(form: HTMLElement) { + form.removeEventListener('submit', formSubmitted, false); + form.addEventListener('submit', formSubmitted, false); + const submitButton = form.querySelector('input[type="submit"], input[type="image"], ' + + 'button[type="submit"], button:not([type])'); + if (submitButton != null) { + submitButton.removeEventListener('click', formSubmitted, false); + submitButton.addEventListener('click', formSubmitted, false); + } else { + const possibleSubmitButtons = form.querySelectorAll('a, span, button[type="button"], ' + + 'input[type="button"]') as NodeListOf; + possibleSubmitButtons.forEach((button) => { + if (button == null || button.tagName == null) { + return; + } + + let buttonText: string = null; + if (button.tagName.toLowerCase() === 'input') { + buttonText = (button as HTMLInputElement).value; + } else { + buttonText = button.innerText; + } + + if (buttonText == null) { + return; + } + + buttonText = buttonText.trim().toLowerCase(); + if (submitButtonNames.has(buttonText)) { + button.removeEventListener('click', formSubmitted, false); + button.addEventListener('click', formSubmitted, false); + } + }); + } + } + + function locateFields(formDataObj: any) { + const passwordId: string = formDataObj.data.password != null ? formDataObj.data.password.htmlID : null; + const usernameId: string = formDataObj.data.username != null ? formDataObj.data.username.htmlID : null; + const passwordName: string = formDataObj.data.password != null ? formDataObj.data.password.htmlName : null; + const usernameName: string = formDataObj.data.username != null ? formDataObj.data.username.htmlName : null; + const inputs = document.getElementsByTagName('input'); + + if (passwordId != null && passwordId !== '') { + try { + formDataObj.passwordEl = formDataObj.formEl.querySelector('#' + passwordId); + } catch { } + } + if (formDataObj.passwordEl == null && passwordName !== '') { + formDataObj.passwordEl = formDataObj.formEl.querySelector('input[name="' + passwordName + '"]'); + } + if (formDataObj.passwordEl == null && formDataObj.passwordEl != null) { + formDataObj.passwordEl = inputs[formDataObj.data.password.elementNumber]; + if (formDataObj.passwordEl != null && formDataObj.passwordEl.type !== 'password') { + formDataObj.passwordEl = null; + } + } + if (formDataObj.passwordEl == null) { + formDataObj.passwordEl = formDataObj.formEl.querySelector('input[type="password"]'); + } + + if (usernameId != null && usernameId !== '') { + try { + formDataObj.usernameEl = formDataObj.formEl.querySelector('#' + usernameId); + } catch { } + } + if (formDataObj.usernameEl == null && usernameName !== '') { + formDataObj.usernameEl = formDataObj.formEl.querySelector('input[name="' + usernameName + '"]'); + } + if (formDataObj.usernameEl == null && formDataObj.data.username != null) { + formDataObj.usernameEl = inputs[formDataObj.data.username.elementNumber]; + } + } + + function formSubmitted(e: Event) { + let form: HTMLFormElement = null; + if (e.type === 'click') { + form = (e.target as HTMLElement).closest('form'); + } else { + form = e.target as HTMLFormElement; + } + + if (form == null || form.dataset.bitwardenProcessed === '1') { + return; + } + + for (let i = 0; i < formData.length; i++) { + if (formData[i].formEl !== form) { + continue; + } + if (formData[i].usernameEl == null || formData[i].passwordEl == null) { + break; + } + + const login = { + username: formData[i].usernameEl.value, + password: formData[i].passwordEl.value, + url: document.URL, + }; + + if (login.username != null && login.username !== '' && login.password != null && login.password !== '') { + form.dataset.bitwardenProcessed = '1'; + window.setTimeout(() => { + form.dataset.bitwardenProcessed = '0'; + }, 500); + + sendPlatformMessage({ + command: 'bgAddLogin', + login: login, + }); + break; + } + } + } + + function closeExistingAndOpenBar(type: string, typeData: any) { + let 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'; + break; + default: + break; + } + + const frame = document.getElementById('bit-notification-bar-iframe') as HTMLIFrameElement; + if (frame != null && frame.src.indexOf(barPage) >= 0) { + return; + } + + closeBar(false); + openBar(type, barPage); + } + + function openBar(type: string, barPage: string) { + barType = type; + + if (document.body == null) { + return; + } + + const barPageUrl: string = isSafari ? (safari.extension.baseURI + barPage) : chrome.extension.getURL(barPage); + + const iframe = document.createElement('iframe'); + iframe.style.cssText = 'height: 42px; width: 100%; border: 0;'; + iframe.id = 'bit-notification-bar-iframe'; + + const frameDiv = document.createElement('div'); + frameDiv.id = 'bit-notification-bar'; + frameDiv.style.cssText = 'height: 42px; width: 100%; top: 0; left: 0; padding: 0; position: fixed; ' + + 'z-index: 2147483647; visibility: visible;'; + frameDiv.appendChild(iframe); + document.body.appendChild(frameDiv); + + (iframe.contentWindow.location as any) = barPageUrl; + + const spacer = document.createElement('div'); + spacer.id = 'bit-notification-bar-spacer'; + spacer.style.cssText = 'height: 42px;'; + document.body.insertBefore(spacer, document.body.firstChild); + } + + function closeBar(explicitClose: boolean) { + const barEl = document.getElementById('bit-notification-bar'); + if (barEl != null) { + barEl.parentElement.removeChild(barEl); + } + + const spacerEl = document.getElementById('bit-notification-bar-spacer'); + if (spacerEl) { + spacerEl.parentElement.removeChild(spacerEl); + } + + if (!explicitClose) { + return; + } + + switch (barType) { + case 'add': + sendPlatformMessage({ + command: 'bgAddClose', + }); + break; + default: + break; + } + } + + function adjustBar(data: any) { + if (data != null && data.height !== 42) { + const newHeight = data.height + 'px'; + doHeightAdjustment('bit-notification-bar-iframe', newHeight); + doHeightAdjustment('bit-notification-bar', newHeight); + doHeightAdjustment('bit-notification-bar-spacer', newHeight); + } + } + + function doHeightAdjustment(elId: string, heightStyle: string) { + const el = document.getElementById(elId); + if (el != null) { + el.style.height = heightStyle; + } + } + + function sendPlatformMessage(msg: any) { + if (isSafari) { + safari.self.tab.dispatchMessage('bitwarden', msg); + } else { + chrome.runtime.sendMessage(msg); + } + } +}); diff --git a/webpack.config.js b/webpack.config.js index c010e0435c..c5a1bc8799 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -160,8 +160,8 @@ const config = { 'popup/main': './src/popup/main.ts', 'background': './src/background.ts', 'content/autofill': './src/content/autofill.js', - 'content/autofiller': './src/content/autofiller.js', - 'content/notificationBar': './src/content/notificationBar.js', + 'content/autofiller': './src/content/autofiller.ts', + 'content/notificationBar': './src/content/notificationBar.ts', 'content/shortcuts': './src/content/shortcuts.js', 'notification/bar': './src/notification/bar.js', 'downloader/downloader': './src/downloader/downloader.ts',