Merge branch 'feature/appmobile'

This commit is contained in:
Michael RICOIS 2017-12-13 15:00:09 +01:00
commit f73558c4d7
8 changed files with 983 additions and 57 deletions

View File

@ -1,68 +1,87 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://ogp.me/ns/fb#" xml:lang="{$lang_iso}">
<head>
<title>{$meta_title|escape:'htmlall':'UTF-8'}</title>
{if isset($meta_description) AND $meta_description}
{if $page_name=='trailer'}
<meta name="description" content="{$meta_description|escape:html:'UTF-8'|utf8_decode}" />
{else}
<meta name="description" content="{$meta_description|escape:html:'UTF-8'}" />
{/if}
{/if}
{if isset($meta_keywords) AND $meta_keywords}
<meta name="keywords" content="{$meta_keywords|escape:html:'UTF-8'}" />
{/if}
{if isset($meta_fb_img) AND $meta_fb_img}
<meta property="og:image" content="{$meta_fb_img|escape:html:'UTF-8'}" />
{/if}
<meta name="theme-color" content="#565485">
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
<meta name="robots" content="{if isset($nobots)}no{/if}index,follow" />
<meta name="apple-itunes-app" content="app-id=1287943233" />
<meta name="google-play-app" content="app-id=com.bebeboutik" />
<link rel="icon" type="image/png" href="{$img_ps_dir}preview.png?{$img_update_time}" />
<link rel="icon" type="image/vnd.microsoft.icon" href="{$img_ps_dir}favicon.ico?{$img_update_time}" />
<link rel="shortcut icon" type="image/x-icon" href="{$img_ps_dir}favicon.ico?{$img_update_time}" />
{if isset($page_name) && $page_name == 'authentication'}
<link rel="canonical" href="{$link->getPageLink('authentication.php', TRUE)}" />
{/if}
<script type="text/javascript">
var baseDirSsl = '{$base_dir_ssl}';
var baseDir = '{$content_dir}';
var static_token = '{$static_token}';
var token = '{$token}';
var priceDisplayPrecision = {$priceDisplayPrecision*$currency->decimals};
var priceDisplayMethod = {$priceDisplay};
var roundMode = {$roundMode};
var isoLang = "{$lang_iso}";
</script>
<title>{$meta_title|escape:'htmlall':'UTF-8'}</title>
{if isset($meta_description) AND $meta_description}
{if $page_name=='trailer'}
<meta name="description" content="{$meta_description|escape:html:'UTF-8'|utf8_decode}" />
{else}
<meta name="description" content="{$meta_description|escape:html:'UTF-8'}" />
{/if}
{/if}
{if isset($meta_keywords) AND $meta_keywords}
<meta name="keywords" content="{$meta_keywords|escape:html:'UTF-8'}" />
{/if}
{if isset($meta_fb_img) AND $meta_fb_img}
<meta property="og:image" content="{$meta_fb_img|escape:html:'UTF-8'}" />
{/if}
<meta name="theme-color" content="#565485">
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
<meta name="robots" content="{if isset($nobots)}no{/if}index,follow" />
<link rel="icon" type="image/png" href="{$img_ps_dir}preview.png?{$img_update_time}" />
<link rel="icon" type="image/vnd.microsoft.icon" href="{$img_ps_dir}favicon.ico?{$img_update_time}" />
<link rel="shortcut icon" type="image/x-icon" href="{$img_ps_dir}favicon.ico?{$img_update_time}" />
{if isset($page_name) && $page_name == 'authentication'}
<link rel="canonical" href="{$link->getPageLink('authentication.php', TRUE)}" />
{/if}
<script type="text/javascript">
var baseDirSsl = '{$base_dir_ssl}';
var baseDir = '{$content_dir}';
var static_token = '{$static_token}';
var token = '{$token}';
var priceDisplayPrecision = {$priceDisplayPrecision*$currency->decimals};
var priceDisplayMethod = {$priceDisplay};
var roundMode = {$roundMode};
var isoLang = "{$lang_iso}";
</script>
{if isset($css_files)}
{foreach from=$css_files key=css_uri item=media}
<link href="{$css_uri}" rel="stylesheet" type="text/css" media="{$media}" />
{/foreach}
{foreach from=$css_files key=css_uri item=media}
<link href="{$css_uri}" rel="stylesheet" type="text/css" media="{$media}" />
{/foreach}
<link rel="stylesheet" href="{$content_dir}themes/site_mobile/js/smartbanner/jquery.smartbanner.css">
{/if}
{if isset($js_files)}
{foreach from=$js_files item=js_uri}
<script type="text/javascript" src="{$js_uri}"></script>
{/foreach}
{foreach from=$js_files item=js_uri}
<script type="text/javascript" src="{$js_uri}"></script>
{/foreach}
<script src="{$content_dir}themes/site_mobile/js/smartbanner/jquery.smartbanner.js"></script>
{/if}
<script src="{$content_dir}themes/site_mobile/js/global.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<link rel="apple-touch-icon" href="{$base_dir_ssl}img/apple-touch-icon.png" />
{$HOOK_HEADER}
<!--[if IE 7]>
<link href="{$css_dir}ie7.css" rel="stylesheet" type="text/css" media="screen" />
<![endif]-->
<!--[if IE 8]>
<link href="{$css_dir}ie8.css" rel="stylesheet" type="text/css" media="screen" />
<![endif]-->
<!--[if IE 9]>
<link href="{$css_dir}ie9.css" rel="stylesheet" type="text/css" media="screen" />
<![endif]-->
<script src="{$content_dir}themes/site_mobile/js/global.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
{if isset($cookie->id_lang) && $cookie->id_lang == 2 && isset($page_name) && $page_name != 'authentication'}
<meta name="apple-itunes-app" content="app-id=1287943233" />
<meta name="google-play-app" content="app-id=com.bebeboutik" />
{/if}
<link rel="apple-touch-icon" href="{$base_dir_ssl}img/apple-touch-icon.png" />
{$HOOK_HEADER}
<!--[if IE 7]>
<link href="{$css_dir}ie7.css" rel="stylesheet" type="text/css" media="screen" />
<![endif]-->
<!--[if IE 8]>
<link href="{$css_dir}ie8.css" rel="stylesheet" type="text/css" media="screen" />
<![endif]-->
<!--[if IE 9]>
<link href="{$css_dir}ie9.css" rel="stylesheet" type="text/css" media="screen" />
<![endif]-->
{if isset($cookie->id_lang) && $cookie->id_lang == 2 && isset($page_name) && $page_name != 'authentication'}
<script type="text/javascript">
$(document).ready(function(){
$.smartbanner({
title: 'Bebeboutik',
author: 'bebeboutik.com',
price: 'Gratuit',
appStoreLanguage: 'fr',
inGooglePlay: 'sur Google play',
button: 'Voir'
});
});
</script>
{/if}
<!-- Google Tag Manager -->
{literal}
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
@ -413,7 +432,7 @@
a.src=document.location.protocol+"//script.crazyegg.com/pages/scripts/0047/9841.js?"+Math.floor(new Date().getTime()/3600000);
a.async=true;a.type="text/javascript";b.parentNode.insertBefore(a,b)}, 1);
</script>
{/literal}
{/literal}
{include file="$tpl_dir./header-meta-fb.tpl"}
</head>

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 B

