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

Commit

Permalink
view fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
akre54 committed Oct 16, 2014
1 parent eba1c20 commit c321e26
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 140 deletions.
104 changes: 36 additions & 68 deletions src/chaplin/views/collection_view.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -5,89 +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
node

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

startAnimation = (elem, useCssAnimation, cls) ->
if useCssAnimation
elem.classList.add 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) ->
$list = $ list
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.$
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 @@ -163,7 +131,7 @@ 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 $
view.$el.stop(true, true) if Backbone.$
toggleElement view.el, included

# View lists
Expand Down
13 changes: 5 additions & 8 deletions src/chaplin/views/layout.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ utils = require 'chaplin/lib/utils'
EventBroker = require 'chaplin/lib/event_broker'
View = require 'chaplin/views/view'

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

module.exports = class Layout extends View
# Bind to document body by default.
el: 'body'
Expand Down Expand Up @@ -100,7 +97,7 @@ module.exports = class Layout extends View
openLink: (event) =>
return if utils.modifierKeyPressed(event)

el = if $ then event.currentTarget else event.delegateTarget
el = if Backbone.$ then event.currentTarget else event.delegateTarget
isAnchor = el.nodeName is 'A'

# Get the href and perform checks on it.
Expand All @@ -118,7 +115,7 @@ module.exports = class Layout extends View
skipRouting = @settings.skipRouting
type = typeof skipRouting
return if type is 'function' and not skipRouting(href, el) or
type is 'string' and (if $ then $(el).is(skipRouting) else Backbone.utils.matchesSelector el, skipRouting)
type is 'string' and (if Backbone.$ then Backbone.$(el).is(skipRouting) else el.matches skipRouting)

# Handle external links.
external = isAnchor and @isExternalLink el
Expand Down Expand Up @@ -206,14 +203,14 @@ module.exports = class Layout extends View

# Apply the region selector.
instance.container = if region.selector is ''
if $
if Backbone.$
region.instance.$el
else
region.instance.el
else
if region.instance.noWrap
if $
$(region.instance.container).find region.selector
if Backbone.$
Backbone.$(region.instance.container).find region.selector
else
region.instance.container.querySelector region.selector
else
Expand Down
70 changes: 28 additions & 42 deletions src/chaplin/views/view.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,6 @@ mediator = require 'chaplin/mediator'
EventBroker = require 'chaplin/lib/event_broker'
utils = require 'chaplin/lib/utils'

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

# Function bind shortcut.
bind = do ->
if Function::bind
(item, ctx) -> item.bind ctx
else if _.bind
_.bind

setHTML = do ->
if $
(elem, html) -> $(elem).html html
else
(elem, html) -> elem.innerHTML = html

attach = do ->
if $
(view) ->
actual = $(view.container)
if typeof view.containerMethod is 'function'
view.containerMethod actual, view.el
else
actual[view.containerMethod] view.el
else
(view) ->
actual = if typeof view.container is 'string'
document.querySelector view.container
else
view.container

if typeof view.containerMethod is 'function'
view.containerMethod actual, view.el
else
actual[view.containerMethod] view.el

module.exports = class View extends Backbone.View
# Mixin an EventBroker.
_.extend @prototype, EventBroker
Expand Down Expand Up @@ -69,7 +33,7 @@ module.exports = class View extends Backbone.View

# Method which is used for adding the view to the DOM
# Like jQuery’s `html`, `prepend`, `append`, `after`, `before` etc.
containerMethod: if $ then 'append' else 'appendChild'
containerMethod: if Backbone.$ then 'append' else 'appendChild'

# Regions
# -------
Expand Down Expand Up @@ -152,7 +116,7 @@ module.exports = class View extends Backbone.View
@el =
if region.instance.container?
if region.instance.region?
$(region.instance.container).find region.selector
Backbone.$(region.instance.container).find region.selector
else
region.instance.container
else
Expand Down Expand Up @@ -193,7 +157,7 @@ module.exports = class View extends Backbone.View
match = key.match /^(\S+)\s*(.*)$/
eventName = "#{match[1]}.delegateEvents#{@cid}"
selector = match[2]
bound = bind handler, this
bound = _.bind handler, this
@delegate eventName, (selector or null), bound
return

