Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.

Bb view hooks #780

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
84fe942
start on removing jquery logic branching for view remove hooks
akre54 Mar 18, 2014
b55f8ec
use a classList for class changes
akre54 Mar 18, 2014
eba1c20
point bower at recent backbone sha
akre54 Aug 19, 2014
c321e26
view fixes
akre54 Aug 20, 2014
73f17aa
stub out jquery in tests...
akre54 Aug 27, 2014
49b8854
use listEl instead of $list
akre54 Sep 10, 2014
bb5567e
Update grunt-mocha
Florian-R Jan 7, 2015
56c922b
Point Bower to correct backbone.nativeview
Florian-R Jan 7, 2015
fc94605
Fix endAnimation
Florian-R Jan 8, 2015
422ea76
Remove some tests for animations
Florian-R Jan 8, 2015
1c63e3e
Fix insertView
Florian-R Jan 8, 2015
a1c6c52
Use Backbone.$ instead of $
Florian-R Jan 9, 2015
cf2ab90
Merge pull request #1 from Florian-R/bb-view-hooks
akre54 Jan 9, 2015
6ad87e3
Add utils.matchesSelector
Florian-R Jan 14, 2015
6e628f9
More fix for insertView
Florian-R Jan 12, 2015
969a9e3
Remove automatic binding of utils.matchesSelector
Florian-R Jan 14, 2015
048a406
Merge pull request #2 from Florian-R/bb-view-hooks
akre54 Jan 14, 2015
ffaa3f9
Start to remove instance of $ in Layout
Florian-R Feb 6, 2015
6b9b4f5
More Layout fixes
Florian-R Feb 9, 2015
f180122
Fix test setup with NativeView
Florian-R Feb 9, 2015
0060d5c
Stub Underscore methods for tests without deps
Florian-R Feb 10, 2015
a455973
bump backbone version
akre54 May 19, 2015
f8da2d0
Revert currentTarget inLayout
Florian-R Sep 1, 2015
a78f929
Fix View
Florian-R Sep 2, 2015
71551c1
Fix CollectionView
Florian-R Sep 2, 2015
567c10c
Merge pull request #4 from Florian-R/bb-view-hooks
akre54 Oct 13, 2015
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
"expect": "0.2.x",
"jquery": "1.9.x",
"lodash": "2.3.x",
"backbone": "1.1.x",
"backbone": "1.2.0",
"benchmark": "git://github.com/bestiejs/benchmark.js.git",
"sinon": "http://sinonjs.org/releases/sinon-1.7.1.js",
"requirejs": "~2.1.8",
"davy": "~0.0.4",
"exoskeleton": "~0.6.0"
"backbone.nativeview": "0.3.1",
"exoskeleton": "~0.7.0"
},
"exportsOverride": {
"mocha": {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"grunt-istanbul": "0.2.x",
"grunt-urequire": "git://github.com/concordusapps/grunt-urequire",
"grunt-coffeelint": "0.0.x",
"grunt-mocha": "0.2.x",
"grunt-mocha": "0.4.11",
"grunt-transbrute": "~0.2.0",
"prompt": "0.2.x",
"phantomjs": "1.9.x"
Expand Down
19 changes: 19 additions & 0 deletions src/chaplin/lib/utils.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,30 @@

_ = require 'underscore'
support = require 'chaplin/lib/support'
ElementProto = if typeof Element != 'undefined' then Element.prototype else {}


# Utilities
# ---------

utils =
# DOM Helpers
# --------------

matchesSelector: ElementProto.matches ||
ElementProto.webkitMatchesSelector ||
ElementProto.mozMatchesSelector ||
ElementProto.msMatchesSelector ||
ElementProto.oMatchesSelector ||
#Make our own `Element#matches` for IE8
(selector) ->
#Use querySelectorAll to find all elements matching the selector,
#then check if the given element is included in that list.
#Executing the query on the parentNode reduces the resulting nodeList,
#(document doesn't have a parentNode).
nodeList = (@parentNode || document).querySelectorAll(selector) || []
!!~indexOf(nodeList, this)

# Object Helpers
# --------------

Expand Down
171 changes: 58 additions & 113 deletions src/chaplin/views/collection_view.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -5,102 +5,57 @@ Backbone = require 'backbone'
View = require 'chaplin/views/view'
utils = require 'chaplin/lib/utils'

# Shortcut to access the DOM manipulation library.
$ = Backbone.$

filterChildren = (nodeList, selector) ->
return nodeList unless selector
for node in nodeList when Backbone.utils.matchesSelector node, selector
for node in nodeList when utils.matchesSelector.call node, selector
node

toggleElement = do ->
if $
(elem, visible) -> elem.toggle visible
toggleElement = (elem, visible) ->
if Backbone.$
Backbone.$(elem).toggle visible
else
(elem, visible) ->
elem.style.display = (if visible then '' else 'none')
elem.style.display = (if visible then '' else 'none')

addClass = do ->
if $
(elem, cls) -> elem.addClass cls
startAnimation = (elem, useCssAnimation, cls) ->
if useCssAnimation
elem.classList.add cls
else
(elem, cls) -> elem.classList.add cls
elem.style.opacity = 0

startAnimation = do ->
if $
(elem, useCssAnimation, cls) ->
if useCssAnimation
addClass elem, cls
else
elem.css 'opacity', 0
else
(elem, useCssAnimation, cls) ->
if useCssAnimation
addClass elem, cls
else
elem.style.opacity = 0

endAnimation = do ->
if $
(elem, duration) -> elem.animate {opacity: 1}, duration
else
(elem, duration) ->
elem.style.transition = "opacity #{(duration / 1000)}s"
elem.style.opacity = 1

insertView = do ->
if $
(list, viewEl, position, length, itemSelector) ->
insertInMiddle = (0 < position < length)
isEnd = (length) -> length is 0 or position is length

if insertInMiddle or itemSelector
# Get the children which originate from item views.
children = list.children itemSelector
childrenLength = children.length

# Check if it needs to be inserted.
unless children[position] is viewEl
if isEnd childrenLength
# Insert at the end.
list.append viewEl
else
# Insert at the right position.
if position is 0
children.eq(position).before viewEl
else
children.eq(position - 1).after viewEl
else
method = if isEnd length then 'append' else 'prepend'
list[method] viewEl
endAnimation = (elem, duration) ->
if Backbone.$
Backbone.$(elem).animate {opacity: 1}, duration
else
(list, viewEl, position, length, itemSelector) ->
insertInMiddle = (0 < position < length)
isEnd = (length) -> length is 0 or position is length

if insertInMiddle or itemSelector
# Get the children which originate from item views.
children = filterChildren list.children, itemSelector
childrenLength = children.length

# Check if it needs to be inserted.
unless children[position] is viewEl
if isEnd childrenLength
# Insert at the end.
list.appendChild viewEl
else if position is 0
# Insert at the right position.
list.insertBefore viewEl, children[position]
else
last = children[position - 1]
if list.lastChild is last
list.appendChild viewEl
else
list.insertBefore viewEl, last.nextElementSibling
else if isEnd length
elem.style.transition = "opacity #{(duration / 1000)}s"
elem.opacity = 1

insertView = (list, viewEl, position, length, itemSelector) ->
insertInMiddle = (0 < position < length)
isEnd = (length) -> length is 0 or position is length

if insertInMiddle or itemSelector
# Get the children which originate from item views.
children = filterChildren list.children, itemSelector
childrenLength = children.length

# Check if it needs to be inserted.
unless children[position] is viewEl
if isEnd childrenLength
# Insert at the end.
list.appendChild viewEl
else if position is 0
# Insert at the right position.
list.insertBefore viewEl, children[position]
else
list.insertBefore viewEl, list.firstChild
last = children[position - 1]
if list.lastChild is last
list.appendChild viewEl
else
list.insertBefore viewEl, last.nextElementSibling
else if isEnd length
list.appendChild viewEl
else
list.insertBefore viewEl, list.firstChild

# General class for rendering Collections.
# Derive this class and declare at least `itemView` or override
Expand Down Expand Up @@ -149,6 +104,7 @@ module.exports = class CollectionView extends View

# The actual element which is fetched using `listSelector`
$list: null
listEl: null

# Selector for a fallback element which is shown if the collection is empty.
fallbackSelector: null
Expand All @@ -164,7 +120,7 @@ module.exports = class CollectionView extends View
$loading: null

# Selector which identifies child elements belonging to collection
# If empty, all children of $list are considered.
# If empty, all children of listEl are considered.
itemSelector: null

# Filtering
Expand All @@ -176,8 +132,8 @@ module.exports = class CollectionView extends View
# A function that will be executed after each filter.
# Hides excluded items by default.
filterCallback: (view, included) ->
view.$el.stop(true, true) if $
toggleElement (if $ then view.$el else view.el), included
view.$el.stop(true, true) if Backbone.$
toggleElement view.el, included

# View lists
# ----------
Expand Down Expand Up @@ -235,13 +191,11 @@ module.exports = class CollectionView extends View
render: ->
super

# Set the $list property with the actual list container.
# Set the listEl property with the actual list container.
listSelector = _.result this, 'listSelector'

if $
@$list = if listSelector then @$(listSelector) else @$el
else
@list = if listSelector then @find(@listSelector) else @el
@listEl = if listSelector then @el.querySelector(listSelector) else @el
@$list = Backbone.$ @listEl if Backbone.$

@initFallback()
@initLoadingIndicator()
Expand Down Expand Up @@ -271,10 +225,8 @@ module.exports = class CollectionView extends View
return unless @fallbackSelector

# Set the $fallback property.
if $
@$fallback = @$ @fallbackSelector
else
@fallback = @find @fallbackSelector
@$fallback = @$ @fallbackSelector
@fallback = @el.querySelector @fallbackSelector

# Listen for visible items changes.
@on 'visibilityChange', @toggleFallback
Expand All @@ -295,7 +247,7 @@ module.exports = class CollectionView extends View
# Assume it is synced.
true
)
toggleElement (if $ then @$fallback else @fallback), visible
toggleElement @$fallback[0], visible

# Loading indicator
# -----------------
Expand All @@ -307,10 +259,8 @@ module.exports = class CollectionView extends View
typeof @collection.isSyncing is 'function'

# Set the $loading property.
if $
@$loading = @$ @loadingSelector
else
@loading = @find @loadingSelector
@$loading = @$ @loadingSelector
@loading = @el.querySelector @loadingSelector

# Listen for sync events on the collection.
@listenTo @collection, 'syncStateChange', @toggleLoadingIndicator
Expand All @@ -325,7 +275,7 @@ module.exports = class CollectionView extends View
# show up in this case, you need to overwrite this method to
# disable the check.
visible = @collection.length is 0 and @collection.isSyncing()
toggleElement (if $ then @$loading else @loading), visible
toggleElement (@$loading[0]), visible

# Filtering
# ---------
Expand Down Expand Up @@ -459,22 +409,17 @@ module.exports = class CollectionView extends View
else
true

# Get the view’s top element.
elem = if $ then view.$el else view.el

# Start animation.
if included and enableAnimation
startAnimation elem, @useCssAnimation, @animationStartClass
startAnimation view.el, @useCssAnimation, @animationStartClass

# Hide or mark the view if it’s filtered.
@filterCallback view, included if @filterer

length = @collection.length

# Insert the view into the list.
list = if $ then @$list else @list

insertView list, elem, position, length, @itemSelector
insertView @listEl, view.el, position, length, @itemSelector

# Tell the view that it was added to its parent.
view.trigger 'addedToParent'
Expand All @@ -486,10 +431,10 @@ module.exports = class CollectionView extends View
if included and enableAnimation
if @useCssAnimation
# Wait for DOM state change.
setTimeout (=> addClass elem, @animationEndClass), 0
setTimeout (=> view.el.classList.add @animationEndClass), 0
else
# Fade the view in if it was made transparent before.
endAnimation elem, @animationDuration
endAnimation view.el, @animationDuration

view

Expand Down Expand Up @@ -532,7 +477,7 @@ module.exports = class CollectionView extends View
return if @disposed

# Remove jQuery objects, item view cache and visible items list.
properties = ['$list', '$fallback', '$loading', 'visibleItems']
properties = ['$list', 'listEl', '$fallback', '$loading', 'visibleItems']
delete this[prop] for prop in properties

# Self-disposal.
Expand Down
Loading