1
0
mirror of http://git.whoc.org.uk/git/password-manager.git synced 2025-01-10 23:30:03 +01:00
password-manager-mirror/frontend/gamma/js/Zepto/event.js
Clipperz 644891059e Added JQTouch and Zepto libraries
JQTouch and Zepto are tentatively used for the mobile version of Clipperz.
No final commitment has been made, though.
2013-01-09 10:03:53 +01:00

249 lines
8.2 KiB
JavaScript

// Zepto.js
// (c) 2010-2012 Thomas Fuchs
// Zepto.js may be freely distributed under the MIT license.
;(function($){
var $$ = $.zepto.qsa, handlers = {}, _zid = 1, specialEvents={},
hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' }
specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents'
function zid(element) {
return element._zid || (element._zid = _zid++)
}
function findHandlers(element, event, fn, selector) {
event = parse(event)
if (event.ns) var matcher = matcherFor(event.ns)
return (handlers[zid(element)] || []).filter(function(handler) {
return handler
&& (!event.e || handler.e == event.e)
&& (!event.ns || matcher.test(handler.ns))
&& (!fn || zid(handler.fn) === zid(fn))
&& (!selector || handler.sel == selector)
})
}
function parse(event) {
var parts = ('' + event).split('.')
return {e: parts[0], ns: parts.slice(1).sort().join(' ')}
}
function matcherFor(ns) {
return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)')
}
function eachEvent(events, fn, iterator){
if ($.isObject(events)) $.each(events, iterator)
else events.split(/\s/).forEach(function(type){ iterator(type, fn) })
}
function eventCapture(handler, captureSetting) {
return handler.del &&
(handler.e == 'focus' || handler.e == 'blur') ||
!!captureSetting
}
function realEvent(type) {
return hover[type] || type
}
function add(element, events, fn, selector, getDelegate, capture){
var id = zid(element), set = (handlers[id] || (handlers[id] = []))
eachEvent(events, fn, function(event, fn){
var handler = parse(event)
handler.fn = fn
handler.sel = selector
// emulate mouseenter, mouseleave
if (handler.e in hover) fn = function(e){
var related = e.relatedTarget
if (!related || (related !== this && !$.contains(this, related)))
return handler.fn.apply(this, arguments)
}
handler.del = getDelegate && getDelegate(fn, event)
var callback = handler.del || fn
handler.proxy = function (e) {
var result = callback.apply(element, [e].concat(e.data))
if (result === false) e.preventDefault(), e.stopPropagation()
return result
}
handler.i = set.length
set.push(handler)
element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
})
}
function remove(element, events, fn, selector, capture){
var id = zid(element)
eachEvent(events || '', fn, function(event, fn){
findHandlers(element, event, fn, selector).forEach(function(handler){
delete handlers[id][handler.i]
element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
})
})
}
$.event = { add: add, remove: remove }
$.proxy = function(fn, context) {
if ($.isFunction(fn)) {
var proxyFn = function(){ return fn.apply(context, arguments) }
proxyFn._zid = zid(fn)
return proxyFn
} else if (typeof context == 'string') {
return $.proxy(fn[context], fn)
} else {
throw new TypeError("expected function")
}
}
$.fn.bind = function(event, callback){
return this.each(function(){
add(this, event, callback)
})
}
$.fn.unbind = function(event, callback){
return this.each(function(){
remove(this, event, callback)
})
}
$.fn.one = function(event, callback){
return this.each(function(i, element){
add(this, event, callback, null, function(fn, type){
return function(){
var result = fn.apply(element, arguments)
remove(element, type, fn)
return result
}
})
})
}
var returnTrue = function(){return true},
returnFalse = function(){return false},
ignoreProperties = /^([A-Z]|layer[XY]$)/,
eventMethods = {
preventDefault: 'isDefaultPrevented',
stopImmediatePropagation: 'isImmediatePropagationStopped',
stopPropagation: 'isPropagationStopped'
}
function createProxy(event) {
var key, proxy = { originalEvent: event }
for (key in event)
if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key]
$.each(eventMethods, function(name, predicate) {
proxy[name] = function(){
this[predicate] = returnTrue
return event[name].apply(event, arguments)
}
proxy[predicate] = returnFalse
})
return proxy
}
// emulates the 'defaultPrevented' property for browsers that have none
function fix(event) {
if (!('defaultPrevented' in event)) {
event.defaultPrevented = false
var prevent = event.preventDefault
event.preventDefault = function() {
this.defaultPrevented = true
prevent.call(this)
}
}
}
$.fn.delegate = function(selector, event, callback){
return this.each(function(i, element){
add(element, event, callback, selector, function(fn){
return function(e){
var evt, match = $(e.target).closest(selector, element).get(0)
if (match) {
evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element})
return fn.apply(match, [evt].concat([].slice.call(arguments, 1)))
}
}
})
})
}
$.fn.undelegate = function(selector, event, callback){
return this.each(function(){
remove(this, event, callback, selector)
})
}
$.fn.live = function(event, callback){
$(document.body).delegate(this.selector, event, callback)
return this
}
$.fn.die = function(event, callback){
$(document.body).undelegate(this.selector, event, callback)
return this
}
$.fn.on = function(event, selector, callback){
return !selector || $.isFunction(selector) ?
this.bind(event, selector || callback) : this.delegate(selector, event, callback)
}
$.fn.off = function(event, selector, callback){
return !selector || $.isFunction(selector) ?
this.unbind(event, selector || callback) : this.undelegate(selector, event, callback)
}
$.fn.trigger = function(event, data){
if (typeof event == 'string' || $.isPlainObject(event)) event = $.Event(event)
fix(event)
event.data = data
return this.each(function(){
// items in the collection might not be DOM elements
// (todo: possibly support events on plain old objects)
if('dispatchEvent' in this) this.dispatchEvent(event)
})
}
// triggers event handlers on current element just as if an event occurred,
// doesn't trigger an actual event, doesn't bubble
$.fn.triggerHandler = function(event, data){
var e, result
this.each(function(i, element){
e = createProxy(typeof event == 'string' ? $.Event(event) : event)
e.data = data
e.target = element
$.each(findHandlers(element, event.type || event), function(i, handler){
result = handler.proxy(e)
if (e.isImmediatePropagationStopped()) return false
})
})
return result
}
// shortcut methods for `.bind(event, fn)` for each event type
;('focusin focusout load resize scroll unload click dblclick '+
'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+
'change select keydown keypress keyup error').split(' ').forEach(function(event) {
$.fn[event] = function(callback) {
return callback ?
this.bind(event, callback) :
this.trigger(event)
}
})
;['focus', 'blur'].forEach(function(name) {
$.fn[name] = function(callback) {
if (callback) this.bind(name, callback)
else this.each(function(){
try { this[name]() }
catch(e) {}
})
return this
}
})
$.Event = function(type, props) {
if (typeof type != 'string') props = type, type = props.type
var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true
if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name])
event.initEvent(type, bubbles, true, null, null, null, null, null, null, null, null, null, null, null, null)
event.isDefaultPrevented = function(){ return this.defaultPrevented }
return event
}
})(Zepto)