From bcf0f19aa2ca5a0691117020af257fa4223c1290 Mon Sep 17 00:00:00 2001 From: Oscar Hinton Date: Thu, 9 Nov 2017 21:33:51 +0100 Subject: [PATCH] [Typescript] Convert password generator (#366) * Convert password generator to typescript. * Misc cleanup. --- src/popup/app/app.js | 1 - src/popup/app/config.js | 3 +- ...html => password-generator.component.html} | 58 ++++---- .../app/tools/password-generator.component.ts | 139 ++++++++++++++++++ src/popup/app/tools/tools.module.ts | 4 + .../tools/toolsPasswordGeneratorController.js | 116 --------------- 6 files changed, 173 insertions(+), 148 deletions(-) rename src/popup/app/tools/{views/toolsPasswordGenerator.html => password-generator.component.html} (60%) create mode 100644 src/popup/app/tools/password-generator.component.ts delete mode 100644 src/popup/app/tools/toolsPasswordGeneratorController.js diff --git a/src/popup/app/app.js b/src/popup/app/app.js index 4d159c95..eb26f150 100644 --- a/src/popup/app/app.js +++ b/src/popup/app/app.js @@ -132,7 +132,6 @@ require('./settings/settingsAddFolderController.js'); require('./settings/settingsEditFolderController.js'); require('./settings/settingsPremiumController.js'); require('./settings/settingsEnvironmentController.js'); -require('./tools/toolsPasswordGeneratorController.js'); require('./tools/toolsPasswordGeneratorHistoryController.js'); require('./tools/toolsExportController.js'); diff --git a/src/popup/app/config.js b/src/popup/app/config.js index 8753349c..6e41d457 100644 --- a/src/popup/app/config.js +++ b/src/popup/app/config.js @@ -167,8 +167,7 @@ angular .state('passwordGenerator', { url: '/password-generator', - template: require('./tools/views/toolsPasswordGenerator.html'), - controller: 'toolsPasswordGeneratorController', + component: 'passwordGenerator', data: { authorize: true }, params: { animation: null, addState: null, editState: null } }) diff --git a/src/popup/app/tools/views/toolsPasswordGenerator.html b/src/popup/app/tools/password-generator.component.html similarity index 60% rename from src/popup/app/tools/views/toolsPasswordGenerator.html rename to src/popup/app/tools/password-generator.component.html index e322c811..3af287c6 100644 --- a/src/popup/app/tools/views/toolsPasswordGenerator.html +++ b/src/popup/app/tools/password-generator.component.html @@ -1,84 +1,84 @@ 
-
{{i18n.generatePassword}}
+
{{$ctrl.i18n.generatePassword}}
- {{password}} + {{$ctrl.password}}
- {{i18n.options}} + {{$ctrl.i18n.options}}
- - {{options.length}} + + {{$ctrl.options.length}}
- +
- +
- +
- +
- +
- - + +
- - + +
- - {{$ctrl.i18n.avoidAmbChar}} + + ng-change="$ctrl.saveOptions($ctrl.options)">
diff --git a/src/popup/app/tools/password-generator.component.ts b/src/popup/app/tools/password-generator.component.ts new file mode 100644 index 00000000..b6efd7ec --- /dev/null +++ b/src/popup/app/tools/password-generator.component.ts @@ -0,0 +1,139 @@ +import * as angular from 'angular'; +import * as template from './password-generator.component.html'; + +export class PasswordGeneratorController { + $transition$: any; + options: any; + showSelect: any; + password: string = '-'; + editState: any; + addState: any; + i18n: any; + + constructor(private $state: any, private passwordGenerationService: any, + private toastr: any, utilsService: any, private $analytics: any, + private i18nService: any) { + this.i18n = i18nService; + + utilsService.initListSectionItemListeners($(document), angular); + + passwordGenerationService.getOptions().then((options: any) => { + this.options = options; + this.regenerate(false); + $analytics.eventTrack('Generated Password'); + passwordGenerationService.addHistory(this.password); + }); + + // Save password once the slider stop moving. + document.querySelector('#length').addEventListener('change', (e) => { + e.preventDefault(); + + $analytics.eventTrack('Generated Password'); + this.saveOptions(this.options, false); + passwordGenerationService.addHistory(this.password); + }); + } + + $onInit() { + const params = this.$transition$.params('to'); + this.addState = params.addState; + this.editState = params.editState; + + this.showSelect = this.addState || this.editState; + } + + sliderMoved() { + this.regenerate(false); + } + + regenerate(trackEvent: any) { + this.password = this.passwordGenerationService.generatePassword(this.options); + + if (trackEvent) { + this.$analytics.eventTrack('Regenerated Password'); + this.passwordGenerationService.addHistory(this.password); + } + } + + saveOptions(options: any, regenerate: boolean = true) { + if (!options.uppercase && !options.lowercase && !options.number && !options.special) { + options.lowercase = this.options.lowercase = true; + } + if (!options.minNumber) { + options.minNumber = this.options.minNumber = 0; + } + if (!options.minSpecial) { + options.minSpecial = this.options.minSpecial = 0; + } + + this.passwordGenerationService.saveOptions(options); + if (regenerate) { + this.regenerate(false); + } + return true; + } + + clipboardError(e: any, password: any) { + this.toastr.info(this.i18nService.browserNotSupportClipboard); + } + + clipboardSuccess(e: any) { + this.$analytics.eventTrack('Copied Generated Password'); + e.clearSelection(); + this.toastr.info(this.i18nService.passwordCopied); + } + + close() { + this.dismiss(); + } + + select() { + this.$analytics.eventTrack('Selected Generated Password'); + + if (this.addState) { + this.addState.cipher.login.password = this.password; + } else if (this.editState) { + this.editState.cipher.login.password = this.password; + } + + this.dismiss(); + } + + goHistory() { + this.$state.go('^.passwordGeneratorHistory', { + animation: 'in-slide-left', + addState: this.addState, + editState: this.editState, + }); + } + + private dismiss() { + if (this.addState) { + this.$state.go('addCipher', { + animation: 'out-slide-down', + from: this.addState.from, + cipher: this.addState.cipher, + }); + } else if (this.editState) { + this.$state.go('editCipher', { + animation: 'out-slide-down', + cipher: this.editState.cipher, + fromView: this.editState.fromView, + cipherId: this.editState.cipherId, + from: this.editState.from, + }); + } else { + this.$state.go('tabs.tools', { + animation: 'out-slide-down', + }); + } + } +} + +export const PasswordGeneratorComponent = { + bindings: { + $transition$: '<', + }, + controller: PasswordGeneratorController, + template, +}; diff --git a/src/popup/app/tools/tools.module.ts b/src/popup/app/tools/tools.module.ts index daedaac1..c0111143 100644 --- a/src/popup/app/tools/tools.module.ts +++ b/src/popup/app/tools/tools.module.ts @@ -1,7 +1,11 @@ import * as angular from 'angular'; +import { PasswordGeneratorComponent } from './password-generator.component'; import { ToolsComponent } from './tools.component'; export default angular .module('bit.tools', ['ngAnimate', 'ngclipboard', 'toastr', 'oitozero.ngSweetAlert']) + .component('tools', ToolsComponent) + .component('passwordGenerator', PasswordGeneratorComponent) + .name; diff --git a/src/popup/app/tools/toolsPasswordGeneratorController.js b/src/popup/app/tools/toolsPasswordGeneratorController.js deleted file mode 100644 index 19da18ea..00000000 --- a/src/popup/app/tools/toolsPasswordGeneratorController.js +++ /dev/null @@ -1,116 +0,0 @@ -angular - .module('bit.tools') - - .controller('toolsPasswordGeneratorController', function ($scope, $state, $stateParams, passwordGenerationService, - toastr, utilsService, $analytics, i18nService) { - $scope.i18n = i18nService; - var addState = $stateParams.addState, - editState = $stateParams.editState; - - $scope.showSelect = $stateParams.addState || $stateParams.editState; - - utilsService.initListSectionItemListeners($(document), angular); - $scope.password = '-'; - - passwordGenerationService.getOptions().then(function (options) { - $scope.options = options; - $scope.regenerate(false); - $analytics.eventTrack('Generated Password'); - passwordGenerationService.addHistory($scope.password); - }); - - $scope.sliderMoved = function () { - $scope.regenerate(false); - }; - - $('#length').change(function (e) { - e.preventDefault(); - $analytics.eventTrack('Generated Password'); - $scope.saveOptions($scope.options); - passwordGenerationService.addHistory($scope.password); - }); - - $scope.regenerate = function (trackEvent) { - $scope.password = passwordGenerationService.generatePassword($scope.options); - - if (trackEvent) { - $analytics.eventTrack('Regenerated Password'); - passwordGenerationService.addHistory($scope.password); - } - }; - - $scope.saveOptions = function (options) { - if (!options.uppercase && !options.lowercase && !options.number && !options.special) { - options.lowercase = $scope.options.lowercase = true; - } - if (!options.minNumber) { - options.minNumber = $scope.options.minNumber = 0; - } - if (!options.minSpecial) { - options.minSpecial = $scope.options.minSpecial = 0; - } - - passwordGenerationService.saveOptions(options); - $scope.regenerate(false); - return true; - }; - - $scope.clipboardError = function (e, password) { - toastr.info(i18n.browserNotSupportClipboard); - }; - - $scope.clipboardSuccess = function (e) { - $analytics.eventTrack('Copied Generated Password'); - e.clearSelection(); - toastr.info(i18nService.passwordCopied); - }; - - $scope.close = function () { - dismiss(); - }; - - $scope.select = function () { - $analytics.eventTrack('Selected Generated Password'); - - if (addState) { - addState.cipher.login.password = $scope.password; - } - else if (editState) { - editState.cipher.login.password = $scope.password; - } - - dismiss(); - }; - - $scope.goHistory = function () { - $state.go('^.passwordGeneratorHistory', { - animation: 'in-slide-left', - addState: $stateParams.addState, - editState: $stateParams.editState - }); - }; - - function dismiss() { - if (addState) { - $state.go('addCipher', { - animation: 'out-slide-down', - from: addState.from, - cipher: addState.cipher - }); - } - else if (editState) { - $state.go('editCipher', { - animation: 'out-slide-down', - cipher: editState.cipher, - fromView: editState.fromView, - cipherId: editState.cipherId, - from: editState.from - }); - } - else { - $state.go('tabs.tools', { - animation: 'out-slide-down' - }); - } - } - });