Skip to content

Loading…

Zepto.qsa & some other ternary operator changes #626

Closed
wants to merge 29 commits into from

3 participants

@shalecraig

I mentioned in #623 that I would submit a pull request that reduced the number of ternary operators that we use inside Zepto.

Here are two of these changes.

Uglify.js seems to be smart enough to inline if statements into ternary operators when they are used to build return statements, but it isn't smart enough to inline variables into ternary operators.

The code/style guide reflects these changes.

shalecraig added some commits
@shalecraig shalecraig fixing up setAttribute d119120
@shalecraig shalecraig fixing up className 677a41f
@shalecraig shalecraig First code change that exists in the minified version. 4f6d23e
@shalecraig shalecraig Yet another identical commit. 77ad587
@shalecraig shalecraig Yet another identical change. 24717c9
@shalecraig shalecraig Commit with identical minified code 390634a
@shalecraig shalecraig Made this more readable. I messed around for a while with this
change, but this is the best I could do. It's not identical in the
minified source.
f4eb5f8
@shalecraig shalecraig finished cleaning up data.js. Compiled code stays the same c8dabb8
@shalecraig shalecraig this one is a bit trickier. I saw an opportunity to minify the on/off…
… function, and went for it. Next commit will kill the ternary operators
d54aa19
@shalecraig shalecraig removed the ternary operator 3116c61
@shalecraig shalecraig opened up (a bit) of the $.Event functoin e0bcff6
@shalecraig shalecraig Looking pretty, normalizeEvent.. :D 7349601
@shalecraig shalecraig Cleaned up some of this ternary operator. 6c64710
@shalecraig shalecraig Wow, Uglify.js is stupid. 0c3d73e
@shalecraig shalecraig Oops. I think I introduced a regression.
Fixed now.
47db98f
@shalecraig shalecraig Another non-minified version change. 8ae586d
@shalecraig shalecraig First part of zepto.qsa... again f466668
@shalecraig shalecraig Another change that doesn't impact the min.js file. 65f7480
@shalecraig shalecraig Another change that doesn't impact the min.js file. 38dddbd
@shalecraig shalecraig I made three changes here that I've been making in tons of places.
We might be able to reduce the size of Zepto by making some of these
into a macro.
c6b7751
@shalecraig shalecraig Removed another ternary operator inside src/zepto.js.
Uglify.js isn't very smart, and doesn't do variable inlining like
this may take advantage of.

That being said, I think it's worth the extra 10-15 bytes for more
readability and the ability to blame without fearing "death"
f0cd5f6
@shalecraig

Ok, I lied. It's more like 29 changes.

Overall, src/zepto.js (the default rake task) is reduced to 9.122K [gzipped].

@mislav
Collaborator
@shalecraig

Looks like it wasn't looked at. Closing pull request.

@shalecraig shalecraig closed this
@mislav
Collaborator

That doesn't mean it won't be for the next release. We just didn't have time while baking the 1.0 to do so many code style & quality changes. For the same reason we also left speed optimizations for the future v1.1.

To save us some time, you chould rebase your changes to the latest master, and cleanup the history in this PR by squashing the "oops" commits into the previous commit they are fixing. Each commit should only describe 1 change to a particular piece of code.

@mislav mislav reopened this
@madrobby
Owner

@shalecraig Feel free to reopen or submit a new pull request if you still want to get this in.

