i18n support

added support for i18n
This commit is contained in:
Artem Nikolaev 2016-10-18 15:10:40 +03:00 committed by Kyle Spearrin
parent 53af5e234b
commit 6d60eb621e
45 changed files with 651 additions and 173 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
.vs
.idea
node_modules
npm-debug.log
lib/

View File

@ -0,0 +1,362 @@
{
"appName": {
"message": "bitwarden",
"description": "bitwarden"
},
"extName": {
"message": "bitwarden - Free Password Manager",
"description": "Extension name."
},
"extDesc": {
"message": "bitwarden is a secure and free password manager for all of your devices.",
"description": "Extension description"
},
"loginOrCreateNewAccount": {
"message": "Log in or create a new account to access your secure vault.",
"description": "Log in or create a new account to access your secure vault."
},
"createAccount": {
"message": "Create Account",
"description": "Create Account"
},
"login": {
"message": "Log In",
"description": "Log In"
},
"cancel": {
"message": "Cancel",
"description": "Cancel"
},
"submit": {
"message": "Submit",
"description": "submit"
},
"emailAddress": {
"message": "Email Address",
"description": "Email Address"
},
"masterPass": {
"message": "Master Password",
"description": "Master Password"
},
"masterPassDesc": {
"message": "The master password is the password you use to access your vault. It is very important that you do not forget your master password. There is no way to recover the password in the event that you forget it.",
"description": "The master password is the password you use to access your vault. It is very important that you do not forget your master password. There is no way to recover the password in the event that you forget it."
},
"reTypeMasterPass": {
"message": "Re-type Master Password",
"description": "Re-type Master Password"
},
"masterPassHint": {
"message": "Master Password Hint (optional)",
"description": "Master Password Hint (optional)"
},
"masterPassHintDecs": {
"message": "A master password hint can help you remember your password if you forget it.",
"description": "A master password hint can help you remember your password if you forget it."
},
"tab": {
"message": "Tab",
"description": "Tab"
},
"myVault": {
"message": "My Vault",
"description": "My Vault"
},
"tools": {
"message": "Tools",
"description": "Tools"
},
"settings": {
"message": "Settings",
"description": "Settings"
},
"currentTab": {
"message": "Current Tab",
"description": "Current Tab"
},
"copyPassword": {
"message": "Copy Password",
"description": "Copy Password"
},
"copyUsername": {
"message": "Copy Username",
"description": "Copy Username"
},
"autoFillInfo": {
"message": "There are no sites available to auto-fill for the current browser tab.",
"description": "There are no sites available to auto-fill for the current browser tab."
},
"addSite": {
"message": "Add a Site",
"description": "Add a Site"
},
"passwordHint": {
"message": "Password Hint",
"description": "Password Hint"
},
"enterEmailToGetHint": {
"message": "Enter your account email address to receive your master password hint.",
"description": "Enter your account email address to receive your master password hint."
},
"getMasterPasswordHint": {
"message": "Get master password hint",
"description": "Get master password hint"
},
"continue": {
"message": "Continue",
"description": "Continue"
},
"verificationCode": {
"message": "Verification Code",
"description": "Verification Code"
},
"enterTwoStepVerCode": {
"message": "Enter your two-step verification code.",
"description": "Enter your two-step verification code."
},
"account": {
"message": "Account",
"description": "Account"
},
"changeMasterPassword": {
"message": "Change Master Password",
"description": "Change Master Password"
},
"changeEmail": {
"message": "Change Email",
"description": "Change Email"
},
"twoStepLogin": {
"message": "Two-step Login",
"description": "Two-step Login"
},
"logOut": {
"message": "Log Out",
"description": "Log Out"
},
"about": {
"message": "About",
"description": "About"
},
"version": {
"message": "Version",
"description": "Version"
},
"save": {
"message": "Save",
"description": "Save"
},
"addFolder": {
"message": "Add Folder",
"description": "Add Folder"
},
"name": {
"message": "Name",
"description": "Name"
},
"editFolder": {
"message": "Edit Folder",
"description": "Edit Folder"
},
"deleteFolder": {
"message": "Delete Folder",
"description": "Delete Folder"
},
"folders": {
"message": "Folders",
"description": "Folders"
},
"noFolders": {
"message": "There are no folders to list.",
"description": "There are no folders to list."
},
"helpFeedback": {
"message": "Help and Feedback",
"description": "Help and Feedback"
},
"emailUs": {
"message": "Email Us",
"description": "Email Us"
},
"emailUsDirectly": {
"message": "Email us directly to get help or leave feedback.",
"description": "Email us directly to get help or leave feedback."
},
"visitOurWebsite": {
"message": "Visit Our Website",
"description": "Visit Our Website"
},
"visitOurWebsiteDirectly": {
"message": "Visit our website to get help, news, email us, and/or learn more about how to use bitwarden.",
"description": "Visit our website to get help, news, email us, and/or learn more about how to use bitwarden."
},
"fileBugReport": {
"message": "File a Bug Report",
"description": "File a Bug Report"
},
"gitHubIssue": {
"message": "Open an issue at our GitHub repository.",
"description": "Open an issue at our GitHub repository."
},
"sync": {
"message": "Sync",
"description": "Sync"
},
"syncVaultNow": {
"message": "Sync Vault Now",
"description": "Sync Vault Now"
},
"lastSync": {
"message": "Last Sync:",
"description": "Last Sync:"
},
"passGen": {
"message": "Password Generator",
"description": "Password Generator"
},
"passGenInfo": {
"message": "Automatically generate strong, unique passwords for your logins.",
"description": "Automatically generate strong, unique passwords for your logins."
},
"bitWebVault": {
"message": "bitwarden Web Vault",
"description": "bitwarden Web Vault"
},
"bitWebVaultInfo": {
"message": "Manage your logins from any web browser with the bitwarden web vault.",
"description": "Manage your logins from any web browser with the bitwarden web vault."
},
"bitIosVault": {
"message": "bitwarden iOS Vault",
"description": "bitwarden iOS Vault"
},
"bitIosVaultInfo": {
"message": "Manage your logins from your mobile devices with the bitwarden iOS vault.",
"description": "Manage your logins from your mobile devices with the bitwarden iOS vault."
},
"bitAndrVault": {
"message": "bitwarden Android Vault",
"description": "bitwarden Android Vault"
},
"bitAndrVaultInfo": {
"message": "Manage your logins from your mobile devices with the bitwarden Android vault.",
"description": "Manage your logins from your mobile devices with the bitwarden Android vault."
},
"importLogins": {
"message": "Import Logins",
"description": "Import Logins"
},
"importLoginsInfo": {
"message": "Quickly bulk import your logins from other password management applications.",
"description": "Quickly bulk import your logins from other password management applications."
},
"select": {
"message": "Select",
"description": "Select"
},
"generatePassword": {
"message": "Generate Password",
"description": "Generate Password"
},
"regeneratePassword": {
"message": "Regenerate Password",
"description": "Regenerate Password"
},
"options": {
"message": "Options",
"description": "Options"
},
"length": {
"message": "Length",
"description": "Length"
},
"minNumbers": {
"message": "Minimum Numbers",
"description": "Minimum Numbers"
},
"minSpecial": {
"message": "Minimum Special",
"description": "Minimum Special"
},
"avoidAmbChar": {
"message": "Avoid Ambiguous Characters",
"description": "Avoid Ambiguous Characters"
},
"searchVault": {
"message": "Search vault",
"description": "Search vault"
},
"edit": {
"message": "Edit",
"description": "Edit"
},
"noSitesInList": {
"message": "There are no sites in list.",
"description": "There are no sites in list."
},
"siteInformation": {
"message": "Site Information",
"description": "Site Information"
},
"username": {
"message": "Username",
"description": "Username"
},
"password": {
"message": "Password",
"description": "Password"
},
"favorite": {
"message": "Favorite",
"description": "Favorite"
},
"notes": {
"message": "Notes",
"description": "Notes"
},
"editSite": {
"message": "Edit Site",
"description": "Edit Site"
},
"folder": {
"message": "Folder",
"description": "Folder"
},
"deleteSite": {
"message": "Delete Site",
"description": "Delete Site"
},
"viewSite": {
"message": "View Site",
"description": "View Site"
},
"launchWebsite": {
"message": "Launch Website",
"description": "Launch Website"
},
"website": {
"message": "Website",
"description": "Website"
},
"togglePassword": {
"message": "Toggle Password",
"description": "Toggle Password"
},
"manage": {
"message": "Manage",
"description": "Manage"
},
"other": {
"message": "Other",
"description": "Other"
},
"rateExtension": {
"message": "Rate the Extension",
"description": "Rate the Extension"
},
"browserNotSupportClipboard": {
"message": "Your web browser does not support easy clipboard copying. Copy it manually instead.",
"description": "Your web browser does not support easy clipboard copying. Copy it manually instead."
}
}

