Browse Source

Redesign settings and lock screen

pull/64/head
brantje 2 years ago
parent
commit
a4df8183d9
No account linked to committer's email address

+ 8
- 0
_locales/en/messages.json View File

@@ -187,6 +187,10 @@
"message": "Disable browser auto fill",
"description": "Disable auto fill of forms"
},
"ignore_site_placeholder": {
"message": "Enter a domain or tld to ignore and press enter",
"description": "Disable auto fill of forms"
},
"disable_password_picker": {
"message": "Disable password picker",
"description": "Disable password picker"
@@ -271,6 +275,10 @@
"message": "Remember master password",
"description": "Remember master password"
},
"master_pw_warning": {
"message": "Warning! Your master password will be stored in plain text",
"description": "Remember master password"
},
"done": {
"message": "Done",
"description": "Done"

+ 242
- 4
css/browser_action.css View File

@@ -50,13 +50,22 @@
color: #737373; }
.list .list-item .mdi {
cursor: pointer; }
.list .list-item.no-hover:hover {
background-color: transparent; }

/**
Source: https://codepen.io/sevilayha/pen/IdGKH
Edited to work with angular
*/
/* form starting stylings ------------------------------- */
.group {
position: relative;
margin-bottom: 45px; }

input[type="text"], input[type="password"] {
.group:last-child {
margin-bottom: 0; }

input[type="text"], input[type="password"], select.input-md {
font-size: 14px;
padding: 10px 10px 10px 5px;
display: block;
@@ -64,9 +73,13 @@ input[type="text"], input[type="password"] {
border: none;
border-bottom: 1px solid #757575; }

input:focus {
input:focus, select.input-md:focus {
outline: none; }

select.input-md {
background-color: #fff;
cursor: pointer; }

/* LABEL ======================================= */
.group label {
color: #999;
@@ -81,7 +94,9 @@ input:focus {
-webkit-transition: 0.2s ease all; }

/* active state */
input:focus ~ label, input.ng-valid:not(.ng-empty) ~ label {
input[type="text"]:focus ~ label, input[type="password"]:focus ~ label,
input[type="text"].ng-valid:not(.ng-empty) ~ label, input[type="password"].ng-valid:not(.ng-empty) ~ label,
select.ng-valid:not(.ng-empty) ~ label {
top: -20px;
font-size: 14px;
color: #1565c0; }
@@ -156,7 +171,7 @@ input:focus ~ .bar:before, input:focus ~ .bar:after {
width: calc(100% - 32px); }

/* active state */
input:focus ~ .highlight {
input:focus ~ .highlight, select.input-md ~ .highlight {
-webkit-animation: inputHighlighter 0.3s ease;
-moz-animation: inputHighlighter 0.3s ease;
animation: inputHighlighter 0.3s ease; }
@@ -180,6 +195,179 @@ input:focus ~ .highlight {
to {
width: 0;
background: transparent; } }
/**
Source: https://codepen.io/guuslieben/pen/YyPRVP
*/
.switch-input {
display: none; }

.switch-label {
position: relative;
display: inline-block;
min-width: 112px;
cursor: pointer;
font-weight: 500;
text-align: left;
padding: 16px 0 16px 44px; }

.switch-label:before, .switch-label:after {
content: "";
position: absolute;
margin: 0;
outline: 0;
top: 50%;
-ms-transform: translate(0, -50%);
-webkit-transform: translate(0, -50%);
transform: translate(0, -50%);
-webkit-transition: all 0.3s ease;
transition: all 0.3s ease; }

.switch-label:before {
left: 1px;
width: 34px;
height: 14px;
background-color: #9E9E9E;
border-radius: 8px; }

.switch-label:after {
left: 0;
width: 20px;
height: 20px;
background-color: #FAFAFA;
border-radius: 50%;
box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.14), 0 2px 2px 0 rgba(0, 0, 0, 0.098), 0 1px 5px 0 rgba(0, 0, 0, 0.084); }

.switch-label .toggle--on {
display: none; }

.switch-label .toggle--off {
display: inline-block; }

.switch-input:checked + .switch-label:before {
background-color: #4f98ec; }

.switch-input:checked + .switch-label:after {
background-color: #1565c0;
-ms-transform: translate(80%, -50%);
-webkit-transform: translate(80%, -50%);
transform: translate(80%, -50%); }

.switch-input:checked + .switch-label .toggle--on {
display: inline-block; }

.switch-input:checked + .switch-label .toggle--off {
display: none; }

/**
Source: https://codepen.io/anon/pen/PmEeyo
*/
.md-checkbox {
color: #818181;
font-size: 15px;
font-weight: bold;
font-family: 'Roboto', sans-serif;
letter-spacing: .5px; }
.md-checkbox .input-checkbox {
position: relative;
display: inline-block;
width: 32px;
text-align: center;
vertical-align: -9px; }
.md-checkbox .input-checkbox input[type="checkbox"] {
visibility: hidden;
position: absolute;
left: 7px;
bottom: 7px;
margin: 0;
padding: 0;
outline: none;
cursor: pointer;
opacity: 0; }
.md-checkbox .input-checkbox input[type="checkbox"] + .checkbox:before {
position: absolute;
left: 4px;
bottom: 8px;
width: 18px;
height: 18px;
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
direction: ltr;
vertical-align: -6px;
/* Support for all WebKit browsers. */
-webkit-font-smoothing: antialiased;
/* Support for Safari and Chrome. */
text-rendering: optimizeLegibility;
/* Support for Firefox. */
-moz-osx-font-smoothing: grayscale;
/* Support for IE. */
font-feature-settings: 'liga';
transition: all .2s ease;
z-index: 1; }
.md-checkbox .input-checkbox input[type="checkbox"] + .checkbox:before {
content: "\e835";
color: #717171; }
.md-checkbox .input-checkbox input[type="checkbox"]:checked + .checkbox:before {
content: "\e834"; }
.md-checkbox .input-checkbox input[type="checkbox"]:active:not(:disabled) + .checkbox:before {
transform: scale3d(0.88, 0.88, 1); }
.md-checkbox .input-checkbox input[type="checkbox"]:disabled + .checkbox:before {
color: rgba(0, 0, 0, 0.157) !important; }
.md-checkbox.checkbox-light label, .md-checkbox.checkbox-light .label {
color: #FFF; }
.md-checkbox.checkbox-light input[type="checkbox"] + .checkbox:before {
color: #FFF; }
.md-checkbox.checkbox-light input[type="checkbox"]:disabled + .checkbox:before {
color: #5d5d5d !important; }
.md-checkbox.checkbox-light.checkbox-rotate input[type="checkbox"] + .checkbox:before {
border-color: #FFF; }
.md-checkbox.checkbox-light.checkbox-rotate input[type="checkbox"]:disabled + .checkbox:before {
border-color: #5d5d5d !important; }
.md-checkbox label, .md-checkbox .label {
cursor: pointer;
color: #797979; }

.md-checkbox.checkbox-rotate .input-checkbox input[type="checkbox"] + .checkbox {
cursor: pointer; }
.md-checkbox.checkbox-rotate .input-checkbox input[type="checkbox"] + .checkbox:before {
content: "";
position: absolute;
left: 7px;
bottom: 7px;
width: 18px;
height: 18px;
border: 2px solid #717171;
border-radius: 2px;
transition: all .2s ease;
z-index: 1; }
.md-checkbox.checkbox-rotate .input-checkbox input[type="checkbox"]:checked + .checkbox:before {
left: 11px;
width: 12px;
height: 20px;
border-width: 2px;
border-style: solid;
border-top: transparent;
border-left: transparent;
transform: rotate(40deg);
border-radius: 1px; }
.md-checkbox.checkbox-rotate .input-checkbox input[type="checkbox"]:disabled + .checkbox:before {
border-color: rgba(0, 0, 0, 0.157) !important; }

.md-checkbox:not(.checkbox-rotate) .checkbox-lightBlue input[type="checkbox"]:checked + .checkbox:before {
color: #03a9f4; }

.md-checkbox.checkbox-rotate .checkbox-lightBlue input[type="checkbox"]:checked + .checkbox:before {
border-color: #03a9f4; }

/**
Source: https://codepen.io/sebj54/pen/oxluI
*/
.md-btn {
position: relative;
margin: 0 15px 15px 15px;
@@ -369,3 +557,53 @@ body.toggled {
float: left;
color: #fff;
cursor: pointer; }

label, .switch-label, label:not(.input-checkbox):not(.label) {
font-weight: normal; }

.ignored_sites {
padding: 0; }
.ignored_sites label {
font-size: 14px;
color: #1565c0; }
.ignored_sites li {
list-style-type: none;
height: 25px;
padding: 5px 0; }
.ignored_sites li .mdi {
margin-top: 2px;
cursor: pointer; }
.ignored_sites li .mdi:hover {
color: #a94442; }
.ignored_sites .group {
margin-bottom: 45px; }

.invisible {
visibility: hidden; }

.master_pw_warning {
padding-left: 6px;
font-size: 10px;
color: #a94442;
margin-bottom: 15px; }

.master_pw_warning.big {
font-size: 14px;
text-align: center; }

.unlock {
width: 350px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
margin: -20px auto 10px;
padding: 20px; }
.unlock .group {
margin-bottom: 25px; }
.unlock img {
height: 50px;
margin: 15px auto;
display: block; }
.unlock .md-checkbox {
margin: 15px 0; }
.unlock .md-btn {
margin: 5px auto;
display: block; }

+ 2
- 2
css/vendor/bootstrap.css View File

@@ -2505,7 +2505,7 @@ legend {
border: 0;
border-bottom: 1px solid #e5e5e5;
}
label {
label:not(.input-checkbox):not(.label) {
display: inline-block;
max-width: 100%;
margin-bottom: 5px;
@@ -4842,7 +4842,7 @@ fieldset[disabled] .navbar-inverse .btn-link:focus {
cursor: not-allowed;
background-color: #fff;
}
.label {
.label:not(.input-checkbox):not(.label) {
display: inline;
padding: .2em .6em .3em;
font-size: 75%;

+ 4
- 1
html/browser_action/browser_action.html View File

@@ -85,10 +85,13 @@
</div>
<!-- /#sidebar-wrapper -->

<header class="header" ng-class="{'toggled': menuIsOpen}">
<header class="header" ng-class="{'toggled': menuIsOpen}" ng-show="showHeader">
<div class="menu-icon" ng-click="toggleMenu()">
<i class="mdi mdi-menu"></i>
</div>
<div class="menu-icon pull-right" ng-click="lockExtension()">
<i class="mdi mdi-lock"></i>
</div>
</header>
<!-- Page Content -->
<div id="page-content-wrapper" ng-view>

+ 3
- 21
html/browser_action/views/list.html View File

@@ -1,8 +1,8 @@
<div class="list">
<!-- <div ng-show="found_credentials.length === 0">
<div class="list-item no-hover" ng-show="found_credentials.length === 0">
{{ 'no_credentials_found_for_site' | translate}}
</div>
<div ng-show="found_credentials.length > 0">{{'credentials_found_for_site' | translate:found_credentials.length.toString() }}</div> -->
<!-- <div ng-show="found_credentials.length > 0">{{'credentials_found_for_site' | translate:found_credentials.length.toString() }}</div> -->
<div class="list-item" ng-repeat="credential in found_credentials">
<div class="title">
{{credential.label}}
@@ -18,22 +18,4 @@
</div>

</div>
</div>
<!--
<div class="footer">
<div style="position: absolute; left: 50%; margin-top: -7px; width: 110px;">
<div style="position: relative; left: -50%; margin-top: 1.3em;">
<small>{{'credentials_in_db' | translate:credential_amount}}</small>
</div>
</div>
<div class="bottomBtn" ng-click="goto_settings()" title="{{'settings' | translate}}"><i class="fa fa-gears"></i></div>
<div class="bottomBtn" ng-click="goto_search()" title="{{'search' | translate}}"><i class="fa fa-search"></i></div>
<div class="bottomBtn" ng-click="refresh()" title="{{'refresh_credential_list' | translate}}"><i class="fa fa-refresh" ng-class="{'fa-spin': refreshing_credentials}"></i></div>
<div class="bottomBtn pull-right"> <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6YS8F97PETVU2" target="_blank"
title="{{'donate_button_title' | translate}}"
rel="nofollow noopener noreferrer"
><i class="fa fa-paypal"></i> </a>
</div>
<div class="bottomBtn pull-right" ng-click="lockExtension()" title="{{'lock_extension' | translate}}"><i class="fa fa-lock"></i></div>

</div> -->
</div>

+ 32
- 12
html/browser_action/views/password_prompt.html View File

@@ -1,15 +1,35 @@
<div class="content unlock" style="max-height: 160px; overflow: auto">
<div>
<i class="fa fa-lock fa-5x"></i>
<div>{{'extension_locked'| translate}}:</div>
<input class="form-control" type="password" ng-enter="apply_settings()" ng-model="master_password" />
<label><input type="checkbox" ng-model="master_password_remember">Remember master password</label>
</div>
<div style="height: 400px">
<div class="content unlock">
<div>
<img src="/icons/passman_logo.png" height="80"/>
<div>{{'extension_locked'| translate}}:</div>
<div class="group">
<input type="password" ng-enter="apply_settings()" placeholder="{{'password' | translate}}"
ng-model="master_password">
<span class="highlight"></span>
<span class="bar"></span>
</div>

<div ng-show="inValidPassword" class="error">
{{'invalid_master_password' | translate}}
</div>
<button class="btn btn-default stepNext" ng-click="apply_settings()" ng-disabled="saving"><i ng-show="saving" ng-class="{'fa-spinner fa-spin': saving}" class="fa"></i><i ng-show="!saving" class="fa fa-unlock"></i> {{'unlock' | translate}}</button>
</div>
</div>

<div class="md-checkbox checkbox-rotate">
<label class="input-checkbox checkbox-lightBlue">
<input type="checkbox" id="master_password_remember" ng-model="master_password_remember">
<span class="checkbox"></span>
</label>
<label for="master_password_remember" class="label">{{'remember_master_password' | translate}}</label>
<div class="master_pw_warning" ng-class="{'invisible': !master_password_remember }">
{{'master_pw_warning' | translate}}
</div>
</div>
<div class="master_pw_warning big" ng-class="{'invisible': !inValidPassword }">
{{'invalid_master_password' | translate}}
</div>
<button class="md-btn default" ng-click="apply_settings()" ng-disabled="saving">
<span><i ng-show="saving" ng-class="{'fa-spinner fa-spin': saving}" class="fa"></i><i ng-show="!saving"
class="fa fa-unlock"></i> {{'unlock' | translate}}</span>
</button>

</div>

</div>

+ 21
- 27
html/browser_action/views/search.html View File

@@ -1,38 +1,32 @@
<div class="col-xs-12 nopadding pwcontainer">
<div class="edit_credential">
<div class="searchContainer">
<input type="text" ng-model="searchText" placeholder="{{'search_for' | translate }}..." class="form-control" ng-enter="search()"/>
<div class="group">
<input type="text" ng-enter="search()" ng-model="searchText">
<span class="highlight"></span>
<span class="bar"></span>
<label>{{'search_for' | translate }}</label>
</div>

</div>
<div ng-show="found_credentials.length === 0">
</div>
<div class="list">
<div class="list-item no-hover" ng-show="found_credentials.length === 0">
{{'no_credentials_found' | translate}}
</div>


<div class="credential" ng-repeat="credential in found_credentials">
<div class="col-xs-7 nopadding">{{credential.label}}<br/>
<small>{{credential.username}}</small>
<small>{{credential.email}}</small>
<div class="list-item" ng-repeat="credential in found_credentials">
<div class="title">
{{credential.label}}
</div>
<div class="info">
{{credential.username}}
</div>
<div class="col-xs-5 OTP" ng-if="credential.otp.secret">
<div class="extra" ng-if="credential.otp.secret">
{{'one_time_password' | translate}}: <div otp-generator secret="credential.otp.secret"></div>
</div>
</div>
</div>

<div class="footer">
<div style="position: absolute; left: 50%; margin-top: -7px; width: 110px;">
<div style="position: relative; left: -50%; margin-top: 1.3em;">
<small>{{'credentials_in_db' | translate:credential_amount}}</small>
<div class="edit" ng-click="editCredential(credential)">
<div class="mdi mdi-pencil"></div>
</div>

</div>
<div class="bottomBtn" ng-click="goto_settings()" title="{{'settings' | translate}}"><i class="fa fa-gears"></i></div>
<div class="bottomBtn" ng-click="goto_search()" title="{{'search' | translate}}"><i class="fa fa-search"></i></div>
<div class="bottomBtn" ng-click="refresh()" title="{{'refresh_credential_list' | translate}}"><i class="fa fa-refresh" ng-class="{'fa-spin': refreshing_credentials}"></i></div>
<div class="bottomBtn pull-right"> <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6YS8F97PETVU2" target="_blank"
title="{{'donate_button_title' | translate}}"
rel="nofollow noopener noreferrer"
><i class="fa fa-paypal"></i> </a>
</div>
<div class="bottomBtn pull-right" ng-click="lockExtension()" title="{{'lock_extension' | translate}}"><i class="fa fa-lock"></i></div>
<!-- <a class="btn btn-success pull-right"
>Donate</a> -->
</div>

+ 211
- 164
html/browser_action/views/settings.html View File

@@ -1,167 +1,214 @@
<div class="edit_credential">
<div class="group">
<input type="text" ng-model="settings.nextcloud_host"
required ng-debounce="1000">
<span class="highlight"></span>
<span class="bar"></span>
<label>{{'server_url' | translate}}</label>
</div>
<div class="group">
<input type="text" ng-model="settings.nextcloud_username"
required ng-debounce="1000">
<span class="highlight"></span>
<span class="bar"></span>
<label>{{'username' | translate}}</label>
</div>
<div class="group">
<input type="password" ng-model="settings.nextcloud_password"
required ng-debounce="1000">
<span class="highlight"></span>
<span class="bar"></span>
<label>{{'password' | translate}}</label>
</div>
<div class="group">
<select id="defaultVault" class="form-control input-sm" ng-model="settings.default_vault" required
ng-options="vault.name for vault in vaults track by vault.guid"></select>
<span class="highlight"></span>
<span class="bar"></span>
<label>{{'select_default_vault' | translate}}</label>
</div>
<div class="group" ng-show="settings.default_vault != ''">
<input type="password" ng-model="settings.vault_password"
required ng-debounce="1000">
<span class="highlight"></span>
<span class="bar"></span>
<label>{{'vault_password' | translate}}</label>
</div>
<!-- Ignored sites-->
<div class="group">
<input type="text" ng-model="settings.nextcloud_host"
required ng-debounce="1000">
<span class="highlight"></span>
<span class="bar"></span>
<label>{{'server_url' | translate}}</label>
</div>
<div class="group">
<input type="text" ng-model="settings.nextcloud_username"
required ng-debounce="1000">
<span class="highlight"></span>
<span class="bar"></span>
<label>{{'username' | translate}}</label>
</div>
<div class="group">
<input type="password" ng-model="settings.nextcloud_password"
required ng-debounce="1000">
<span class="highlight"></span>
<span class="bar"></span>
<label>{{'password' | translate}}</label>
</div>
<div class="group">
<select id="defaultVault" class="input-md" ng-model="settings.default_vault" required
ng-options="vault.name for vault in vaults track by vault.guid"></select>
<span class="highlight"></span>
<span class="bar"></span>
<label>{{'select_default_vault' | translate}}</label>
</div>
<div class="group" ng-show="settings.default_vault != ''">
<input type="password" ng-model="settings.vault_password"
required ng-debounce="1000">
<span class="highlight"></span>
<span class="bar"></span>
<label>{{'vault_password' | translate}}</label>
</div>
<div class="ignored_sites">
<label>{{'ignored_sites' | translate}}</label>
<ul class="ignored_sites">
<li ng-repeat="site in settings.ignored_sites">{{site}} <i class="mdi mdi-delete pull-right"
ng-click="removeSite(site)"></i></li>
<li ng-show="settings.ignored_sites.length === 0">{{'no_sites_ignored' | translate}}</li>
</ul>
<div class="group" ng-show="settings.default_vault != ''">
<input type="text"
ng-model="ignoreSite" ng-enter="addSite(ignoreSite)" placeholder="{{'ignore_site_placeholder' | translate}}">
<span class="highlight"></span>
<span class="bar"></span>
</div>
</div>
<div class="switch-row">
<input type="checkbox" id="ignore_protocol" ng-model="settings.ignoreProtocol" class="switch-input">
<label for="ignore_protocol" class="switch-label">{{'ignore_protocol' | translate}}</label>
</div>
<div class="switch-row">
<input type="checkbox" id="ignore_subdomain" ng-model="settings.ignoreSubdomain" class="switch-input">
<label for="ignore_subdomain" class="switch-label">{{'ignore_subdomain' | translate}}</label>
</div>
<div class="switch-row">
<input type="checkbox" id="ignore_port" ng-model="settings.ignorePort" class="switch-input">
<label for="ignore_port" class="switch-label">{{'ignore_port' | translate}}</label>
</div>
<div class="switch-row">
<input type="checkbox" id="disable_autofill" ng-model="settings.disableAutoFill" class="switch-input">
<label for="disable_autofill" class="switch-label">{{'disable_autofill' | translate}}</label>
</div>
<div class="switch-row">
<input type="checkbox" id="disable_browser_autofill" ng-model="settings.disable_browser_autofill" class="switch-input">
<label for="disable_browser_autofill" class="switch-label">{{'disable_browser_autofill' | translate}}</label>
</div>
<div class="switch-row">
<input type="checkbox" id="disable_password_picker" ng-model="settings.disablePasswordPicker" class="switch-input">
<label for="disable_password_picker" class="switch-label">{{'disable_password_picker' | translate}}</label>
</div>
<div class="switch-row">
<input type="checkbox" id="enable_debug" ng-model="settings.debug" class="switch-input">
<label for="enable_debug" class="switch-label">{{'enable_debug' | translate}}</label>
</div>
<div class="clearfix"></div>
<button class="md-btn default" ng-click="saveSettings()" ng-disabled="saving">
<span>
<i ng-show="saving"
ng-class="{'fa-spinner fa-spin': saving}"
class="fa"></i>
{{'save' | translate}}
</span>
</button>
<button class="md-btn" ng-click="cancel()">
<span>{{'cancel' | translate}}</span>
</button>
<!--
<h4 align="center">{{'please_enter_nextcloud_credentials' | translate}}:</h4>
<div class="alerts alert alert-warning" ng-if="errors.length > 0">
<li ng-repeat="error in errors">{{error}}</li>
</div>
<div>
<table class="table">
<tr>
<td>
<small>{{'server_url' | translate}}:</small>
</td>
<td><input type="url" class="form-control input-sm" id="host" ng-model="settings.nextcloud_host"
required ng-debounce="1000">
</td>
</tr>
<tr ng-if="settings.nextcloud_host.indexOf('http://') == 0">
<td colspan=2>
<div class="alert alert-warning">Warning: This connection is insecure!</div>
</td>
</tr>
<tr>
<td>
<small>{{'username' | translate}}:</small>
</td>
<td><input type="text" class="form-control input-sm" id="user" ng-model="settings.nextcloud_username"
required ng-debounce="1000"></td>
</tr>
<tr>
<td>
<small>{{'password' | translate}}:</small>
</td>
<td><input type="password" class="form-control input-sm" id="password"
ng-model="settings.nextcloud_password" required ng-debounce="1000"></td>
</tr>
<tr class="login-req" ng-if="vaults">
<td>
<small>{{'select_default_vault' | translate}}:</small>
</td>
<td><select id="defaultVault" class="form-control input-sm" ng-model="settings.default_vault" required
ng-options="vault.name for vault in vaults track by vault.guid"></select></td>
</tr>
<tr class="login-req" id="vaultPassRow" ng-show="settings.default_vault != ''">
<td valign="top">
<small>{{'vault_password' | translate}}</small>
</td>
<td>
<input type="password" class="form-control input-sm" id="vaultPassword"
ng-model="settings.vault_password">
</td>
</tr>
<tr class="login-req">
<td valign="top">
<small>{{'ignored_sites' | translate}}</small>
</td>
<td>

<label class="label--checkbox">
<input type="checkbox" class="checkbox" checked>
Item 1
</label>

<!--
<h4 align="center">{{'please_enter_nextcloud_credentials' | translate}}:</h4>
<div class="alerts alert alert-warning" ng-if="errors.length > 0">
<li ng-repeat="error in errors">{{error}}</li>
</div>
<div>
<table class="table">
<tr>
<td>
<small>{{'server_url' | translate}}:</small>
</td>
<td><input type="url" class="form-control input-sm" id="host" ng-model="settings.nextcloud_host"
required ng-debounce="1000">
</td>
</tr>
<tr ng-if="settings.nextcloud_host.indexOf('http://') == 0">
<td colspan=2>
<div class="alert alert-warning">Warning: This connection is insecure!</div>
</td>
</tr>
<tr>
<td>
<small>{{'username' | translate}}:</small>
</td>
<td><input type="text" class="form-control input-sm" id="user" ng-model="settings.nextcloud_username"
required ng-debounce="1000"></td>
</tr>
<tr>
<td>
<small>{{'password' | translate}}:</small>
</td>
<td><input type="password" class="form-control input-sm" id="password"
ng-model="settings.nextcloud_password" required ng-debounce="1000"></td>
</tr>
<tr class="login-req" ng-if="vaults">
<td>
<small>{{'select_default_vault' | translate}}:</small>
</td>
<td><select id="defaultVault" class="form-control input-sm" ng-model="settings.default_vault" required
ng-options="vault.name for vault in vaults track by vault.guid"></select></td>
</tr>
<tr class="login-req" id="vaultPassRow" ng-show="settings.default_vault != ''">
<td valign="top">
<small>{{'vault_password' | translate}}</small>
</td>
<td>
<input type="password" class="form-control input-sm" id="vaultPassword"
ng-model="settings.vault_password">
</td>
</tr>
<tr class="login-req">
<td valign="top">
<small>{{'ignored_sites' | translate}}</small>
</td>
<td>

<ul class="ignored_sites">
<li ng-repeat="site in settings.ignored_sites">{{site}} <i class="fa fa-trash pull-right"
ng-click="removeSite(site)"></i></li>
<li ng-show="settings.ignored_sites.length === 0">{{'no_sites_ignored' | translate}}</li>
<li><input type="text" class="form-control" placeholder="Enter a domain or tld"
ng-model="ignoreSite" ng-enter="addSite(ignoreSite)"></li>
</ul>
</td>
</tr>
<tr>
<td>
<small>{{'refresh_timer' | translate}}:</small>
</td>
<td><input type="text" id="timer" class="form-control input-sm" ng-model="settings.refreshTime"></td>
</tr>
<tr>
<td colspan=2><input type="checkbox" id="ignoreProtocol" ng-model="settings.ignoreProtocol">
<small>{{'ignore_protocol' | translate}}</small>
</td>
</tr>
<tr>
<td colspan=2><input type="checkbox" id="ignoreSubdomain" ng-model="settings.ignoreSubdomain">
<small>{{'ignore_subdomain' | translate}}</small>
</td>
</tr>
<tr>
<td colspan=2><input type="checkbox" id="ignorePath" ng-model="settings.ignorePort">
<small>{{'ignore_port' | translate}}</small>
</td>
</tr>
<tr>
<td colspan=2><input type="checkbox" id="disableAutoFill" ng-model="settings.disableAutoFill">
<small>{{'disable_autofill' | translate}}</small>
</td>
</tr>
<tr>
<td colspan=2><input type="checkbox" id="disableBrowserAutoFill"
ng-model="settings.disable_browser_autofill">
<small>{{'disable_browser_autofill' | translate}}</small>
</td>
</tr>
<tr>
<td colspan=2><input type="checkbox" id="disablePasswordPicker"
ng-model="settings.disablePasswordPicker">
<small>{{'disable_password_picker' | translate}}</small>
</td>
</tr>
<tr>
<td colspan=2><input type="checkbox" id="enableDebug" ng-model="settings.debug">
<small>{{'enable_debug' | translate}}</small>
</td>
</tr>
<tr>
<td colspan=2 align="center">
<button class="btn btn-success" ng-click="saveSettings()" ng-disabled="saving"><i ng-show="saving"
ng-class="{'fa-spinner fa-spin': saving}"
class="fa"></i>
{{'save' | translate}}
</button>
<button class="btn btn-warning" ng-click="cancel()">{{'cancel' | translate}}</button>
</td>
</tr>
</table>
<div class="version">
{{extension}}
</div>
</div>-->
<ul class="ignored_sites">
<li ng-repeat="site in settings.ignored_sites">{{site}} <i class="fa fa-trash pull-right"
ng-click="removeSite(site)"></i></li>
<li ng-show="settings.ignored_sites.length === 0">{{'no_sites_ignored' | translate}}</li>
<li><input type="text" class="form-control" placeholder="Enter a domain or tld"
ng-model="ignoreSite" ng-enter="addSite(ignoreSite)"></li>
</ul>
</td>
</tr>
<tr>
<td>
<small>{{'refresh_timer' | translate}}:</small>
</td>
<td><input type="text" id="timer" class="form-control input-sm" ng-model="settings.refreshTime"></td>
</tr>
<tr>
<td colspan=2><input type="checkbox" id="ignoreProtocol" ng-model="settings.ignoreProtocol">
<small>{{'ignore_protocol' | translate}}</small>
</td>
</tr>
<tr>
<td colspan=2><input type="checkbox" id="ignoreSubdomain" ng-model="settings.ignoreSubdomain">
<small>{{'ignore_subdomain' | translate}}</small>
</td>
</tr>
<tr>
<td colspan=2><input type="checkbox" id="ignorePath" ng-model="settings.ignorePort">
<small>{{'ignore_port' | translate}}</small>
</td>
</tr>
<tr>
<td colspan=2><input type="checkbox" id="disableAutoFill" ng-model="settings.disableAutoFill">
<small>{{'disable_autofill' | translate}}</small>
</td>
</tr>
<tr>
<td colspan=2><input type="checkbox" id="disableBrowserAutoFill"
ng-model="settings.disable_browser_autofill">
<small>{{'disable_browser_autofill' | translate}}</small>
</td>
</tr>
<tr>
<td colspan=2><input type="checkbox" id="disablePasswordPicker"
ng-model="settings.disablePasswordPicker">
<small>{{'disable_password_picker' | translate}}</small>
</td>
</tr>
<tr>
<td colspan=2><input type="checkbox" id="enableDebug" ng-model="settings.debug">
<small>{{'enable_debug' | translate}}</small>
</td>
</tr>
<tr>
<td colspan=2 align="center">
<button class="btn btn-success" ng-click="saveSettings()" ng-disabled="saving"><i ng-show="saving"
ng-class="{'fa-spinner fa-spin': saving}"
class="fa"></i>
{{'save' | translate}}
</button>
<button class="btn btn-warning" ng-click="cancel()">{{'cancel' | translate}}</button>
</td>
</tr>
</table>
<div class="version">
{{extension}}
</div>
</div>-->
</div>

BIN
icons/passman_logo.png View File


+ 2
- 25
js/ui/popup/controllers/list.js View File

@@ -57,14 +57,8 @@
var initApp = function () {
port.onMessage.addListener(messageParser);
API.runtime.sendMessage(API.runtime.id, {method: "getMasterPasswordSet"}).then(function (isPasswordSet) {
function redirectToPrompt() {
window.location = '#!/locked';
return;
}

//First check attributes
if (!isPasswordSet) {
redirectToPrompt();
return;
}

@@ -86,7 +80,7 @@
});
};

var getActiveTab = function (cb) {
var getActiveTab = function () {
API.tabs.query({currentWindow: true, active: true}).then(function (tab) {
API.runtime.sendMessage(API.runtime.id, {
method: "getCredentialsByUrl",
@@ -99,24 +93,7 @@
});
};

$scope.lockExtension = function () {
API.runtime.sendMessage(API.runtime.id, {method: "setMasterPassword", args: {password: null}}).then(function () {
window.location = '#!/locked';
});
};

API.runtime.sendMessage(API.runtime.id, {'method': 'getRuntimeSettings'}).then(function (settings) {

$rootScope.app_settings = settings;
if (!settings || Object.keys(settings).length === 0) {
window.location = '#!/setup';
} else if (settings.hasOwnProperty('isInstalled')) {
window.location = '#!/locked';
} else {
initApp();
}
});

initApp();

$scope.editCredential = function (credential) {
window.location = '#!/edit/' + credential.guid;

+ 33
- 1
js/ui/popup/controllers/main.js View File

@@ -38,6 +38,8 @@

$scope.menuIsOpen = false;
$scope.bodyOverflow = false;
$scope.showHeader = true;

$scope.toggleMenu = function () {
console.log('click');
$scope.menuIsOpen = !$scope.menuIsOpen;
@@ -47,11 +49,41 @@
}, 1500);
};

$rootScope.$on('hideHeader', function () {
$scope.showHeader = false;
});

$rootScope.$on('showHeader', function () {
$scope.showHeader = true;
});

API.runtime.sendMessage(API.runtime.id, {'method': 'getRuntimeSettings'}).then(function (settings) {

$rootScope.app_settings = settings;
if (!settings || Object.keys(settings).length === 0) {
window.location = '#!/setup';
} else if (settings.hasOwnProperty('isInstalled')) {
window.location = '#!/locked';
} else {
// initApp();
}
});


$scope.goto = function (page) {
window.location = '#!/'+page;
window.location = '#!/' + page;
$scope.menuIsOpen = false;
};


$scope.lockExtension = function () {
API.runtime.sendMessage(API.runtime.id, {
method: "setMasterPassword",
args: {password: null}
}).then(function () {
window.location = '#!/locked';
});
};
}]);
}());


+ 5
- 2
js/ui/popup/controllers/password_prompt.js View File

@@ -42,6 +42,8 @@
});
API.runtime.sendMessage(API.runtime.id, {method: "getSettings"});

$rootScope.$broadcast('hideHeader');
$scope.master_password_remember = false;
$scope.master_password = '';
$scope.apply_settings = function() {
$scope.saving = true;
@@ -52,8 +54,9 @@
setTimeout(function () {
window.location = '#!/';
$scope.saving = false;
$scope.saving = false;
},1500);
$rootScope.$broadcast('showHeader');

},750);
});
} else {
$scope.saving = false;

+ 0
- 13
js/ui/popup/controllers/search.js View File

@@ -54,13 +54,6 @@
port.onMessage.addListener(messageParser);
port.postMessage("credential_amount");


$scope.lockExtension = function () {
API.runtime.sendMessage(API.runtime.id, {method: "setMasterPassword", args: {password: null}}).then(function () {
window.location = '#!/locked';
});
};

$scope.found_credentials = false;
$scope.searchText = '';
$scope.search = function () {
@@ -71,13 +64,7 @@
};


$scope.goto_settings = function () {
window.location = '#!/settings';
};

$scope.goto_search = function () {
window.location = '#!/search';
};


}]);

+ 75
- 6
style/browser_action.scss View File

@@ -2,7 +2,10 @@
@import "partials/cicle";
@import "partials/list";
@import "partials/material-input";
@import "partials/buttons";
@import "partials/material-switch";
@import "partials/material-checkbox";
@import "partials/material-buttons";

$sidebarWidth: 250px;
body {
width: 450px;
@@ -72,9 +75,11 @@ body.toggled {
margin-right: -$sidebarWidth;
/* width: calc(100% - 250px);*/
}
.ng-hide{

.ng-hide {
display: none;
}

/* Sidebar Styles */

.sidebar-nav {
@@ -91,7 +96,7 @@ body.toggled {
display: block;
text-decoration: none;
color: #000;
.mdi{
.mdi {
padding-left: 15px;
padding-right: 15px;
color: $linkColor;
@@ -124,7 +129,7 @@ body.toggled {
color: #fff;
background: none;
}
.mdi{
.mdi {
padding-left: 15px;
padding-right: 15px;
float: right;
@@ -134,7 +139,8 @@ body.toggled {
}
}
}
.menuToggler{

.menuToggler {
position: absolute;
background-color: transparent;
width: calc(100% - 250px);
@@ -142,7 +148,8 @@ body.toggled {
z-index: 9999999;
right: 0;
}
.edit_credential{

.edit_credential {
padding-top: 30px;
padding-left: 15px;
padding-right: 15px;
@@ -154,4 +161,66 @@ body.toggled {
float: left;
color: #fff;
cursor: pointer;
}

label, .switch-label, label:not(.input-checkbox):not(.label) {
font-weight: normal;
}

.ignored_sites {
label {
font-size: 14px;
color: #1565c0;
}
padding: 0;
li {
list-style-type: none;
height: 25px;
padding: 5px 0;
.mdi {
margin-top: 2px;
cursor: pointer;
}
.mdi:hover {
color: #a94442;
}
}
.group {
margin-bottom: 45px;
}
}
.invisible{
visibility: hidden;
}
.master_pw_warning{
padding-left: 6px;
font-size: 10px;
color: #a94442;
margin-bottom: 15px;
}
.master_pw_warning.big{
font-size: 14px;
text-align: center;

}
.unlock {
width: 350px;
box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);
margin: -20px auto 10px;
padding: 20px;
.group{
margin-bottom: 25px;
}
img {
height: 50px;
margin: 15px auto;
display: block;
}
.md-checkbox {
margin: 15px 0;
}
.md-btn {
margin: 5px auto;
display: block;
}
}

+ 62
- 0
style/css/material-buttons.css View File

@@ -0,0 +1,62 @@
.md-btn {
position: relative;
margin: 0 15px 15px 15px;
padding: 0;
overflow: hidden;
border-width: 0;
outline: none;
border-radius: 2px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
color: #212121;
background-color: #fafafa;
cursor: pointer;
display: inline-block;
transition: background-color .3s; }

.md-btn.default, .btn:focus {
background-color: #106cc8;
color: rgba(255, 255, 255, 0.87); }

.md-btn.default:hover, .btn:focus {
background-color: #0159a2; }

.md-btn > * {
position: relative; }

.md-btn span {
display: inline-block;
padding: 12px 24px; }

.md-btn:before {
content: "";
position: absolute;
top: 50%;
left: 50%;
display: block;
width: 0;
padding-top: 0;
border-radius: 100%;
background-color: rgba(236, 240, 241, 0.3);
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
transform: translate(-50%, -50%); }

.md-btn:active:before {
width: 120%;
padding-top: 120%;
transition: width .2s ease-out, padding-top .2s ease-out; }

.md-btn.orange {
background-color: #e67e22; }

.md-btn.orange:hover, .btn.orange:focus {
background-color: #d35400; }

.md-btn.red {
background-color: #ff5722;
color: rgba(255, 255, 255, 0.87); }

.md-btn.red:hover, .btn.red:focus {
background-color: #f4511e; }

+ 115
- 0
style/css/material-checkbox.css View File

@@ -0,0 +1,115 @@
/* ----------------------------------------------------------------------
Material Design Checkbox - by Ravikumar Chauhan
------------------------------------------------------------------------- */
.md-checkbox {
color: #818181;
font-size: 15px;
font-weight: bold;
font-family: 'Roboto', sans-serif;
letter-spacing: .5px; }
.md-checkbox .input-checkbox {
position: relative;
display: inline-block;
width: 32px;
height: 32px;
text-align: center;
vertical-align: -9px; }
.md-checkbox .input-checkbox input[type="checkbox"] {
visibility: hidden;
position: absolute;
left: 7px;
bottom: 7px;
margin: 0;
padding: 0;
outline: none;
cursor: pointer;
opacity: 0; }
.md-checkbox .input-checkbox input[type="checkbox"] + .checkbox:before {
position: absolute;
left: 4px;
bottom: 8px;
width: 18px;
height: 18px;
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
direction: ltr;
vertical-align: -6px;
/* Support for all WebKit browsers. */
-webkit-font-smoothing: antialiased;
/* Support for Safari and Chrome. */
text-rendering: optimizeLegibility;
/* Support for Firefox. */
-moz-osx-font-smoothing: grayscale;
/* Support for IE. */
font-feature-settings: 'liga';
transition: all .2s ease;
z-index: 1; }
.md-checkbox .input-checkbox input[type="checkbox"] + .checkbox:before {
content: "\e835";
color: #717171; }
.md-checkbox .input-checkbox input[type="checkbox"]:checked + .checkbox:before {
content: "\e834"; }
.md-checkbox .input-checkbox input[type="checkbox"]:active:not(:disabled) + .checkbox:before {
transform: scale3d(0.88, 0.88, 1); }
.md-checkbox .input-checkbox input[type="checkbox"]:disabled + .checkbox:before {
color: rgba(0, 0, 0, 0.157) !important; }
.md-checkbox.checkbox-light label, .md-checkbox.checkbox-light .label {
color: #FFF; }
.md-checkbox.checkbox-light input[type="checkbox"] + .checkbox:before {
color: #FFF; }
.md-checkbox.checkbox-light input[type="checkbox"]:disabled + .checkbox:before {
color: #5d5d5d !important; }
.md-checkbox.checkbox-light.checkbox-rotate input[type="checkbox"] + .checkbox:before {
border-color: #FFF; }
.md-checkbox.checkbox-light.checkbox-rotate input[type="checkbox"]:disabled + .checkbox:before {
border-color: #5d5d5d !important; }
.md-checkbox label, .md-checkbox .label {
cursor: pointer; }

/* ----------------------------------------------------------------------
Rotate Checkbox - by Ravikumar Chauhan
------------------------------------------------------------------------- */
.md-checkbox.checkbox-rotate .input-checkbox input[type="checkbox"] + .checkbox {
cursor: pointer; }
.md-checkbox.checkbox-rotate .input-checkbox input[type="checkbox"] + .checkbox:before {
content: "";
position: absolute;
left: 7px;
bottom: 7px;
width: 18px;
height: 18px;
border: 2px solid #717171;
border-radius: 2px;
transition: all .2s ease;
z-index: 1; }
.md-checkbox.checkbox-rotate .input-checkbox input[type="checkbox"]:checked + .checkbox:before {
left: 11px;
width: 12px;
height: 20px;
border-width: 2px;
border-style: solid;
border-top: transparent;
border-left: transparent;
transform: rotate(40deg);
border-radius: 1px; }
.md-checkbox.checkbox-rotate .input-checkbox input[type="checkbox"]:disabled + .checkbox:before {
border-color: rgba(0, 0, 0, 0.157) !important; }

/* ----------------------------------------------------------------------
Normal Checkbox Color - by Ravikumar Chauhan
------------------------------------------------------------------------- */
.md-checkbox:not(.checkbox-rotate) .checkbox-lightBlue input[type="checkbox"]:checked + .checkbox:before {
color: #03a9f4; }

/* ----------------------------------------------------------------------
Rotate Checkbox Color - by Ravikumar Chauhan
------------------------------------------------------------------------- */
.md-checkbox.checkbox-rotate .checkbox-lightBlue input[type="checkbox"]:checked + .checkbox:before {
border-color: #03a9f4; }

+ 60
- 0
style/css/material-switch.css View File

@@ -0,0 +1,60 @@
.switch-input {
display: none; }

.switch-label {
position: relative;
display: inline-block;
min-width: 112px;
cursor: pointer;
font-weight: 500;
text-align: left;
margin: 16px;
padding: 16px 0 16px 44px; }

.switch-label:before, .switch-label:after {
content: "";
position: absolute;
margin: 0;
outline: 0;
top: 50%;
-ms-transform: translate(0, -50%);
-webkit-transform: translate(0, -50%);
transform: translate(0, -50%);
-webkit-transition: all 0.3s ease;
transition: all 0.3s ease; }

.switch-label:before {
left: 1px;
width: 34px;
height: 14px;
background-color: #9E9E9E;
border-radius: 8px; }

.switch-label:after {
left: 0;
width: 20px;
height: 20px;
background-color: #FAFAFA;
border-radius: 50%;
box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.14), 0 2px 2px 0 rgba(0, 0, 0, 0.098), 0 1px 5px 0 rgba(0, 0, 0, 0.084); }

.switch-label .toggle--on {
display: none; }

.switch-label .toggle--off {
display: inline-block; }

.switch-input:checked + .switch-label:before {
background-color: #4f98ec; }

.switch-input:checked + .switch-label:after {
background-color: #1565c0;
-ms-transform: translate(80%, -50%);
-webkit-transform: translate(80%, -50%);
transform: translate(80%, -50%); }

.switch-input:checked + .switch-label .toggle--on {
display: inline-block; }

.switch-input:checked + .switch-label .toggle--off {
display: none; }

+ 3
- 0
style/partials/list.scss View File

@@ -37,4 +37,7 @@ $linkColor: #737373;
cursor: pointer;
}
}
.list-item.no-hover:hover{
background-color: transparent;
}
}

style/partials/buttons.scss → style/partials/material-buttons.scss View File

@@ -1,3 +1,6 @@
/**
Source: https://codepen.io/sebj54/pen/oxluI
*/
.md-btn {
position: relative;


+ 149
- 38
style/partials/material-checkbox.scss View File

@@ -1,55 +1,166 @@
.label--checkbox {
position: relative;
font-family: Arial, sans-serif;
line-height: 135%;
cursor: pointer;
/**
Source: https://codepen.io/anon/pen/PmEeyo
*/
// Checkbox Color
$btn_lightBlue: #03a9f4;


// KEYFRAMES
@mixin keyframes($animation-name) {
@-webkit-keyframes #{$animation-name} {
@content;
}
@-moz-keyframes #{$animation-name} {
@content;
}
@-ms-keyframes #{$animation-name} {
@content;
}
@-o-keyframes #{$animation-name} {
@content;
}
@keyframes #{$animation-name} {
@content;
}
}

.checkbox {
position: relative;
margin: 0 1rem 0 0 ;

cursor: pointer;
.md-checkbox {
color: #818181;
font-size: 15px;
font-weight: bold;
font-family: 'Roboto', sans-serif;
letter-spacing: .5px;

.input-checkbox {
position: relative;
display: inline-block;
width: 32px;
text-align: center;
vertical-align: -9px;

input[type="checkbox"] {
visibility: hidden;
position: absolute;
left: 7px;
bottom: 7px;
margin: 0;
padding: 0;
outline: none;
cursor: pointer;
opacity: 0;

&:before {
@include transition(all .800s ease-in-out);
& + .checkbox:before {
position: absolute;
left: 4px;
bottom: 8px;
width: 18px;
height: 18px;
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
direction: ltr;
vertical-align: -6px;

content: "";
/* Support for all WebKit browsers. */
-webkit-font-smoothing: antialiased;
/* Support for Safari and Chrome. */
text-rendering: optimizeLegibility;

position: absolute;
left: 0;
z-index: 1;
/* Support for Firefox. */
-moz-osx-font-smoothing: grayscale;

width: 1rem;
height: 1rem;
/* Support for IE. */
font-feature-settings: 'liga';

border: 2px solid #f2f2f2;
}
transition: all .2s ease;
z-index: 1;
}

&:checked {
&:before {
@include transform(rotate(-45deg));
& + .checkbox:before { content: "\e835"; color: #717171; }

height: .5rem;
&:checked + .checkbox:before { content: "\e834"; }

border-color: $green;
border-top-style: none;
border-right-style: none;
}
}
&:active:not(:disabled) + .checkbox:before { transform: scale3d(0.88, 0.88, 1); }

&:after {
content: "";
&:disabled + .checkbox:before { color: rgba(0,0,0,0.157) !important; }
}
}

&.checkbox-light {
label, .label { color: #FFF; }
input[type="checkbox"] + .checkbox:before { color: #FFF; }
input[type="checkbox"]:disabled + .checkbox:before { color: #5d5d5d !important; }

&.checkbox-rotate {
input[type="checkbox"] + .checkbox:before { border-color: #FFF; }
input[type="checkbox"]:disabled + .checkbox:before { border-color: #5d5d5d !important; }
}
}

label, .label { cursor: pointer; color: #797979 }
}

position: absolute;
top: rem(-2);
left: 0;

width: 1.1rem;
height: 1.1rem;
.md-checkbox {
&.checkbox-rotate {
.input-checkbox {
input[type="checkbox"] {
& + .checkbox {
cursor: pointer;

&:before {
content: "";
position: absolute;
left: 7px;
bottom: 7px;
width: 18px;
height: 18px;
border: 2px solid #717171;
border-radius: 2px;
transition: all .2s ease;
z-index: 1;
}
}

&:checked + .checkbox:before {
left: 11px;
width: 12px;
height: 20px;
border-width: 2px;
border-style: solid;
border-top: transparent;
border-left: transparent;
transform: rotate(40deg);
border-radius: 1px;
}

&:disabled + .checkbox:before { border-color: rgba(0,0,0,0.157) !important; }
}
}
}
}

.md-checkbox {
&:not(.checkbox-rotate) {
.checkbox-lightBlue {
input[type="checkbox"]:checked + .checkbox:before { color: $btn_lightBlue; }
}
}
}

.md-checkbox {
&.checkbox-rotate {

background: #fff;

cursor: pointer;
}
.checkbox-lightBlue {
input[type="checkbox"]:checked + .checkbox:before { border-color: $btn_lightBlue; }
}
}
}

+ 18
- 7
style/partials/material-input.scss View File

@@ -1,12 +1,18 @@
@import "../bourbon/bourbon";

/**
Source: https://codepen.io/sevilayha/pen/IdGKH
Edited to work with angular
*/
/* form starting stylings ------------------------------- */
.group {
position: relative;
margin-bottom: 45px;
}
.group:last-child{
margin-bottom: 0;
}

input[type="text"], input[type="password"] {
input[type="text"], input[type="password"], select.input-md {
font-size: 14px;
padding: 10px 10px 10px 5px;
display: block;
@@ -15,10 +21,13 @@ input[type="text"], input[type="password"] {
border-bottom: 1px solid #757575;
}

input:focus {
input:focus, select.input-md:focus {
outline: none;
}

select.input-md{
background-color: #fff;
cursor: pointer;
}
/* LABEL ======================================= */
.group label {
color: #999;
@@ -35,7 +44,9 @@ input:focus {
}

/* active state */
input:focus ~ label, input.ng-valid:not(.ng-empty) ~ label {
input[type="text"]:focus ~ label,input[type="password"]:focus ~ label,
input[type="text"].ng-valid:not(.ng-empty) ~ label,input[type="password"].ng-valid:not(.ng-empty) ~ label,
select.ng-valid:not(.ng-empty) ~ label {
top: -20px;
font-size: 14px;
color: #1565c0;
@@ -69,7 +80,7 @@ input:focus ~ label, input.ng-valid:not(.ng-empty) ~ label {
}

/* active state */
input:focus ~ .bar:before, input:focus ~ .bar:after {
input:focus ~ .bar:before, input:focus ~ .bar:after {
width: 50%;
}

@@ -121,7 +132,7 @@ input:focus ~ .bar:before, input:focus ~ .bar:after {
width: calc(100% - 32px);
}
/* active state */
input:focus ~ .highlight {
input:focus ~ .highlight, select.input-md ~ .highlight {
-webkit-animation: inputHighlighter 0.3s ease;
-moz-animation: inputHighlighter 0.3s ease;
animation: inputHighlighter 0.3s ease;

+ 63
- 0
style/partials/material-switch.scss View File

@@ -0,0 +1,63 @@
/**
Source: https://codepen.io/guuslieben/pen/YyPRVP
*/
.switch-input {
display: none;
}
.switch-label {
position: relative;
display: inline-block;
min-width: 112px;
cursor: pointer;
font-weight: 500;
text-align: left;
padding: 16px 0 16px 44px;
}
.switch-label:before, .switch-label:after {
content: "";
position: absolute;
margin: 0;
outline: 0;
top: 50%;
-ms-transform: translate(0, -50%);
-webkit-transform: translate(0, -50%);
transform: translate(0, -50%);
-webkit-transition: all 0.3s ease;
transition: all 0.3s ease;
}
.switch-label:before {
left: 1px;
width: 34px;
height: 14px;
background-color: #9E9E9E;
border-radius: 8px;
}
.switch-label:after {
left: 0;
width: 20px;
height: 20px;
background-color: #FAFAFA;
border-radius: 50%;
box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.14), 0 2px 2px 0 rgba(0, 0, 0, 0.098), 0 1px 5px 0 rgba(0, 0, 0, 0.084);
}
.switch-label .toggle--on {
display: none;
}
.switch-label .toggle--off {
display: inline-block;
}
.switch-input:checked + .switch-label:before {
background-color:lighten(#1565c0, 20%);
}
.switch-input:checked + .switch-label:after {
background-color: #1565c0;
-ms-transform: translate(80%, -50%);
-webkit-transform: translate(80%, -50%);
transform: translate(80%, -50%);
}
.switch-input:checked + .switch-label .toggle--on {
display: inline-block;
}
.switch-input:checked + .switch-label .toggle--off {
display: none;
}

Loading…
Cancel
Save