@madrobby madrobby closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 25, 2012
  1. @shalecraig
  2. @shalecraig
  3. @shalecraig
  4. @shalecraig
  5. @shalecraig

    Second pass of qsa madness.

    shalecraig committed
  6. @shalecraig

    Third pass of qsa madness.

    shalecraig committed
  7. @shalecraig

    Fixed some indentation, because.

    shalecraig committed
    I didn't separate the result into its own variable, because uglify
    isn't smart enough to inline that. I'll look into adding closure to
    the build system next.
  8. @shalecraig
  9. @shalecraig

    fixing up setAttribute

    shalecraig committed
  10. @shalecraig

    fixing up className

    shalecraig committed
  11. @shalecraig
  12. @shalecraig

    Yet another identical commit.

    shalecraig committed
  13. @shalecraig

    Yet another identical change.

    shalecraig committed
  14. @shalecraig
  15. @shalecraig

    Made this more readable. I messed around for a while with this

    shalecraig committed
    change, but this is the best I could do. It's not identical in the
    minified source.
  16. @shalecraig
  17. @shalecraig

    this one is a bit trickier. I saw an opportunity to minify the on/off…

    shalecraig committed
    … function, and went for it. Next commit will kill the ternary operators
  18. @shalecraig

    removed the ternary operator

    shalecraig committed
  19. @shalecraig
  20. @shalecraig
  21. @shalecraig
  22. @shalecraig

    Wow, Uglify.js is stupid.

    shalecraig committed
  23. @shalecraig

    Oops. I think I introduced a regression.

    shalecraig committed
    Fixed now.
  24. @shalecraig
  25. @shalecraig
  26. @shalecraig
  27. @shalecraig
  28. @shalecraig

    I made three changes here that I've been making in tons of places.

    shalecraig committed
    We might be able to reduce the size of Zepto by making some of these
    into a macro.
  29. @shalecraig

    Removed another ternary operator inside src/zepto.js.

    shalecraig committed
    Uglify.js isn't very smart, and doesn't do variable inlining like
    this may take advantage of.
    
    That being said, I think it's worth the extra 10-15 bytes for more
    readability and the ability to blame without fearing "death"
Showing with 159 additions and 60 deletions.
  1. +1 −0 README.md
  2. +9 −4 src/ajax.js
  3. +17 −9 src/data.js
  4. +23 −5 src/event.js
  5. +15 −5 src/fx.js
  6. +3 −1 src/gesture.js
  7. +3 −2 src/selector.js
  8. +10 −2 src/touch.js
  9. +78 −32 src/zepto.js
