193 lines
5.2 KiB
JavaScript
193 lines
5.2 KiB
JavaScript
/*
|
|
* Sensitive field widget plugin.
|
|
*
|
|
* Data attributes:
|
|
* - data-control="sensitive" - enables the plugin on an element
|
|
*
|
|
* JavaScript API:
|
|
* $('div#someElement').sensitive({...})
|
|
*/
|
|
+function ($) { "use strict";
|
|
var Base = $.oc.foundation.base,
|
|
BaseProto = Base.prototype
|
|
|
|
var Sensitive = function(element, options) {
|
|
this.$el = $(element)
|
|
this.options = options
|
|
this.clean = Boolean(this.$el.data('clean'))
|
|
this.hidden = true
|
|
|
|
this.$input = this.$el.find('[data-input]').first()
|
|
this.$toggle = this.$el.find('[data-toggle]').first()
|
|
this.$icon = this.$el.find('[data-icon]').first()
|
|
this.$loader = this.$el.find('[data-loader]').first()
|
|
this.$copy = this.$el.find('[data-copy]').first()
|
|
|
|
$.oc.foundation.controlUtils.markDisposable(element)
|
|
Base.call(this)
|
|
this.init()
|
|
}
|
|
|
|
Sensitive.DEFAULTS = {
|
|
readOnly: false,
|
|
disabled: false,
|
|
eventHandler: null,
|
|
hideOnTabChange: false,
|
|
}
|
|
|
|
Sensitive.prototype = Object.create(BaseProto)
|
|
Sensitive.prototype.constructor = Sensitive
|
|
|
|
Sensitive.prototype.init = function() {
|
|
this.$input.on('keydown', this.proxy(this.onInput))
|
|
this.$toggle.on('click', this.proxy(this.onToggle))
|
|
|
|
if (this.options.hideOnTabChange) {
|
|
// Watch for tab change or minimise
|
|
document.addEventListener('visibilitychange', this.proxy(this.onTabChange))
|
|
}
|
|
|
|
if (this.$copy.length) {
|
|
this.$copy.on('click', this.proxy(this.onCopy))
|
|
}
|
|
}
|
|
|
|
Sensitive.prototype.dispose = function () {
|
|
this.$input.off('keydown', this.proxy(this.onInput))
|
|
this.$toggle.off('click', this.proxy(this.onToggle))
|
|
|
|
if (this.options.hideOnTabChange) {
|
|
document.removeEventListener('visibilitychange', this.proxy(this.onTabChange))
|
|
}
|
|
|
|
if (this.$copy.length) {
|
|
this.$copy.off('click', this.proxy(this.onCopy))
|
|
}
|
|
|
|
this.$input = this.$toggle = this.$icon = this.$loader = null
|
|
this.$el = null
|
|
|
|
BaseProto.dispose.call(this)
|
|
}
|
|
|
|
Sensitive.prototype.onInput = function() {
|
|
if (this.clean) {
|
|
this.clean = false
|
|
this.$input.val('')
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
Sensitive.prototype.onToggle = function() {
|
|
if (this.$input.val() !== '' && this.clean) {
|
|
this.reveal()
|
|
} else {
|
|
this.toggleVisibility()
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
Sensitive.prototype.onTabChange = function() {
|
|
if (document.hidden && !this.hidden) {
|
|
this.toggleVisibility()
|
|
}
|
|
}
|
|
|
|
Sensitive.prototype.onCopy = function() {
|
|
var that = this,
|
|
deferred = $.Deferred(),
|
|
isHidden = this.hidden
|
|
|
|
deferred.then(function () {
|
|
if (that.hidden) {
|
|
that.toggleVisibility()
|
|
}
|
|
|
|
that.$input.focus()
|
|
that.$input.select()
|
|
|
|
try {
|
|
document.execCommand('copy')
|
|
} catch (err) {
|
|
}
|
|
|
|
that.$input.blur()
|
|
if (isHidden) {
|
|
that.toggleVisibility()
|
|
}
|
|
})
|
|
|
|
if (this.$input.val() !== '' && this.clean) {
|
|
this.reveal(deferred)
|
|
} else {
|
|
deferred.resolve()
|
|
}
|
|
}
|
|
|
|
Sensitive.prototype.toggleVisibility = function() {
|
|
if (this.hidden) {
|
|
this.$input.attr('type', 'text')
|
|
} else {
|
|
this.$input.attr('type', 'password')
|
|
}
|
|
|
|
this.$icon.toggleClass('icon-eye icon-eye-slash')
|
|
|
|
this.hidden = !this.hidden
|
|
}
|
|
|
|
Sensitive.prototype.reveal = function(deferred) {
|
|
var that = this
|
|
this.$icon.css({
|
|
visibility: 'hidden'
|
|
})
|
|
this.$loader.removeClass('hide')
|
|
|
|
this.$input.request(this.options.eventHandler, {
|
|
success: function (data) {
|
|
that.$input.val(data.value)
|
|
that.clean = false
|
|
|
|
that.$icon.css({
|
|
visibility: 'visible'
|
|
})
|
|
that.$loader.addClass('hide')
|
|
|
|
that.toggleVisibility()
|
|
|
|
if (deferred) {
|
|
deferred.resolve()
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
var old = $.fn.sensitive
|
|
|
|
$.fn.sensitive = function (option) {
|
|
var args = Array.prototype.slice.call(arguments, 1), result
|
|
this.each(function () {
|
|
var $this = $(this)
|
|
var data = $this.data('oc.sensitive')
|
|
var options = $.extend({}, Sensitive.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
|
if (!data) $this.data('oc.sensitive', (data = new Sensitive(this, options)))
|
|
if (typeof option == 'string') result = data[option].apply(data, args)
|
|
if (typeof result != 'undefined') return false
|
|
})
|
|
|
|
return result ? result : this
|
|
}
|
|
|
|
$.fn.sensitive.noConflict = function () {
|
|
$.fn.sensitive = old
|
|
return this
|
|
}
|
|
|
|
$(document).render(function () {
|
|
$('[data-control="sensitive"]').sensitive()
|
|
});
|
|
|
|
}(window.jQuery);
|