From 84fe942d61bc719673d1211bb5e6d44e8efcb1fd Mon Sep 17 00:00:00 2001 From: Adam Krebs Date: Tue, 18 Mar 2014 11:10:54 +0200 Subject: [PATCH 01/23] start on removing jquery logic branching for view remove hooks --- src/chaplin/views/collection_view.coffee | 43 +++++--------- src/chaplin/views/layout.coffee | 12 +--- src/chaplin/views/view.coffee | 75 ++---------------------- test/spec/layout_spec.coffee | 6 +- test/spec/view_spec.coffee | 14 ++--- 5 files changed, 32 insertions(+), 118 deletions(-) diff --git a/src/chaplin/views/collection_view.coffee b/src/chaplin/views/collection_view.coffee index 60dc1e98..e5cc1b96 100644 --- a/src/chaplin/views/collection_view.coffee +++ b/src/chaplin/views/collection_view.coffee @@ -15,7 +15,7 @@ filterChildren = (nodeList, selector) -> toggleElement = do -> if $ - (elem, visible) -> elem.toggle visible + (elem, visible) -> $(elem).toggle visible else (elem, visible) -> elem.style.display = (if visible then '' else 'none') @@ -51,19 +51,20 @@ endAnimation = do -> 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 + 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 + $list.append viewEl else # Insert at the right position. if position is 0 @@ -72,7 +73,7 @@ insertView = do -> children.eq(position - 1).after viewEl else method = if isEnd length then 'append' else 'prepend' - list[method] viewEl + $list[method] viewEl else (list, viewEl, position, length, itemSelector) -> insertInMiddle = (0 < position < length) @@ -177,7 +178,7 @@ module.exports = class CollectionView extends View # Hides excluded items by default. filterCallback: (view, included) -> view.$el.stop(true, true) if $ - toggleElement (if $ then view.$el else view.el), included + toggleElement view.el, included # View lists # ---------- @@ -238,10 +239,7 @@ module.exports = class CollectionView extends View # Set the $list 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 + @$list = if listSelector then @$(listSelector)[0] else @el @initFallback() @initLoadingIndicator() @@ -271,10 +269,7 @@ module.exports = class CollectionView extends View return unless @fallbackSelector # Set the $fallback property. - if $ - @$fallback = @$ @fallbackSelector - else - @fallback = @find @fallbackSelector + @$fallback = @$ @fallbackSelector # Listen for visible items changes. @on 'visibilityChange', @toggleFallback @@ -295,7 +290,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 # ----------------- @@ -307,10 +302,7 @@ module.exports = class CollectionView extends View typeof @collection.isSyncing is 'function' # Set the $loading property. - if $ - @$loading = @$ @loadingSelector - else - @loading = @find @loadingSelector + @$loading = @$ @loadingSelector # Listen for sync events on the collection. @listenTo @collection, 'syncStateChange', @toggleLoadingIndicator @@ -325,7 +317,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 # --------- @@ -459,12 +451,9 @@ 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 @@ -472,9 +461,7 @@ module.exports = class CollectionView extends View length = @collection.length # Insert the view into the list. - list = if $ then @$list else @list - - insertView list, elem, position, length, @itemSelector + insertView @$list, view.el, position, length, @itemSelector # Tell the view that it was added to its parent. view.trigger 'addedToParent' @@ -486,10 +473,10 @@ module.exports = class CollectionView extends View if included and enableAnimation if @useCssAnimation # Wait for DOM state change. - setTimeout (=> addClass elem, @animationEndClass), 0 + setTimeout (=> addClass view.el, @animationEndClass), 0 else # Fade the view in if it was made transparent before. - endAnimation elem, @animationDuration + endAnimation view.el, @animationDuration view diff --git a/src/chaplin/views/layout.coffee b/src/chaplin/views/layout.coffee index 21cad8d6..76b179e7 100644 --- a/src/chaplin/views/layout.coffee +++ b/src/chaplin/views/layout.coffee @@ -84,17 +84,11 @@ module.exports = class Layout extends View startLinkRouting: -> route = @settings.routeLinks return unless route - if $ - @$el.on 'click', route, @openLink - else - @delegate 'click', route, @openLink + @delegate 'click', route, @openLink stopLinkRouting: -> route = @settings.routeLinks - if $ - @$el.off 'click', route if route - else - @undelegate 'click', route, @openLink + @undelegate 'click', route, @openLink isExternalLink: (link) -> link.target is '_blank' or @@ -223,7 +217,7 @@ module.exports = class Layout extends View else region.instance.container.querySelector region.selector else - region.instance[if $ then '$' else 'find'] region.selector + region.instance.$ region.selector # Disposal # -------- diff --git a/src/chaplin/views/view.coffee b/src/chaplin/views/view.coffee index c331bb6c..6890dc8d 100644 --- a/src/chaplin/views/view.coffee +++ b/src/chaplin/views/view.coffee @@ -18,7 +18,7 @@ bind = do -> setHTML = do -> if $ - (elem, html) -> elem.html html + (elem, html) -> $(elem).html html else (elem, html) -> elem.innerHTML = html @@ -156,7 +156,7 @@ module.exports = class View extends Backbone.View else region.instance.container else - region.instance.$ region.selector + region.instance.$(region.selector)[0] @el = @container if @container @@ -183,47 +183,6 @@ module.exports = class View extends Backbone.View # User input event handling # ------------------------- - # Event handling using event delegation - # Register a handler for a specific event type - # For the whole view: - # delegate(eventName, handler) - # e.g. - # @delegate('click', @clicked) - # For an element in the passing a selector: - # delegate(eventName, selector, handler) - # e.g. - # @delegate('click', 'button.confirm', @confirm) - delegate: (eventName, second, third) -> - if Backbone.utils - return Backbone.utils.delegate(this, eventName, second, third) - if typeof eventName isnt 'string' - throw new TypeError 'View#delegate: first argument must be a string' - - if arguments.length is 2 - handler = second - else if arguments.length is 3 - selector = second - if typeof selector isnt 'string' - throw new TypeError 'View#delegate: ' + - 'second argument must be a string' - handler = third - else - throw new TypeError 'View#delegate: ' + - 'only two or three arguments are allowed' - - if typeof handler isnt 'function' - throw new TypeError 'View#delegate: ' + - 'handler argument must be function' - - # Add an event namespace, bind handler it to view. - list = ("#{event}.delegate#{@cid}" for event in eventName.split ' ') - events = list.join(' ') - bound = bind handler, this - @$el.on events, (selector or null), bound - - # Return the bound handler. - bound - # Copy of original Backbone method without `undelegateEvents` call. _delegateEvents: (events) -> if Backbone.View::delegateEvents.length is 2 @@ -235,7 +194,7 @@ module.exports = class View extends Backbone.View eventName = "#{match[1]}.delegateEvents#{@cid}" selector = match[2] bound = bind handler, this - @$el.on eventName, (selector or null), bound + @delegate eventName, (selector or null), bound return # Override Backbones method to combine the events @@ -249,32 +208,6 @@ module.exports = class View extends Backbone.View @_delegateEvents classEvents return - # Remove all handlers registered with @delegate. - undelegate: (eventName, second, third) -> - if Backbone.utils - return Backbone.utils.undelegate(this, eventName, second, third) - if eventName - if typeof eventName isnt 'string' - throw new TypeError 'View#undelegate: first argument must be a string' - - if arguments.length is 2 - if typeof second is 'string' - selector = second - else - handler = second - else if arguments.length is 3 - selector = second - if typeof selector isnt 'string' - throw new TypeError 'View#undelegate: ' + - 'second argument must be a string' - handler = third - - list = ("#{event}.delegate#{@cid}" for event in eventName.split ' ') - events = list.join(' ') - @$el.off events, (selector or null) - else - @$el.off ".delegate#{@cid}" - # Handle declarative event bindings from `listen` delegateListeners: -> return unless @listen @@ -434,7 +367,7 @@ module.exports = class View extends Backbone.View # Delegate events to the top-level container in the template. @setElement el.firstChild, true else - setHTML (if $ then @$el else @el), html + setHTML @el, html # Return the view. this diff --git a/test/spec/layout_spec.coffee b/test/spec/layout_spec.coffee index 2e9761bb..70c46ac8 100644 --- a/test/spec/layout_spec.coffee +++ b/test/spec/layout_spec.coffee @@ -80,9 +80,9 @@ define [ after -> document.body.removeEventListener 'click', preventDefault unless $ - it 'should have el, $el and $ props / methods', -> - expect(layout.el).to.be document.body - expect(layout.$el).to.be.a $ if $ + # it 'should have el, $el and $ props / methods', -> + # expect(layout.el).to.be document.body + # expect(layout.$el).to.be.a $ if $ it 'should set the document title', (done) -> spy = sinon.spy() diff --git a/test/spec/view_spec.coffee b/test/spec/view_spec.coffee index 6e01dcaf..ed1a0454 100644 --- a/test/spec/view_spec.coffee +++ b/test/spec/view_spec.coffee @@ -292,13 +292,13 @@ define [ expect(spy).was.calledOnce() expect(spy2).was.calledOnce() - it 'should check delegate parameters', -> - expect(-> view.delegate 1, 2, 3).to.throwError() - expect(-> view.delegate 'click', 'foo').to.throwError() - expect(-> view.delegate 'click', 'foo', 'bar').to.throwError() - expect(-> view.delegate 'click', 123).to.throwError() - # expect(-> view.delegate 'click', (->), 123).to.throwError() - # expect(-> view.delegate 'click', 'foo', (->), 'other').to.throwError() + # it 'should check delegate parameters', -> + # expect(-> view.delegate 1, 2, 3).to.throwError() + # expect(-> view.delegate 'click', 'foo').to.throwError() + # expect(-> view.delegate 'click', 'foo', 'bar').to.throwError() + # expect(-> view.delegate 'click', 123).to.throwError() + # # expect(-> view.delegate 'click', (->), 123).to.throwError() + # # expect(-> view.delegate 'click', 'foo', (->), 'other').to.throwError() it 'should correct inheritance of events object', (done) -> class A extends TestView From b55f8ec4c6337aa2a2b91926090016320a77f4f5 Mon Sep 17 00:00:00 2001 From: Adam Krebs Date: Tue, 18 Mar 2014 13:20:33 +0200 Subject: [PATCH 02/23] use a classList for class changes --- src/chaplin/views/collection_view.coffee | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/src/chaplin/views/collection_view.coffee b/src/chaplin/views/collection_view.coffee index e5cc1b96..7b42b08d 100644 --- a/src/chaplin/views/collection_view.coffee +++ b/src/chaplin/views/collection_view.coffee @@ -20,25 +20,11 @@ toggleElement = do -> (elem, visible) -> elem.style.display = (if visible then '' else 'none') -addClass = do -> - if $ - (elem, cls) -> elem.addClass cls - else - (elem, cls) -> elem.classList.add cls - -startAnimation = do -> - if $ - (elem, useCssAnimation, cls) -> - if useCssAnimation - addClass elem, cls - else - elem.css 'opacity', 0 +startAnimation = (elem, useCssAnimation, cls) -> + if useCssAnimation + elem.classList.add cls else - (elem, useCssAnimation, cls) -> - if useCssAnimation - addClass elem, cls - else - elem.style.opacity = 0 + elem.style.opacity = 0 endAnimation = do -> if $ @@ -473,7 +459,7 @@ module.exports = class CollectionView extends View if included and enableAnimation if @useCssAnimation # Wait for DOM state change. - setTimeout (=> addClass view.el, @animationEndClass), 0 + setTimeout (=> view.el.classList.add @animationEndClass), 0 else # Fade the view in if it was made transparent before. endAnimation view.el, @animationDuration From eba1c20ce3aa9133f249654a3d9b2d71e3688959 Mon Sep 17 00:00:00 2001 From: Adam Krebs Date: Tue, 19 Aug 2014 14:25:42 -0400 Subject: [PATCH 03/23] point bower at recent backbone sha --- bower.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index 0286a65d..b2ba943b 100644 --- a/bower.json +++ b/bower.json @@ -6,12 +6,13 @@ "expect": "0.2.x", "jquery": "1.9.x", "lodash": "2.3.x", - "backbone": "1.1.x", + "backbone": "git://github.com/jashkenas/backbone#3994c1cb8592c7e30613e9f869fe60c1cdce6164", "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": { From c321e269a9f3ecebbe6ee805de8b087b6963fe81 Mon Sep 17 00:00:00 2001 From: Adam Krebs Date: Tue, 19 Aug 2014 23:07:50 -0400 Subject: [PATCH 04/23] view fixes --- src/chaplin/views/collection_view.coffee | 104 ++++++++--------------- src/chaplin/views/layout.coffee | 13 ++- src/chaplin/views/view.coffee | 70 ++++++--------- test/initialize.js | 47 +++++++--- test/spec/view_spec.coffee | 12 +-- 5 files changed, 106 insertions(+), 140 deletions(-) diff --git a/src/chaplin/views/collection_view.coffee b/src/chaplin/views/collection_view.coffee index 7b42b08d..c8b3038c 100644 --- a/src/chaplin/views/collection_view.coffee +++ b/src/chaplin/views/collection_view.coffee @@ -5,20 +5,16 @@ 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 @@ -26,68 +22,40 @@ startAnimation = (elem, useCssAnimation, 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 @@ -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 diff --git a/src/chaplin/views/layout.coffee b/src/chaplin/views/layout.coffee index 76b179e7..e21c81e0 100644 --- a/src/chaplin/views/layout.coffee +++ b/src/chaplin/views/layout.coffee @@ -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' @@ -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. @@ -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 @@ -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 diff --git a/src/chaplin/views/view.coffee b/src/chaplin/views/view.coffee index 6890dc8d..54037cf1 100644 --- a/src/chaplin/views/view.coffee +++ b/src/chaplin/views/view.coffee @@ -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 @@ -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 # ------- @@ -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 @@ -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 @@ -367,11 +331,16 @@ 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. @@ -379,8 +348,25 @@ module.exports = class View extends Backbone.View # 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 diff --git a/test/initialize.js b/test/initialize.js index e39e8741..3c9ecae9 100644 --- a/test/initialize.js +++ b/test/initialize.js @@ -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 = { @@ -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. @@ -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); diff --git a/test/spec/view_spec.coffee b/test/spec/view_spec.coffee index ed1a0454..adcdd3c1 100644 --- a/test/spec/view_spec.coffee +++ b/test/spec/view_spec.coffee @@ -224,26 +224,22 @@ define [ expect(view.undelegate).to.be.a 'function' spy = sinon.spy() - handler = view.delegate 'click', spy - expect(handler).to.be.a 'function' + view.delegate 'click', spy view.render() window.clickOnElement view.el expect(spy).was.called() - view.undelegate() + view.undelegateEvents() window.clickOnElement view.el expect(spy.callCount).to.be 1 spy = sinon.spy() - handler = view.delegate 'click', 'p', spy - expect(handler).to.be.a 'function' + view.delegate 'click', 'p', spy p = view.el.querySelector('p') window.clickOnElement p expect(spy).was.called() - expect(-> view.delegate spy).to.throwError() - - view.undelegate() + view.undelegateEvents() window.clickOnElement p expect(spy.callCount).to.be 1 From 73f17aafbb1178ef9e6000b0712070d97f92c0ac Mon Sep 17 00:00:00 2001 From: Adam Krebs Date: Wed, 27 Aug 2014 11:29:48 -0400 Subject: [PATCH 05/23] stub out jquery in tests... --- test/spec/collection_view_spec.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/spec/collection_view_spec.coffee b/test/spec/collection_view_spec.coffee index f27e5b28..87fa7484 100644 --- a/test/spec/collection_view_spec.coffee +++ b/test/spec/collection_view_spec.coffee @@ -9,6 +9,8 @@ define [ ], (_, jQuery, Model, Collection, View, CollectionView, SyncMachine) -> 'use strict' + jQuery = null unless jQuery?.fn + describe 'CollectionView', -> # Initialize shared variables collection = null From 49b8854c39053bfad28fc36079cde73868aa4302 Mon Sep 17 00:00:00 2001 From: Adam Krebs Date: Wed, 10 Sep 2014 14:49:32 -0400 Subject: [PATCH 06/23] use listEl instead of $list --- src/chaplin/views/collection_view.coffee | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/chaplin/views/collection_view.coffee b/src/chaplin/views/collection_view.coffee index c8b3038c..6a84700f 100644 --- a/src/chaplin/views/collection_view.coffee +++ b/src/chaplin/views/collection_view.coffee @@ -104,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 @@ -119,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 @@ -190,10 +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' - @$list = if listSelector then @$(listSelector)[0] else @el + @listEl = if listSelector then @$(listSelector)[0] else @el + @$list = Backbone.$ @listEl if Backbone.$ @initFallback() @initLoadingIndicator() @@ -415,7 +417,7 @@ module.exports = class CollectionView extends View length = @collection.length # Insert the view into the list. - insertView @$list, view.el, position, length, @itemSelector + insertView @listEl, view.el, position, length, @itemSelector # Tell the view that it was added to its parent. view.trigger 'addedToParent' @@ -473,7 +475,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. From bb5567ed5587d1cc840d680cf90167ca3f5952a3 Mon Sep 17 00:00:00 2001 From: Florian-R Date: Wed, 7 Jan 2015 17:35:43 +0100 Subject: [PATCH 07/23] Update grunt-mocha --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 54ff525a..9e048130 100644 --- a/package.json +++ b/package.json @@ -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" From 56c922b712981291fdb653e53f9e904e1f8943a6 Mon Sep 17 00:00:00 2001 From: Florian-R Date: Wed, 7 Jan 2015 17:36:50 +0100 Subject: [PATCH 08/23] Point Bower to correct backbone.nativeview --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index b2ba943b..4e6648b5 100644 --- a/bower.json +++ b/bower.json @@ -11,7 +11,7 @@ "sinon": "http://sinonjs.org/releases/sinon-1.7.1.js", "requirejs": "~2.1.8", "davy": "~0.0.4", - "Backbone.NativeView": "0.3.1", + "backbone.nativeview": "0.3.1", "exoskeleton": "~0.7.0" }, "exportsOverride": { From fc946051de4a4a72ff57f3df6518d6f09008d454 Mon Sep 17 00:00:00 2001 From: Florian-R Date: Thu, 8 Jan 2015 12:01:56 +0100 Subject: [PATCH 09/23] Fix endAnimation --- src/chaplin/views/collection_view.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chaplin/views/collection_view.coffee b/src/chaplin/views/collection_view.coffee index 6a84700f..04137162 100644 --- a/src/chaplin/views/collection_view.coffee +++ b/src/chaplin/views/collection_view.coffee @@ -24,7 +24,7 @@ startAnimation = (elem, useCssAnimation, cls) -> endAnimation = (elem, duration) -> if Backbone.$ - elem.animate {opacity: 1}, duration + $(elem).animate {opacity: 1}, duration else elem.style.transition = "opacity #{(duration / 1000)}s" elem.opacity = 1 From 422ea76445f47de65cbe05dfb114dc80c7e44f5b Mon Sep 17 00:00:00 2001 From: Florian-R Date: Thu, 8 Jan 2015 12:13:22 +0100 Subject: [PATCH 10/23] Remove some tests for animations --- test/spec/collection_view_spec.coffee | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/test/spec/collection_view_spec.coffee b/test/spec/collection_view_spec.coffee index 87fa7484..f534f736 100644 --- a/test/spec/collection_view_spec.coffee +++ b/test/spec/collection_view_spec.coffee @@ -412,51 +412,36 @@ define [ it 'should animate the opacity of new items', -> return unless jQuery - $css = sinon.stub jQuery.prototype, 'css', -> this $animate = sinon.stub jQuery.prototype, 'animate', -> this createCollection() collectionView = new AnimatingCollectionView {collection} - expect($css.callCount).to.be collection.length - expect($css).was.calledWith 'opacity', 0 - expect($animate.callCount).to.be collection.length args = $animate.firstCall.args expect(args[0]).to.eql opacity: 1 expect(args[1]).to.be collectionView.animationDuration - expect($css.calledBefore($animate)).to.be true - - addThree() - expect($css.callCount).to.be collection.length - - $css.restore() $animate.restore() it 'should not animate if animationDuration is 0', -> return unless jQuery - $css = sinon.spy jQuery.prototype, 'css' $animate = sinon.spy jQuery.prototype, 'animate' createCollection() collectionView = new TestCollectionView {collection} - expect($css).was.notCalled() expect($animate).was.notCalled() addThree() - expect($css).was.notCalled() expect($animate).was.notCalled() - $css.restore() $animate.restore() it 'should not animate when re-inserting', -> return unless jQuery - $css = sinon.stub jQuery.prototype, 'css', -> this $animate = sinon.stub jQuery.prototype, 'animate', -> this model1 = new Model id: 1 @@ -466,15 +451,12 @@ define [ createCollection [model1, model2] collectionView = new AnimatingCollectionView {collection} - expect($css).was.calledTwice() expect($animate).was.calledTwice() collection.reset [model1, model2, model3] - expect($css.callCount).to.be collection.length expect($animate.callCount).to.be collection.length - $css.restore() $animate.restore() it 'should animate with CSS classes', (done) -> From 1c63e3e3c7d71e45af969f92d31ccba4c5c222f9 Mon Sep 17 00:00:00 2001 From: Florian-R Date: Thu, 8 Jan 2015 14:51:13 +0100 Subject: [PATCH 11/23] Fix insertView --- src/chaplin/views/collection_view.coffee | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/chaplin/views/collection_view.coffee b/src/chaplin/views/collection_view.coffee index 04137162..1b0df030 100644 --- a/src/chaplin/views/collection_view.coffee +++ b/src/chaplin/views/collection_view.coffee @@ -5,11 +5,6 @@ Backbone = require 'backbone' View = require 'chaplin/views/view' utils = require 'chaplin/lib/utils' -filterChildren = (nodeList, selector) -> - return nodeList unless selector - for node in nodeList when Backbone.utils.matchesSelector node, selector - node - toggleElement = (elem, visible) -> if Backbone.$ $(elem).toggle visible @@ -35,7 +30,7 @@ insertView = (list, viewEl, position, length, itemSelector) -> if insertInMiddle or itemSelector # Get the children which originate from item views. - children = filterChildren list.children, itemSelector + children = list.querySelectorAll(itemSelector) childrenLength = children.length # Check if it needs to be inserted. From a1c6c52b676074c8f07399c358b1b7527b472363 Mon Sep 17 00:00:00 2001 From: Florian-R Date: Fri, 9 Jan 2015 10:12:42 +0100 Subject: [PATCH 12/23] Use Backbone.$ instead of $ --- src/chaplin/views/collection_view.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chaplin/views/collection_view.coffee b/src/chaplin/views/collection_view.coffee index 1b0df030..96ffc29d 100644 --- a/src/chaplin/views/collection_view.coffee +++ b/src/chaplin/views/collection_view.coffee @@ -7,7 +7,7 @@ utils = require 'chaplin/lib/utils' toggleElement = (elem, visible) -> if Backbone.$ - $(elem).toggle visible + Backbone.$(elem).toggle visible else elem.style.display = (if visible then '' else 'none') @@ -19,7 +19,7 @@ startAnimation = (elem, useCssAnimation, cls) -> endAnimation = (elem, duration) -> if Backbone.$ - $(elem).animate {opacity: 1}, duration + Backbone.$(elem).animate {opacity: 1}, duration else elem.style.transition = "opacity #{(duration / 1000)}s" elem.opacity = 1 From 6ad87e374cec8ca20fb00b6cb651dffb1b329383 Mon Sep 17 00:00:00 2001 From: Florian-R Date: Wed, 14 Jan 2015 11:47:21 +0100 Subject: [PATCH 13/23] Add utils.matchesSelector --- src/chaplin/lib/utils.coffee | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/chaplin/lib/utils.coffee b/src/chaplin/lib/utils.coffee index 14bb787b..1e6d5f9d 100644 --- a/src/chaplin/lib/utils.coffee +++ b/src/chaplin/lib/utils.coffee @@ -2,11 +2,34 @@ _ = require 'underscore' support = require 'chaplin/lib/support' +ElementProto = if typeof Element != 'undefined' then Element.prototype else {} + # Utilities # --------- utils = + # DOM Helpers + # -------------- + + matchesSelector: do -> + matches = 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 = (this.parentNode || document).querySelectorAll(selector) || [] + !!~indexOf(nodeList, this) + + (node, selector) -> + matches.call(node, selector) + # Object Helpers # -------------- From 6e628f9329f0006f7a99fc69400c201d948ec5b0 Mon Sep 17 00:00:00 2001 From: Florian-R Date: Mon, 12 Jan 2015 17:00:03 +0100 Subject: [PATCH 14/23] More fix for insertView --- src/chaplin/lib/utils.coffee | 2 +- src/chaplin/views/collection_view.coffee | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/chaplin/lib/utils.coffee b/src/chaplin/lib/utils.coffee index 1e6d5f9d..bcc1a145 100644 --- a/src/chaplin/lib/utils.coffee +++ b/src/chaplin/lib/utils.coffee @@ -24,7 +24,7 @@ utils = #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 = (this.parentNode || document).querySelectorAll(selector) || [] + nodeList = (@parentNode || document).querySelectorAll(selector) || [] !!~indexOf(nodeList, this) (node, selector) -> diff --git a/src/chaplin/views/collection_view.coffee b/src/chaplin/views/collection_view.coffee index 96ffc29d..1a82925f 100644 --- a/src/chaplin/views/collection_view.coffee +++ b/src/chaplin/views/collection_view.coffee @@ -5,6 +5,11 @@ Backbone = require 'backbone' View = require 'chaplin/views/view' utils = require 'chaplin/lib/utils' +filterChildren = (nodeList, selector) -> + return nodeList unless selector + for node in nodeList when utils.matchesSelector node, selector + node + toggleElement = (elem, visible) -> if Backbone.$ Backbone.$(elem).toggle visible @@ -30,7 +35,7 @@ insertView = (list, viewEl, position, length, itemSelector) -> if insertInMiddle or itemSelector # Get the children which originate from item views. - children = list.querySelectorAll(itemSelector) + children = filterChildren list.children, itemSelector childrenLength = children.length # Check if it needs to be inserted. From 969a9e372a889ca115840944abcbcee3155c5e07 Mon Sep 17 00:00:00 2001 From: Florian-R Date: Wed, 14 Jan 2015 16:36:40 +0100 Subject: [PATCH 15/23] Remove automatic binding of utils.matchesSelector --- src/chaplin/lib/utils.coffee | 30 ++++++++++-------------- src/chaplin/views/collection_view.coffee | 2 +- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/chaplin/lib/utils.coffee b/src/chaplin/lib/utils.coffee index bcc1a145..7af7897b 100644 --- a/src/chaplin/lib/utils.coffee +++ b/src/chaplin/lib/utils.coffee @@ -12,23 +12,19 @@ utils = # DOM Helpers # -------------- - matchesSelector: do -> - matches = 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) - - (node, selector) -> - matches.call(node, selector) + 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 # -------------- diff --git a/src/chaplin/views/collection_view.coffee b/src/chaplin/views/collection_view.coffee index 1a82925f..fa1f8613 100644 --- a/src/chaplin/views/collection_view.coffee +++ b/src/chaplin/views/collection_view.coffee @@ -7,7 +7,7 @@ utils = require 'chaplin/lib/utils' filterChildren = (nodeList, selector) -> return nodeList unless selector - for node in nodeList when utils.matchesSelector node, selector + for node in nodeList when utils.matchesSelector.call node, selector node toggleElement = (elem, visible) -> From ffaa3f956bc3eda540ebeb92a2d964a647562ef5 Mon Sep 17 00:00:00 2001 From: Florian-R Date: Fri, 6 Feb 2015 18:12:50 +0100 Subject: [PATCH 16/23] Start to remove instance of $ in Layout --- src/chaplin/views/layout.coffee | 15 +++++---------- test/spec/layout_spec.coffee | 20 ++++++-------------- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/src/chaplin/views/layout.coffee b/src/chaplin/views/layout.coffee index e21c81e0..453bf943 100644 --- a/src/chaplin/views/layout.coffee +++ b/src/chaplin/views/layout.coffee @@ -203,18 +203,13 @@ module.exports = class Layout extends View # Apply the region selector. instance.container = if region.selector is '' - if Backbone.$ - region.instance.$el - else - region.instance.el + region.instance.el else - if region.instance.noWrap - if Backbone.$ - Backbone.$(region.instance.container).find region.selector + root = if region.instance.noWrap + region.instance.container else - region.instance.container.querySelector region.selector - else - region.instance.$ region.selector + region.instance.el + root.querySelector region.selector # Disposal # -------- diff --git a/test/spec/layout_spec.coffee b/test/spec/layout_spec.coffee index 70c46ac8..daaf4037 100644 --- a/test/spec/layout_spec.coffee +++ b/test/spec/layout_spec.coffee @@ -343,12 +343,8 @@ define [ instance2 = new Test2View {region: 'test2'} instance3 = new Test2View {region: 'test0'} - if $ - expect(instance2.container.attr('id')).to.be 'test2' - expect(instance3.container).to.be instance1.$el - else - expect(instance2.container.id).to.be 'test2' - expect(instance3.container).to.be instance1.el + expect(instance2.container.id).to.be 'test2' + expect(instance3.container).to.be instance1.el instance1.dispose() instance2.dispose() @@ -375,10 +371,8 @@ define [ instance1 = new Test1View() instance2 = new Test2View() instance3 = new Test3View {region: 'test2'} - if $ - expect(instance3.container.attr('id')).to.be 'test5' - else - expect(instance3.container.id).to.be 'test5' + + expect(instance3.container.id).to.be 'test5' instance1.dispose() instance2.dispose() @@ -407,10 +401,8 @@ define [ instance2 = new Test2View() instance2.stale = true instance3 = new Test3View {region: 'test2'} - if $ - expect(instance3.container.attr('id')).to.be 'test2' - else - expect(instance3.container.id).to.be 'test2' + + expect(instance3.container.id).to.be 'test2' instance1.dispose() instance2.dispose() From 6b9b4f56de1570142ce94bfbf0772881a2b3cf7c Mon Sep 17 00:00:00 2001 From: Florian-R Date: Mon, 9 Feb 2015 17:33:52 +0100 Subject: [PATCH 17/23] More Layout fixes --- src/chaplin/views/layout.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chaplin/views/layout.coffee b/src/chaplin/views/layout.coffee index 453bf943..8aae7d78 100644 --- a/src/chaplin/views/layout.coffee +++ b/src/chaplin/views/layout.coffee @@ -97,7 +97,7 @@ module.exports = class Layout extends View openLink: (event) => return if utils.modifierKeyPressed(event) - el = if Backbone.$ then event.currentTarget else event.delegateTarget + el = event.currentTarget isAnchor = el.nodeName is 'A' # Get the href and perform checks on it. @@ -115,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 Backbone.$ then Backbone.$(el).is(skipRouting) else el.matches skipRouting) + type is 'string' and utils.matchesSelector.call el, skipRouting # Handle external links. external = isAnchor and @isExternalLink el From f1801227d77fae6e07eefede1b9b63ea85d0ee92 Mon Sep 17 00:00:00 2001 From: Florian-R Date: Mon, 9 Feb 2015 18:22:44 +0100 Subject: [PATCH 18/23] Fix test setup with NativeView --- test/initialize.js | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/test/initialize.js b/test/initialize.js index 3c9ecae9..ca36a1aa 100644 --- a/test/initialize.js +++ b/test/initialize.js @@ -14,11 +14,10 @@ var testType = window.testType || (match ? match[1] : 'backbone'); var useDeps = window.useDeps || (match ? match[2] : true); var addDeps = function() { - if (useDeps) { - paths.underscore = '../' + componentsFolder + '/lodash/lodash.compat'; + if (useDeps === true) { paths.jquery = '../' + componentsFolder + '/jquery/jquery'; } else { - paths.NativeView = '../' + componentsFolder + '/Backbone.NativeView/backbone.nativeview'; + paths.NativeView = '../' + componentsFolder + '/backbone.nativeview/backbone.nativeview'; } }; if (testType === 'backbone') { @@ -29,6 +28,8 @@ if (testType === 'backbone') { paths.backbone = '../' + componentsFolder + '/exoskeleton/exoskeleton'; } +paths.underscore = '../' + componentsFolder + '/lodash/lodash.compat'; + var config = { baseUrl: 'temp/', paths: paths, @@ -51,11 +52,6 @@ if (testType === 'backbone' || testType === 'deps') { requirejs.config(config); if (testType === 'exos') { define('jquery', function(){}); - 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. @@ -107,14 +103,12 @@ window.addEventListener('DOMContentLoaded', function() { } }; - require(specs, function() { - if (useDeps) { - run(); - } else { - require(['backbone', 'NativeView'], function(Backbone, NativeView) { - Backbone.View = NativeView; - run(); - }); - } - }); + if (useDeps === true) { + require(specs, run) + } else { + require(['backbone', 'NativeView'], function(Backbone, NativeView) { + Backbone.View = NativeView; + require(specs, run) + }); + } }, false); From 0060d5c3fcca4c7492b6e71df5d8985e2159412e Mon Sep 17 00:00:00 2001 From: Florian-R Date: Tue, 10 Feb 2015 15:35:26 +0100 Subject: [PATCH 19/23] Stub Underscore methods for tests without deps --- test/initialize.js | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/test/initialize.js b/test/initialize.js index ca36a1aa..61337d06 100644 --- a/test/initialize.js +++ b/test/initialize.js @@ -16,6 +16,7 @@ var useDeps = window.useDeps || (match ? match[2] : true); var addDeps = function() { if (useDeps === true) { paths.jquery = '../' + componentsFolder + '/jquery/jquery'; + paths.underscore = '../' + componentsFolder + '/lodash/lodash.compat'; } else { paths.NativeView = '../' + componentsFolder + '/backbone.nativeview/backbone.nativeview'; } @@ -28,7 +29,6 @@ if (testType === 'backbone') { paths.backbone = '../' + componentsFolder + '/exoskeleton/exoskeleton'; } -paths.underscore = '../' + componentsFolder + '/lodash/lodash.compat'; var config = { baseUrl: 'temp/', @@ -37,18 +37,6 @@ var config = { urlArgs: 'bust=' + (new Date()).getTime() }; -if (testType === 'backbone' || testType === 'deps') { - config.shim = { - backbone: { - deps: ['underscore', 'jquery'], - exports: 'Backbone' - }, - underscore: { - exports: '_' - } - }; -} - requirejs.config(config); if (testType === 'exos') { define('jquery', function(){}); @@ -106,7 +94,27 @@ window.addEventListener('DOMContentLoaded', function() { if (useDeps === true) { require(specs, run) } else { + define('underscore', function(){}); require(['backbone', 'NativeView'], function(Backbone, NativeView) { + requirejs.undef('underscore') + define('underscore', function(){ + var _ = Backbone.utils + _.bind = function(fn, ctx) { return fn.bind(ctx); } + _.isObject = function(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; + }; + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return Array.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + _.isEmpty = function(obj) { + if (obj == null) return true; + if (obj.length !== undefined) return obj.length === 0; + return Object.keys(obj).length === 0; + }; + return _ + }); Backbone.View = NativeView; require(specs, run) }); From a455973af784cc820a16e9bced3c9fe85785a1b4 Mon Sep 17 00:00:00 2001 From: Adam Krebs Date: Tue, 19 May 2015 16:31:29 -0400 Subject: [PATCH 20/23] bump backbone version --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index 4e6648b5..3b5de7c2 100644 --- a/bower.json +++ b/bower.json @@ -6,7 +6,7 @@ "expect": "0.2.x", "jquery": "1.9.x", "lodash": "2.3.x", - "backbone": "git://github.com/jashkenas/backbone#3994c1cb8592c7e30613e9f869fe60c1cdce6164", + "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", From f8da2d04e77afcf759d060e85877499921012ce8 Mon Sep 17 00:00:00 2001 From: Florian-R Date: Tue, 1 Sep 2015 17:33:56 +0200 Subject: [PATCH 21/23] Revert currentTarget inLayout --- src/chaplin/views/layout.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chaplin/views/layout.coffee b/src/chaplin/views/layout.coffee index 8aae7d78..1c15c11c 100644 --- a/src/chaplin/views/layout.coffee +++ b/src/chaplin/views/layout.coffee @@ -97,7 +97,7 @@ module.exports = class Layout extends View openLink: (event) => return if utils.modifierKeyPressed(event) - el = event.currentTarget + el = if Backbone.$ then event.currentTarget else event.delegateTarget isAnchor = el.nodeName is 'A' # Get the href and perform checks on it. From a78f929861462d1883136d62eb393aafe685ffd4 Mon Sep 17 00:00:00 2001 From: Florian-R Date: Wed, 2 Sep 2015 10:22:50 +0200 Subject: [PATCH 22/23] Fix View --- src/chaplin/views/view.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chaplin/views/view.coffee b/src/chaplin/views/view.coffee index 54037cf1..fc5ed377 100644 --- a/src/chaplin/views/view.coffee +++ b/src/chaplin/views/view.coffee @@ -155,7 +155,7 @@ module.exports = class View extends Backbone.View handler = if typeof value is 'function' then value else this[value] throw new Error "Method '#{value}' does not exist" unless handler match = key.match /^(\S+)\s*(.*)$/ - eventName = "#{match[1]}.delegateEvents#{@cid}" + eventName = match[1] selector = match[2] bound = _.bind handler, this @delegate eventName, (selector or null), bound From 71551c1af99eafea51b6bf3c0c200682ed0e9d3c Mon Sep 17 00:00:00 2001 From: Florian-R Date: Wed, 2 Sep 2015 12:04:27 +0200 Subject: [PATCH 23/23] Fix CollectionView --- src/chaplin/views/collection_view.coffee | 4 +++- test/spec/collection_view_spec.coffee | 17 +++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/chaplin/views/collection_view.coffee b/src/chaplin/views/collection_view.coffee index fa1f8613..59e6654e 100644 --- a/src/chaplin/views/collection_view.coffee +++ b/src/chaplin/views/collection_view.coffee @@ -194,7 +194,7 @@ module.exports = class CollectionView extends View # Set the listEl property with the actual list container. listSelector = _.result this, 'listSelector' - @listEl = if listSelector then @$(listSelector)[0] else @el + @listEl = if listSelector then @el.querySelector(listSelector) else @el @$list = Backbone.$ @listEl if Backbone.$ @initFallback() @@ -226,6 +226,7 @@ module.exports = class CollectionView extends View # Set the $fallback property. @$fallback = @$ @fallbackSelector + @fallback = @el.querySelector @fallbackSelector # Listen for visible items changes. @on 'visibilityChange', @toggleFallback @@ -259,6 +260,7 @@ module.exports = class CollectionView extends View # Set the $loading property. @$loading = @$ @loadingSelector + @loading = @el.querySelector @loadingSelector # Listen for sync events on the collection. @listenTo @collection, 'syncStateChange', @toggleLoadingIndicator diff --git a/test/spec/collection_view_spec.coffee b/test/spec/collection_view_spec.coffee index f534f736..961e0862 100644 --- a/test/spec/collection_view_spec.coffee +++ b/test/spec/collection_view_spec.coffee @@ -6,7 +6,8 @@ define [ 'chaplin/views/view' 'chaplin/views/collection_view' 'chaplin/lib/sync_machine' -], (_, jQuery, Model, Collection, View, CollectionView, SyncMachine) -> + 'chaplin/lib/utils' +], (_, jQuery, Model, Collection, View, CollectionView, SyncMachine, utils) -> 'use strict' jQuery = null unless jQuery?.fn @@ -86,9 +87,9 @@ define [ collectionView.$list.children collectionView.itemSelector else if collectionView.itemSelector - (item for item in collectionView.list.children when Backbone.utils.matchesSelector item, collectionView.itemSelector) + (item for item in collectionView.listEl.children when utils.matchesSelector.call item, collectionView.itemSelector) else - collectionView.list.children + collectionView.listEl.children getAllChildren = -> if jQuery @@ -176,7 +177,7 @@ define [ expect(collectionView.$list).to.be.a jQuery expect(collectionView.$list.length).to.be 1 else - expect(collectionView.list).to.be.a Element + expect(collectionView.listEl).to.be.a Element collectionView.renderAllItems() viewsMatchCollection() @@ -735,10 +736,10 @@ define [ children = getViewChildren() expect(children.length).to.be collection.length else - list = collectionView.list + list = collectionView.listEl expect(list).to.be.true - list2 = collectionView.find(collectionView.listSelector) + list2 = collectionView.el.querySelector(collectionView.listSelector) expect(list).to.be list2 children = getViewChildren() @@ -788,7 +789,7 @@ define [ else {fallback} = collectionView expect(fallback).to.be.true - fallback2 = collectionView.find(collectionView.fallbackSelector) + fallback2 = collectionView.el.querySelector(collectionView.fallbackSelector) expect(fallback).to.be fallback2 it 'should show the fallback element properly', -> @@ -857,7 +858,7 @@ define [ else {loading} = collectionView expect(loading).to.be.true - loading2 = collectionView.find(collectionView.loadingSelector) + loading2 = collectionView.el.querySelector(collectionView.loadingSelector) expect(loading).to.be loading2 it 'should show the loading indicator properly', ->