197 lines
9.7 KiB
JavaScript
197 lines
9.7 KiB
JavaScript
/*!
|
|
* jQuery Smart Banner
|
|
* Copyright (c) 2012 Arnold Daniels <arnold@jasny.net>
|
|
* Based on 'jQuery Smart Web App Banner' by Kurt Zenisek @ kzeni.com
|
|
*/
|
|
!function ($) {
|
|
var SmartBanner = function (options) {
|
|
this.origHtmlMargin = parseFloat($('html').css('margin-top')) // Get the original margin-top of the HTML element so we can take that into account
|
|
this.options = $.extend({}, $.smartbanner.defaults, options)
|
|
|
|
var standalone = navigator.standalone // Check if it's already a standalone web app or running within a webui view of an app (not mobile safari)
|
|
, UA = navigator.userAgent
|
|
|
|
// Detect banner type (iOS or Android)
|
|
if (this.options.force) {
|
|
this.type = this.options.force
|
|
} else if (UA.match(/iPad|iPhone|iPod/i) != null) {
|
|
if (UA.match(/Safari/i) != null &&
|
|
(UA.match(/CriOS/i) != null ||
|
|
window.Number(navigator.userAgent.substr(navigator.userAgent.indexOf('OS ') + 3, 3).replace('_', '.')) < 6)) this.type = 'ios' // Check webview and native smart banner support (iOS 6+)
|
|
} else if (UA.match(/Android/i) != null) {
|
|
this.type = 'android'
|
|
} else if (UA.match(/Windows NT 6.2/i) != null && UA.match(/Touch/i) !== null) {
|
|
this.type = 'windows'
|
|
}
|
|
|
|
// Don't show banner if device isn't iOS or Android, website is loaded in app or user dismissed banner
|
|
if (!this.type || standalone || this.getCookie('sb-closed') || this.getCookie('sb-installed')) {
|
|
return
|
|
}
|
|
|
|
// Calculate scale
|
|
this.scale = this.options.scale == 'auto' ? $(window).width() / window.screen.width : this.options.scale
|
|
if (this.scale < 1) this.scale = 1
|
|
|
|
// Get info from meta data
|
|
var meta = $(this.type == 'android' ? 'meta[name="google-play-app"]' :
|
|
this.type == 'ios' ? 'meta[name="apple-itunes-app"]' : 'meta[name="msApplication-ID"]');
|
|
if (meta.length == 0) return
|
|
|
|
// For Windows Store apps, get the PackageFamilyName for protocol launch
|
|
if (this.type == 'windows') {
|
|
this.pfn = $('meta[name="msApplication-PackageFamilyName"]').attr('content');
|
|
this.appId = meta.attr('content')[1]
|
|
} else {
|
|
this.appId = /app-id=([^\s,]+)/.exec(meta.attr('content'))[1]
|
|
}
|
|
|
|
this.title = this.options.title ? this.options.title : $('title').text().replace(/\s*[|\-·].*$/, '')
|
|
this.author = this.options.author ? this.options.author : ($('meta[name="author"]').length ? $('meta[name="author"]').attr('content') : window.location.hostname)
|
|
|
|
// Create banner
|
|
this.create()
|
|
this.show()
|
|
this.listen()
|
|
}
|
|
|
|
SmartBanner.prototype = {
|
|
|
|
constructor: SmartBanner
|
|
|
|
, create: function() {
|
|
var iconURL
|
|
, link=(this.options.url ? this.options.url : (this.type == 'windows' ? 'ms-windows-store:PDP?PFN=' + this.pfn : (this.type == 'android' ? 'market://details?id=' : 'https://itunes.apple.com/' + this.options.appStoreLanguage + '/app/id')) + this.appId)
|
|
, inStore=this.options.price ? this.options.price + ' - ' + (this.type == 'android' ? this.options.inGooglePlay : this.type == 'ios' ? this.options.inAppStore : this.options.inWindowsStore) : ''
|
|
, gloss=this.options.iconGloss === null ? (this.type=='ios') : this.options.iconGloss
|
|
|
|
$('body').append('<div id="smartbanner" class="'+this.type+'"><div class="sb-container"><a href="#" class="sb-close">×</a><span class="sb-icon"></span><div class="sb-info"><strong>'+this.title+'</strong><span>'+this.author+'</span><span>'+inStore+'</span></div><a href="'+link+'" class="sb-button"><span>'+this.options.button+'</span></a></div></div>')
|
|
|
|
if (this.options.icon) {
|
|
iconURL = this.options.icon
|
|
} else if ($('link[rel="apple-touch-icon-precomposed"]').length > 0) {
|
|
iconURL = $('link[rel="apple-touch-icon-precomposed"]').attr('href')
|
|
if (this.options.iconGloss === null) gloss = false
|
|
} else if ($('link[rel="apple-touch-icon"]').length > 0) {
|
|
iconURL = $('link[rel="apple-touch-icon"]').attr('href')
|
|
} else if ($('meta[name="msApplication-TileImage"]').length > 0) {
|
|
iconURL = $('meta[name="msApplication-TileImage"]').attr('content')
|
|
} else if ($('meta[name="msapplication-TileImage"]').length > 0) { /* redundant because ms docs show two case usages */
|
|
iconURL = $('meta[name="msapplication-TileImage"]').attr('content')
|
|
}
|
|
|
|
if (iconURL) {
|
|
$('#smartbanner .sb-icon').css('background-image','url('+iconURL+')')
|
|
if (gloss) $('#smartbanner .sb-icon').addClass('gloss')
|
|
} else{
|
|
$('#smartbanner').addClass('no-icon')
|
|
}
|
|
|
|
this.bannerHeight = $('#smartbanner').outerHeight() + 2
|
|
|
|
if (this.scale > 1) {
|
|
$('#smartbanner')
|
|
.css('top', parseFloat($('#smartbanner').css('top')) * this.scale)
|
|
.css('height', parseFloat($('#smartbanner').css('height')) * this.scale)
|
|
$('#smartbanner .sb-container')
|
|
.css('-webkit-transform', 'scale('+this.scale+')')
|
|
.css('-msie-transform', 'scale('+this.scale+')')
|
|
.css('-moz-transform', 'scale('+this.scale+')')
|
|
.css('width', $(window).width() / this.scale)
|
|
}
|
|
}
|
|
|
|
, listen: function () {
|
|
$('#smartbanner .sb-close').on('click',$.proxy(this.close, this))
|
|
$('#smartbanner .sb-button').on('click',$.proxy(this.install, this))
|
|
}
|
|
|
|
, show: function(callback) {
|
|
$('#smartbanner').stop().animate({top:0},this.options.speedIn).addClass('shown')
|
|
$('html').animate({marginTop:this.origHtmlMargin+(this.bannerHeight*this.scale)},this.options.speedIn,'swing',callback)
|
|
}
|
|
|
|
, hide: function(callback) {
|
|
$('#smartbanner').stop().animate({top:-1*this.bannerHeight*this.scale},this.options.speedOut).removeClass('shown')
|
|
$('html').animate({marginTop:this.origHtmlMargin},this.options.speedOut,'swing',callback)
|
|
}
|
|
|
|
, close: function(e) {
|
|
e.preventDefault()
|
|
this.hide()
|
|
this.setCookie('sb-closed','true',this.options.daysHidden)
|
|
}
|
|
|
|
, install: function(e) {
|
|
this.hide()
|
|
this.setCookie('sb-installed','true',this.options.daysReminder)
|
|
}
|
|
|
|
, setCookie: function(name, value, exdays) {
|
|
var exdate = new Date()
|
|
exdate.setDate(exdate.getDate()+exdays)
|
|
value=escape(value)+((exdays==null)?'':'; expires='+exdate.toUTCString())
|
|
document.cookie=name+'='+value+'; path=/;'
|
|
}
|
|
|
|
, getCookie: function(name) {
|
|
var i,x,y,ARRcookies = document.cookie.split(";")
|
|
for(i=0;i<ARRcookies.length;i++) {
|
|
x = ARRcookies[i].substr(0,ARRcookies[i].indexOf("="))
|
|
y = ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1)
|
|
x = x.replace(/^\s+|\s+$/g,"")
|
|
if (x==name) {
|
|
return unescape(y)
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
// Demo only
|
|
, switchType: function() {
|
|
var that = this
|
|
|
|
this.hide(function () {
|
|
that.type = that.type == 'android' ? 'ios' : 'android'
|
|
var meta = $(that.type == 'android' ? 'meta[name="google-play-app"]' : 'meta[name="apple-itunes-app"]').attr('content')
|
|
that.appId = /app-id=([^\s,]+)/.exec(meta)[1]
|
|
|
|
$('#smartbanner').detach()
|
|
that.create()
|
|
that.show()
|
|
})
|
|
}
|
|
}
|
|
|
|
$.smartbanner = function (option) {
|
|
var $window = $(window)
|
|
, data = $window.data('typeahead')
|
|
, options = typeof option == 'object' && option
|
|
if (!data) $window.data('typeahead', (data = new SmartBanner(options)))
|
|
if (typeof option == 'string') data[option]()
|
|
}
|
|
|
|
// override these globally if you like (they are all optional)
|
|
$.smartbanner.defaults = {
|
|
title: null, // What the title of the app should be in the banner (defaults to <title>)
|
|
author: null, // What the author of the app should be in the banner (defaults to <meta name="author"> or hostname)
|
|
price: 'FREE', // Price of the app
|
|
appStoreLanguage: 'us', // Language code for App Store
|
|
inAppStore: 'On the App Store', // Text of price for iOS
|
|
inGooglePlay: 'In Google Play', // Text of price for Android
|
|
inWindowsStore: 'In the Windows Store', //Text of price for Windows
|
|
icon: null, // The URL of the icon (defaults to <meta name="apple-touch-icon">)
|
|
iconGloss: null, // Force gloss effect for iOS even for precomposed
|
|
button: 'VIEW', // Text for the install button
|
|
url: null, // The URL for the button. Keep null if you want the button to link to the app store.
|
|
scale: 'auto', // Scale based on viewport size (set to 1 to disable)
|
|
speedIn: 300, // Show animation speed of the banner
|
|
speedOut: 400, // Close animation speed of the banner
|
|
daysHidden: 15, // Duration to hide the banner after being closed (0 = always show banner)
|
|
daysReminder: 90, // Duration to hide the banner after "VIEW" is clicked *separate from when the close button is clicked* (0 = always show banner)
|
|
force: null // Choose 'ios', 'android' or 'windows'. Don't do a browser check, just always show this banner
|
|
}
|
|
|
|
$.smartbanner.Constructor = SmartBanner
|
|
|
|
}(window.jQuery);
|