View File

@ -0,0 +1,25 @@
#smartbanner { position:absolute; left:0; top:-82px; border-bottom:1px solid #e8e8e8; width:100%; height:78px; font-family:'Helvetica Neue',sans-serif; background:-webkit-linear-gradient(top, #f4f4f4 0%,#cdcdcd 100%); box-shadow:0 1px 2px rgba(0,0,0,0.5); z-index:9998; -webkit-font-smoothing:antialiased; overflow:hidden; -webkit-text-size-adjust:none; }
#smartbanner .sb-container { margin: 0 auto; }
#smartbanner .sb-close { position:absolute; left:5px; top:5px; display:block; border:2px solid #fff; width:14px; height:14px; font-family:'ArialRoundedMTBold',Arial; font-size:15px; line-height:15px; text-align:center; color:#fff; background:#070707; text-decoration:none; text-shadow:none; border-radius:14px; box-shadow:0 2px 3px rgba(0,0,0,0.4); -webkit-font-smoothing:subpixel-antialiased; }
#smartbanner .sb-close:active { font-size:13px; color:#aaa; }
#smartbanner .sb-icon { position:absolute; left:30px; top:10px; display:block; width:57px; height:57px; background:rgba(0,0,0,0.6); background-size:cover; border-radius:10px; box-shadow:0 1px 3px rgba(0,0,0,0.3); }
#smartbanner.no-icon .sb-icon { display:none; }
#smartbanner .sb-info { position:absolute; left:98px; top:18px; width:44%; font-size:11px; line-height:1.2em; font-weight:bold; color:#6a6a6a; text-shadow:0 1px 0 rgba(255,255,255,0.8); }
#smartbanner #smartbanner.no-icon .sb-info { left:34px; }
#smartbanner .sb-info strong { display:block; font-size:13px; color:#4d4d4d; line-height: 18px; }
#smartbanner .sb-info > span { display:block; }
#smartbanner .sb-info em { font-style:normal; text-transform:uppercase; }
#smartbanner .sb-button { position:absolute; right:20px; top:24px; border:1px solid #bfbfbf; padding: 0 10px; min-width: 10%; height:24px; font-size:14px; line-height:24px; text-align:center; font-weight:bold; color:#6a6a6a; background:-webkit-linear-gradient(top, #efefef 0%,#dcdcdc 100%); text-transform:uppercase; text-decoration:none; text-shadow:0 1px 0 rgba(255,255,255,0.8); border-radius:3px; box-shadow:0 1px 0 rgba(255,255,255,0.6),0 1px 0 rgba(255,255,255,0.7) inset; }
#smartbanner .sb-button:active, #smartbanner .sb-button:hover { background:-webkit-linear-gradient(top, #dcdcdc 0%,#efefef 100%); }
#smartbanner .sb-icon.gloss:after { content:''; position:absolute; left:0; top:-1px; border-top:1px solid rgba(255,255,255,0.8); width:100%; height:50%; background:-webkit-linear-gradient(top, rgba(255,255,255,0.7) 0%,rgba(255,255,255,0.2) 100%); border-radius:10px 10px 12px 12px; }
#smartbanner.android { border-color:#212228; background: #3d3d3d url('dark_background_stripes.gif'); border-top: 5px solid #88B131; box-shadow: none; }
#smartbanner.android .sb-close { border:0; width:17px; height:17px; line-height:17px; color:#b1b1b3; background:#1c1e21; text-shadow:0 1px 1px #000; box-shadow:0 1px 2px rgba(0,0,0,0.8) inset,0 1px 1px rgba(255,255,255,0.3); }
#smartbanner.android .sb-close:active { color:#eee; }
#smartbanner.android .sb-info { color:#ccc; text-shadow:0 1px 2px #000; }
#smartbanner.android .sb-info strong { color:#fff; }
#smartbanner.android .sb-button { min-width: 12%; border:1px solid #DDDCDC; padding:1px; color:#d1d1d1; background: none; border-radius: 0; box-shadow: none; }
#smartbanner.android .sb-button span { text-align: center; display: block; padding: 0 10px; background-color: #42B6C9; background-image: -webkit-gradient(linear,0 0,0 100%,from(#42B6C9),to(#39A9BB)); background-image: -moz-linear-gradient(top,#42B6C9,#39A9BB); text-transform:none; text-shadow:none; box-shadow:none; }
#smartbanner.android .sb-button:active, #smartbanner.android .sb-button:hover { background: none; }
#smartbanner.android .sb-button:active span, #smartbanner.android .sb-button:hover span { background:#2AC7E1; }

