diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json
index a404572c2c0..ed722ddfed3 100644
--- a/src/_locales/en/messages.json
+++ b/src/_locales/en/messages.json
@@ -780,5 +780,11 @@
},
"popup2faCloseMessage": {
"message": "Clicking outside the popup window to check your email for your verification code will cause this popup to close. Do you want to open this popup in a new window so that it does not close?"
+ },
+ "disableFavicon": {
+ "message": "Disable Website Icons"
+ },
+ "disableFaviconDesc": {
+ "message": "Website Icons, also known as \"Favicons\", provides an image next to the login vault."
}
}
diff --git a/src/images/fa-globe.png b/src/images/fa-globe.png
new file mode 100644
index 00000000000..c3331f36584
Binary files /dev/null and b/src/images/fa-globe.png differ
diff --git a/src/popup/app/app.js b/src/popup/app/app.js
index e6e3916fb89..0a9c77db351 100644
--- a/src/popup/app/app.js
+++ b/src/popup/app/app.js
@@ -7,6 +7,7 @@
'angulartics.google.analytics',
'bit.directives',
+ 'bit.components',
'bit.services',
'bit.global',
diff --git a/src/popup/app/components/componentsModule.js b/src/popup/app/components/componentsModule.js
new file mode 100644
index 00000000000..df72afaf0e0
--- /dev/null
+++ b/src/popup/app/components/componentsModule.js
@@ -0,0 +1,2 @@
+angular
+ .module('bit.components', []);
diff --git a/src/popup/app/components/iconComponent.js b/src/popup/app/components/iconComponent.js
new file mode 100644
index 00000000000..66c587f780e
--- /dev/null
+++ b/src/popup/app/components/iconComponent.js
@@ -0,0 +1,26 @@
+angular
+ .module('bit.components')
+ .component('icon', {
+ bindings: {
+ uri: '<'
+ },
+ template: '
',
+ controller: function(stateService) {
+ this.$onInit = (function() {
+ this.enabled = function() {
+ return stateService.getState('faviconEnabled');
+ };
+ }).bind(this);
+
+ this.$onChanges = (function () {
+ var hostname;
+ try {
+ hostname = new URL(this.uri).hostname;
+ this.url = 'https://icons.bitwarden.com/' + hostname + '/icon.png';
+ } catch (e) {
+ // Invalid URL.
+ this.url = chrome.extension.getURL('images/fa-globe.png');
+ }
+ }).bind(this);
+ }
+ });
diff --git a/src/popup/app/config.js b/src/popup/app/config.js
index e834cdfa11a..611ffed5d04 100644
--- a/src/popup/app/config.js
+++ b/src/popup/app/config.js
@@ -1,7 +1,9 @@
angular
.module('bit')
- .config(function ($stateProvider, $urlRouterProvider, toastrConfig) {
+ .config(function ($stateProvider, $urlRouterProvider, $compileProvider, $sceDelegateProvider, toastrConfig) {
+ $compileProvider.imgSrcSanitizationWhitelist(/^\s*((https?|ftp|file|blob):|data:image\/|(moz|chrome|ms-browser)-extension)/);
+
angular.extend(toastrConfig, {
closeButton: true,
progressBar: true,
@@ -256,9 +258,14 @@
});
})
.run(function ($rootScope, userService, $state, constantsService, stateService) {
+ chrome.storage.local.get(constantsService.disableFaviconKey, function(obj) {
+ stateService.saveState('faviconEnabled', !obj[constantsService.disableFaviconKey]);
+ });
+
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
if ($state.current.name.indexOf('tabs.') > -1 && toState.name.indexOf('tabs.') > -1) {
- stateService.purgeState();
+ stateService.removeState('vault');
+ stateService.removeState('viewFolder');
}
if (!userService) {
diff --git a/src/popup/app/current/views/current.html b/src/popup/app/current/views/current.html
index 7ceb109557c..62d7e1900af 100644
--- a/src/popup/app/current/views/current.html
+++ b/src/popup/app/current/views/current.html
@@ -37,6 +37,7 @@
title="{{i18n.edit}} {{login.name}}">
+
{{login.name}}
diff --git a/src/popup/app/settings/settingsFeaturesController.js b/src/popup/app/settings/settingsFeaturesController.js
index 6c739410228..8fb2b482b80 100644
--- a/src/popup/app/settings/settingsFeaturesController.js
+++ b/src/popup/app/settings/settingsFeaturesController.js
@@ -2,13 +2,14 @@
.module('bit.settings')
.controller('settingsFeaturesController', function ($scope, i18nService, $analytics, constantsService, utilsService,
- totpService, $timeout) {
+ totpService, stateService, $timeout) {
$scope.i18n = i18nService;
$scope.disableGa = false;
$scope.disableAddLoginNotification = false;
$scope.disableContextMenuItem = false;
$scope.disableAutoTotpCopy = false;
$scope.enableAutoFillOnPageLoad = false;
+ $scope.disableFavicon = false;
chrome.storage.local.get(constantsService.enableAutoFillOnPageLoadKey, function (obj) {
$timeout(function () {
@@ -57,6 +58,12 @@
});
});
+ chrome.storage.local.get(constantsService.disableFaviconKey, function (obj) {
+ $timeout(function () {
+ $scope.disableFavicon = obj && obj[constantsService.disableFaviconKey] === true;
+ });
+ });
+
$scope.updateGa = function () {
chrome.storage.local.get(constantsService.disableGaKey, function (obj) {
// Default for Firefox is disabled.
@@ -176,4 +183,28 @@
});
});
};
+
+ $scope.updateDisableFavicon = function () {
+ chrome.storage.local.get(constantsService.disableFaviconKey, function (obj) {
+ if (obj[constantsService.disableFaviconKey]) {
+ // enable
+ obj[constantsService.disableFaviconKey] = false;
+ }
+ else {
+ // disable
+ $analytics.eventTrack('Disabled Favicon');
+ obj[constantsService.disableFaviconKey] = true;
+ }
+
+ chrome.storage.local.set(obj, function () {
+ $timeout(function () {
+ $scope.disableFavicon = obj[constantsService.disableFaviconKey];
+ stateService.saveState('faviconEnabled', !$scope.disableFavicon);
+ });
+ if (!obj[constantsService.disableFaviconKey]) {
+ $analytics.eventTrack('Enabled Favicon');
+ }
+ });
+ });
+ };
});
diff --git a/src/popup/app/settings/views/settingsFeatures.html b/src/popup/app/settings/views/settingsFeatures.html
index 4594fc60a62..18bc5c7a289 100644
--- a/src/popup/app/settings/views/settingsFeatures.html
+++ b/src/popup/app/settings/views/settingsFeatures.html
@@ -65,5 +65,17 @@
{{i18n.disableContextMenuItemDesc}}
+
+
+
+ {{i18n.disableFavicon}}
+
+
+
+
+
diff --git a/src/popup/app/vault/views/vault.html b/src/popup/app/vault/views/vault.html
index 6a9785b8a4e..d80a218c863 100644
--- a/src/popup/app/vault/views/vault.html
+++ b/src/popup/app/vault/views/vault.html
@@ -55,6 +55,7 @@
ng-class="{'disabled': !login.uri}">
+
{{login.name}}
@@ -87,6 +88,7 @@
ng-class="{'disabled': !login.uri}">
+
{{login.name}}
diff --git a/src/popup/index.html b/src/popup/index.html
index 53fc5d12b9b..bba0d921775 100644
--- a/src/popup/index.html
+++ b/src/popup/index.html
@@ -59,6 +59,9 @@
+
+
+
diff --git a/src/popup/less/components.less b/src/popup/less/components.less
index 3bd4eaf98d4..775f321dfdb 100644
--- a/src/popup/less/components.less
+++ b/src/popup/less/components.less
@@ -349,6 +349,20 @@
width: ~"calc(100% - 27px)";
}
+ .icon {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ float: left;
+ height: 36px;
+ width: 36px;
+ img {
+ border-radius: 3px;
+ max-height: 24px;
+ max-width: 24px;
+ }
+ }
+
.btn-list {
cursor: pointer;
float: right;
diff --git a/src/services/constantsService.js b/src/services/constantsService.js
index 4618609fa84..e8cfce30b36 100644
--- a/src/services/constantsService.js
+++ b/src/services/constantsService.js
@@ -4,6 +4,7 @@ function ConstantsService(i18nService) {
disableGaKey: 'disableGa',
disableAddLoginNotificationKey: 'disableAddLoginNotification',
disableContextMenuItemKey: 'disableContextMenuItem',
+ disableFaviconKey: 'disableFavicon',
disableAutoTotpCopyKey: 'disableAutoTotpCopy',
enableAutoFillOnPageLoadKey: 'enableAutoFillOnPageLoad',
lockOptionKey: 'lockOption',