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}} +
+
+
+ + +
+
+ +
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',