diff --git a/ruby/lib/jam_ruby/models/affiliate_partner.rb b/ruby/lib/jam_ruby/models/affiliate_partner.rb index 58c4a1b8b..4408ffa42 100644 --- a/ruby/lib/jam_ruby/models/affiliate_partner.rb +++ b/ruby/lib/jam_ruby/models/affiliate_partner.rb @@ -418,12 +418,13 @@ class JamRuby::AffiliatePartner < ActiveRecord::Base elsif quarter == 2 [Date.new(year, 7, 1), Date.new(year, 9, 30)] elsif quarter == 3 - [Date.new(year, 7, 1), Date.new(year, 9, 30)] + [Date.new(year, 10, 1), Date.new(year, 12, 31)] else raise "invalid quarter #{quarter}" end end + # 1-based month def self.boundary_dates_for_month(year, month) [Date.new(year, month, 1), Date.civil(year, month, -1)] end diff --git a/ruby/spec/jam_ruby/models/affiliate_partner_spec.rb b/ruby/spec/jam_ruby/models/affiliate_partner_spec.rb index 26c660daf..822a1f527 100644 --- a/ruby/spec/jam_ruby/models/affiliate_partner_spec.rb +++ b/ruby/spec/jam_ruby/models/affiliate_partner_spec.rb @@ -722,6 +722,116 @@ describe AffiliatePartner do traffic_total_day2.signups.should eq(1) end end + + describe "boundary_dates" do + it "1st quarter" do + start_date, end_date = AffiliatePartner.boundary_dates(2015, 0) + start_date.should eq(Date.new(2015, 1, 1)) + end_date.should eq(Date.new(2015, 3, 31)) + end + + it "2nd quarter" do + start_date, end_date = AffiliatePartner.boundary_dates(2015, 1) + start_date.should eq(Date.new(2015, 4, 1)) + end_date.should eq(Date.new(2015, 6, 30)) + end + + it "3rd quarter" do + start_date, end_date = AffiliatePartner.boundary_dates(2015, 2) + start_date.should eq(Date.new(2015, 7, 1)) + end_date.should eq(Date.new(2015, 9, 30)) + end + + it "4th quarter" do + start_date, end_date = AffiliatePartner.boundary_dates(2015, 3) + start_date.should eq(Date.new(2015, 10, 1)) + end_date.should eq(Date.new(2015, 12, 31)) + end + end + + describe "boundary_dates_for_month" do + it "invalid month" do + expect{AffiliatePartner.boundary_dates_for_month(2015, 0)}.to raise_error + end + + it "January" do + start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 1) + start_date.should eq(Date.new(2015, 1, 1)) + end_date.should eq(Date.new(2015, 1, 31)) + end + + it "February" do + start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 2) + start_date.should eq(Date.new(2015, 2, 1)) + end_date.should eq(Date.new(2015, 2, 28)) + end + + it "March" do + start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 3) + start_date.should eq(Date.new(2015, 3, 1)) + end_date.should eq(Date.new(2015, 3, 31)) + end + + it "April" do + start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 4) + start_date.should eq(Date.new(2015, 4, 1)) + end_date.should eq(Date.new(2015, 4, 30)) + end + + it "May" do + start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 5) + start_date.should eq(Date.new(2015, 5, 1)) + end_date.should eq(Date.new(2015, 5, 31)) + end + + it "June" do + start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 6) + start_date.should eq(Date.new(2015, 6, 1)) + end_date.should eq(Date.new(2015, 6, 30)) + end + + it "July" do + start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 7) + start_date.should eq(Date.new(2015, 7, 1)) + end_date.should eq(Date.new(2015, 7, 31)) + end + + it "August" do + start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 8) + start_date.should eq(Date.new(2015, 8, 1)) + end_date.should eq(Date.new(2015, 8, 31)) + end + + it "September" do + start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 9) + start_date.should eq(Date.new(2015, 9, 1)) + end_date.should eq(Date.new(2015, 9, 30)) + end + + it "October" do + start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 10) + start_date.should eq(Date.new(2015, 10, 1)) + end_date.should eq(Date.new(2015, 10, 31)) + end + + it "November" do + start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 11) + start_date.should eq(Date.new(2015, 11, 1)) + end_date.should eq(Date.new(2015, 11, 30)) + end + + it "December" do + start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 12) + start_date.should eq(Date.new(2015, 12, 1)) + end_date.should eq(Date.new(2015, 12, 31)) + end + + it "February in a leap year" do + start_date, end_date = AffiliatePartner.boundary_dates_for_month(2016, 2) + start_date.should eq(Date.new(2016, 2, 1)) + end_date.should eq(Date.new(2016, 2, 29)) + end + end end end diff --git a/web/app/assets/javascripts/application.js b/web/app/assets/javascripts/application.js index 474503da2..03ccbd2a7 100644 --- a/web/app/assets/javascripts/application.js +++ b/web/app/assets/javascripts/application.js @@ -36,6 +36,7 @@ //= require jquery.custom-protocol //= require jquery.exists //= require jquery.payment +//= require jquery.visible //= require howler.core.js //= require jstz //= require class diff --git a/web/app/assets/javascripts/globals.js b/web/app/assets/javascripts/globals.js index 175a96fd6..85ebcc250 100644 --- a/web/app/assets/javascripts/globals.js +++ b/web/app/assets/javascripts/globals.js @@ -52,7 +52,8 @@ JAMTRACK_DOWNLOADER_STATE_CHANGED: 'jamtrack_downloader_state', METRONOME_PLAYBACK_MODE_SELECTED: 'metronome_playback_mode_selected', CHECKOUT_SIGNED_IN: 'checkout_signed_in', - CHECKOUT_SKIP_SIGN_IN: 'checkout_skip_sign_in' + CHECKOUT_SKIP_SIGN_IN: 'checkout_skip_sign_in', + PREVIEW_PLAYED: 'preview_played' }; context.JK.PLAYBACK_MONITOR_MODE = { diff --git a/web/app/assets/javascripts/helpBubbleHelper.js b/web/app/assets/javascripts/helpBubbleHelper.js index eb68a4a6c..c8ccdc4cf 100644 --- a/web/app/assets/javascripts/helpBubbleHelper.js +++ b/web/app/assets/javascripts/helpBubbleHelper.js @@ -62,6 +62,24 @@ } } + helpBubble.rotateJamTrackLandingBubbles = function($preview, $video, $ctaButton, $alternativeCta) { + $(window).on('load', function() { + setTimeout(function() { + helpBubble.jamtrackLandingPreview($preview, $preview.offsetParent()) + + setTimeout(function() { + helpBubble.jamtrackLandingVideo($video, $video.offsetParent()) + + setTimeout(function() { + helpBubble.jamtrackLandingCta($ctaButton, $alternativeCta) + }, 11000); // 5 seconds on top of 6 second show time of bubbles + }, 11000); // 5 seconds on top of 6 second show time of bubbles + }, 1500) + + + }) + } + helpBubble.clearJamTrackGuide = clearJamTrackGuideTimeout; helpBubble.jamtrackGuideTile = function ($element, $offsetParent) { @@ -82,4 +100,33 @@ }) } + helpBubble.jamtrackLandingPreview = function($element, $offsetParent) { + context.JK.prodBubble($element, 'jamtrack-landing-preview', {}, bigHelpOptions({positions:['right'], offsetParent: $offsetParent})) + } + + helpBubble.jamtrackLandingVideo = function($element, $offsetParent) { + context.JK.prodBubble($element, 'jamtrack-landing-video', {}, bigHelpOptions({positions:['left'], offsetParent: $offsetParent})) + } + + helpBubble.jamtrackLandingCta = function($element, $alternativeElement) { + if ($element.visible()) { + context.JK.prodBubble($element, 'jamtrack-landing-cta', {}, bigHelpOptions({positions:['left']})) + } + else { + context.JK.prodBubble($alternativeElement, 'jamtrack-landing-cta', {}, bigHelpOptions({positions:['right']})) + } + } + + helpBubble.jamtrackBrowseBand = function($element, $offsetParent) { + return context.JK.prodBubble($element, 'jamtrack-browse-band', {}, bigHelpOptions({positions:['top'], offsetParent: $offsetParent})) + } + + helpBubble.jamtrackBrowseMasterMix = function($element, $offsetParent) { + return context.JK.prodBubble($element, 'jamtrack-browse-master-mix', {}, bigHelpOptions({positions:['top'], offsetParent: $offsetParent})) + } + + helpBubble.jamtrackBrowseCta = function($element, $offsetParent) { + return context.JK.prodBubble($element, 'jamtrack-browse-cta', {}, bigHelpOptions({positions:['top'], offsetParent: $offsetParent})) + } + })(window, jQuery); \ No newline at end of file diff --git a/web/app/assets/javascripts/jam_track_preview.js.coffee b/web/app/assets/javascripts/jam_track_preview.js.coffee index 585b500dd..f78a25d05 100644 --- a/web/app/assets/javascripts/jam_track_preview.js.coffee +++ b/web/app/assets/javascripts/jam_track_preview.js.coffee @@ -129,6 +129,8 @@ context.JK.JamTrackPreview = class JamTrackPreview if e? e.stopPropagation() + $(this).triggerHandler(@EVENTS.PREVIEW_PLAYED) + if @no_audio context.JK.prodBubble(@playButton, 'There is no preview available for this track.', {}, {duration:2000}) else diff --git a/web/app/assets/javascripts/jam_track_screen.js.coffee b/web/app/assets/javascripts/jam_track_screen.js.coffee index 43411b93b..ac25cc4c8 100644 --- a/web/app/assets/javascripts/jam_track_screen.js.coffee +++ b/web/app/assets/javascripts/jam_track_screen.js.coffee @@ -6,7 +6,8 @@ context.JK.JamTrackScreen=class JamTrackScreen LIMIT = 10 instrument_logo_map = context.JK.getInstrumentIconMap24() - constructor: (@app) -> + constructor: (@app) -> + @EVENTS = context.JK.EVENTS @logger = context.JK.logger @screen = null @content = null @@ -21,6 +22,7 @@ context.JK.JamTrackScreen=class JamTrackScreen @next = null @currentQuery = this.defaultQuery() @expanded = null + @shownHelperBubbles = false beforeShow:(data) => this.setFilterFromURL() @@ -38,11 +40,17 @@ context.JK.JamTrackScreen=class JamTrackScreen ) else this.refresh() + unless @shownHelperBubbles + @shownHelperBubbles = true + @startHelperBubbles() afterShow:(data) => context.JK.Tracking.jamtrackBrowseTrack(@app) beforeHide: () => + this.clearCtaHelpTimeout() + this.clearBandFilterHelpTimeout() + this.clearMasterHelpTimeout() this.clearResults(); events:() => @@ -57,6 +65,104 @@ context.JK.JamTrackScreen=class JamTrackScreen @noMoreJamtracks.hide() @next = null + startHelperBubbles: () => + @showBandFilterHelpTimeout = setTimeout(@showBandFilterHelp, 3500) + + showBandFilterHelp: () => + context.JK.HelpBubbleHelper.jamtrackBrowseBand(@artist.closest('.easydropdown-wrapper'), $('body')) + + @showMasterHelpDueTime = new Date().getTime() + 11000 # 6000 ms for band tooltip to display, and 5 seconds of quiet time + @scroller.on('scroll', @masterHelpScrollWatch) + @scroller.on('scroll', @clearBubbles) + @showMasterHelpTimeout = setTimeout(@showMasterHelp, @masterHelpDueTime()) + + clearBubbles: () => + if @helpBubble? + @helpBubble.btOff() + @helpBubble = null + + # computes when we should show the master help bubble + masterHelpDueTime: () => + dueTime = @showMasterHelpDueTime - new Date().getTime() + if dueTime <= 0 + dueTime = 2000 + dueTime + + + # computes when we should show the master help bubble + ctaHelpDueTime: () => + dueTime = @showCtaHelpDueTime - new Date().getTime() + if dueTime <= 0 + dueTime = 2000 + dueTime + + # if the user scrolls, reset the master help due time + masterHelpScrollWatch: () => + @clearMasterHelpTimeout() + @showMasterHelpTimeout = setTimeout(@showMasterHelp, @masterHelpDueTime() + 2000) + + # if the user scrolls, reset the master help due time + ctaHelpScrollWatch: () => + @clearCtaHelpTimeout() + @showCtaHelpTimeout = setTimeout(@showCtaHelp, @ctaHelpDueTime() + 2000) + + + showCtaHelp: () => + @scroller.off('scroll', @ctaHelpScrollWatch) + @clearCtaHelpTimeout() + + cutoff = @scroller.offset().top; + + @screen.find('.jamtrack-actions').each((i, element) => + $element = $(element) + + if ($element.offset().top >= cutoff) + @helpBubble = context.JK.HelpBubbleHelper.jamtrackBrowseCta($element, $('body')) + return false + else + return true + ) + + showMasterHelp: () => + @scroller.off('scroll', @masterHelpScrollWatch) + @clearMasterHelpTimeout() + + # don't show the help if the user has already clicked a preview + unless @userPreviewed + cutoff = @scroller.offset().top; + + @screen.find('.jamtrack-preview[data-track-type="Master"]').each((i, element) => + $element = $(element) + + if ($element.offset().top >= cutoff) + @helpBubble = context.JK.HelpBubbleHelper.jamtrackBrowseMasterMix($element.find('.play-button'), $('body')) + return false + else + return true + ) + + @showCtaHelpDueTime = new Date().getTime() + 11000 + @scroller.on('scroll', @ctaHelpScrollWatch) + @showCtaHelpTimeout = setTimeout(@showCtaHelp, @ctaHelpDueTime()) # 6000 ms for bubble show time, and 5000ms for delay + + previewPlayed: () => + @userPreviewed = true + + clearCtaHelpTimeout:() => + if @showCtaHelpTimeout? + clearTimeout(@showCtaHelpTimeout) + @showCtaHelpTimeout = null + + clearBandFilterHelpTimeout: () => + if @showBandFilterHelpTimeout? + clearTimeout(@showBandFilterHelpTimeout) + @showBandFilterHelpTimeout = null + + clearMasterHelpTimeout: () => + if @showMasterHelpTimeout? + clearTimeout(@showMasterHelpTimeout) + @showMasterHelpTimeout = null + setFilterFromURL:() => # Grab parms from URL for artist, instrument, and availability parms=this.getParams() @@ -73,7 +179,9 @@ context.JK.JamTrackScreen=class JamTrackScreen @availability.val(parms.availability) else @availability.val('') - window.history.replaceState({}, "", "/client#/jamtrackBrowse") + + if window.history.replaceState #ie9 proofing + window.history.replaceState({}, "", "/client#/jamtrackBrowse") getParams:() => params = {} @@ -320,7 +428,8 @@ context.JK.JamTrackScreen=class JamTrackScreen for track in jamTrack.tracks trackRow = jamtrackElement.find("[jamtrack-track-id='#{track.id}']") previewElement = trackRow.find(".jamtrack-preview") - new JK.JamTrackPreview(@app, previewElement, jamTrack, track, {master_shows_duration: true, color:'gray'}) + preview = new JK.JamTrackPreview(@app, previewElement, jamTrack, track, {master_shows_duration: true, color:'gray'}) + $(preview).on(@EVENTS.PREVIEW_PLAYED, @previewPlayed) this.handleExpanded(jamtrackElement, false) diff --git a/web/app/assets/javascripts/jamtrack_landing.js.coffee b/web/app/assets/javascripts/jamtrack_landing.js.coffee index 2fb470923..5198a1f64 100644 --- a/web/app/assets/javascripts/jamtrack_landing.js.coffee +++ b/web/app/assets/javascripts/jamtrack_landing.js.coffee @@ -72,7 +72,8 @@ context.JK.JamTrackLanding = class JamTrackLanding that=this @bandList.on "click", "a.artist-link", (event)-> context.location="client#/jamtrackBrowse" - window.history.replaceState({}, "", this.href) + if window.history.replaceState # ie9 proofing + window.history.replaceState({}, "", this.href) event.preventDefault() handleFailure:(error) => diff --git a/web/app/assets/javascripts/web/individual_jamtrack.js b/web/app/assets/javascripts/web/individual_jamtrack.js index 82863ad74..ebb720f2c 100644 --- a/web/app/assets/javascripts/web/individual_jamtrack.js +++ b/web/app/assets/javascripts/web/individual_jamtrack.js @@ -45,11 +45,13 @@ $previews.append($element); new context.JK.JamTrackPreview(app, $element, jam_track, track, {master_shows_duration: false, color:'black', master_adds_line_break: true, preload_master:true}) + + if(track.track_type =='Master') { + context.JK.HelpBubbleHelper.rotateJamTrackLandingBubbles($element.find('.jam-track-preview'), $page.find('.video-wrapper'), $page.find('.cta-free-jamtrack a'), $page.find('a.browse-jamtracks')); + } }) $previews.append('
') - - }) .fail(function () { app.notify({title: 'Unable to fetch JamTrack', text: "Please refresh the page or try again later."}) diff --git a/web/app/assets/javascripts/web/individual_jamtrack_band.js b/web/app/assets/javascripts/web/individual_jamtrack_band.js index aaac3ca8c..22ceb52a3 100644 --- a/web/app/assets/javascripts/web/individual_jamtrack_band.js +++ b/web/app/assets/javascripts/web/individual_jamtrack_band.js @@ -35,6 +35,10 @@ $previews.append($element); new context.JK.JamTrackPreview(app, $element, jam_track, track, {master_shows_duration: false, color:'black', master_adds_line_break:true, preload_master:true}) + + if(track.track_type =='Master') { + context.JK.HelpBubbleHelper.rotateJamTrackLandingBubbles($element.find('.jam-track-preview'), $page.find('.video-wrapper'), $page.find('.cta-free-jamtrack a'), $page.find('a.browse-jamtracks')); + } }) $previews.append('
') diff --git a/web/app/assets/javascripts/web/web.js b/web/app/assets/javascripts/web/web.js index 99dc9de2d..a2a2c58d2 100644 --- a/web/app/assets/javascripts/web/web.js +++ b/web/app/assets/javascripts/web/web.js @@ -20,6 +20,7 @@ //= require jquery.icheck //= require jquery.bt //= require jquery.exists +//= require jquery.visible //= require howler.core.js //= require AAA_Log //= require AAC_underscore diff --git a/web/app/assets/stylesheets/client/help.css.scss b/web/app/assets/stylesheets/client/help.css.scss index b5c3cf17b..1bd085fa4 100644 --- a/web/app/assets/stylesheets/client/help.css.scss +++ b/web/app/assets/stylesheets/client/help.css.scss @@ -50,6 +50,8 @@ body.jam, body.web, .dialog{ .big-help { font-size:20px; + color: #ed3618; + p {color:#ed3618} } .help-hover-recorded-tracks, .help-hover-stream-mix, .help-hover-recorded-backing-tracks { diff --git a/web/app/assets/stylesheets/client/jamtrack.css.scss b/web/app/assets/stylesheets/client/jamtrack.css.scss index 238465fdd..7b3a27aaf 100644 --- a/web/app/assets/stylesheets/client/jamtrack.css.scss +++ b/web/app/assets/stylesheets/client/jamtrack.css.scss @@ -209,14 +209,10 @@ @include border_box_sizing; width: 20%; text-align: center; + vertical-align: middle; .jamtrack-action-container { - display: flex; - align-items: center; - justify-content: center; - position:absolute; - height:100%; - width:100%; + display:inline-block; } .play-button { diff --git a/web/app/views/clients/_help.html.slim b/web/app/views/clients/_help.html.slim index 2ec8bf719..9af12062e 100644 --- a/web/app/views/clients/_help.html.slim +++ b/web/app/views/clients/_help.html.slim @@ -261,4 +261,28 @@ script type="text/template" id="template-help-jamtrack-guide-private" script type="text/template" id="template-help-jamtrack-guide-session" .jamtrack-guide-open.big-help - p To try out your JamTrack, click here to open it. \ No newline at end of file + p To try out your JamTrack, click here to open it. + +script type="text/template" id="template-help-jamtrack-landing-preview" + .jamtrack-landing-preview.big-help + p click a play button to preview the master mix and individual tracks of the JamTrack + +script type="text/template" id="template-help-jamtrack-landing-video" + .jamtrack-landing-video.big-help + p click to watch JamTracks video + +script type="text/template" id="template-help-jamtrack-landing-cta" + .jamtrack-landing-cta.big-help + p click to browse through our JamTracks collection and get your first one free! + +script type="text/template" id="template-help-jamtrack-browse-band" + .jamtrack-browse-band.big-help + p List JamTracks of a specified band + +script type="text/template" id="template-help-jamtrack-browse-master-mix" + .jamtrack-browse-master-mix.big-help + p Listen to master mix and individual tracks + +script type="text/template" id="template-help-jamtrack-browse-cta" + .jamtrack-browse-cta.big-help + p Click to select your first free JamTrack! \ No newline at end of file diff --git a/web/app/views/landings/individual_jamtrack.html.slim b/web/app/views/landings/individual_jamtrack.html.slim index c3b6e9daa..cb1cfc771 100644 --- a/web/app/views/landings/individual_jamtrack.html.slim +++ b/web/app/views/landings/individual_jamtrack.html.slim @@ -1,5 +1,6 @@ - provide(:page_name, 'landing_page full landing_jamtrack individual_jamtrack') - provide(:description, @jam_track.nil? ? nil : "Preview multi-track JamTrack recording: #{@jam_track.name} by #{@jam_track.original_artist}. Way better than a backing track.") +- provide(:title, @jam_track.nil? ? nil : "Preview JamTrack: #{@jam_track.name} by #{@jam_track.original_artist}") .one_by_two .row diff --git a/web/app/views/landings/individual_jamtrack_band.html.slim b/web/app/views/landings/individual_jamtrack_band.html.slim index 88237cd56..9b2b72b19 100644 --- a/web/app/views/landings/individual_jamtrack_band.html.slim +++ b/web/app/views/landings/individual_jamtrack_band.html.slim @@ -1,5 +1,6 @@ - provide(:page_name, 'landing_page full landing_jamtrack individual_jamtrack_band') - provide(:description, @jam_track.nil? ? nil : "Preview multi-track JamTrack recording: #{@jam_track.name} by #{@jam_track.original_artist}. Way better than a backing track.") +- provide(:title, @jam_track.nil? ? nil : "Preview JamTrack: #{@jam_track.name} by #{@jam_track.original_artist}") .one_by_two .row diff --git a/web/config/application.rb b/web/config/application.rb index 60c645415..1e61dc1ab 100644 --- a/web/config/application.rb +++ b/web/config/application.rb @@ -346,5 +346,7 @@ if defined?(Bundler) config.expire_fingerprint_days = 14 config.found_conflict_count = 1 config.web_performance_timing_enabled = true + config.jamtrack_landing_bubbles_enabled = true + config.jamtrack_browser_bubbles_enabled = true end end diff --git a/web/config/environments/test.rb b/web/config/environments/test.rb index b20761c29..a5b075118 100644 --- a/web/config/environments/test.rb +++ b/web/config/environments/test.rb @@ -108,6 +108,6 @@ SampleApp::Application.configure do config.jam_tracks_available = true config.video_available = "full" config.guard_against_fraud = true - config.error_on_fraud = true + config.error_on_fraud = false end diff --git a/web/config/initializers/gon.rb b/web/config/initializers/gon.rb index 71c0a7493..f82a4a1d7 100644 --- a/web/config/initializers/gon.rb +++ b/web/config/initializers/gon.rb @@ -17,4 +17,6 @@ Gon.global.gear_check_ignore_high_latency = Rails.application.config.gear_check_ Gon.global.purchases_enabled = Rails.application.config.purchases_enabled Gon.global.estimate_taxes = Rails.application.config.estimate_taxes Gon.global.web_performance_timing_enabled = Rails.application.config.web_performance_timing_enabled +Gon.global.jamtrack_landing_bubbles_enabled = Rails.application.config.jamtrack_landing_bubbles_enabled +Gon.global.jamtrack_browser_bubbles_enabled = Rails.application.config.jamtrack_browser_bubbles_enabled Gon.global.env = Rails.env diff --git a/web/vendor/assets/javascripts/jquery.visible.js b/web/vendor/assets/javascripts/jquery.visible.js new file mode 100644 index 000000000..1e340099b --- /dev/null +++ b/web/vendor/assets/javascripts/jquery.visible.js @@ -0,0 +1,68 @@ +(function($){ + + /** + * Copyright 2012, Digital Fusion + * Licensed under the MIT license. + * http://teamdf.com/jquery-plugins/license/ + * + * @author Sam Sehnert + * @desc A small plugin that checks whether elements are within + * the user visible viewport of a web browser. + * only accounts for vertical position, not horizontal. + */ + var $w = $(window); + $.fn.visible = function(partial,hidden,direction){ + + if (this.length < 1) + return; + + var $t = this.length > 1 ? this.eq(0) : this, + t = $t.get(0), + vpWidth = $w.width(), + vpHeight = $w.height(), + direction = (direction) ? direction : 'both', + clientSize = hidden === true ? t.offsetWidth * t.offsetHeight : true; + + if (typeof t.getBoundingClientRect === 'function'){ + + // Use this native browser method, if available. + var rec = t.getBoundingClientRect(), + tViz = rec.top >= 0 && rec.top < vpHeight, + bViz = rec.bottom > 0 && rec.bottom <= vpHeight, + lViz = rec.left >= 0 && rec.left < vpWidth, + rViz = rec.right > 0 && rec.right <= vpWidth, + vVisible = partial ? tViz || bViz : tViz && bViz, + hVisible = partial ? lViz || rViz : lViz && rViz; + + if(direction === 'both') + return clientSize && vVisible && hVisible; + else if(direction === 'vertical') + return clientSize && vVisible; + else if(direction === 'horizontal') + return clientSize && hVisible; + } else { + + var viewTop = $w.scrollTop(), + viewBottom = viewTop + vpHeight, + viewLeft = $w.scrollLeft(), + viewRight = viewLeft + vpWidth, + offset = $t.offset(), + _top = offset.top, + _bottom = _top + $t.height(), + _left = offset.left, + _right = _left + $t.width(), + compareTop = partial === true ? _bottom : _top, + compareBottom = partial === true ? _top : _bottom, + compareLeft = partial === true ? _right : _left, + compareRight = partial === true ? _left : _right; + + if(direction === 'both') + return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop)) && ((compareRight <= viewRight) && (compareLeft >= viewLeft)); + else if(direction === 'vertical') + return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop)); + else if(direction === 'horizontal') + return !!clientSize && ((compareRight <= viewRight) && (compareLeft >= viewLeft)); + } + }; + +})(jQuery); \ No newline at end of file