View
1 README.md
@@ -200,6 +200,7 @@ $ script/test test/selector.html
* `function name() { }` for named functions
* `function(){ }` for anonymous functions
+* Ternary operators should only be used inside return statements, and shouldn't be nested.
* No curly braces for single-line control flow statements such as `if` & friends
* Don't write [semicolons that are optional][optional]
* Put a single semicolon _before_ statements that start with `(` or `[`
View
13 src/ajax.js
@@ -142,10 +142,15 @@
}
function mimeToDataType(mime) {
- return mime && ( mime == htmlType ? 'html' :
- mime == jsonType ? 'json' :
- scriptTypeRE.test(mime) ? 'script' :
- xmlTypeRE.test(mime) && 'xml' ) || 'text'
+ if (mime == htmlType)
+ return 'html'
+ else if (mime == jsonType)
+ return 'json'
+ else if (scriptTypeRE.test(mime))
+ return 'script'
+ else if (xmlTypeRE.test(mime))
+ return 'xml'
+ return mime || 'text'
}
function appendQuery(url, query) {
View
26 src/data.js
@@ -45,16 +45,24 @@
}
$.fn.data = function(name, value) {
- return value === undefined ?
+ if (value === undefined) {
// set multiple values via object
- $.isPlainObject(name) ?
- this.each(function(i, node){
- $.each(name, function(key, value){ setData(node, key, value) })
- }) :
- // get value from first element
- this.length == 0 ? undefined : getData(this[0], name) :
- // set value on all elements
- this.each(function(){ setData(this, name, value) })
+ if ($.isPlainObject(name)) {
+ return this.each(function(i, node){
+ $.each(
+ name,
+ function(key, value){
+ setData(node, key, value)
+ })
+ })
+ }
+ // get value from first element
+ if (this.length == 0) {
+ return undefined
+ }
+ return getData(this[0], name)
+ }
+ return this.each(function(){ setData(this, name, value) })
}
$.fn.removeData = function(names) {
View
28 src/event.js
@@ -178,13 +178,24 @@
return this
}
- $.fn.on = function(event, selector, callback){
+ var onOffMacro = function(isOn, event, selector, callback, context) {
+ var bind, delegate
+ if (isOn) {
+ bind = context.bind
+ delegate = context.delegate
+ } else {
+ bind = context.unbind
+ delegate = context.undelegate
+ }
return !selector || $.isFunction(selector) ?
- this.bind(event, selector || callback) : this.delegate(selector, event, callback)
+ bind.call(context, event, selector || callback) : delegate.call(context, selector, event, callback)
+ }
+
+ $.fn.on = function(event, selector, callback) {
+ return onOffMacro(true, event, selector, callback, this)
}
$.fn.off = function(event, selector, callback){
- return !selector || $.isFunction(selector) ?
- this.unbind(event, selector || callback) : this.undelegate(selector, event, callback)
+ return onOffMacro(false, event, selector, callback, this)
}
$.fn.trigger = function(event, data){
@@ -239,7 +250,14 @@
$.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])
+ if (props)
+ for (var name in props)
+ if (name == 'bubbles')
+ (bubbles = !!props[name])
+ else
+ (event[name] = props[name])
+ // TODO: this isn't the method signature. WTF
+ // https://developer.mozilla.org/en-US/docs/DOM/event.initEvent
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
20 src/fx.js
@@ -14,7 +14,12 @@
function dasherize(str) { return downcase(str.replace(/([a-z])([A-Z])/, '$1-$2')) }
function downcase(str) { return str.toLowerCase() }
- function normalizeEvent(name) { return eventPrefix ? eventPrefix + name : downcase(name) }
+ function normalizeEvent(name) {
+ if (eventPrefix) {
+ return eventPrefix + name
+ }
+ return downcase(name)
+ }
$.each(vendors, function(vendor, event){
if (testEl.style[vendor + 'TransitionProperty'] !== undefined) {
@@ -41,10 +46,15 @@
}
$.fn.animate = function(properties, duration, ease, callback){
- if ($.isObject(duration))
- ease = duration.easing, callback = duration.complete, duration = duration.duration
- if (duration) duration = (typeof duration == 'number' ? duration :
- ($.fx.speeds[duration] || $.fx.speeds._default)) / 1000
+ if ($.isObject(duration)) {
+ ease = duration.easing
+ callback = duration.complete
+ duration = duration.duration
+ }
+ if (duration && typeof duration != 'number')
+ duration = ($.fx.speeds[duration] || $.fx.speeds._default)
+ if (duration)
+ duration /= 1000
return this.anim(properties, duration, ease, callback)
}
View
4 src/gesture.js
@@ -7,7 +7,9 @@
var gesture = {}, gestureTimeout
function parentIfText(node){
- return 'tagName' in node ? node : node.parentNode
+ if ('tagName' in node)
+ return node
+ return node.parentNode
}
$(document).bind('gesturestart', function(e){
View
5 src/selector.js
@@ -67,8 +67,9 @@
} finally {
if (taggedParent) taggedParent.removeClass(classTag)
}
- return !filter ? nodes :
- zepto.uniq($.map(nodes, function(n, i){ return filter.call(n, i, nodes, arg) }))
+ if (!filter)
+ return nodes
+ return zepto.uniq($.map(nodes, function(n, i){ return filter.call(n, i, nodes, arg) }))
})
}
View
12 src/touch.js
@@ -8,12 +8,20 @@
longTapDelay = 750, longTapTimeout
function parentIfText(node) {
- return 'tagName' in node ? node : node.parentNode
+ if ('tagName' in node)
+ return node
+ return node.parentNode
}
function swipeDirection(x1, x2, y1, y2) {
var xDelta = Math.abs(x1 - x2), yDelta = Math.abs(y1 - y2)
- return xDelta >= yDelta ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
+ if (xDelta >= yDelta)
+ if (x1 - x2) > 0
+ return 'Left'
+ return 'Right'
+ if (y1 - y2) > 0
+ return 'Up'
+ return 'Down'
}
function longTap() {
View
110 src/zepto.js
@@ -55,8 +55,13 @@ var Zepto = (function() {
function likeArray(obj) { return typeof obj.length == 'number' }
function compact(array) { return filter.call(array, function(item){ return item !== undefined && item !== null }) }
- function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array }
camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) }
+ function flatten(array) {
+ if (array.length > 0) {
+ return $.fn.concat.apply([], array)
+ }
+ return array
+ }
function dasherize(str) {
return str.replace(/::/g, '/')
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
@@ -67,12 +72,15 @@ var Zepto = (function() {
uniq = function(array){ return filter.call(array, function(item, idx){ return array.indexOf(item) == idx }) }
function classRE(name) {
- return name in classCache ?
- classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)'))
+ if (name in classCache)
+ return classCache[name]
+ return (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)'))
}
function maybeAddPx(name, value) {
- return (typeof value == "number" && !cssNumber[dasherize(name)]) ? value + "px" : value
+ if (typeof value == "number" && !cssNumber[dasherize(name)])
+ return value + "px"
+ return value
}
function defaultDisplay(nodeName) {
@@ -89,9 +97,14 @@ var Zepto = (function() {
}
function children(element) {
- return 'children' in element ?
- slice.call(element.children) :
- $.map(element.childNodes, function(node){ if (node.nodeType == 1) return node })
+ if ('children' in element)
+ return slice.call(element.children)
+ return $.map(
+ element.childNodes,
+ function(node){
+ if (node.nodeType == 1)
+ return node
+ })
}
// `$.zepto.fragment` takes a html string and an optional tag name
@@ -201,18 +214,24 @@ var Zepto = (function() {
// This method can be overriden in plugins.
zepto.qsa = function(element, selector){
var found
- return (element === document && idSelectorRE.test(selector)) ?
- ( (found = element.getElementById(RegExp.$1)) ? [found] : [] ) :
- (element.nodeType !== 1 && element.nodeType !== 9) ? [] :
- slice.call(
- classSelectorRE.test(selector) ? element.getElementsByClassName(RegExp.$1) :
- tagSelectorRE.test(selector) ? element.getElementsByTagName(selector) :
- element.querySelectorAll(selector)
- )
+ if (element === document && idSelectorRE.test(selector)) {
+ if (found = element.getElementById(RegExp.$1))
+ return [found]
+ return []
+ }
+ if (element.nodeType !== 1 && element.nodeType !== 9)
+ return []
+ return slice.call(
+ classSelectorRE.test(selector) ? element.getElementsByClassName(RegExp.$1) :
+ tagSelectorRE.test(selector) ? element.getElementsByTagName(selector) :
+ element.querySelectorAll(selector)
+ )
}
function filtered(nodes, selector) {
- return selector === undefined ? $(nodes) : $(nodes).filter(selector)
+ if (selector === undefined )
+ return $(nodes)
+ return $(nodes).filter(selector)
}
$.contains = function(parent, node) {
@@ -220,11 +239,16 @@ var Zepto = (function() {
}
function funcArg(context, arg, idx, payload) {
- return isFunction(arg) ? arg.call(context, idx, payload) : arg
+ if (isFunction(arg))
+ return arg.call(context, idx, payload)
+ return arg
}
function setAttribute(node, name, value) {
- value == null ? node.removeAttribute(name) : node.setAttribute(name, value)
+ if (value == null)
+ node.removeAttribute(name)
+ else
+ node.setAttribute(name, value)
}
// access className property while respecting SVGAnimatedString
@@ -232,8 +256,15 @@ var Zepto = (function() {
var klass = node.className,
svg = klass && klass.baseVal !== undefined
- if (value === undefined) return svg ? klass.baseVal : klass
- svg ? (klass.baseVal = value) : (node.className = value)
+ if (value === undefined) {
+ if (svg)
+ return klass.baseVal
+ return klass
+ }
+ if (svg)
+ klass.baseVal = value
+ else
+ node.className = value
}
// "true" => true
@@ -246,14 +277,21 @@ var Zepto = (function() {
function deserializeValue(value) {
var num
try {
- return value ?
- value == "true" ||
- ( value == "false" ? false :
- value == "null" ? null :
- !isNaN(num = Number(value)) ? num :
- /^[\[\{]/.test(value) ? $.parseJSON(value) :
- value )
- : value
+ if (value)
+ if (value == "true")
+ return true
+ else if (value == "false")
+ return false
+ else if (value == "null")
+ return null
+ else if (!isNaN(num = Number(value)))
+ return num
+ else if (/^[\[\{]/.test(value))
+ return $.parseJSON(value)
+ else
+ return value
+ else
+ return value
} catch(e) {
return value
}
@@ -337,7 +375,9 @@ var Zepto = (function() {
return this
},
get: function(idx){
- return idx === undefined ? slice.call(this) : this[idx]
+ if (idx === undefined)
+ return slice.call(this)
+ return this[idx]
},
toArray: function(){ return this.get() },
size: function(){
@@ -372,10 +412,16 @@ var Zepto = (function() {
if (!selector.call(this,idx)) nodes.push(this)
})
else {
- var excludes = typeof selector == 'string' ? this.filter(selector) :
- (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector)
+ var excludes;
+ if (typeof selector == 'string')
+ excludes = this.filter(selector)
+ else if (likeArray(selector) && isFunction(selector.item))
+ excludes = slice.call(selector)
+ else
+ excludes = $(selector)
this.forEach(function(el){
- if (excludes.indexOf(el) < 0) nodes.push(el)
+ if (excludes.indexOf(el) < 0)
+ nodes.push(el)
})
}
return $(nodes)
Something went wrong with that request. Please try again.