Password Meter with Mithril
by ramnathv
HTML
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
CSS
#main{margin-top: 30px;}
.progress{height: 10px;}
CoffeeScript
## https://gist.github.com/impinball/5e4d6e64aba2ffb7cd23
## Patches Mithril to accept components as well as strings
@m = ((o) ->
Object.assign (->
(if typeof arguments[0] == 'string' then o else o.component).apply undefined, arguments
), o
)(m)
m.bind = (prop, args = {}) ->
args.value = prop()
args.oninput = m.withAttr("value", prop)
return args
###
Reference: http://reactkungfu.com/showcases/password-strength-meter/
TODOS:
1. Refactor
2. Add Error State to Input Box
###
goodPasswordPrinciples = [
{
label: '6+ characters'
predicate: (password) -> password.length > 6
},
{
label: 'with at least one digit'
predicate: (password) -> password.match(/\d+/g) != null
},
{
label: '6+ characters'
predicate: (password) ->
password.match(/[-!$%^&*()_+|~=`{}\[\]:";'<>?,.\/]/) != null
}
]
ProgressBar =
view: (c, props) ->
principleSatisfied = (principle) ->
password = props.text
principle.predicate(password)
num = goodPasswordPrinciples
.filter(principleSatisfied)
.length
pct = num*100/3
type = ['danger', 'warning', 'success'][num - 1]
m ".progress",
m ".progress-bar.progress-bar-#{type}[role='progressbar']",
{style: {width: "#{pct}%"}}
ProgressText =
view: (c, props) ->
principleSatisfied = (principle) ->
password = props.text
principle.predicate(password)
principleClass = (principle) ->
satisfied = principleSatisfied(principle)
if satisfied then 'text-success' else 'text-danger'
console.log(goodPasswordPrinciples.map(principleSatisfied))
m 'ul', goodPasswordPrinciples.map (p) ->
m 'li', {class: principleClass(p)}, p.label
Panel =
view: (c, props) ->
m '.panel.panel-default', Object.keys(props).map (k) ->
m ".panel-#{k}", props[k]
PasswordInput =
view: (c, props) ->
m 'input[type="password"].form-control',
m.bind props.text, {placeholder: "Enter...