View File

@ -0,0 +1,185 @@
/*!
* 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)
// Detect banner type (iOS or Android)
if (this.options.force) {
this.type = this.options.force
} else if (navigator.userAgent.match(/iPad|iPhone|iPod/i) != null) {
if (navigator.userAgent.match(/Safari/i) != null &&
(navigator.userAgent.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 (navigator.userAgent.match(/Android/i) != null) {
this.type = 'android'
}
// 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"]' : 'meta[name="apple-itunes-app"]')
if (meta.length == 0) return
this.appId = /app-id=([^\s,]+)/.exec(meta.attr('content'))[1]
this.title = this.options.title ? this.options.title : meta.data('title') || $('title').text().replace(/\s*[|\-·].*$/, '')
this.author = this.options.author ? this.options.author : meta.data('author') || ($('meta[name="author"]').length ? $('meta[name="author"]').attr('content') : window.location.hostname)
this.iconUrl = meta.data('icon-url');
this.price = meta.data('price');
// 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=='android' ? 'market://details?id=' : ('https://itunes.apple.com/' + this.options.appStoreLanguage + '/app/id')) + this.appId)
, price = this.price || this.options.price
, inStore = price ? price + ' - ' + (this.type=='android' ? this.options.inGooglePlay : this.options.inAppStore) : ''
, 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">&times;</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(this.iconUrl) {
iconURL = this.iconUrl;
} 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')
}
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
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' or 'android'. Don't do a browser check, just always show this banner
}
$.smartbanner.Constructor = SmartBanner
}(window.jQuery);

View File

@ -0,0 +1,136 @@
/*!
* smartbanner.js v1.9.0 <https://github.com/ain/smartbanner.js>
* Copyright © 2017 Ain Tohvri, contributors. Licensed under GPL-3.0.
*/
.smartbanner {
position: absolute;
top: 0;
left: 0;
overflow-x: hidden;
width: 100%;
height: 84px;
background: #f3f3f3;
font-family: Helvetica, sans, sans-serif;
/** Android styles **/ }
.smartbanner__exit {
position: absolute;
top: calc(50% - 6px);
left: 9px;
display: block;
margin: 0;
width: 12px;
height: 12px;
border: 0;
text-align: center; }
.smartbanner__exit::before, .smartbanner__exit::after {
position: absolute;
width: 1px;
height: 12px;
background: #767676;
content: ' '; }
.smartbanner__exit::before {
-webkit-transform: rotate(45deg);
transform: rotate(45deg); }
.smartbanner__exit::after {
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg); }
.smartbanner__icon {
position: absolute;
top: 10px;
left: 30px;
width: 64px;
height: 64px;
border-radius: 15px;
background-size: 64px 64px; }
.smartbanner__info {
position: absolute;
top: 10px;
left: 104px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
overflow-y: hidden;
width: 60%;
height: 64px;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center; }
.smartbanner__info__title {
font-size: 14px; }
.smartbanner__info__author, .smartbanner__info__price {
font-size: 12px; }
.smartbanner__button {
position: absolute;
top: 32px;
right: 10px;
z-index: 1;
display: block;
padding: 0 10px;
min-width: 10%;
border-radius: 5px;
background: #f3f3f3;
color: #1474fc;
font-size: 18px;
text-align: center;
text-decoration: none; }
.smartbanner__button__label {
text-align: center; }
.smartbanner.smartbanner--android {
background: #3d3d3d url(data:image/gif;base64,R0lGODlhCAAIAIABAFVVVf///yH5BAEHAAEALAAAAAAIAAgAAAINRG4XudroGJBRsYcxKAA7);
box-shadow: inset 0 4px 0 #88b131; }
.smartbanner.smartbanner--android .smartbanner__exit {
left: 6px;
margin-right: 7px;
width: 17px;
height: 17px;
border-radius: 14px;
background: #1c1e21;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.8) inset, 0 1px 1px rgba(255, 255, 255, 0.3);
color: #b1b1b3;
font-family: 'ArialRoundedMTBold', Arial;
font-size: 20px;
-webkit-font-smoothing: subpixel-antialiased;
line-height: 17px;
text-shadow: 0 1px 1px #000; }
.smartbanner.smartbanner--android .smartbanner__exit::before, .smartbanner.smartbanner--android .smartbanner__exit::after {
top: 3px;
left: 8px;
width: 2px;
height: 11px;
background: #b1b1b3; }
.smartbanner.smartbanner--android .smartbanner__exit:active, .smartbanner.smartbanner--android .smartbanner__exit:hover {
color: #eee; }
.smartbanner.smartbanner--android .smartbanner__icon {
background-color: transparent;
box-shadow: none; }
.smartbanner.smartbanner--android .smartbanner__info {
color: #ccc;
text-shadow: 0 1px 2px #000; }
.smartbanner.smartbanner--android .smartbanner__info__title {
color: #fff;
font-weight: bold; }
.smartbanner.smartbanner--android .smartbanner__button {
top: 30px;
right: 20px;
padding: 0;
min-width: 12%;
border-radius: 0;
background: none;
box-shadow: 0 0 0 1px #333, 0 0 0 2px #dddcdc;
color: #d1d1d1;
font-size: 14px;
font-weight: bold; }
.smartbanner.smartbanner--android .smartbanner__button:active, .smartbanner.smartbanner--android .smartbanner__button:hover {
background: none; }
.smartbanner.smartbanner--android .smartbanner__button__label {
display: block;
padding: 0 10px;
background: #42b6c9;
background: linear-gradient(to bottom, #42b6c9, #39a9bb);
box-shadow: none;
line-height: 24px;
text-align: center;
text-shadow: none;
text-transform: none; }
.smartbanner.smartbanner--android .smartbanner__button__label:active, .smartbanner.smartbanner--android .smartbanner__button__label:hover {
background: #2ac7e1; }

View File

@ -0,0 +1,551 @@
/*!
* smartbanner.js v1.9.0 <https://github.com/ain/smartbanner.js>
* Copyright © 2017 Ain Tohvri, contributors. Licensed under GPL-3.0.
*/
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Bakery = function () {
function Bakery() {
_classCallCheck(this, Bakery);
}
_createClass(Bakery, null, [{
key: 'getCookieExpiresString',
value: function getCookieExpiresString(hideTtl) {
var now = new Date();
var expireTime = new Date(now.getTime() + hideTtl);
return 'expires=' + expireTime.toGMTString() + ';';
}
}, {
key: 'getPathString',
value: function getPathString(path) {
return 'path=' + path + ';';
}
}, {
key: 'bake',
value: function bake(hideTtl) {
var hidePath = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
document.cookie = 'smartbanner_exited=1; ' + (hideTtl ? Bakery.getCookieExpiresString(hideTtl) : '') + ' ' + (hidePath ? Bakery.getPathString(hidePath) : '');
}
}, {
key: 'unbake',
value: function unbake() {
document.cookie = 'smartbanner_exited=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
}
}, {
key: 'baked',
get: function get() {
var value = document.cookie.replace(/(?:(?:^|.*;\s*)smartbanner_exited\s*\=\s*([^;]*).*$)|^.*$/, '$1');
return value === '1';
}
}]);
return Bakery;
}();
exports.default = Bakery;
},{}],2:[function(require,module,exports){
(function (global){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Detector = function () {
function Detector() {
_classCallCheck(this, Detector);
}
_createClass(Detector, null, [{
key: 'platform',
value: function platform() {
if (/iPhone|iPad|iPod/i.test(window.navigator.userAgent)) {
return 'ios';
} else if (/Android/i.test(window.navigator.userAgent)) {
return 'android';
}
}
}, {
key: 'userAgentMatchesRegex',
value: function userAgentMatchesRegex(regexString) {
return new RegExp(regexString).test(window.navigator.userAgent);
}
}, {
key: 'jQueryMobilePage',
value: function jQueryMobilePage() {
return typeof global.$ !== 'undefined' && global.$.mobile !== 'undefined' && document.querySelector('.ui-page') !== null;
}
}, {
key: 'wrapperElement',
value: function wrapperElement() {
var selector = Detector.jQueryMobilePage() ? '.ui-page' : 'html';
return document.querySelectorAll(selector);
}
}]);
return Detector;
}();
exports.default = Detector;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],3:[function(require,module,exports){
'use strict';
var _smartbanner = require('./smartbanner.js');
var _smartbanner2 = _interopRequireDefault(_smartbanner);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var smartbanner = void 0;
window.addEventListener('load', function () {
smartbanner = new _smartbanner2.default();
smartbanner.publish();
});
},{"./smartbanner.js":7}],4:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
require('./polyfills/array/from.js');
require('./polyfills/array/includes.js');
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function valid(name) {
// TODO: validate against options dictionary
return name.indexOf('smartbanner:') !== -1 && name.split(':')[1].length > 0;
}
function convertToCamelCase(name) {
var parts = name.split('-');
parts.map(function (part, index) {
if (index > 0) {
parts[index] = part.charAt(0).toUpperCase() + part.substring(1);
}
});
return parts.join('');
}
var OptionParser = function () {
function OptionParser() {
_classCallCheck(this, OptionParser);
}
_createClass(OptionParser, [{
key: 'parse',
value: function parse() {
var metas = document.getElementsByTagName('meta');
var options = {};
var optionName = null;
Array.from(metas).forEach(function (meta) {
var name = meta.getAttribute('name');
var content = meta.getAttribute('content');
if (name && content && valid(name) && content.length > 0) {
optionName = name.split(':')[1];
if (Array.from(optionName).includes('-')) {
optionName = convertToCamelCase(optionName);
}
options[optionName] = content;
}
});
return options;
}
}]);
return OptionParser;
}();
exports.default = OptionParser;
},{"./polyfills/array/from.js":5,"./polyfills/array/includes.js":6}],5:[function(require,module,exports){
'use strict';
// Production steps of ECMA-262, Edition 6, 22.1.2.1
// Reference: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from
if (!Array.from) {
Array.from = function () {
var toStr = Object.prototype.toString;
var isCallable = function isCallable(fn) {
return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
};
var toInteger = function toInteger(value) {
var number = Number(value);
if (isNaN(number)) {
return 0;
}
if (number === 0 || !isFinite(number)) {
return number;
}
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
};
var maxSafeInteger = Math.pow(2, 53) - 1;
var toLength = function toLength(value) {
var len = toInteger(value);
return Math.min(Math.max(len, 0), maxSafeInteger);
};
// The length property of the from method is 1.
return function from(arrayLike /*, mapFn, thisArg */) {
// 1. Let C be the this value.
var C = this;
// 2. Let items be ToObject(arrayLike).
var items = Object(arrayLike);
// 3. ReturnIfAbrupt(items).
if (arrayLike == null) {
throw new TypeError("Array.from requires an array-like object - not null or undefined");
}
// 4. If mapfn is undefined, then let mapping be false.
var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
var T;
if (typeof mapFn !== 'undefined') {
// 5. else
// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
if (!isCallable(mapFn)) {
throw new TypeError('Array.from: when provided, the second argument must be a function');
}
// 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (arguments.length > 2) {
T = arguments[2];
}
}
// 10. Let lenValue be Get(items, "length").
// 11. Let len be ToLength(lenValue).
var len = toLength(items.length);
// 13. If IsConstructor(C) is true, then
// 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len.
// 14. a. Else, Let A be ArrayCreate(len).
var A = isCallable(C) ? Object(new C(len)) : new Array(len);
// 16. Let k be 0.
var k = 0;
// 17. Repeat, while k < len… (also steps a - h)
var kValue;
while (k < len) {
kValue = items[k];
if (mapFn) {
A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
} else {
A[k] = kValue;
}
k += 1;
}
// 18. Let putStatus be Put(A, "length", len, true).
A.length = len;
// 20. Return A.
return A;
};
}();
}
},{}],6:[function(require,module,exports){
'use strict';
if (!Array.prototype.includes) {
Array.prototype.includes = function (searchElement /*, fromIndex*/) {
'use strict';
if (this == null) {
throw new TypeError('Array.prototype.includes called on null or undefined');
}
var O = Object(this);
var len = parseInt(O.length, 10) || 0;
if (len === 0) {
return false;
}
var n = parseInt(arguments[1], 10) || 0;
var k;
if (n >= 0) {
k = n;
} else {
k = len + n;
if (k < 0) {
k = 0;
}
}
var currentElement;
while (k < len) {
currentElement = O[k];
if (searchElement === currentElement || searchElement !== searchElement && currentElement !== currentElement) {
// NaN !== NaN
return true;
}
k++;
}
return false;
};
}
},{}],7:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _optionparser = require('./optionparser.js');
var _optionparser2 = _interopRequireDefault(_optionparser);
var _detector = require('./detector.js');
var _detector2 = _interopRequireDefault(_detector);
var _bakery = require('./bakery.js');
var _bakery2 = _interopRequireDefault(_bakery);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var DEFAULT_PLATFORMS = 'android,ios';
var datas = {
originalTop: 'data-smartbanner-original-top',
originalMarginTop: 'data-smartbanner-original-margin-top'
};
function handleExitClick(event, self) {
self.exit();
event.preventDefault();
}
function handleJQueryMobilePageLoad(event) {
if (!this.positioningDisabled) {
setContentPosition(event.data.height);
}
}
function addEventListeners(self) {
var closeIcon = document.querySelector('.js_smartbanner__exit');
closeIcon.addEventListener('click', function (event) {
return handleExitClick(event, self);
});
if (_detector2.default.jQueryMobilePage()) {
$(document).on('pagebeforeshow', self, handleJQueryMobilePageLoad);
}
}
function removeEventListeners() {
if (_detector2.default.jQueryMobilePage()) {
$(document).off('pagebeforeshow', handleJQueryMobilePageLoad);
}
}
function setContentPosition(value) {
var wrappers = _detector2.default.wrapperElement();
for (var i = 0, l = wrappers.length, wrapper; i < l; i++) {
wrapper = wrappers[i];
if (_detector2.default.jQueryMobilePage()) {
if (wrapper.getAttribute(datas.originalTop)) {
continue;
}
var top = parseFloat(getComputedStyle(wrapper).top);
wrapper.setAttribute(datas.originalTop, isNaN(top) ? 0 : top);
wrapper.style.top = value + 'px';
} else {
if (wrapper.getAttribute(datas.originalMarginTop)) {
continue;
}
var margin = parseFloat(getComputedStyle(wrapper).marginTop);
wrapper.setAttribute(datas.originalMarginTop, isNaN(margin) ? 0 : margin);
wrapper.style.marginTop = value + 'px';
}
}
}
function restoreContentPosition() {
var wrappers = _detector2.default.wrapperElement();
for (var i = 0, l = wrappers.length, wrapper; i < l; i++) {
wrapper = wrappers[i];
if (_detector2.default.jQueryMobilePage() && wrapper.getAttribute(datas.originalTop)) {
wrapper.style.top = wrapper.getAttribute(datas.originalTop) + 'px';
} else if (wrapper.getAttribute(datas.originalMarginTop)) {
wrapper.style.marginTop = wrapper.getAttribute(datas.originalMarginTop) + 'px';
}
}
}
var SmartBanner = function () {
function SmartBanner() {
_classCallCheck(this, SmartBanner);
var parser = new _optionparser2.default();
this.options = parser.parse();
this.platform = _detector2.default.platform();
}
// DEPRECATED. Will be removed.
_createClass(SmartBanner, [{
key: 'publish',
value: function publish() {
if (Object.keys(this.options).length === 0) {
throw new Error('No options detected. Please consult documentation.');
}
if (_bakery2.default.baked) {
return false;
}
// User Agent was explicetely excluded by defined excludeUserAgentRegex
if (this.userAgentExcluded) {
return false;
}
// User agent was neither included by platformEnabled,
// nor by defined includeUserAgentRegex
if (!(this.platformEnabled || this.userAgentIncluded)) {
return false;
}
var bannerDiv = document.createElement('div');
document.querySelector('body').appendChild(bannerDiv);
bannerDiv.outerHTML = this.html;
if (!this.positioningDisabled) {
setContentPosition(this.height);
}
addEventListeners(this);
}
}, {
key: 'exit',
value: function exit() {
removeEventListeners();
if (!this.positioningDisabled) {
restoreContentPosition();
}
var banner = document.querySelector('.js_smartbanner');
document.querySelector('body').removeChild(banner);
_bakery2.default.bake(this.hideTtl, this.hidePath);
}
}, {
key: 'originalTop',
get: function get() {
var wrapper = _detector2.default.wrapperElement()[0];
return parseFloat(wrapper.getAttribute(datas.originalTop));
}
// DEPRECATED. Will be removed.
}, {
key: 'originalTopMargin',
get: function get() {
var wrapper = _detector2.default.wrapperElement()[0];
return parseFloat(wrapper.getAttribute(datas.originalMarginTop));
}
}, {
key: 'priceSuffix',
get: function get() {
if (this.platform === 'ios') {
return this.options.priceSuffixApple;
} else if (this.platform === 'android') {
return this.options.priceSuffixGoogle;
}
return '';
}
}, {
key: 'icon',
get: function get() {
if (this.platform === 'android') {
return this.options.iconGoogle;
} else {
return this.options.iconApple;
}
}
}, {
key: 'buttonUrl',
get: function get() {
if (this.platform === 'android') {
return this.options.buttonUrlGoogle;
} else if (this.platform === 'ios') {
return this.options.buttonUrlApple;
}
return '#';
}
}, {
key: 'html',
get: function get() {
var modifier = !this.options.customDesignModifier ? this.platform : this.options.customDesignModifier;
return '<div class="smartbanner smartbanner--' + modifier + ' js_smartbanner">\n <a href="javascript:void();" class="smartbanner__exit js_smartbanner__exit"></a>\n <div class="smartbanner__icon" style="background-image: url(' + this.icon + ');"></div>\n <div class="smartbanner__info">\n <div>\n <div class="smartbanner__info__title">' + this.options.title + '</div>\n <div class="smartbanner__info__author">' + this.options.author + '</div>\n <div class="smartbanner__info__price">' + this.options.price + this.priceSuffix + '</div>\n </div>\n </div>\n <a href="' + this.buttonUrl + '" target="_blank" class="smartbanner__button"><span class="smartbanner__button__label">' + this.options.button + '</span></a>\n </div>';
}
}, {
key: 'height',
get: function get() {
var height = document.querySelector('.js_smartbanner').offsetHeight;
return height !== undefined ? height : 0;
}
}, {
key: 'platformEnabled',
get: function get() {
var enabledPlatforms = this.options.enabledPlatforms || DEFAULT_PLATFORMS;
return enabledPlatforms && enabledPlatforms.replace(/\s+/g, '').split(',').indexOf(this.platform) !== -1;
}
}, {
key: 'positioningDisabled',
get: function get() {
return this.options.disablePositioning === 'true';
}
}, {
key: 'userAgentExcluded',
get: function get() {
if (!this.options.excludeUserAgentRegex) {
return false;
}
return _detector2.default.userAgentMatchesRegex(this.options.excludeUserAgentRegex);
}
}, {
key: 'userAgentIncluded',
get: function get() {
if (!this.options.includeUserAgentRegex) {
return false;
}
return _detector2.default.userAgentMatchesRegex(this.options.includeUserAgentRegex);
}
}, {
key: 'hideTtl',
get: function get() {
return this.options.hideTtl ? parseInt(this.options.hideTtl) : false;
}
}]);
return SmartBanner;
}();
exports.default = SmartBanner;
},{"./bakery.js":1,"./detector.js":2,"./optionparser.js":4}]},{},[3]);

View File

@ -0,0 +1,5 @@
/*!
* smartbanner.js v1.9.0 <https://github.com/ain/smartbanner.js>
* Copyright © 2017 Ain Tohvri, contributors. Licensed under GPL-3.0.
*/
.smartbanner{position:absolute;top:0;left:0;overflow-x:hidden;width:100%;height:84px;background:#f3f3f3;font-family:Helvetica, sans, sans-serif}.smartbanner__exit{position:absolute;top:calc(50% - 6px);left:9px;display:block;margin:0;width:12px;height:12px;border:0;text-align:center}.smartbanner__exit::before,.smartbanner__exit::after{position:absolute;width:1px;height:12px;background:#767676;content:' '}.smartbanner__exit::before{transform:rotate(45deg)}.smartbanner__exit::after{transform:rotate(-45deg)}.smartbanner__icon{position:absolute;top:10px;left:30px;width:64px;height:64px;border-radius:15px;background-size:64px 64px}.smartbanner__info{position:absolute;top:10px;left:104px;display:flex;overflow-y:hidden;width:60%;height:64px;align-items:center}.smartbanner__info__title{font-size:14px}.smartbanner__info__author,.smartbanner__info__price{font-size:12px}.smartbanner__button{position:absolute;top:32px;right:10px;z-index:1;display:block;padding:0 10px;min-width:10%;border-radius:5px;background:#f3f3f3;color:#1474fc;font-size:18px;text-align:center;text-decoration:none}.smartbanner__button__label{text-align:center}.smartbanner.smartbanner--android{background:#3d3d3d url(data:image/gif;base64,R0lGODlhCAAIAIABAFVVVf///yH5BAEHAAEALAAAAAAIAAgAAAINRG4XudroGJBRsYcxKAA7);box-shadow:inset 0 4px 0 #88b131}.smartbanner.smartbanner--android .smartbanner__exit{left:6px;margin-right:7px;width:17px;height:17px;border-radius:14px;background:#1c1e21;box-shadow:0 1px 2px rgba(0,0,0,0.8) inset,0 1px 1px rgba(255,255,255,0.3);color:#b1b1b3;font-family:'ArialRoundedMTBold', Arial;font-size:20px;-webkit-font-smoothing:subpixel-antialiased;line-height:17px;text-shadow:0 1px 1px #000}.smartbanner.smartbanner--android .smartbanner__exit::before,.smartbanner.smartbanner--android .smartbanner__exit::after{top:3px;left:8px;width:2px;height:11px;background:#b1b1b3}.smartbanner.smartbanner--android .smartbanner__exit:active,.smartbanner.smartbanner--android .smartbanner__exit:hover{color:#eee}.smartbanner.smartbanner--android .smartbanner__icon{background-color:transparent;box-shadow:none}.smartbanner.smartbanner--android .smartbanner__info{color:#ccc;text-shadow:0 1px 2px #000}.smartbanner.smartbanner--android .smartbanner__info__title{color:#fff;font-weight:bold}.smartbanner.smartbanner--android .smartbanner__button{top:30px;right:20px;padding:0;min-width:12%;border-radius:0;background:none;box-shadow:0 0 0 1px #333, 0 0 0 2px #dddcdc;color:#d1d1d1;font-size:14px;font-weight:bold}.smartbanner.smartbanner--android .smartbanner__button:active,.smartbanner.smartbanner--android .smartbanner__button:hover{background:none}.smartbanner.smartbanner--android .smartbanner__button__label{display:block;padding:0 10px;background:#42b6c9;background:linear-gradient(to bottom, #42b6c9, #39a9bb);box-shadow:none;line-height:24px;text-align:center;text-shadow:none;text-transform:none}.smartbanner.smartbanner--android .smartbanner__button__label:active,.smartbanner.smartbanner--android .smartbanner__button__label:hover{background:#2ac7e1}

File diff suppressed because one or more lines are too long