Permalink
Browse files

Twitter Bootstrap compatibility

To use Zepto with Bootstrap:

  1. Ensure that you use the optional "data", "selector", and "detect"
     Zepto modules. "detect" is unnecessary, however, if you simply define:
     `Zepto.browser = {webkit: true}
  2. Assign `window.jQuery = Zepto` before loading Bootstrap js files
  • Loading branch information...
2 parents 17f69f4 + c6bd87e commit 1d5daef9f8abd9b92340c135bfbb11a7ce1a83a6 @mislav mislav committed Oct 7, 2012
Showing with 319 additions and 46 deletions.
  1. +3 −2 src/data.js
  2. +34 −14 src/event.js
  3. +15 −4 src/selector.js
  4. +92 −11 src/zepto.js
  5. +6 −4 test/data.html
  6. +9 −5 test/event.html
  7. +32 −1 test/selector.html
  8. +128 −5 test/zepto.html
View
@@ -5,7 +5,7 @@
// The following code is heavily inspired by jQuery's $.fn.data()
;(function($) {
- var data = {}, dataAttr = $.fn.data, camelize = $.zepto.camelize,
+ var data = {}, dataAttr = $.fn.data, camelize = $.camelCase,
exp = $.expando = 'Zepto' + (+new Date())
// Get value from node:
@@ -38,7 +38,8 @@
var store = {}
$.each(node.attributes, function(i, attr){
if (attr.name.indexOf('data-') == 0)
- store[camelize(attr.name.replace('data-', ''))] = attr.value
+ store[camelize(attr.name.replace('data-', ''))] =
+ $.zepto.deserializeValue(attr.value)
})
return store
}
View
@@ -3,7 +3,8 @@
// Zepto.js may be freely distributed under the MIT license.
;(function($){
- var $$ = $.zepto.qsa, handlers = {}, _zid = 1, specialEvents={}
+ var $$ = $.zepto.qsa, handlers = {}, _zid = 1, specialEvents={},
+ hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' }
specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents'
@@ -40,27 +41,40 @@
!!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 delegate = getDelegate && getDelegate(fn, event),
- callback = delegate || fn
- var proxyfn = function (event) {
- var result = callback.apply(element, [event].concat(event.data))
- if (result === false) event.preventDefault()
+ 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
}
- var handler = $.extend(parse(event), {fn: fn, proxy: proxyfn, sel: selector, del: delegate, i: set.length})
+ handler.i = set.length
set.push(handler)
- element.addEventListener(handler.e, proxyfn, eventCapture(handler, capture))
+ 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(handler.e, handler.proxy, eventCapture(handler, capture))
+ element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
})
})
}
@@ -165,16 +179,16 @@
}
$.fn.on = function(event, selector, callback){
- return selector == undefined || $.isFunction(selector) ?
+ return !selector || $.isFunction(selector) ?
this.bind(event, selector || callback) : this.delegate(selector, event, callback)
}
$.fn.off = function(event, selector, callback){
- return selector == undefined || $.isFunction(selector) ?
+ return !selector || $.isFunction(selector) ?
this.unbind(event, selector || callback) : this.undelegate(selector, event, callback)
}
$.fn.trigger = function(event, data){
- if (typeof event == 'string') event = $.Event(event)
+ if (typeof event == 'string' || $.isPlainObject(event)) event = $.Event(event)
fix(event)
event.data = data
return this.each(function(){
@@ -202,9 +216,13 @@
// shortcut methods for `.bind(event, fn)` for each event type
;('focusin focusout load resize scroll unload click dblclick '+
- 'mousedown mouseup mousemove mouseover mouseout '+
+ 'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+
'change select keydown keypress keyup error').split(' ').forEach(function(event) {
- $.fn[event] = function(callback){ return this.bind(event, callback) }
+ $.fn[event] = function(callback) {
+ return callback ?
+ this.bind(event, callback) :
+ this.trigger(event)
+ }
})
;['focus', 'blur'].forEach(function(name) {
@@ -219,9 +237,11 @@
})
$.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
}
View
@@ -16,9 +16,8 @@
//
// Complex selectors are not supported:
// li:has(label:contains("foo")) + li:has(label:contains("bar"))
- // "> h2"
// ul.inner:first > li
- var filters = zepto.cssFilters = {
+ var filters = $.expr[':'] = {
visible: function(){ if (visible(this)) return this },
hidden: function(){ if (!visible(this)) return this },
selected: function(){ if (this.selected) return this },
@@ -31,10 +30,14 @@
has: function(idx, _, sel){ if (zepto.qsa(this, sel).length) return this }
}
- var re = new RegExp('(.*):(\\w+)(?:\\(([^)]+)\\))?$\\s*')
+ var filterRe = new RegExp('(.*):(\\w+)(?:\\(([^)]+)\\))?$\\s*'),
+ childRe = /^\s*>/,
+ classTag = 'Zepto' + (+new Date())
function process(sel, fn) {
- var filter, arg, match = sel.match(re)
+ // quote the hash in `a[href^=#]` expression
+ sel = sel.replace(/=#\]/g, '="#"]')
+ var filter, arg, match = filterRe.exec(sel)
if (match && match[2] in filters) {
var filter = filters[match[2]], arg = match[3]
sel = match[1]
@@ -50,11 +53,19 @@
zepto.qsa = function(node, selector) {
return process(selector, function(sel, filter, arg){
try {
+ var taggedParent
if (!sel && filter) sel = '*'
+ else if (childRe.test(sel))
+ // support "> *" child queries by tagging the parent node with a
+ // unique class and prepending that classname onto the selector
+ taggedParent = $(node).addClass(classTag), sel = '.'+classTag+' '+sel
+
var nodes = oldQsa(node, sel)
} catch(e) {
console.error('error performing selector: %o', selector)
throw e
+ } finally {
+ if (taggedParent) taggedParent.removeClass(classTag)
}
return !filter ? nodes :
zepto.uniq($.map(nodes, function(n, i){ return filter.call(n, i, nodes, arg) }))
Oops, something went wrong.

2 comments on commit 1d5daef

❤️

Great!

Please sign in to comment.