Yahoo! UI Library

crypto  1.0.0

Yahoo! UI Library > crypto > chromahash.js (source view)
Search:
 
Filters
/*
 * Chroma-Hash : A sexy, non-reversable live visualization of password field input
 * Idea based on jQuery module by Mattt Thompson (http://github.com/mattt/Chroma-Hash/)
 */

var LBL_TMPL = '<label for="{id}" class="{color} chroma-hash"></label>',
		_C = function(conf) { 
			this._animations = [];
			_C.superclass.constructor.apply(this, arguments);
			this.renderUI();
			this.bindUI();
		};
_C.NAME = "ChromaHash";
_C.NS = "ChromaHash";
_C.ATTRS = 
	{
		bars: {
			value: 3,
			validator: function(b) {
				if (b < 1 || b > 4) {
					return false;
				}
			}
		},
		salt: {
			value: "7be82b35cb0199120eea35a4507c9acf",
			validator: Y.Lang.isString
		},
		minimum: {
			value: 6,
			validator: Y.Lang.isNumber
		},
		animationDuration: {
			value: 0.5,
			validator: Y.Lang.isNumber,
			setter: function(value) {
				Y.Array.each(this._animations, function(anim) {
					anim.set('duration',  value);
				});
			}
		},
		host: {
			validator:function(node) {
				if(!node.test('input[type=password]')) {
					Y.fail("ChromaHash can't be attached to this node.");
					return false;
				}
				return true;
			},
			setter: function(node) {
				this._lblQry = 'label[for=' + node.get('name') + '].chroma-hash';
				return node;
			}
		}
 };
Y.extend(_C, Y.Plugin.Base, {
	renderBars: function() {
		var colors = ["primary", "secondary", "tertiary", "quaternary"].slice(0, this.get('bars')),
			c = Y.get('body'), n = this.get('host'), i, lbl, width = n.get('clientWidth'),
			height = n.get('clientHeight'), position = n.getXY();
		for (i = 0 ; i < colors.length ; i += 1) {
			lbl = Y.Node.create(LBL_TMPL.replace(/\{id\}/g, n.get('id')).replace(/\{color\}/g, colors[i]));
			lbl.setStyles({
				position: 'absolute',
				height: height + "px",
				width: "8px",
				margin: "5px",
				marginLeft: "0px",
				backgroundColor: n.getStyle('backgroundColor')
			});
			c.insert(lbl);
			lbl.setXY([position[0] + width - 2 + (-8 * (i + 1)), position[1] + 3]);
			this._animations.push(new Y.Anim({node: lbl, duration: this.get('animationDuration')}));
		}
	},
	renderUI: function() {
		if (!this._rendered) {
			this.renderBars();
			this._rendered = true;
		}
	},
	bindUI: function() {
		this._keyHandler = this.get('host').after('keyup', this._handleKey, this);
	},
	hide: function() {
		Y.all(this._lblQry).setStyle('display','none');
	},
	clear: function() {
		this.hide();
		Y.all(this._lblQry).remove();
		this._rendered = false;
	},
	destroy: function() {
		this._keyHandler.detach();
		this._clear();
	},
	_handleKey: function(e) {
		var n = this.get('host'), value = n.get('value'), i,
				col = [], bars = this.get('bars'), md5, g;
		if(value === "" ) {
			for( i = 0 ; i < bars ; i += 1) { col.push('fff'); }
		} else {
			md5 = Y.Crypto.MD5('' + value + ':' + this.get('salt'));
			col = md5.match(/([\dABCDEF]{6})/ig);
			if (value.length < this.get('minimum')) {
				for (i = 0; i < bars ; i += 1) {
					g = (parseInt(col[i], 0x10) % 0xF).toString(0x10);
					col[i] = g + g + g;
				}
			}
		}

		Y.Array.each(this._animations,
				function(a, index) {
					a.stop();
					a.set('from', {backgroundColor: n.getStyle('backgroundColor')});
					a.set('to', {backgroundColor: '#' + col[index] });
					a.run();
				});
	}
});
Y.ChromaHash = _C;

Copyright © 2011 Yahoo! Inc. All rights reserved.