Expand Down Expand Up @@ -367,20 +331,42 @@ module.exports = class View extends Backbone.View
# Delegate events to the top-level container in the template.
@setElement el.firstChild, true
else
setHTML @el, html
@setHTML html

# Return the view.
this

# Set the innerHTML of the view's `el`. Override this method to support
# older browsers (IE needs the html empty before, e.g.)
setHTML: (html) ->
@el.innerHTML = html

# This method is called after a specific `render` of a derived class.
attach: ->
# Attempt to bind this view to its named region.
mediator.execute 'region:show', @region, this if @region?

# Automatically append to DOM if the container element is set.
if @container and not document.body.contains @el
attach this
# Trigger an event.
if Backbone.$
actual = Backbone.$(this.container)
if typeof this.containerMethod is 'function'
this.containerMethod actual, this.el
else
actual[this.containerMethod] this.el
else
actual = if typeof this.container is 'string'
document.querySelector this.container
else
this.container

if typeof this.containerMethod is 'function'
this.containerMethod actual, this.el
else
actual[this.containerMethod] this.el

# Hook into this event for things that require the view to be in the DOM
# (like calculating height / width or position).
@trigger 'addedToDOM'

# Disposal
Expand Down
47 changes: 33 additions & 14 deletions test/initialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,24 @@ window.clearInterval = timers.clearInterval;
var paths = {};
var componentsFolder = 'bower_components';

var match = window.location.search.match(/type=([-\w]+)/);
var match = window.location.search.match(/type=([-\w]+)&useDeps=([-\w]+)/);
var testType = window.testType || (match ? match[1] : 'backbone');
var useDeps = window.useDeps || (match ? match[2] : true);

var addDeps = function() {
paths.underscore = '../' + componentsFolder + '/lodash/lodash.compat';
paths.jquery = '../' + componentsFolder + '/jquery/jquery';
if (useDeps) {
paths.underscore = '../' + componentsFolder + '/lodash/lodash.compat';
paths.jquery = '../' + componentsFolder + '/jquery/jquery';
} else {
paths.NativeView = '../' + componentsFolder + '/Backbone.NativeView/backbone.nativeview';
}
};
if (testType === 'backbone') {
paths.backbone = '../' + componentsFolder + '/backbone/backbone'
addDeps()
paths.backbone = '../' + componentsFolder + '/backbone/backbone';
addDeps();
} else {
if (testType === 'deps') addDeps();
paths.backbone = '../' + componentsFolder + '/exoskeleton/exoskeleton'
addDeps();
paths.backbone = '../' + componentsFolder + '/exoskeleton/exoskeleton';
}

var config = {
Expand All @@ -46,7 +51,11 @@ if (testType === 'backbone' || testType === 'deps') {
requirejs.config(config);
if (testType === 'exos') {
define('jquery', function(){});
define('underscore', ['backbone'], function(Backbone){return Backbone.utils;});
define('underscore', ['backbone'], function(Backbone){
var _ = Backbone.utils;
_.bind = function(fn, ctx) { return fn.bind(ctx); }
return _;
});
}
mocha.setup({ui: 'bdd', ignoreLeaks: true});
// Wonderful hack to send a message to grunt from inside a mocha test.
Expand Down Expand Up @@ -86,16 +95,26 @@ window.addEventListener('DOMContentLoaded', function() {
'view',
'utils',
'sync_machine'
];
var loaded = [];
for (var i = 0, l = specs.length; i < l; i++) {
loaded.push(specs[i] + '_spec');
}
require(loaded, function() {
].map(function(file) {
return file + '_spec';
});

var run = function() {
if (window.mochaPhantomJS) {
mochaPhantomJS.run();
} else {
mocha.run();
}
};

require(specs, function() {
if (useDeps) {
run();
} else {
require(['backbone', 'NativeView'], function(Backbone, NativeView) {
Backbone.View = NativeView;
run();
});
}
});
}, false);
Loading

0 comments on commit c321e26

Please sign in to comment.