Skip to content

Commit

Permalink
Foreach (#1), automatic wrapping, feedback message, feature flags
Browse files Browse the repository at this point in the history
* added feedback message; $.each(...) functionality; restructuring wrapping; feature flags

* wrapper should have flexible height

* strength bar width should be limited

* Updated with changes for pull request

Reverted version to 0.5.0.  Reverted URL.  Fixed foreach.  Added 'use
strict'.  Granularized javascript.  Warn if no visualizations enabled.

* changing version to 0.5.0 in css
  • Loading branch information
emragins authored and MorrisJobke committed Apr 6, 2016
1 parent b3df934 commit 8001334
Show file tree
Hide file tree
Showing 4 changed files with 212 additions and 120 deletions.
40 changes: 30 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,26 @@ Combine jQuery and zxcvbn to create a password strength meter.
How to use
----------

Add the following wrapper to your document - preferably near the
password field.
As of 0.5.0, the wrapper will be automatically added beneath the target input field

```HTML
<div class="strengthify-wrapper"></div>
```

Add `jquery` (tested with 1.10.0), bootstrap's `tooltip.js`, `jquery.strengthify.js` and
Add `jquery` (tested with 1.10.0), `jquery.strengthify.js` and
`strengthify.css` to your document.

If using the message option, include bootstrap.

If using the titles option, include bootstrap's `tooltip.js`,

```HTML
<script src="jquery-1.10.0.min.js"></script>
<script src="tooltip.js"></script>
<script src="jquery.strengthify.js"></script>
<link rel="stylesheet" href="bootstrap.min.css" type="text/css">
<link rel="stylesheet" href="strengthify.css" type="text/css">
```

Because [zxcvbn](https://github.com/lowe/zxcvbn) is really
heavyweight, it will be loaded asynchronously from `zxcvbn/zxcvbn.js`. This can however be configured with an optional parameter.
heavyweight, it will be loaded asynchronously from `zxcvbn/zxcvbn.js`.
This can however be configured with an optional parameter.

Then call `.strengthify` on the password input field.

Expand All @@ -41,6 +42,13 @@ Configuration
The path and the title of the different strength categories can
be configured with the first parameter of `.strengthify`.


<dl>
<dt>drawTitles</dt><dd> pop-up text (above)</dd>
<dt>drawMessage</dt><dd> detailed message beneath input</dd>
<dt>drawBars</dt><dd> password strength color progression bars beneath input</dd>
</dl>

Default:

```JSON
Expand All @@ -52,10 +60,12 @@ Default:
"So-so",
"Good",
"Perfect"
]
],
"drawTitles": false,
"drawMessage": false,
"drawBars": true
}
```

Overwrite example:

```JavaScript
Expand All @@ -66,6 +76,16 @@ Versions
--------

<dl>
<dt>0.5.0</dt>
<dd> fairly substantial changes:
<ul>
<li>added feedback message</li>
<li> $.each(...) functionality</li>
<li> restructuring wrapping</li>
<li> feature flags</li>
</ul>
"strengthify-wrapper" added automatically beneath target input
</dd>
<dt>0.4.1</dt>
<dd>hotfix for missing ;</dd>
<dt>0.4</dt>
Expand Down
3 changes: 2 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"name": "strengthify",
"version": "0.4.2",
"version": "0.5.0",
"homepage": "https://github.com/MorrisJobke/strengthify",
"authors": [
"Eve Ragins <[email protected]",
"Morris Jobke <[email protected]>"
],
"description": "Combine jQuery and zxcvbn to create a password strength meter.",
Expand Down
277 changes: 170 additions & 107 deletions jquery.strengthify.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
* Strengthify - show the weakness of a password (uses zxcvbn for this)
* https://github.com/MorrisJobke/strengthify
*
* Version: 0.4.2
* Author: Morris Jobke (github.com/MorrisJobke)
* Version: 0.5.0
* Author: Morris Jobke (github.com/MorrisJobke) - original
* Eve Ragins @ Eve Corp (github.com/eve-corp)
*
*
* License:
*
Expand All @@ -30,108 +32,169 @@
*/

/* global jQuery */
(function ($) {
$.fn.strengthify = function(paramOptions) {
var me = this,
defaults = {
zxcvbn: 'zxcvbn/zxcvbn.js',
titles: [
'Weakest',
'Weak',
'So-so',
'Good',
'Perfect'
]
},
options = $.extend(defaults, paramOptions),
drawStrengthify = function() {
var password = $(me).val(),
// hide strengthigy if no input is provided
opacity = (password === '') ? 0 : 1,
// calculate result
result = zxcvbn(password),
css = '',
// cache jQuery selections
$container = $('.strengthify-container'),
$wrapper = $('.strengthify-wrapper');

$wrapper.children().css(
'opacity',
opacity
).css(
'-ms-filter',
'"progid:DXImageTransform.Microsoft.Alpha(Opacity=' + opacity * 100 + ')"'
);

// style strengthify bar
// possible scores: 0-4
switch(result.score) {
case 0:
case 1:
css = 'password-bad';
break;
case 2:
css = 'password-medium';
break;
case 3:
case 4:
css = 'password-good';
break;
}

$container
.attr('class', css + ' strengthify-container')
// possible scores: 0-4
.css(
'width',
// if score is '0' it will be changed to '1' to
// not hide strengthify if the password is extremely weak
((result.score === 0 ? 1 : result.score) * 25) + '%'
);

// set a title for the wrapper
$wrapper.attr(
'title',
options.titles[result.score]
).tooltip({
placement: 'bottom',
trigger: 'manual',
}).tooltip(
'show'
);

if(opacity === 0) {
$wrapper.tooltip(
'hide'
);
}

// reset state for empty string password
if(password === '') {
$container.css('width', 0);
}

};

// add elements
$('.strengthify-wrapper')
.append('<div class="strengthify-bg" />')
.append('<div class="strengthify-container" />')
.append('<div class="strengthify-separator" style="left: 25%" />')
.append('<div class="strengthify-separator" style="left: 50%" />')
.append('<div class="strengthify-separator" style="left: 75%" />');

me.parents().on('scroll', drawStrengthify);

$.ajax({
cache: true,
dataType: 'script',
url: options.zxcvbn
}).done(function() {
me.bind('keyup input change', drawStrengthify);
});

return me;
};

}(jQuery));
(function($) {
$.fn.strengthify = function(paramOptions) {
"use strict";

var defaults = {
zxcvbn: 'zxcvbn/zxcvbn.js',
titles: [
'Weakest',
'Weak',
'So-so',
'Good',
'Perfect'
],
drawTitles: false,
drawMessage: false,
drawBars: true
};

return this.each(function() {
var options = $.extend(defaults, paramOptions);

if (!options.drawTitles
&& !options.drawMessage
&& !options.drawBars)
console.warn("expect at least one of 'drawTitles', 'drawMessage', or 'drawBars' to be true");

function getWrapperFor(id) {
return $('div[data-strengthifyFor="' + id + '"]');
};

function drawStrengthify() {
var password = $(this).val(),
elemId = $(this).attr('id'),
// hide strengthify if no input is provided
opacity = (password === '') ? 0 : 1,
// calculate result
result = zxcvbn(password),
// setup some vars for later
css = '',
bsLevel = '',
message = '',
// cache jQuery selections
$wrapper = getWrapperFor(elemId),
$container = $wrapper.find('.strengthify-container'),
$message = $wrapper.find('[data-strengthifyMessage]');


$wrapper.children()
.css('opacity', opacity)
.css('-ms-filter',
'"progid:DXImageTransform.Microsoft.Alpha(Opacity=' + opacity * 100 + ')"'
);

// style strengthify bar
// possible scores: 0-4
switch (result.score) {
case 0:
case 1:
css = 'password-bad';
bsLevel = 'danger';
message = result.feedback ? result.feedback.suggestions.join('<br/>') : "";
break;
case 2:
bsLevel = 'warning';
message = result.feedback ? result.feedback.suggestions.join('<br/>') : "";
css = 'password-medium';
break;
case 3:
css = 'password-good';
bsLevel = 'info';
message = "Getting better.";
case 4:
css = 'password-good';
bsLevel = 'success';
message = "Looks good.";
break;
}

if ($message) {
$message.removeAttr('class');
$message.addClass('bg-' + bsLevel);

// reset state for empty string password
if (password === '') {
message = '';
}
$message.html(message);
}
if ($container) {
$container
.attr('class', css + ' strengthify-container')
// possible scores: 0-4
.css(
'width',
// if score is '0' it will be changed to '1' to
// not hide strengthify if the password is extremely weak
((result.score === 0 ? 1 : result.score) * 25) + '%'
);

// reset state for empty string password
if (password === '') {
$container.css('width', 0);
}
}

if (options.drawTitles) {
// set a title for the wrapper
$wrapper.attr(
'title',
options.titles[result.score]
).tooltip({
placement: 'bottom',
trigger: 'manual',
}).tooltip(
'fixTitle'
).tooltip(
'show'
);

if (opacity === 0) {
$wrapper.tooltip(
'hide'
);
}
}
};

function init() {
var $elem = $(this),
elemId = $elem.attr('id');
var drawSelf = drawStrengthify.bind(this);

// add elements
$elem.after('<div class="strengthify-wrapper" data-strengthifyFor="' + $elem.attr('id') + '"></div>');

if (options.drawBars) {
getWrapperFor(elemId)
.append('<div class="strengthify-bg" />')
.append('<div class="strengthify-container" />')
.append('<div class="strengthify-separator" style="left: 25%" />')
.append('<div class="strengthify-separator" style="left: 50%" />')
.append('<div class="strengthify-separator" style="left: 75%" />');
}

if (options.drawMessage) {
getWrapperFor(elemId).append('<div data-strengthifyMessage></div>');
}

$elem.parent().on('scroll', drawSelf);

$.ajax({
cache: true,
dataType: 'script',
url: options.zxcvbn
}).done(function() {
$elem.bind('keyup input change', drawSelf);
});
};

init.call(this);

//return me;
});
};

} (jQuery));
Loading

0 comments on commit 8001334

Please sign in to comment.