View File

@ -1,9 +1,10 @@
{
"manifest_version": 2,
"name": "bitwarden - Free Password Manager",
"short_name": "bitwarden",
"name": "__MSG_extName__",
"short_name": "__MSG_appName__",
"version": "1.1.0",
"description": "bitwarden is a secure and free password manager for all of your devices.",
"description": "__MSG_extDesc__",
"default_locale": "en",
"homepage_url": "https://bitwarden.com",
"icons": {
"16": "images/icon16.png",

View File

@ -2,7 +2,8 @@
.module('bit.accounts')
.controller('accountsHintController', function ($scope, $state, apiService, toastr, $q, utilsService,
$analytics) {
$analytics, i18nService) {
$scope.i18n = i18nService;
$scope.model = {};
utilsService.initListSectionItemListeners($(document), angular);

View File

@ -2,8 +2,9 @@
.module('bit.accounts')
.controller('accountsLoginController', function ($scope, $state, $stateParams, loginService, userService, toastr,
utilsService, $analytics) {
utilsService, $analytics, i18nService) {
utilsService.initListSectionItemListeners($(document), angular);
$scope.i18n = i18nService;
if ($stateParams.email) {
$('#master-password').focus();

View File

@ -2,7 +2,8 @@
.module('bit.accounts')
.controller('accountsLoginTwoFactorController', function ($scope, $state, loginService, toastr, utilsService,
$analytics) {
$analytics, i18nService) {
$scope.i18n = i18nService;
$scope.model = {};
utilsService.initListSectionItemListeners($(document), angular);
$('#code').focus();

View File

@ -1,8 +1,11 @@
angular
.module('bit.accounts')
.controller('accountsRegisterController', function ($scope, $state, cryptoService, toastr, $q, apiService, utilsService,
$analytics) {
.controller(
'accountsRegisterController',
function ($scope, $state, cryptoService, toastr, $q, apiService, utilsService, $analytics, i18nService) {
$scope.i18n = i18nService;
$scope.model = {};
utilsService.initListSectionItemListeners($(document), angular);
$('#email').focus();

View File

@ -4,10 +4,10 @@
<a ui-sref="login({animation: 'out-slide-right'})"><i class="fa fa-chevron-left"></i> Log In</a>
</div>
<div class="right">
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">Submit</button>
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">{{ i18n.submit }}</button>
<i class="fa fa-spinner fa-lg" ng-show="theForm.$loading" ng-class="{'fa-spin' : theForm.$loading}"></i>
</div>
<div class="title">Password Hint</div>
<div class="title">{{ i18n.passwordHint }}</div>
</div>
<div class="content">
<div class="list">
@ -15,12 +15,12 @@
<div class="list-section-items">
<div class="list-section-item list-section-item-icon-input">
<i class="fa fa-envelope fa-lg fa-fw"></i>
<label for="email" class="sr-only">Email Address</label>
<input id="email" type="text" name="Email" placeholder="Email Address" ng-model="model.email">
<label for="email" class="sr-only">{{ i18n.emailAddress }}</label>
<input id="email" type="text" name="Email" placeholder="{{ i18n.emailAddress }}" ng-model="model.email">
</div>
</div>
<div class="list-section-footer">
Enter your account email address to receive your master password hint.
{{ i18n.enterEmailToGetHint }}
</div>
</div>
</div>

View File

@ -1,13 +1,13 @@
<form name="theForm" ng-submit="login(model)" bit-form="loginPromise">
<div class="header">
<div class="left">
<a ui-sref="home({animation: 'out-slide-down'})">Cancel</a>
<a ui-sref="home({animation: 'out-slide-down'})">{{ i18n.cancel }}</a>
</div>
<div class="right">
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">Log In</button>
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">{{ i18n.login }}</button>
<i class="fa fa-spinner fa-lg" ng-show="theForm.$loading" ng-class="{'fa-spin' : theForm.$loading}"></i>
</div>
<div class="title">bitwarden</div>
<div class="title">{{ i18n.bitwarden }}</div>
</div>
<div class="content">
<div class="list">
@ -15,20 +15,20 @@
<div class="list-section-items">
<div class="list-section-item list-section-item-icon-input">
<i class="fa fa-envelope fa-lg fa-fw"></i>
<label for="email" class="sr-only">Email Address</label>
<input id="email" type="text" name="Email" placeholder="Email Address" ng-model="model.email">
<label for="email" class="sr-only">{{ i18n.emailAddress }}</label>
<input id="email" type="text" name="Email" placeholder="{{ i18n.emailAddress }}" ng-model="model.email">
</div>
<div class="list-section-item list-section-item-icon-input">
<i class="fa fa-lock fa-lg fa-fw"></i>
<label for="master-password" class="sr-only">Master Password</label>
<input id="master-password" type="password" name="MasterPassword" placeholder="Master Password"
<label for="master-password" class="sr-only">{{ i18n.masterPass }}</label>
<input id="master-password" type="password" name="MasterPassword" placeholder="{{ i18n.masterPass }}"
ng-model="model.masterPassword">
</div>
</div>
</div>
</div>
<p class="text-center text-accent">
<a ui-sref="hint({animation: 'in-slide-left'})">Get master password hint</a>
<a ui-sref="hint({animation: 'in-slide-left'})">{{ i18n.getMasterPasswordHint }}</a>
</p>
</div>
</form>

View File

@ -4,10 +4,10 @@
<a ui-sref="login({animation: 'out-slide-right'})"><i class="fa fa-chevron-left"></i> Log In</a>
</div>
<div class="right">
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">Continue</button>
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">{{ i18n.continue }}</button>
<i class="fa fa-spinner fa-lg" ng-show="theForm.$loading" ng-class="{'fa-spin' : theForm.$loading}"></i>
</div>
<div class="title">Verification Code</div>
<div class="title">{{ i18n.verificationCode }}</div>
</div>
<div class="content">
<div class="list">
@ -15,12 +15,12 @@
<div class="list-section-items">
<div class="list-section-item list-section-item-icon-input">
<i class="fa fa-lock fa-lg fa-fw"></i>
<label for="code" class="sr-only">Verification Code</label>
<input id="code" type="text" name="Code" placeholder="Verification Code" ng-model="model.code">
<label for="code" class="sr-only">{{ i18n.verificationCode }}</label>
<input id="code" type="text" name="Code" placeholder="{{ i18n.verificationCode }}" ng-model="model.code">
</div>
</div>
<div class="list-section-footer">
Enter your two-step verification code.
{{ i18n.enterTwoStepVerCode }}
</div>
</div>
</div>

View File

@ -1,13 +1,13 @@
<form name="theForm" ng-submit="submit(model)" bit-form="submitPromise">
<div class="header">
<div class="left">
<a ui-sref="home({animation: 'out-slide-down'})">Cancel</a>
<a ui-sref="home({animation: 'out-slide-down'})">{{ i18n.cancel }}</a>
</div>
<div class="right">
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">Submit</button>
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">{{ i18n.submit }}</button>
<i class="fa fa-spinner fa-lg" ng-show="theForm.$loading" ng-class="{'fa-spin' : theForm.$loading}"></i>
</div>
<div class="title">Create Account</div>
<div class="title">{{ i18n.createAccount }}</div>
</div>
<div class="content">
<div class="list">
@ -15,38 +15,37 @@
<div class="list-section-items">
<div class="list-section-item list-section-item-icon-input">
<i class="fa fa-envelope fa-lg fa-fw"></i>
<label for="email" class="sr-only">Email Address</label>
<input id="email" type="text" name="Email" placeholder="Email Address" ng-model="model.email">
<label for="email" class="sr-only">{{ i18n.emailAddress }}</label>
<input id="email" type="text" name="Email" placeholder="{{ i18n.emailAddress }}" ng-model="model.email">
</div>
<div class="list-section-item list-section-item-icon-input">
<i class="fa fa-lock fa-lg fa-fw"></i>
<label for="master-password" class="sr-only">Master Password</label>
<label for="master-password" class="sr-only">{{ i18n.masterPass }}</label>
<input id="master-password" type="password" name="MasterPassword"
placeholder="Master Password" ng-model="model.masterPassword">
placeholder="{{ i18n.masterPass }}" ng-model="model.masterPassword">
</div>
</div>
<div class="list-section-footer">
The master password is the password you use to access your vault. It is very important that you do not.
forget your master password. There is no way to recover the password in the event that you forget it.
{{ i18n.masterPassDesc }}
</div>
</div>
<div class="list-section">
<div class="list-section-items">
<div class="list-section-item list-section-item-icon-input">
<i class="fa fa-lock fa-lg fa-fw"></i>
<label for="master-password-retype" class="sr-only">Re-type Master Password</label>
<label for="master-password-retype" class="sr-only">{{ i18n.reTypeMasterPass }}</label>
<input id="master-password-retype" type="password" name="MasterPasswordRetype"
placeholder="Re-type Master Password" ng-model="model.masterPasswordRetype">
placeholder="{{ i18n.reTypeMasterPass }}" ng-model="model.masterPasswordRetype">
</div>
<div class="list-section-item list-section-item-icon-input">
<i class="fa fa-lightbulb-o fa-lg fa-fw"></i>
<label for="hint" class="sr-only">Master Password Hint (optional)</label>
<input id="hint" type="text" name="Hint" placeholder="Master Password Hint (optional)"
<label for="hint" class="sr-only">{{ i18n.masterPassHint }}</label>
<input id="hint" type="text" name="Hint" placeholder="{{ i18n.masterPassHint }}"
ng-model="model.hint">
</div>
</div>
<div class="list-section-footer">
A master password hint can help you remember your password if you forget it.
{{ i18n.masterPassHintDesc }}
</div>
</div>
</div>

View File

@ -2,7 +2,9 @@ angular
.module('bit.current')
.controller('currentController', function ($scope, siteService, tldjs, toastr, $q, $window, $state, autofillService,
$analytics) {
$analytics, i18nService) {
$scope.i18n = i18nService;
var pageDetails = null,
tabId = null,
url = null,
@ -51,7 +53,7 @@ angular
}
$scope.clipboardError = function (e, password) {
toastr.info('Your web browser does not support easy clipboard copying. Copy it manually instead.');
toastr.info(i18n.browserNotSupportClipboard);
};
$scope.clipboardSuccess = function (e, type) {

View File

@ -2,7 +2,7 @@
<div class="right">
<a href="" ng-click="addSite()"><i class="fa fa-plus fa-lg"></i></a>
</div>
<div class="title">Current Tab</div>
<div class="title">{{ i18n.currentTab }}</div>
</div>
<div class="content content-tabs">
<div ng-if="sites.length">
@ -10,13 +10,13 @@
<div class="list-grouped">
<a href="javascript:void(0)" ng-click="fillSite(site)" class="list-grouped-item condensed"
title="Auto-fill {{site.name}}" ng-repeat="site in theSites = (sites | orderBy: ['name', 'username'])">
<span class="btn-list" href="" ng-click="$event.stopPropagation()" title="Copy Password"
<span class="btn-list" href="" ng-click="$event.stopPropagation()" title="{{ i18n.copyPassword }}"
ngclipboard ngclipboard-error="clipboardError(e)"
ngclipboard-success="clipboardSuccess(e, 'Password')"
data-clipboard-text="{{site.password}}" ng-class="{'disabled': !site.password}">
<i class="fa fa-lg fa-key"></i>
</span>
<span class="btn-list" href="" ng-click="$event.stopPropagation()" title="Copy Username"
<span class="btn-list" href="" ng-click="$event.stopPropagation()" title="{{ i18n.copyUsername }}"
ngclipboard ngclipboard-error="clipboardError(e)"
ngclipboard-success="clipboardSuccess(e, 'Username')"
data-clipboard-text="{{site.username}}" ng-class="{'disabled': !site.username}">
@ -30,8 +30,8 @@
</div>
<div class="centered-message" ng-if="loaded && !sites.length">
<p>
There are no sites available to auto-fill for the current browser tab.
<button ng-click="addSite()" style="margin-top: 20px;" class="btn btn-link btn-block">Add a Site</button>
{{ i18n.autoFillInfo }}
<button ng-click="addSite()" style="margin-top: 20px;" class="btn btn-link btn-block">{{ i18n.addSite }}</button>
</p>
</div>
<div class="page-loading" ng-if="!loaded">

View File

@ -1,15 +1,15 @@
<div class="content">
<div class="home-page">
<img src="../../../../images/logo@3x.png" alt="bitwarden" />
<p>Log in or create a new account to access your secure vault.</p>
<p>{{ i18n.loginOrCreateNewAccount }}</p>
<div class="buttons">
<a class="btn btn-lg btn-primary btn-block" ui-sref="register({animation: 'in-slide-up'})"
analytics-on="click" analytics-event="Clicked Create Account">
<b>Create Account</b>
<b>{{ i18n.createAccount }}</b>
</a>
<a class="btn btn-lg btn-link btn-block" ui-sref="login({animation: 'in-slide-up'})"
analytics-on="click" analytics-event="Clicked Log In">
Log In
{{ i18n.login }}
</a>
</div>
</div>

View File

@ -1,6 +1,6 @@
angular
.module('bit.global')
.controller('homeController', function ($scope) {
.controller('homeController', function ($scope, i18nService) {
$scope.i18n = i18nService;
});

View File

@ -2,16 +2,16 @@
<div class="tabs" ng-controller="tabsController">
<ul>
<li ng-class="{active: $state.includes('tabs.current')}">
<a ui-sref="tabs.current"><i class="fa fa-folder fa-2x"></i> Tab</a>
<a ui-sref="tabs.current"><i class="fa fa-folder fa-2x"></i>{{ i18n.tab }}</a>
</li>
<li ng-class="{active: $state.includes('tabs.vault')}">
<a ui-sref="tabs.vault"><i class="fa fa-lock fa-2x"></i> My Vault</a>
<a ui-sref="tabs.vault"><i class="fa fa-lock fa-2x"></i>{{ i18n.myVault }}</a>
</li>
<li ng-class="{active: $state.includes('tabs.tools')}">
<a ui-sref="tabs.tools"><i class="fa fa-wrench fa-2x"></i> Tools</a>
<a ui-sref="tabs.tools"><i class="fa fa-wrench fa-2x"></i>{{ i18n.tools }}</a>
</li>
<li ng-class="{active: $state.includes('tabs.settings')}">
<a ui-sref="tabs.settings"><i class="fa fa-cogs fa-2x"></i> Settings</a>
<a ui-sref="tabs.settings"><i class="fa fa-cogs fa-2x"></i>{{ i18n.settings }}</a>
</li>
</ul>
</div>

View File

@ -1,6 +1,7 @@
angular
.module('bit.global')
.controller('tabsController', function ($scope, $state) {
.controller('tabsController', function ($scope, $state, i18nService) {
$scope.$state = $state;
$scope.i18n = i18nService;
});

View File

@ -0,0 +1,92 @@
angular
.module('bit.services')
.factory('i18nService', function () {
return {
loginOrCreateNewAccount: chrome.i18n.getMessage("loginOrCreateNewAccount"),
createAccount: chrome.i18n.getMessage("createAccount"),
login: chrome.i18n.getMessage("login"),
cancel: chrome.i18n.getMessage("cancel"),
submit: chrome.i18n.getMessage("submit"),
emailAddress: chrome.i18n.getMessage("emailAddress"),
masterPass: chrome.i18n.getMessage("masterPass"),
masterPassDesc: chrome.i18n.getMessage("masterPassDesc"),
reTypeMasterPass: chrome.i18n.getMessage("reTypeMasterPass"),
masterPassHint: chrome.i18n.getMessage("masterPassHint"),
masterPassHintDesc: chrome.i18n.getMessage("masterPassHintDesc"),
tab: chrome.i18n.getMessage("tab"),
myVault: chrome.i18n.getMessage("myVault"),
tools: chrome.i18n.getMessage("tools"),
settings: chrome.i18n.getMessage("settings"),
currentTab: chrome.i18n.getMessage("currentTab"),
copyPassword: chrome.i18n.getMessage("copyPassword"),
copyUsername: chrome.i18n.getMessage("copyUsername"),
autoFillInfo: chrome.i18n.getMessage("autoFillInfo"),
addSite: chrome.i18n.getMessage("addSite"),
passwordHint: chrome.i18n.getMessage("passwordHint"),
enterEmailToGetHint: chrome.i18n.getMessage("enterEmailToGetHint"),
getMasterPasswordHint: chrome.i18n.getMessage("getMasterPasswordHint"),
continue: chrome.i18n.getMessage("continue"),
verificationCode: chrome.i18n.getMessage("verificationCode"),
enterTwoStepVerCode: chrome.i18n.getMessage("enterTwoStepVerCode"),
account: chrome.i18n.getMessage("account"),
changeMasterPassword: chrome.i18n.getMessage("changeMasterPassword"),
changeEmail: chrome.i18n.getMessage("changeEmail"),
twoStepLogin: chrome.i18n.getMessage("twoStepLogin"),
logOut: chrome.i18n.getMessage("logOut"),
about: chrome.i18n.getMessage("about"),
version: chrome.i18n.getMessage("version"),
save: chrome.i18n.getMessage("save"),
addFolder: chrome.i18n.getMessage("addFolder"),
name: chrome.i18n.getMessage("name"),
editFolder: chrome.i18n.getMessage("editFolder"),
deleteFolder: chrome.i18n.getMessage("deleteFolder"),
folders: chrome.i18n.getMessage("folders"),
noFolders: chrome.i18n.getMessage("noFolders"),
helpFeedback: chrome.i18n.getMessage("helpFeedback"),
emailUs: chrome.i18n.getMessage("emailUs"),
emailUsDirectly: chrome.i18n.getMessage("emailUsDirectly"),
visitOurWebsite: chrome.i18n.getMessage("visitOurWebsite"),
visitOurWebsiteDirectly: chrome.i18n.getMessage("visitOurWebsiteDirectly"),
fileBugReport: chrome.i18n.getMessage("fileBugReport"),
gitHubIssue: chrome.i18n.getMessage("gitHubIssue"),
sync: chrome.i18n.getMessage("sync"),
syncVaultNow: chrome.i18n.getMessage("syncVaultNow"),
lastSync: chrome.i18n.getMessage("lastSync"),
passGen: chrome.i18n.getMessage("passGen"),
passGenInfo: chrome.i18n.getMessage("passGenInfo"),
bitWebVault: chrome.i18n.getMessage("bitWebVault"),
bitWebVaultInfo: chrome.i18n.getMessage("bitWebVaultInfo"),
bitIosVault: chrome.i18n.getMessage("bitIosVault"),
bitIosVaultInfo: chrome.i18n.getMessage("bitIosVaultInfo"),
bitAndrVault: chrome.i18n.getMessage("bitAndrVault"),
bitAndrVaultInfo: chrome.i18n.getMessage("bitAndrVaultInfo"),
importLogins: chrome.i18n.getMessage("importLogins"),
importLoginsInfo: chrome.i18n.getMessage("importLoginsInfo"),
select: chrome.i18n.getMessage("select"),
generatePassword: chrome.i18n.getMessage("generatePassword"),
regeneratePassword: chrome.i18n.getMessage("regeneratePassword"),
options: chrome.i18n.getMessage("options"),
length: chrome.i18n.getMessage("length"),
minNumbers: chrome.i18n.getMessage("minNumbers"),
minSpecial: chrome.i18n.getMessage("minSpecial"),
avoidAmbChar: chrome.i18n.getMessage("avoidAmbChar"),
searchVault: chrome.i18n.getMessage("searchVault"),
edit: chrome.i18n.getMessage("edit"),
noSitesInList: chrome.i18n.getMessage("noSitesInList"),
siteInformation: chrome.i18n.getMessage("siteInformation"),
username: chrome.i18n.getMessage("username"),
password: chrome.i18n.getMessage("password"),
favorite: chrome.i18n.getMessage("favorite"),
notes: chrome.i18n.getMessage("notes"),
editSite: chrome.i18n.getMessage("editSite"),
folder: chrome.i18n.getMessage("folder"),
deleteSite: chrome.i18n.getMessage("deleteSite"),
viewSite: chrome.i18n.getMessage("viewSite"),
launchWebsite: chrome.i18n.getMessage("launchWebsite"),
website: chrome.i18n.getMessage("website"),
togglePassword: chrome.i18n.getMessage("togglePassword"),
rateExtension: chrome.i18n.getMessage("rateExtension"),
browserNotSupportClipboard: chrome.i18n.getMessage("browserNotSupportClipboard")
};
});

View File

@ -1,7 +1,8 @@
angular
.module('bit.settings')
.controller('settingsAboutController', function ($scope) {
.controller('settingsAboutController', function ($scope, i18nService) {
$scope.i18n = i18nService;
$scope.year = (new Date()).getFullYear();
$scope.version = chrome.runtime.getManifest().version;
});

View File

@ -2,7 +2,8 @@ angular
.module('bit.settings')
.controller('settingsAddFolderController', function ($scope, $q, folderService, $state, toastr, utilsService,
$analytics) {
$analytics, i18nService) {
$scope.i18n = i18nService;
$scope.folder = {};
utilsService.initListSectionItemListeners($(document), angular);
$('#name').focus();

View File

@ -1,7 +1,8 @@
angular
.module('bit.settings')
.controller('settingsController', function ($scope, loginService, $state, SweetAlert, utilsService, $analytics) {
.controller('settingsController', function ($scope, loginService, $state, SweetAlert, utilsService, $analytics, i18nService) {
$scope.i18n = i18nService;
$scope.logOut = function () {
SweetAlert.swal({
title: 'Log Out',

View File

@ -2,7 +2,8 @@
.module('bit.settings')
.controller('settingsEditFolderController', function ($scope, $stateParams, folderService, toastr, $q, $state, SweetAlert,
utilsService, $analytics) {
utilsService, $analytics, i18nService) {
$scope.i18n = i18nService;
$scope.folder = {};
var folderId = $stateParams.folderId;

View File

@ -1,7 +1,8 @@
angular
.module('bit.settings')
.controller('settingsFoldersController', function ($scope, folderService, $q, $state) {
.controller('settingsFoldersController', function ($scope, folderService, $q, $state, i18nService) {
$scope.i18n = i18nService;
$scope.loaded = false;
load();

View File

@ -1,7 +1,8 @@
angular
.module('bit.settings')
.controller('settingsHelpController', function ($scope, $analytics) {
.controller('settingsHelpController', function ($scope, $analytics, i18nService) {
$scope.i18n = i18nService;
$scope.email = function () {
$analytics.eventTrack('Selected Help Email');
chrome.tabs.create({ url: 'mailto:hello@bitwarden.com' });

View File

@ -1,7 +1,8 @@
angular
.module('bit.settings')
.controller('settingsSyncController', function ($scope, syncService, toastr, $analytics) {
.controller('settingsSyncController', function ($scope, syncService, toastr, $analytics, i18nService) {
$scope.i18n = i18nService;
$scope.lastSync = '--';
$scope.loading = false;
setLastSync();

View File

@ -1,60 +1,60 @@
<div class="header">
<div class="title">Settings</div>
<div class="title">{{ i18n.settings }}</div>
</div>
<div class="content content-tabs">
<div class="list">
<div class="list-section">
<div class="list-section-header">
Account
{{ i18n.account }}
</div>
<div class="list-section-items">
<a class="list-section-item" href="" ng-click="changePassword()">
Change Master Password
{{ i18n.changeMasterPassword }}
<i class="fa fa-chevron-right fa-lg"></i>
</a>
<a class="list-section-item" href="" ng-click="changeEmail()">
Change Email
{{ i18n.changeEmail }}
<i class="fa fa-chevron-right fa-lg"></i>
</a>
<a class="list-section-item" href="" ng-click="twoStep()">
Two-step Login
{{ i18n.twoStepLogin }}
<i class="fa fa-chevron-right fa-lg"></i>
</a>
<a class="list-section-item" href="" ng-click="logOut()">
Log Out
{{ i18n.logOut }}
</a>
</div>
</div>
<div class="list-section">
<div class="list-section-header">
Manage
{{ i18n.manage }}
</div>
<div class="list-section-items">
<a class="list-section-item" ui-sref="folders({animation: 'in-slide-left'})">
Folders
{{ i18n.folders }}
<i class="fa fa-chevron-right fa-lg"></i>
</a>
<a class="list-section-item" ui-sref="sync({animation: 'in-slide-left'})">
Sync
{{ i18n.sync }}
<i class="fa fa-chevron-right fa-lg"></i>
</a>
</div>
</div>
<div class="list-section">
<div class="list-section-header">
Other
{{ i18n.other }}
</div>
<div class="list-section-items">
<a class="list-section-item" ui-sref="about({animation: 'in-slide-left'})">
About
{{ i18n.about }}
<i class="fa fa-chevron-right fa-lg"></i>
</a>
<a class="list-section-item" ui-sref="help({animation: 'in-slide-left'})">
Help &amp; Feedback
{{ i18n.helpFeedback }}
<i class="fa fa-chevron-right fa-lg"></i>
</a>
<a class="list-section-item" href="" ng-click="rate()">
Rate the Extension
{{ i18n.rateExtension }}
<i class="fa fa-chevron-right fa-lg"></i>
</a>
</div>

View File

@ -1,13 +1,13 @@
<div class="header">
<div class="left">
<a ui-sref="tabs.settings({animation: 'out-slide-right'})"><i class="fa fa-chevron-left"></i> Settings</a>
<a ui-sref="tabs.settings({animation: 'out-slide-right'})"><i class="fa fa-chevron-left"></i>{{ i18n.settings }}</a>
</div>
<div class="title">About</div>
<div class="title">{{ i18n.about }}</div>
</div>
<div class="content">
<div class="about-page">
<img src="../../../../images/logo@3x.png" alt="bitwarden" />
Version {{version}}<br />
{{ i18n.version }} {{version}}<br />
&copy; 8bit Solutions LLC 2015-{{year}}
</div>
</div>

View File

@ -1,20 +1,20 @@
<form name="theForm" ng-submit="save(folder)" bit-form="savePromise">
<div class="header">
<div class="left">
<a ui-sref="folders({animation: 'out-slide-down'})">Cancel</a>
<a ui-sref="folders({animation: 'out-slide-down'})">{{ i18n.cancel }}</a>
</div>
<div class="right">
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">Save</button>
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">{{ i18n.save }}</button>
<i class="fa fa-spinner fa-lg" ng-show="theForm.$loading" ng-class="{'fa-spin' : theForm.$loading}"></i>
</div>
<div class="title">Add Folder</div>
<div class="title">{{ i18n.addFolder }}</div>
</div>
<div class="content">
<div class="list">
<div class="list-section">
<div class="list-section-items">
<div class="list-section-item">
<label for="name" class="item-label">Name</label>
<label for="name" class="item-label">{{ i18n.name }}</label>
<input id="name" type="text" name="Name" ng-model="folder.name">
</div>
</div>

View File

@ -1,20 +1,20 @@
<form name="theForm" ng-submit="save(folder)" bit-form="savePromise">
<div class="header">
<div class="left">
<a ui-sref="folders({animation: 'out-slide-down'})">Cancel</a>
<a ui-sref="folders({animation: 'out-slide-down'})">{{ i18n.cancel }}</a>
</div>
<div class="right">
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">Save</button>
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">{{ i18n.save }}</button>
<i class="fa fa-spinner fa-lg" ng-show="theForm.$loading" ng-class="{'fa-spin' : theForm.$loading}"></i>
</div>
<div class="title">Edit Folder</div>
<div class="title">{{ i18n.editFolder }}</div>
</div>
<div class="content">
<div class="list">
<div class="list-section">
<div class="list-section-items">
<div class="list-section-item">
<label for="name" class="item-label">Name</label>
<label for="name" class="item-label">{{ i18n.name }}</label>
<input id="name" type="text" name="Name" ng-model="folder.name">
</div>
</div>
@ -22,7 +22,7 @@
<div class="list-section">
<div class="list-section-items">
<a href="" ng-click="delete()" class="list-section-item text-danger">
<i class="fa fa-trash fa-fw fa-lg"></i> Delete Folder
<i class="fa fa-trash fa-fw fa-lg"></i>{{ i18n.deleteFolder }}
</a>
</div>
</div>

View File

@ -1,6 +1,6 @@
<div class="header">
<div class="left">
<a ui-sref="tabs.settings({animation: 'out-slide-right'})"><i class="fa fa-chevron-left"></i> Settings</a>
<a ui-sref="tabs.settings({animation: 'out-slide-right'})"><i class="fa fa-chevron-left"></i>{{ i18n.settings }}</a>
</div>
<div class="right">
<a ui-sref="addFolder({animation: 'in-slide-up'})"><i class="fa fa-plus fa-lg"></i></a>
@ -20,9 +20,9 @@
</div>
<div class="centered-message" ng-if="loaded && !folders.length">
<p>
There are no folders to list.
{{ i18n.noFolders }}
<a ui-sref="addFolder({animation: 'in-slide-up'})" style="margin-top: 20px;"
class="btn btn-link btn-block">Add a Folder</a>
class="btn btn-link btn-block">{{ i18n.addFolder }}</a>
</p>
</div>
<div class="page-loading" ng-if="!loaded">

View File

@ -1,42 +1,42 @@
<div class="header">
<div class="left">
<a ui-sref="tabs.settings({animation: 'out-slide-right'})"><i class="fa fa-chevron-left"></i> Settings</a>
<a ui-sref="tabs.settings({animation: 'out-slide-right'})"><i class="fa fa-chevron-left"></i>{{ i18n.settings }}</a>
</div>
<div class="title">Help and Feedback</div>
<div class="title">{{ i18n.helpFeedback }}</div>
</div>
<div class="content">
<div class="list">
<div class="list-section">
<div class="list-section-items">
<a class="list-section-item" href="" ng-click="email()">
Email Us
{{ i18n.emailUs }}
<i class="fa fa-chevron-right fa-lg"></i>
</a>
</div>
<div class="list-section-footer">
Email us directly to get help or leave feedback.
{{ i18n.emailUsDirectly }}
</div>
</div>
<div class="list-section">
<div class="list-section-items">
<a class="list-section-item" href="" ng-click="website()">
Visit Our Website
{{ i18n.visitOurWebsite }}
<i class="fa fa-chevron-right fa-lg"></i>
</a>
</div>
<div class="list-section-footer">
Visit our website to get help, news, email us, and/or learn more about how to use bitwarden.
{{ i18n.visitOurWebsiteDirectly }}
</div>
</div>
<div class="list-section">
<div class="list-section-items">
<a class="list-section-item" href="" ng-click="bug()">
File a Bug Report
{{ i18n.fileBugReport }}
<i class="fa fa-chevron-right fa-lg"></i>
</a>
</div>
<div class="list-section-footer">
Open an issue at our GitHub repository.
{{ i18n.gitHubIssue }}
</div>
</div>
</div>

View File

@ -1,16 +1,16 @@
<div class="header">
<div class="left">
<a ui-sref="tabs.settings({animation: 'out-slide-right'})"><i class="fa fa-chevron-left"></i> Settings</a>
<a ui-sref="tabs.settings({animation: 'out-slide-right'})"><i class="fa fa-chevron-left"></i>{{ i18n.settings }}</a>
</div>
<div class="title">Sync</div>
<div class="title">{{ i18n.sync }}</div>
</div>
<div class="content">
<div class="centered-message">
<p style="margin-top: -50px;">
<a href="" class="btn btn-lg btn-link btn-block" ng-click="sync()">
Sync Vault Now
{{ i18n.syncVaultNow }}
</a>
<small class="text-muted">Last Sync: {{lastSync}}</small>
<small class="text-muted">{{ i18n.lastSync }} {{lastSync}}</small>
<span ng-show="loading" style="display: block; margin-top: 20px;">
<i class="text-muted fa fa-lg fa-spinner fa-spin"></i>
</span>

View File

@ -1,7 +1,8 @@
angular
.module('bit.tools')
.controller('toolsController', function ($scope, SweetAlert) {
.controller('toolsController', function ($scope, SweetAlert, i18nService) {
$scope.i18n = i18nService;
$scope.launchWebVault = function () {
chrome.tabs.create({ url: 'https://vault.bitwarden.com' });
};

View File

@ -2,7 +2,8 @@
.module('bit.tools')
.controller('toolsPasswordGeneratorController', function ($scope, $state, $stateParams, passwordGenerationService,
toastr, $q, utilsService, $analytics) {
toastr, $q, utilsService, $analytics, i18nService) {
$scope.i18n = i18nService;
var addState = $stateParams.addState,
editState = $stateParams.editState;
@ -62,7 +63,7 @@
};
$scope.clipboardError = function (e, password) {
toastr.info('Your web browser does not support easy clipboard copying. Copy it manually instead.');
toastr.info(i18n.browserNotSupportClipboard);
};
$scope.clipboardSuccess = function (e) {

View File

@ -1,5 +1,5 @@
<div class="header">
<div class="title">Tools</div>
<div class="title">{{ i18n.tools }}</div>
</div>
<div class="content content-tabs">
<div class="list">
@ -7,28 +7,28 @@
<div class="list-section-items">
<a class="list-section-item wrap" href="" ui-sref="passwordGenerator({animation: 'in-slide-up'})">
<span class="leading-icon" style="color: #eba776;"><i class="fa fa-refresh fa-fw"></i></span>
<span class="text">Password Generator</span>
<span class="detail">Automatically generate strong, unique passwords for your logins.</span>
<span class="text">{{ i18n.passGen }}</span>
<span class="detail">{{ i18n.passGenInfo }}</span>
</a>
<a class="list-section-item wrap" href="" ng-click="launchWebVault()">
<span class="leading-icon" style="color: #5bb630;"><i class="fa fa-globe fa-fw"></i></span>
<span class="text">bitwarden Web Vault</span>
<span class="detail">Manage your logins from any web browser with the bitwarden web vault.</span>
<span class="text">{{ i18n.bitWebVault }}</span>
<span class="detail">{{ i18n.bitWebVaultInfo }}</span>
</a>
<a class="list-section-item wrap" href="" ng-click="launchiOS()">
<span class="leading-icon" style="color: #999999;"><i class="fa fa-apple fa-fw"></i></span>
<span class="text">bitwarden iOS Vault</span>
<span class="detail">Manage your logins from your mobile devices with the bitwarden iOS vault.</span>
<span class="text">{{ i18n.bitIosVault }}</span>
<span class="detail">{{ i18n.bitIosVaultInfo }}</span>
</a>
<a class="list-section-item wrap" href="" ng-click="launchAndroid()">
<span class="leading-icon" style="color: #a4c639;"><i class="fa fa-android fa-fw"></i></span>
<span class="text">bitwarden Android Vault</span>
<span class="detail">Manage your logins from your mobile devices with the bitwarden Android vault.</span>
<span class="text">{{ i18n.bitAndrVault }}</span>
<span class="detail">{{ i18n.bitAndrVaultInfo }}</span>
</a>
<a class="list-section-item wrap" href="" ng-click="launchImport()">
<span class="leading-icon" style="color: #6fc2ff;"><i class="fa fa-cloud-upload fa-fw"></i></span>
<span class="text">Import Logins</span>
<span class="detail">Quickly bulk import your logins from other password management applications.</span>
<span class="text">{{ i18n.importLogins }}</span>
<span class="detail">{{ i18n.importLoginsInfo }}</span>
</a>
</div>
</div>

View File

@ -3,9 +3,9 @@
<a ng-click="close()" href="">Close</a>
</div>
<div class="right">
<a ng-click="select()" ng-show="showSelect" href="">Select</a>
<a ng-click="select()" ng-show="showSelect" href="">{{ i18n.select }}</a>
</div>
<div class="title">Generate Password</div>
<div class="title">{{ i18n.generatePassword }}</div>
</div>
<div class="content">
<div class="generate-password-block" id="generated-password">
@ -15,21 +15,21 @@
<div class="list-section" style="padding-top: 0;">
<div class="list-section-items">
<a class="list-section-item text-primary" href="" ng-click="regenerate(true)">
Regenerate Password
{{ i18n.regeneratePassword }}
</a>
<a class="list-section-item text-primary" href="" ngclipboard ngclipboard-error="clipboardError(e)"
ngclipboard-success="clipboardSuccess(e)" data-clipboard-target="#generated-password">
Copy Password
{{ i18n.copyPassword }}
</a>
</div>
</div>
<div class="list-section">
<div class="list-section-header">
Options
{{ i18n.options }}
</div>
<div class="list-section-items">
<div class="list-section-item list-section-item-slider">
<label for="length">Length</label>
<label for="length">{{ i18n.length }}</label>
<span class="slider-value">{{slider.value}}</span>
<rzslider rz-slider-model="slider.value"
rz-slider-options="slider.options"></rzslider>
@ -55,12 +55,12 @@
<div class="list-section">
<div class="list-section-items">
<div class="list-section-item list-section-item-input">
<label for="min-numbers">Minimum Numbers</label>
<label for="min-numbers">{{ i18n.minNumbers }}</label>
<input id="min-numbers" type="number" min="0" max="5" ng-model="options.minNumber"
ng-change="saveOptions(options)">
</div>
<div class="list-section-item list-section-item-input">
<label for="min-special">Minimum Special</label>
<label for="min-special">{{ i18n.minSpecial</label>
<input id="min-special" type="number" min="0" max="5" ng-model="options.minSpecial"
ng-change="saveOptions(options)">
</div>
@ -69,7 +69,7 @@
<div class="list-section">
<div class="list-section-items">
<div class="list-section-item list-section-item-checkbox">
<label for="ambiguous">Avoid Ambiguous Characters</label>
<label for="ambiguous">{{ i18n.avoidAmbChar }}</label>
<input id="ambiguous" type="checkbox" ng-model="options.ambiguous" ng-change="saveOptions(options)">
</div>
</div>

View File

@ -2,7 +2,8 @@
.module('bit.vault')
.controller('vaultAddSiteController', function ($scope, $state, $stateParams, siteService, folderService,
cryptoService, $q, toastr, utilsService, $analytics) {
cryptoService, $q, toastr, utilsService, $analytics, i18nService) {
$scope.i18n = i18nService;
var returnScrollY = $stateParams.returnScrollY;
var returnSearchText = $stateParams.returnSearchText;
var fromCurrent = $stateParams.fromCurrent || $stateParams.uri !== null;

View File

@ -2,7 +2,8 @@
.module('bit.vault')
.controller('vaultController', function ($scope, $rootScope, siteService, folderService, $q, $state, $stateParams, toastr,
syncService, utilsService, $analytics) {
syncService, utilsService, $analytics, i18nService) {
$scope.i18n = i18nService;
$('#search').focus();
var syncOnLoad = $stateParams.syncOnLoad;
@ -109,7 +110,7 @@
};
$scope.clipboardError = function (e) {
toastr.info('Your web browser does not support easy clipboard copying. Copy it manually instead.');
toastr.info(i18n.browserNotSupportClipboard);
};
$scope.clipboardSuccess = function (e, type) {

View File

@ -2,7 +2,8 @@ angular
.module('bit.vault')
.controller('vaultEditSiteController', function ($scope, $state, $stateParams, siteService, folderService,
cryptoService, $q, toastr, SweetAlert, utilsService, $analytics) {
cryptoService, $q, toastr, SweetAlert, utilsService, $analytics, i18nService) {
$scope.i18n = i18nService;
var returnScrollY = $stateParams.returnScrollY;
var returnSearchText = $stateParams.returnSearchText;
var siteId = $stateParams.siteId;

View File

@ -2,7 +2,8 @@ angular
.module('bit.vault')
.controller('vaultViewSiteController', function ($scope, $state, $stateParams, siteService, tldjs, toastr, $q,
$analytics) {
$analytics, i18nService) {
$scope.i18n = i18nService;
var returnScrollY = $stateParams.returnScrollY;
var returnSearchText = $stateParams.returnSearchText;
@ -66,7 +67,7 @@ angular
};
$scope.clipboardError = function (e, password) {
toastr.info('Your web browser does not support easy clipboard copying. Copy it manually instead.');
toastr.info(i18n.browserNotSupportClipboard);
};
$scope.clipboardSuccess = function (e, type) {

View File

@ -3,7 +3,7 @@
<a href="" ng-click="addSite()"><i class="fa fa-plus fa-lg"></i></a>
</div>
<div class="search">
<input type="search" placeholder="Search vault" ng-model="searchText" id="search" />
<input type="search" placeholder="{{ i18n.searchVault }}" ng-model="searchText" id="search" />
<i class="fa fa-search"></i>
</div>
</div>
@ -16,7 +16,7 @@
<i class="fa fa-folder-open"></i> {{folder.name}}
</div>
<a href="javascript:void(0)" ng-click="viewSite(site)"
class="list-grouped-item condensed" title="Edit {{site.name}}"
class="list-grouped-item condensed" title="{{ i18n.edit }} {{site.name}}"
ng-repeat="site in folderSites = (vaultSites | filter: { folderId: folder.id }
| filter: searchSites() | orderBy: ['name', 'username'])">
<span class="btn-list" ng-click="$event.stopPropagation()" title="Copy Password" ngclipboard
@ -24,7 +24,7 @@
data-clipboard-text="{{site.password}}" ng-class="{'disabled': !site.password}">
<i class="fa fa-lg fa-key"></i>
</span>
<span class="btn-list" ng-click="$event.stopPropagation()" title="Copy Username" ngclipboard
<span class="btn-list" ng-click="$event.stopPropagation()" title="{{ i18n.copyUsername }}" ngclipboard
ngclipboard-error="clipboardError(e)" ngclipboard-success="clipboardSuccess(e, 'Username')"
data-clipboard-text="{{site.username}}" ng-class="{'disabled': !site.username}">
<i class="fa fa-lg fa-user"></i>
@ -38,8 +38,8 @@
</div>
<div class="centered-message" ng-if="loaded && !vaultSites.length">
<p>
There are no sites to list.
<button ng-click="addSite()" style="margin-top: 20px;" class="btn btn-link btn-block">Add a Site</button>
{{ i18n.noSitesInList }}
<button ng-click="addSite()" style="margin-top: 20px;" class="btn btn-link btn-block">{{ i18n.addSite }}</button>
</p>
</div>
<div class="page-loading" ng-if="!loaded">

View File

@ -1,23 +1,23 @@
<form name="theForm" ng-submit="save(site)" bit-form="savePromise">
<div class="header">
<div class="left">
<a ng-click="close()" href="">Cancel</a>
<a ng-click="close()" href="">{{ i18n.cancel }}</a>
</div>
<div class="right">
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">Save</button>
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">{{ i18n.save }}</button>
<i class="fa fa-spinner fa-lg" ng-show="theForm.$loading" ng-class="{'fa-spin' : theForm.$loading}"></i>
</div>
<div class="title">Add Site</div>
<div class="title">{{ i18n.addSite }}</div>
</div>
<div class="content">
<div class="list">
<div class="list-section">
<div class="list-section-header">
Site Information
{{ i18n.siteInformation }}
</div>
<div class="list-section-items">
<div class="list-section-item">
<label for="name" class="item-label">Name</label>
<label for="name" class="item-label">{{ i18n.name }}</label>
<input id="name" type="text" name="Name" ng-model="site.name">
</div>
<div class="list-section-item">
@ -25,15 +25,15 @@
<input id="uri" type="text" name="Uri" ng-model="site.uri">
</div>
<div class="list-section-item">
<label for="username" class="item-label">Username</label>
<label for="username" class="item-label">{{ i18n.username }}</label>
<input id="username" type="text" name="Username" ng-model="site.username">
</div>
<div class="list-section-item">
<label for="password" class="item-label">Password</label>
<label for="password" class="item-label">{{ i18n.password }}</label>
<input id="password" type="password" name="Password" ng-model="site.password">
</div>
<a class="list-section-item" href="" ng-click="generatePassword()">
Generate Password
{{ i18n.generatePassword }}
<i class="fa fa-chevron-right"></i>
</a>
</div>
@ -49,14 +49,14 @@
</select>
</div>
<div class="list-section-item list-section-item-checkbox">
<label for="favorite">Favorite</label>
<label for="favorite">{{ i18n.favorite }}</label>
<input id="favorite" name="Favorite" type="checkbox" ng-model="site.favorite">
</div>
</div>
</div>
<div class="list-section">
<div class="list-section-header">
<label for="notes">Notes</label>
<label for="notes">{{ i18n.notes }}</label>
</div>
<div class="list-section-items">
<div class="list-section-item">

View File

@ -1,23 +1,23 @@
<form name="theForm" ng-submit="save(site)" bit-form="savePromise">
<div class="header">
<div class="left">
<a ng-click="close()" href="">Cancel</a>
<a ng-click="close()" href="">{{ i18n.cancel }}</a>
</div>
<div class="right">
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">Save</button>
<button type="submit" class="btn btn-link" ng-show="!theForm.$loading">{{ i18n.save }}</button>
<i class="fa fa-spinner fa-lg" ng-show="theForm.$loading" ng-class="{'fa-spin' : theForm.$loading}"></i>
</div>
<div class="title">Edit Site</div>
<div class="title">{{ i18n.editSite }}</div>
</div>
<div class="content">
<div class="list">
<div class="list-section">
<div class="list-section-header">
Site Information
{{ i18n.siteInformation }}
</div>
<div class="list-section-items">
<div class="list-section-item">
<label for="name" class="item-label">Name</label>
<label for="name" class="item-label">{{ i18n.name }}</label>
<input id="name" type="text" name="Name" ng-model="site.name">
</div>
<div class="list-section-item">
@ -25,15 +25,15 @@
<input id="uri" type="text" name="Uri" ng-model="site.uri">
</div>
<div class="list-section-item">
<label for="username" class="item-label">Username</label>
<label for="username" class="item-label">{{ i18n.username }}</label>
<input id="username" type="text" name="Username" ng-model="site.username">
</div>
<div class="list-section-item">
<label for="password" class="item-label">Password</label>
<label for="password" class="item-label">{{ i18n.password }}</label>
<input id="password" type="password" name="Password" ng-model="site.password">
</div>
<a class="list-section-item" href="" ng-click="generatePassword()">
Generate Password
{{ i18n.generatePassword }}
<i class="fa fa-chevron-right"></i>
</a>
</div>
@ -41,7 +41,7 @@
<div class="list-section">
<div class="list-section-items">
<div class="list-section-item">
<label for="folder" class="item-label">Folder</label>
<label for="folder" class="item-label">{{ i18n.folder }}</label>
<select id="folder" name="FolderId" ng-model="site.folderId">
<option ng-repeat="folder in folders | orderBy: ['name']" value="{{folder.id}}">
{{folder.name}}
@ -49,14 +49,14 @@
</select>
</div>
<div class="list-section-item list-section-item-checkbox">
<label for="favorite">Favorite</label>
<label for="favorite">{{ i18n.favorite }}</label>
<input id="favorite" name="Favorite" type="checkbox" ng-model="site.favorite">
</div>
</div>
</div>
<div class="list-section">
<div class="list-section-header">
<label for="notes">Notes</label>
<label for="notes">{{ i18n.notes }}</label>
</div>
<div class="list-section-items">
<div class="list-section-item">
@ -67,7 +67,7 @@
<div class="list-section">
<div class="list-section-items">
<a href="" ng-click="delete()" class="list-section-item text-danger">
<i class="fa fa-trash fa-fw fa-lg"></i> Delete Site
<i class="fa fa-trash fa-fw fa-lg"></i> {{ i18n.deleteSite }}
</a>
</div>
</div>

View File

@ -1,48 +1,48 @@
<div class="header">
<div class="left">
<a href="" ng-click="close()">Close</a>
<a href="" ng-click="close()">{{ i18n.close }}</a>
</div>
<div class="right">
<a href="" ng-click="edit(site)">Edit</a>
<a href="" ng-click="edit(site)">{{ i18n.edit }}</a>
</div>
<div class="title">View Site</div>
<div class="title">{{ i18n.viewSite }}</div>
</div>
<div class="content">
<div class="list list-no-selection">
<div class="list-section">
<div class="list-section-header">
Site Information
{{ i18n.siteInformation }}
</div>
<div class="list-section-items">
<div class="list-section-item">
<span class="item-label">Name</span>
<span class="item-label">{{ i18n.name }}</span>
{{site.name}}
</div>
<div class="list-section-item" ng-if="site.uri">
<a class="btn-list" href="" title="Launch Website" ng-click="launchWebsite(site)"
<a class="btn-list" href="" title="{{ i18n.launchWebsite }}" ng-click="launchWebsite(site)"
ng-show="site.showLaunch">
<i class="fa fa-lg fa-share-square-o"></i>
</a>
<span class="item-label">Website</span>
<span class="item-label">{{ i18n.website }}</span>
{{site.website}}
</div>
<div class="list-section-item" ng-if="site.username">
<a class="btn-list" href="" title="Copy Username" ngclipboard ngclipboard-error="clipboardError(e)"
<a class="btn-list" href="" title="{{ i18n.copyUsername }}" ngclipboard ngclipboard-error="clipboardError(e)"
ngclipboard-success="clipboardSuccess(e, 'Username')" data-clipboard-target="#username">
<i class="fa fa-lg fa-clipboard"></i>
</a>
<span class="item-label">Username</span>
<span class="item-label">{{ i18n.username }}</span>
<span id="username" class="monospaced">{{site.username}}</span>
</div>
<div class="list-section-item" ng-if="site.password">
<a class="btn-list" href="" title="Copy Password" ngclipboard ngclipboard-error="clipboardError(e)"
<a class="btn-list" href="" title="{{ i18n.copyPassword }}" ngclipboard ngclipboard-error="clipboardError(e)"
ngclipboard-success="clipboardSuccess(e, 'Password')" data-clipboard-target="#password">
<i class="fa fa-lg fa-clipboard"></i>
</a>
<a class="btn-list" href="" title="Toggle Password" ng-click="togglePassword()">
<a class="btn-list" href="" title="{{ i18n.togglePassword }}" ng-click="togglePassword()">
<i class="fa fa-lg" ng-class="[{'fa-eye': !showPassword}, {'fa-eye-slash': showPassword}]"></i>
</a>
<span class="item-label">Password</span>
<span class="item-label">{{ i18n.password }}</span>
<span ng-show="!showPassword">{{site.maskedPassword}}</span>
<span id="password" ng-show="showPassword" class="monospaced">{{site.password}}</span>
</div>
@ -50,7 +50,7 @@
</div>
<div class="list-section" ng-if="site.notes">
<div class="list-section-header">
Notes
{{ i18n.notes }}
</div>
<div class="list-section-items">
<div class="list-section-item">

View File

@ -40,6 +40,7 @@
<script src="app/services/servicesModule.js"></script>
<script src="app/services/backgroundService.js"></script>
<script src="app/services/i18n.js"></script>
<script src="app/services/loginService.js"></script>
<script src="app/services/validationService.js"></script>