From e1b25ebdeda55de0a550b5c3a13b2cc5e91f5f35 Mon Sep 17 00:00:00 2001 From: brewster Date: Thu, 2 Jun 2016 18:00:12 -0700 Subject: [PATCH] 2.x-bug-fixes --- CHANGELOG.md | 4 + Newfile | 2 +- bower.json | 4 +- demo/tiler_demo.coffee | 6 +- demo/tiler_demo.js | 2 +- lib/tiler.js | 149 +++++++++++++------------- spec/index.html | 91 ++++++++++------ spec/tiler_spec.coffee | 230 ++++++++++++++++++++++++++++++----------- spec/tiler_spec.sass | 12 +-- src/tiler.coffee | 205 ++++++++++++++++++------------------ 10 files changed, 416 insertions(+), 289 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e3c099..7f40247 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ #### CHANGE LOG +###### 2.0.2 +* code refactor +* added tests + ###### 2.0.1 * viewport sizing bugfix diff --git a/Newfile b/Newfile index 9a27c9d..b6737cb 100644 --- a/Newfile +++ b/Newfile @@ -2,7 +2,7 @@ sources: default: ~/Code/ruby/new-tasks name: Tiler -version: 2.0.1 +version: 2.0.2 tasks: changelog: git: diff --git a/bower.json b/bower.json index 208f346..29aed5e 100644 --- a/bower.json +++ b/bower.json @@ -5,8 +5,10 @@ "jquery-ui": "latest" }, "devDependencies": { - "chai": "latest", "chai-as-promised": "latest", + "chai-jquery": "latest", + "chai": "latest", + "lolex": "sinonjs/lolex", "mocha": "latest", "sinon-chai": "latest", "sinon": "latest" diff --git a/demo/tiler_demo.coffee b/demo/tiler_demo.coffee index d572dfc..dc48512 100644 --- a/demo/tiler_demo.coffee +++ b/demo/tiler_demo.coffee @@ -2,16 +2,16 @@ $ -> # initalize tiler $('.tiler-viewport').each -> - $(@).tiler().tiler('goTo', 1, false) + $(@).tiler() # set the button text to match the tile title $('button[data-tiler-link]').each -> - $(@).text($(@).data('tiler-title')) + $(@).text $(@).data('tiler-title') # go to a tile on click based on the link id $('button').click -> tileId = $(@).data('tiler-link') - $(@).closest('.tiler-viewport').tiler('goTo', tileId) + $(@).closest('.tiler-viewport').tiler 'goTo', tileId # event to set background $('#background').on 'tiler.goto', (e, data) -> diff --git a/demo/tiler_demo.js b/demo/tiler_demo.js index 0159fce..450455a 100644 --- a/demo/tiler_demo.js +++ b/demo/tiler_demo.js @@ -2,7 +2,7 @@ (function() { $(function() { $('.tiler-viewport').each(function() { - return $(this).tiler().tiler('goTo', 1, false); + return $(this).tiler(); }); $('button[data-tiler-link]').each(function() { return $(this).text($(this).data('tiler-title')); diff --git a/lib/tiler.js b/lib/tiler.js index e7b895c..f10cae5 100644 --- a/lib/tiler.js +++ b/lib/tiler.js @@ -4,7 +4,7 @@ * * tiler * * https://github.com/brewster1134/tiler * * - * * @version 2.0.1 + * * @version 2.0.2 * * @author Ryan Brewster * * Copyright (c) 2014 * * Licensed under the MIT license. @@ -23,19 +23,13 @@ return $.widget('ui.tiler', { widgetEventPrefix: 'tiler', options: { - isReversible: true, - startingActiveTile: 1, - startingPreviousTile: 2 - }, - _create: function() { - this.currentActiveTileIndex = this.options.startingActiveTile; - return this.currentPreviousTileIndex = this.options.startingPreviousTile; + activeTile: 1, + isReversible: true }, _init: function() { - this.element.addClass('animation-disabled'); this.$tiles = $('.tiler-tile', this.element).not(this.element.find('.tiler-viewport .tiler-tile')); - this.$enterTile = this.$tiles.eq(this.currentActiveTileIndex - 1); - this.$exitTile = this.$tiles.eq(this.currentPreviousTileIndex - 1); + this.$currentActiveTile || (this.$currentActiveTile = this._getTile(this.options.activeTile)); + this.$currentPreviousTile || (this.$currentPreviousTile = this._getTile(this._getTileIndex(this.$currentActiveTile) + 1)); this._setupTiles(); return this._setupLinks(); }, @@ -45,90 +39,97 @@ this.element.trigger('tiler.refresh'); return (ref = this.$enterTile) != null ? ref.trigger('tiler.refresh') : void 0; }, + goTo: function(tileValue, animation) { + var $enteringTile, $exitingTile; + $enteringTile = this._getTile(tileValue); + $exitingTile = this.$currentActiveTile; + if (!$enteringTile.length || $enteringTile[0] === this.$currentActiveTile[0]) { + return; + } + this._transitionCss($enteringTile, $exitingTile, animation); + return $enteringTile; + }, _getTile: function(tileValue) { - if (typeof tileValue === 'string') { - return $("#" + tileValue, this.element); - } else if (tileValue.jquery) { - return tileValue.jquery; - } else if (tileValue.nodeType) { - return $(tileValue); + var $tile; + $tile = (function() { + switch (typeof tileValue) { + case 'number': + return this.$tiles.eq(tileValue - 1); + case 'string': + return $("#" + tileValue, this.element); + default: + return $(tileValue, this.element); + } + }).call(this); + if ($tile.length) { + return $tile; } else { - return this.$tiles.eq(tileValue - 1); + return this.$tiles.eq(0); } }, - goTo: function(tile, animation) { - var enterTileIndex; - this.$enterTile = this._getTile(tile); - enterTileIndex = this.$tiles.index(this.$enterTile); - this.$exitTile = this._getTile(this.currentActiveTileIndex + 1); - if (!this.$enterTile.length || this.currentActiveTileIndex === enterTileIndex) { - return; - } - this._transitionCss(this._getAnimationClass(), animation); - this.element.trigger('tiler.goto', { - enterTile: this.$enterTile, - exitTile: this.$exitTile - }); - this.$enterTile.trigger('tiler.enter'); - this.$exitTile.trigger('tiler.exit'); - this.currentActiveTileIndex = enterTileIndex; - this.currentPreviousTileIndex = this.currentActiveTileIndex; - this.element.attr('data-tiler-active-tile', this.$enterTile.attr('id')); - return this.$enterTile; + _getTileIndex: function($tile) { + return this.$tiles.index($tile) + 1; }, - _getAnimationClass: function() { - return this.$enterTile.data('tiler-animation') || this.element.data('tiler-animation') || ''; + _getAnimationClass: function($tile) { + return $tile.data('tiler-animation') || this.element.data('tiler-animation') || ''; }, - _transitionCss: function(animationClass, animation) { - var enterStartClass, enterTileIndex, exitStartClass, otherTileClass, position, reverseClass; - if (typeof animation === 'string') { - animationClass = animation; - } - position = animation === false ? 'end' : 'start'; - enterTileIndex = this.$tiles.index(this.$enterTile); - reverseClass = this.options.isReversible && !this._isNavigatingForward(enterTileIndex) ? 'reverse' : ''; + _transitionCss: function($enteringTile, $exitingTile, animation) { + var animationClass, positionClass, reverseClass; + animationClass = typeof animation === 'string' ? animation : this._getAnimationClass($enteringTile); + reverseClass = this.options.isReversible && this._getTileIndex($enteringTile) < this._getTileIndex(this.$currentActiveTile) ? 'reverse' : ''; + positionClass = animation === false ? 'end' : 'start'; this.element.addClass('animation-disabled'); - enterStartClass = "tiler-tile " + animationClass + " active enter " + reverseClass + " " + position; - exitStartClass = "tiler-tile " + animationClass + " previous exit " + reverseClass + " " + position; - otherTileClass = 'tiler-tile'; - this.$enterTile.attr('class', enterStartClass); - this.$exitTile.attr('class', exitStartClass); - this.$tiles.not(this.$enterTile).not(this.$exitTile).attr('class', otherTileClass); - if (animation !== false) { + $enteringTile.attr('class', "tiler-tile " + animationClass + " active enter " + reverseClass + " " + positionClass); + $exitingTile.attr('class', "tiler-tile " + animationClass + " previous exit " + reverseClass + " " + positionClass); + this.$tiles.not($enteringTile).not($exitingTile).attr('class', 'tiler-tile'); + if (animation === false) { + return this._finalizeNewTiles($enteringTile, $exitingTile); + } else { return setTimeout((function(_this) { return function() { _this.element.removeClass('animation-disabled'); - return _this.$enterTile.add(_this.$exitTile).switchClass('start', 'end'); + $enteringTile.add($exitingTile).switchClass('start', 'end'); + return _this._finalizeNewTiles($enteringTile, $exitingTile); }; })(this), 10); } }, - _setupLinks: function() { - return $('[data-tiler-link]').each(function() { - var tile, tileId, tileIds; - tileIds = $(this).data('tiler-link').split(':').reverse(); - tileId = tileIds[0]; - tile = tileIds[1] ? $(".tiler-tile#" + tileId, "#" + tileIds[1]) : $(".tiler-tile#" + tileId); - if (!tile.length) { - return; - } - return $.extend($(this).data(), tile.data()); + _finalizeNewTiles: function($enterTile, $exitTile) { + this.$currentActiveTile = $enterTile; + this.$currentPreviousTile = $exitTile; + this.element.attr('data-tiler-active-tile', this.$currentActiveTile.attr('id')); + this.element.trigger('tiler.goto', { + enterTile: $enterTile, + exitTile: $exitTile }); + $enterTile.trigger('tiler.enter'); + return $exitTile.trigger('tiler.exit'); }, _setupTiles: function() { - var self; - self = this; - this.$tiles.each(function() { - $(this).attr('data-tiler-viewport-id', self.element.attr('id')); - return $(this).addClass(self._getAnimationClass(true)); - }); - return this.element.add(this.$tiles).css({ + this.element.addClass('animation-disabled'); + this.$tiles.attr('data-tiler-viewport-id', this.element.attr('id')); + this.$tiles.css({ width: this.element.outerWidth(), height: this.element.outerHeight() }); + this.$currentActiveTile.add(this.$currentPreviousTile).addClass(this._getAnimationClass(this.$currentActiveTile)); + this.$currentActiveTile.addClass('active enter end'); + this.$currentPreviousTile.addClass('previous exit end'); + if (this.options.isReversible) { + return this.$currentPreviousTile.addClass('reverse'); + } }, - _isNavigatingForward: function(enterTileIndex) { - return enterTileIndex > this.currentActiveTileIndex; + _setupLinks: function() { + return $('[data-tiler-link]').each(function() { + var $tile, tileId, tileIds; + tileIds = $(this).data('tiler-link').split(':').reverse(); + tileId = tileIds[0]; + $tile = tileIds[1] ? $(".tiler-tile#" + tileId, "#" + tileIds[1]) : $(".tiler-tile#" + tileId); + if (!$tile.length) { + return; + } + return $.extend($(this).data(), $tile.data()); + }); } }); }); diff --git a/spec/index.html b/spec/index.html index e974099..835b9e3 100644 --- a/spec/index.html +++ b/spec/index.html @@ -10,38 +10,73 @@
-
+
+ +
-
+
-
-
-
-
- - - - -
-
-
+ + + + +
+
+
-
-
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
-
-
+
+
@@ -52,26 +87,16 @@ + + - + - - - - - - - - - - - - - - + + diff --git a/spec/tiler_spec.coffee b/spec/tiler_spec.coffee index af266f3..8fc945f 100644 --- a/spec/tiler_spec.coffee +++ b/spec/tiler_spec.coffee @@ -1,92 +1,198 @@ describe 'Tiler', -> + $tiler = null + describe 'initialize', -> before -> - $('#initialize').tiler() + $tiler = $('#initialize') + $tiler.tiler + activeTile: 1 + isReversible: true it 'should not include tiles from nested tiler instances', -> - expect($('#initialize > .tiler-tile').data 'tiler-viewport-id').to.equal 'initialize' - expect($('#initialize-nested > .tiler-tile').data 'tiler-viewport-id').to.not.equal 'initialize' + expect($('.tiler-tile', $tiler).data 'tiler-viewport-id').to.equal 'initialize' + expect($('#initialize-nested > .tiler-tile').data 'tiler-viewport-id').to.be.undefined + + it 'should setup enter and exit tiles', -> + # tile 1 + $activeTile = $('#tile-initialize-1', $tiler) + expect($activeTile).to.have.class 'tile-initialize-1-animation' + expect($activeTile).to.have.class 'active' + expect($activeTile).to.have.class 'enter' + expect($activeTile).to.have.class 'end' + expect($activeTile).to.not.have.class 'previous' + expect($activeTile).to.not.have.class 'exit' + expect($activeTile).to.not.have.class 'start' + expect($activeTile).to.not.have.class 'reverse' + + # tile 2 + $previousTile = $('#tile-initialize-2', $tiler) + expect($previousTile).to.have.class 'tile-initialize-1-animation' + expect($previousTile).to.have.class 'previous' + expect($previousTile).to.have.class 'exit' + expect($previousTile).to.have.class 'end' + expect($previousTile).to.have.class 'reverse' + expect($previousTile).to.not.have.class 'active' + expect($previousTile).to.not.have.class 'enter' + expect($previousTile).to.not.have.class 'start' + + it 'should match the tiles size to the viewport size', -> + expect($('.tiler-tile', $tiler).outerWidth()).to.equal 321 + expect($('.tiler-tile', $tiler).outerHeight()).to.equal 123 + + it 'should add tile data to the link', -> + $button = $('button') + expect($button.data('tiler-title')).to.equal 'Tile Initialize 2 Title' + expect($button.data('tiler-animation')).to.equal 'tile-initialize-2-animation' + + context 'with custom activeTile', -> + before -> + $tiler = $('#active-tile') + $tiler.tiler + activeTile: 2 - describe '_buildLinks', -> - it 'should add tile data to the link', -> - expect($('button').data('tiler-title')).to.equal 'Tile 1' - expect($('button').data('tiler-foo')).to.equal 'Foo 1' + it 'should set the active & pervious tiles', -> + expect($('#tile-active-tile-2', $tiler)).to.have.class 'active' + expect($('#tile-active-tile-2', $tiler)).to.not.have.class 'previous' + expect($('#tile-active-tile-1', $tiler)).to.have.class 'previous' + expect($('#tile-active-tile-1', $tiler)).to.not.have.class 'active' - context 'with options', -> - describe 'isReversible', -> - before -> - $('#reverse-support').tiler - isReversible: true - $('#reverse-support').tiler('goTo', 2) - $('#reverse-support').tiler('goTo', 1) + describe 'goTo', -> + before -> + $tiler = $('#go-to') + $tiler.tiler() + $tiler.tiler 'goTo', 2, false - it 'should set the reverse classes', -> - expect($('#reverse-support #tile-1').hasClass('reverse')).to.be.true + it 'should set the active tile id on the viewport', -> + expect($tiler.attr('data-tiler-active-tile')).to.equal 'tile-go-to-2' - describe '_setupTiles', -> - context 'when viewport has a height', -> - before -> - $('#viewport-height').tiler() + context 'when going to the current tile', -> + currentTileViewportSpy = null - it 'should match the tiles size to the viewport size', -> - expect($('#viewport-height .tiler-tile').outerWidth()).to.equal 321 - expect($('#viewport-height .tiler-tile').outerHeight()).to.equal 123 + before -> + currentTileViewportSpy = sinon.spy() + $tiler = $('#current-tile') + $tiler.one 'tiler.goto', (e, data) -> + currentTileViewportSpy data + + $tiler.tiler() + $tiler.tiler 'goTo', 1, false + + it 'should not fire events', -> + expect(currentTileViewportSpy).to.not.be.called + + it 'should not update the tile classes', -> + # tile 1 + expect($('#tile-current-tile-1', $tiler)).to.have.class 'active' + expect($('#tile-current-tile-1', $tiler)).to.have.class 'enter' + expect($('#tile-current-tile-1', $tiler)).to.not.have.class 'previous' + expect($('#tile-current-tile-1', $tiler)).to.not.have.class 'exit' + + # tile 2 + expect($('#tile-current-tile-2', $tiler)).to.have.class 'previous' + expect($('#tile-current-tile-2', $tiler)).to.have.class 'exit' + expect($('#tile-current-tile-2', $tiler)).to.not.have.class 'active' + expect($('#tile-current-tile-2', $tiler)).to.not.have.class 'enter' + + context 'with events', -> + viewportEventSpy = null + enterTileSpy = null + exitTileSpy = null - describe 'goTo', -> - eventSpy = null + before -> + viewportEventSpy = sinon.spy() + $tiler = $('#events') + $tiler.one 'tiler.goto', (e, data) -> + viewportEventSpy data.enterTile.attr('id'), data.exitTile.attr('id') - before -> - eventSpy = sinon.spy() - $('#go-to').tiler() - $('#go-to').tiler('goTo', 1) + enterTileSpy = sinon.spy() + $('#tile-events-2', $tiler).one 'tiler.enter', -> + enterTileSpy $(@).attr('id') - # setup event after initialize to only test the event being called on the goTo call - $('#go-to').on 'tiler.goto', (e, data) -> - eventSpy data.enterTile.attr('id'), data.exitTile.attr('id') + exitTileSpy = sinon.spy() + $('#tile-events-1', $tiler).one 'tiler.exit', -> + exitTileSpy $(@).attr('id') - after -> - eventSpy.reset() + $tiler.tiler() + $tiler.tiler 'goTo', 2, false - it 'should set the active tile id on the viewport', -> - expect($('#go-to').attr('data-tiler-active-tile')).to.equal 'tile-1' + it 'should fire event on viewport', -> + expect(viewportEventSpy).to.be.calledWith 'tile-events-2', 'tile-events-1' - context 'without an active class', -> - before -> - $('#go-to').tiler('goTo', 2) + it 'should fire event on enter tile', -> + expect(enterTileSpy).to.be.calledWith 'tile-events-2' + + it 'should fire event on exit tile', -> + expect(exitTileSpy).to.be.calledWith 'tile-events-1' - it 'should activate the tile', -> - expect($('#go-to #tile-2').hasClass('active')).to.be.true + context 'isReversible', -> + context 'is true', -> + before -> + $tiler = $('#is-reversible') + $tiler.tiler + isReversible: true + $tiler.tiler 'goTo', 2, false + $tiler.tiler 'goTo', 1, false + + it 'should set the reverse class', -> + expect($('#tile-is-reversible-1', $tiler)).to.have.class 'reverse' + expect($('#tile-is-reversible-2', $tiler)).to.have.class 'reverse' + + context 'is false', -> + before -> + $tiler.tiler + isReversible: false + $tiler.tiler 'goTo', 2, false + $tiler.tiler 'goTo', 1, false - it 'should fire an event', -> - expect(eventSpy).to.be.calledWith 'tile-2', 'tile-1' + it 'should set the reverse class', -> + expect($('#tile-is-reversible-1', $tiler)).to.not.have.class 'reverse' + expect($('#tile-is-reversible-2', $tiler)).to.not.have.class 'reverse' - context 'with an active class', -> + context 'with a custom animation', -> before -> - $('#go-to').tiler('goTo', 1, 'foo-animation') + clock = sinon.useFakeTimers() + $tiler = $('#custom-animation') + $tiler.tiler() + $tiler.tiler 'goTo', 2, 'foo-animation' + clock.tick 10 - it 'should add the active class', -> - expect($('#go-to #tile-1').hasClass('foo-animation')).to.be.true + it 'should enable animation', -> + expect($tiler).to.not.have.class 'animation-disabled' - context 'when passing a boolean to active class', -> + it 'should add the animation class', -> + expect($('#tile-custom-animation-2', $tiler)).to.have.class 'foo-animation' + expect($('#tile-custom-animation-1', $tiler)).to.have.class 'foo-animation' + + context 'when animation is true or not passed', -> before -> - $('#tile-1', '#go-to').data 'tiler-animation', 'goto-animate-1' - $('#tile-2', '#go-to').data 'tiler-animation', 'goto-animate-2' + clock = sinon.useFakeTimers() + $tiler = $('#animation-true-or-undefined') + $tiler.tiler() + $tiler.tiler 'goTo', 2, true + clock.tick 10 - context 'when passing true', -> - before -> - $('#go-to').tiler('goTo', 2, true) + it 'should enable animation', -> + expect($tiler).to.not.have.class 'animation-disabled' - it 'should add the active class from the first tile', -> - expect($('#go-to #tile-2').hasClass('goto-animate-2')).to.be.true + it 'should use the animation of the tile', -> + expect($('#tile-animation-true-or-undefined-1', $tiler)).to.have.class 'tile-animation-true-or-undefined-animation-2' + expect($('#tile-animation-true-or-undefined-2', $tiler)).to.have.class 'tile-animation-true-or-undefined-animation-2' - describe 'refresh', -> - newWidth = null - newHeight = null + context 'when animation is false', -> + before -> + $tiler = $('#animation-false') + $tiler.tiler() + $tiler.tiler 'goTo', 2, false + + it 'should not enable animation', -> + expect($tiler).to.have.class 'animation-disabled' + describe 'refresh', -> before -> - $('#refresh').tiler() - $('#refresh').tiler('goTo', 'tile-2') - $('#refresh').tiler('refresh') + $tiler = $('#refresh') + $tiler.tiler() + $tiler.tiler 'goTo', 2, false + $tiler.tiler 'refresh' it 'should stay on the current tile', -> - expect($('#refresh').attr('data-tiler-active-tile')).to.equal 'tile-2' + expect($tiler.attr('data-tiler-active-tile')).to.equal 'tile-refresh-2' diff --git a/spec/tiler_spec.sass b/spec/tiler_spec.sass index 0fed251..9f95435 100644 --- a/spec/tiler_spec.sass +++ b/spec/tiler_spec.sass @@ -1,17 +1,7 @@ .tiler-viewport - &#viewport-height + &#initialize width: 321px height: 123px - &#tile-height - width: 0 - height: 0 - #tile-1 - width: 234px - height: 432px - #tile-2 - width: 432px - height: 234px - .tiler-tile transition: none !important diff --git a/src/tiler.coffee b/src/tiler.coffee index 82ede37..594a5d9 100644 --- a/src/tiler.coffee +++ b/src/tiler.coffee @@ -2,7 +2,7 @@ # * tiler # * https://github.com/brewster1134/tiler # * -# * @version 2.0.1 +# * @version 2.0.2 # * @author Ryan Brewster # * Copyright (c) 2014 # * Licensed under the MIT license. @@ -21,130 +21,152 @@ ) @, ($) -> $.widget 'ui.tiler', - # - # WIDGET SETUP/METHODS - # widgetEventPrefix: 'tiler' options: + activeTile: 1 isReversible: true - startingActiveTile: 1 - startingPreviousTile: 2 - - _create: -> - @currentActiveTileIndex = @options.startingActiveTile - @currentPreviousTileIndex = @options.startingPreviousTile _init: -> - @element.addClass 'animation-disabled' - # Collect all the tiles, except for those nested inside another tiler instance @$tiles = $('.tiler-tile', @element).not(@element.find('.tiler-viewport .tiler-tile')) - @$enterTile = @$tiles.eq @currentActiveTileIndex - 1 - @$exitTile = @$tiles.eq @currentPreviousTileIndex - 1 + @$currentActiveTile ||= @_getTile @options.activeTile + @$currentPreviousTile ||= @_getTile @_getTileIndex(@$currentActiveTile) + 1 + # Setup DOM elements @_setupTiles() @_setupLinks() # - # PUBLIC METHODS + # PUBLIC Methods # refresh: -> @_init() @element.trigger 'tiler.refresh' @$enterTile?.trigger 'tiler.refresh' - # Find tile with various values - # - _getTile: (tileValue) -> - # ...as a css ID (String) - if typeof tileValue == 'string' - $("##{tileValue}", @element) - - # ...as jquery object - else if tileValue.jquery - tileValue.jquery - - # ...as dom node - else if tileValue.nodeType - $(tileValue) - - # ...as index (starting at 1) - else - @$tiles.eq tileValue - 1 - - goTo: (tile, animation) -> - # New active tile - @$enterTile = @_getTile tile - enterTileIndex = @$tiles.index @$enterTile - @$exitTile = @_getTile @currentActiveTileIndex + 1 + goTo: (tileValue, animation) -> + # Get new active & previous tiles + $enteringTile = @_getTile tileValue + $exitingTile = @$currentActiveTile # Return if we are already on that tile - return if !@$enterTile.length || @currentActiveTileIndex == enterTileIndex - - @_transitionCss @_getAnimationClass(), animation - - # Fire js events - # ...on viewport - @element.trigger 'tiler.goto', - enterTile: @$enterTile - exitTile: @$exitTile - - # ...on animating tiles - @$enterTile.trigger 'tiler.enter' - @$exitTile.trigger 'tiler.exit' + return if !$enteringTile.length || $enteringTile[0] == @$currentActiveTile[0] - # Update the current tile id - @currentActiveTileIndex = enterTileIndex - @currentPreviousTileIndex = @currentActiveTileIndex - @element.attr 'data-tiler-active-tile', @$enterTile.attr('id') + # Update css classes for animation + @_transitionCss $enteringTile, $exitingTile, animation - return @$enterTile + return $enteringTile # # PRIVATE METHODS # - _getAnimationClass: -> - @$enterTile.data('tiler-animation') || @element.data('tiler-animation') || '' - _transitionCss: (animationClass, animation) -> - animationClass = animation if typeof animation == 'string' + # Find tile with various values + # + _getTile: (tileValue) -> + $tile = switch typeof tileValue + # jquery object or dom element + when 'number' + @$tiles.eq tileValue - 1 + when 'string' + $("##{tileValue}", @element) + else + $(tileValue, @element) - position = if animation == false - 'end' + # if no tile is found, return the first tile + if $tile.length + $tile else - 'start' + @$tiles.eq 0 - enterTileIndex = @$tiles.index @$enterTile + # get HUMAN COUNTABLE index (eg starting at 1, not 0) + # + _getTileIndex: ($tile) -> + @$tiles.index($tile) + 1 + + _getAnimationClass: ($tile) -> + $tile.data('tiler-animation') || @element.data('tiler-animation') || '' + + _transitionCss: ($enteringTile, $exitingTile, animation) -> + # Get animation class + animationClass = if typeof animation == 'string' + animation + else + @_getAnimationClass $enteringTile - # Add reverse class if supported and navigating in reverse order (according to the dom) - reverseClass = if @options.isReversible && !@_isNavigatingForward(enterTileIndex) + # Get reverse class + reverseClass = if @options.isReversible && @_getTileIndex($enteringTile) < @_getTileIndex(@$currentActiveTile) 'reverse' else '' + # Get position class + positionClass = if animation == false + 'end' + else + 'start' + # Disable animations @element.addClass 'animation-disabled' # Build tile starting position animations classes - enterStartClass = "tiler-tile #{animationClass} active enter #{reverseClass} #{position}" - exitStartClass = "tiler-tile #{animationClass} previous exit #{reverseClass} #{position}" - otherTileClass = 'tiler-tile' - - # Set tile classes - @$enterTile.attr 'class', enterStartClass - @$exitTile.attr 'class', exitStartClass - @$tiles.not(@$enterTile).not(@$exitTile).attr 'class', otherTileClass + $enteringTile.attr 'class', "tiler-tile #{animationClass} active enter #{reverseClass} #{positionClass}" + $exitingTile.attr 'class', "tiler-tile #{animationClass} previous exit #{reverseClass} #{positionClass}" + @$tiles.not($enteringTile).not($exitingTile).attr 'class', 'tiler-tile' # setTimeout needed to give the browser time to repaint the tiles (if neccessary) with the animation starting position - unless animation == false + if animation == false + @_finalizeNewTiles $enteringTile, $exitingTile + else setTimeout => # Enable transitions @element.removeClass 'animation-disabled' # Replace position classes to trigger animation - @$enterTile.add(@$exitTile).switchClass 'start', 'end' + $enteringTile.add($exitingTile).switchClass 'start', 'end' + + @_finalizeNewTiles $enteringTile, $exitingTile , 10 + _finalizeNewTiles: ($enterTile, $exitTile) -> + @$currentActiveTile = $enterTile + @$currentPreviousTile = $exitTile + @element.attr 'data-tiler-active-tile', @$currentActiveTile.attr('id') + + # Fire js events + # ...on viewport + @element.trigger 'tiler.goto', + enterTile: $enterTile + exitTile: $exitTile + + # ...on animating tiles + $enterTile.trigger 'tiler.enter' + $exitTile.trigger 'tiler.exit' + + # Setup tiles with neccessary meta data + # + _setupTiles: -> + # Disable animations while we setup everything + @element.addClass 'animation-disabled' + + # Add a data attribute with the viewport id + @$tiles.attr 'data-tiler-viewport-id', @element.attr('id') + + # Set sizes + @$tiles.css + width: @element.outerWidth() + height: @element.outerHeight() + + # Add active tile animation to both active and previous tiles + @$currentActiveTile.add(@$currentPreviousTile).addClass @_getAnimationClass(@$currentActiveTile) + + # Setup active tile + @$currentActiveTile.addClass 'active enter end' + + # Setup (fake) previous tile + @$currentPreviousTile.addClass 'previous exit end' + @$currentPreviousTile.addClass 'reverse' if @options.isReversible + # Find possible links throughout the entire page and set meta data on them # _setupLinks: -> @@ -156,35 +178,12 @@ tileId = tileIds[0] # Get the tile with matching id and viewport - tile = if tileIds[1] + $tile = if tileIds[1] $(".tiler-tile##{tileId}", "##{tileIds[1]}") else $(".tiler-tile##{tileId}") - return unless tile.length + return unless $tile.length # Apply tile data attributes to link - $.extend $(@).data(), tile.data() - - # Match all the tiles to the size of the viewport - # - _setupTiles: -> - self = @ - - # Loop through all tiles - @$tiles.each -> - # Add a data attribute with the viewport id - $(@).attr 'data-tiler-viewport-id', self.element.attr('id') - - # Add animation class - $(@).addClass self._getAnimationClass(true) - - # Set sizes - @element.add(@$tiles).css - width: @element.outerWidth() - height: @element.outerHeight() - - # Determine if we are advancing or retreating through our virtual tiles - # - _isNavigatingForward: (enterTileIndex) -> - enterTileIndex > @currentActiveTileIndex + $.extend $(@).data(), $tile.data()