1// JavaScript to modify 2//ENTER THE APP IDS FROM APPLE STORE AND ANDROID PACKAGE IDS FROM GOOGLE PLAY STORE HERE 3 4//THIS SECTION YOU EDIT TO BUILD THE ANDROID SMART APP BANNER INFORMATION 5$(function () { 6 7 //THIS SECTION SETS THE IOS AND ANDROID SMART APP BANNERS **DO NOT MODIFY** 8 var mobile = (/iphone|ipad|ipod|android|blackberry|mini|windows\sce|palm/i.test(navigator.userAgent.toLowerCase())); 9 if (mobile) { 10 var userAgent = navigator.userAgent.toLowerCase(); 11 if ((userAgent.search("android") > -1) && (userAgent.search("mobile") > -1)) $('head').append("<meta name='google-play-app' content='app-id=" + AndroidPhoneID + "'>"); 12 else if ((userAgent.search("android") > -1) && !(userAgent.search("mobile") > -1)) $('head').append("<meta name='google-play-app' content='app-id=" + AndroidTabletID + "'>"); 13 else if (userAgent.search("ipad") > -1) $('head').append("<meta name='apple-itunes-app' content='app-id=" + iPadID + "'>"); 14 else if ((userAgent.search("iphone") > -1) || (userAgent.search("ipod") > -1)) $('head').append("<meta name='apple-itunes-app' content='app-id=" + iPhoneID + "'>"); 15 } 16 17 //THIS SECTION ADDS THE REQUIRE FILE REFERENCES FOR THE SMART BANNERS TO WORK. ONLY MODIFY THE FILE LOCATION IF NECESSARY 18 $('head').append("<meta name='viewport' content='width=device-width, initial-scale=1.0'>"); 19 $('head').append("<link rel='apple-touch-icon' href='/files/images/sab-icon.jpg'>"); 20 $('head').append("<link rel='android-touch-icon' href='/files/images/sab-icon.jpg' />"); 21 $.smartbanner({ 22 title: SABTitle, 23 author: SABAuthor 24 }); 25}); 26// Main JavaScript 27/*! 28 * jQuery Smart Banner 29 * Copyright (c) 2014 Nicolas KOKLA 30 * Forked from the Copyrighted project 'jquery.smartbanner' [Copyright (c) 2012 Arnold Daniels <[email protected]>] 31 * Based on 'jQuery Smart Web App Banner' by Kurt Zenisek @ kzeni.com 32 */ 33! function ($) { 34 var SmartBanner = function (options) { 35 this.options = $.extend({}, $.smartbanner.defaults, options); 36 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) 37 // Detect banner type (iOS, Android, Windows Phone or Windows RT) 38 if (this.options.force) { 39 this.type = this.options.force 40 } 41 else if (navigator.userAgent.match(/iPad|iPhone|iPod/i) != null && navigator.userAgent.match(/Safari/i) != null) { 42 if (
43 (window.Number(navigator.userAgent.substr(navigator.userAgent.indexOf('OS ') + 3, 3).replace('_', '.')) < 6) || navigator.userAgent.match(/Version/i) == null) this.type = 'ios'; // Check webview and native smart banner support (iOS 6+) 44 } 45 else if (navigator.userAgent.match(/Android/i) != null) { 46 this.type = 'android' 47 } 48 else if (navigator.userAgent.match(/Windows NT 6.2/i) != null) { 49 this.type = 'windows' 50 } 51 else if (navigator.userAgent.match(/Windows Phone/i) != null) { 52 this.type = 'windows-phone' 53 } 54 // Don't show banner if device isn't iOS or Android, website is loaded in app or user dismissed banner 55 if (!this.type || standalone || this.getCookie('sb-closed') || this.getCookie('sb-installed')) { 56 return 57 } 58 // Calculate scale 59 this.scale = this.options.scale == 'auto' ? $(window).width() / window.screen.width : this.options.scale; 60 if (this.scale < 1) this.scale = 1; 61 // Get info from meta data 62 var metaString, metaTrackingString, specificDeviceOption; 63 switch (this.type) { 64 case 'windows': 65 metaString = 'meta[name="msApplication-ID"]'; 66 metaTrackingString = 'meta[name="ms-store-rt-tracking"]'; 67 specificDeviceOption = this.options.windowsRtConfig || null; 68 break; 69 case 'windows-phone': 70 metaString = 'meta[name="msApplication-WinPhonePackageUrl"]'; 71 metaTrackingString = 'meta[name="ms-store-phone-tracking"]'; 72 specificDeviceOption = this.options.windowsPhoneConfig || null; 73 break; 74 case 'android': 75 metaString = 'meta[name="google-play-app"]'; 76 metaTrackingString = 'meta[name="google-play-app-tracking"]'; 77 specificDeviceOption = this.options.androidConfig || null; 78 break; 79 case 'ios': 80 metaString = 'meta[name="apple-itunes-app"]'; 81 metaTrackingString = 'meta[name="apple-itunes-app-tracking"]'; 82 specificDeviceOption = this.options.iphoneConfig || null; 83 break; 84 } 85 var meta = $(metaString); 86 var metaTracking = $(metaTrackingString); 87 if (meta.length == 0) return; 88 if (metaTracking.length == 0) metaTracking = $('<meta name="" content="" />'); 89 // For Windows Store apps, get the PackageFamilyName for protocol launch 90 if (this.type == 'windows') { 91 this.pfn = $('meta[name="msApplication-PackageFamilyName"]').attr('content'); 92 this.appId = meta.attr('content')[1]; 93 } 94 else if (this.type == 'windows-phone') { 95 this.appId = meta.attr('content') 96 } 97 else { 98 this.appId = /app-id=([^\s,]+)/.exec(meta.attr('content'))[1] 99 } 100 // Get Tracking URL : 101 this.appTracking = metaTracking.attr('content'); 102 // Get Device Configuration Specific : 103 if (specificDeviceOption) $.extend(this.options, specificDeviceOption); 104 // Get default Title and Author : 105 this.title = this.options.title ? this.options.title : $('title').text().replace(/\s*[|\-·].*$/, ''); 106 this.author = this.options.author ? this.options.author : ($('meta[name="author"]').length ? $('meta[name="author"]').attr('content') : window.location.hostname); 107 // Create banner 108 this.create(); 109 this.show(); 110 this.listen(); 111 } 112 SmartBanner.prototype = { 113 constructor: SmartBanner, 114 create: function () { 115 var iconURL, link, inStore = this.options.price ? '<span class="sb-price">' + this.options.price + '</span> ' + (this.type == 'android' ? this.options.inGooglePlay : this.type == 'ios' ? this.options.inAppStore : this.options.inWindowsStore) : '', 116 gloss = this.options.iconGloss; 117 if (this.appTracking == "") { 118 switch (this.type) { 119 case ('windows'): 120 link = 'ms-windows-store:PDP?PFN=' + this.pfn; 121 break; 122 case ('windows-phone'): 123 link = 'http://windowsphone.com/s?appId=' + this.appId; 124 break; 125 case ('android'): 126 link = 'market://details?id=' + this.appId; 127 break; 128 case ('ios'): 129 link = 'https://itunes.apple.com/' + this.options.appStoreLanguage + '/app/id' + this.appId; 130 break; 131 } 132 } 133 else { 134 link = this.appTracking; 135 } 136 var container = this.options.container; 137 if ($(container).length < 1) return; 138 $(container).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 + '" target="_blank" class="sb-button"><span>' + this.options.button + '</span></a>' + '</div>' + '</div>'); 139 var ejqSmartBanner = $('#smartbanner'); 140 if (this.options.icon) { 141 iconURL = this.options.icon 142 } 143 else if ($('link[rel="apple-touch-icon-precomposed"]').length > 0) { 144 iconURL = $('link[rel="apple-touch-icon-precomposed"]').attr('href'); 145 } 146 else if ($('link[rel="apple-touch-icon"]').length > 0) { 147 iconURL = $('link[rel="apple-touch-icon"]').attr('href'); 148 } 149 else if ($('meta[name="msApplication-TileImage"]').length > 0) { 150 iconURL = $('meta[name="msApplication-TileImage"]').attr('content'); 151 } 152 else if ($('meta[name="msapplication-TileImage"]').length > 0) { /* redundant because ms docs show two case usages */ 153 iconURL = $('meta[name="msapplication-TileImage"]').attr('content'); 154 } 155 if (iconURL) { 156 var eSbIcon = $('#smartbanner .sb-icon'); 157 eSbIcon.css('background-image', 'url(' + iconURL + ')'); 158 if (gloss) eSbIcon.addClass('gloss'); 159 } 160 else { 161 ejqSmartBanner.addClass('no-icon'); 162 } 163 if (this.scale > 1) { 164 ejqSmartBanner.css('top', parseFloat(ejqSmartBanner.css('top')) * this.scale).css('height', parseFloat(ejqSmartBanner.css('height')) * this.scale); 165 $('#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) 166 } 167 }, 168 listen: function () { 169 $('#smartbanner .sb-close').on('click', $.proxy(this.close, this)) 170 $('#smartbanner .sb-button').on('click', $.proxy(this.install, this)) 171 }, 172 show: function (callback) { 173 var ejqHtml = $('html'); 174 ejqHtml.get(0).className = ejqHtml.get(0).className + ' smartBanner '; 175 if (callback) callback(); 176 }, 177 hide: function (callback) { 178 $('html').removeClass('smartBanner'); 179 $("#smartbanner").hide(); 180 if (callback) callback(); 181 }, 182 close: function (e) { 183 debugger; 184 e.preventDefault(); 185 this.hide();
186 this.setCookie('sb-closed', 'true', this.options.daysHidden); 187 }, 188 install: function (e) { 189 this.hide(); 190 this.setCookie('sb-installed', 'true', this.options.daysReminder); 191 }, 192 setCookie: function (name, value, exdays) { 193 var exdate = new Date(); 194 exdate.setDate(exdate.getDate() + exdays); 195 value = encodeURIComponent(value) + ((exdays == null) ? '' : '; expires=' + exdate.toUTCString()); 196 document.cookie = name + '=' + value + '; path=/;'; 197 }, 198 getCookie: function (name) { 199 var i, x, y, ARRcookies = document.cookie.split(";"); 200 for (i = 0; i < ARRcookies.length; i++) { 201 x = ARRcookies[i].substr(0, ARRcookies[i].indexOf("=")); 202 y = ARRcookies[i].substr(ARRcookies[i].indexOf("=") + 1); 203 x = x.replace(/^\s+|\s+$/g, ""); 204 if (x == name) { 205 return decodeURIComponent(y); 206 } 207 } 208 return null 209 } 210 // For demo only 211 , 212 switchType: function () { 213 // Array.indexOf polyfill from mozilla : 214 // >> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf 215 if (!Array.prototype.indexOf) { 216 Array.prototype.indexOf = function (searchElement, fromIndex) { 217 if (this === undefined || this === null) throw new TypeError('"this" is null or not defined'); 218 var length = this.length >>> 0; // Hack to convert object.length to a UInt32 219 fromIndex = +fromIndex || 0; 220 if (Math.abs(fromIndex) === Infinity) fromIndex = 0; 221 if (fromIndex < 0) { 222 fromIndex += length; 223 if (fromIndex < 0) fromIndex = 0; 224 } 225 for (; fromIndex < length; fromIndex++) 226 if (this[fromIndex] === searchElement) return fromIndex; 227 return -1; 228 }; 229 } 230 var that = this; 231 that.hide(function () { 232 var a_format = ['ios', 'android', 'windows', 'windows-phone']; 233 var newIndex = a_format.indexOf(that.type) + 1; 234 that.type = (!a_format[newIndex]) ? a_format[0] : a_format[newIndex]; 235 var meta = $(that.type == 'android' ? 'meta[name="google-play-app"]' : 'meta[name="apple-itunes-app"]').attr('content'); 236 that.appId = /app-id=([^\s,]+)/.exec(meta)[1]; 237 $('#smartbanner').detach(); 238 that.create(); 239 that.show(); 240 if (window.console && console.log) console.log(that.type); 241 }) 242 } 243 }; 244 $.smartbanner = function (option) { 245 var $window = $(window), 246 data = $window.data('typeahead'), 247 options = typeof option == 'object' && option; 248 if (!data) $window.data('typeahead', (data = new SmartBanner(options))); 249 if (typeof option == 'string') data[option](); 250 }; 251 // override these globally if you like (they are all optional) 252 $.smartbanner.defaults = { 253 //Smart Banner default config : 254 title: null, // What the title of the app should be in the banner (defaults to <title>) 255 author: null, // What the author of the app should be in the banner (defaults to <meta name="author"> or hostname) 256 price: 'FREE', // Price of the app 257 priceText: 'On the store', // Text of price for store 258 icon: null, // The URL of the icon (defaults to <meta name="apple-touch-icon">) 259 button: 'View', // Text for the install button 260 appStoreLanguage: 'us', // Language code for iOS App Store 261 // Deprecated - replaced by 'priceText' and 'Device Configuration Specific' section : 262 inAppStore: 'On the App Store', // Text of price for iOS - iPhone 263 inGooglePlay: 'In Google Play', // Text of price for Android Phone 264 inWindowsStore: 'In the Windows Store', //Text of price for Windows Phone 265 iconGloss: null, // Force gloss CSS effect for iOS even for precomposed 266 // Technical config : 267 daysHidden: 15, // Duration to hide the banner after being closed (0 = always show banner) 268 daysReminder: 90, // Duration to hide the banner after "VIEW" is clicked *separate from when the close button is clicked* (0 = always show banner) 269 scale: 'auto', // Scale based on viewport size (set to 1 to disable) 270 container: 'body', // Container where the banner will be injected 271 force: null, // Choose 'ios', 'android' or 'windows'. Don't do a browser check, just always show this banner 272 // Device Configuration Specific - Use JSON similar to the 'defaultDeviceConfig' variable : 273 iphoneConfig: null, 274 ipadConfig: null, 275 androidConfig: null, 276 androidTabsConfig: null, 277 windowsPhoneConfig: null, 278 windowsRtConfig: null 279 }; 280 var defaultDeviceConfig = { 281 title: null, // What the title of the app should be in the banner (defaults to <title>) 282 author: null, // What the author of the app should be in the banner (defaults to <meta name="author"> or hostname) 283 price: 'FREE', // Price of the app 284 icon: null, // The URL of the icon (defaults to <meta name="apple-touch-icon">) 285 button: 'View', // Text for the install button 286 storeLanguage: 'us' // iOS Only : Language code for App Store 287 }; 288 $.smartbanner.Constructor = SmartBanner; 289}(window.jQuery); 290$(function () { 291 // CSS 292 $("#smartbanner").css({ 293 "position": "absolute", 294 "left": "0", 295 "top": "0", 296 "border-bottom": "2px solid #e8e8e8", 297 "width": "100%", 298 "height": "80px", 299 "font-family": "'Helvetica Neue',sans-serif", 300 "background": "#fff", 301 "z-index": "9998", 302 "-webkit-font-smoothing": "antialiased", 303 "overflow": "hidden", 304 "-webkit-text-size-adjust": "none", 305 "box-sizing": "border-box" 306 }); 307 $("#smartbanner .sb-container").css({ 308 "margin": "0 auto" 309 }); 310 $("#smartbanner .sb-close").css({ 311 "position": "absolute", 312 "left": "0", 313 "top": "0", 314 "display": "block", 315 "text-align": "center", 316 "text-decoration": "none", 317 "-webkit-font-smoothing": "subpixel-antialiased", 318 "border": "0", 319 "width": "17px", 320 "height": "100%", 321 "line-height": "25px", 322 "color": "#999 !important", 323 "border-radius": "0", 324 "background": "none", 325 "box-shadow": "none", 326 "text-shadow": "none", 327 "font-size": "25px", 328 "padding": "2px 5px" 329 }); 330 $("#smartbanner .sb-close:active").css({ 331 "color": "#aaa" 332 }); 333 $("#smartbanner .sb-icon").css({ 334 "position": "absolute", 335 "left": "30px", 336 "top": "10px", 337 "display": "block", 338 "width": "55px", 339 "height": "55px", 340 "background-size": "cover" 341 }); 342 $("#smartbanner.no-icon .sb-icon").css({ 343 "display": "none" 344 }); 345 $("#smartbanner .sb-info").css({ 346 "position": "absolute", 347 "left": "98px", 348 "top": "18px", 349 "width": "44%", 350 "font-size": "12px", 351 "line-height": "1.2em", 352 "color": "#6a6a6a", 353 "text-shadow": "0 1px 0 rgba(255,255,255,0.8)" 354 }); 355 $("#smartbanner #smartbanner.no-icon .sb-info").css({ 356 "left": "34px" 357 }); 358 $("#smartbanner .sb-info strong").css({ 359 "display": "block", 360 "font-size": "13px", 361 "color": "#000", 362 "line-height": "18px", 363 "font-weight": "bold" 364 }); 365 $("#smartbanner .sb-info > span").css({ 366 "display": "block" 367 }); 368 $("#smartbanner .sb-info .sb-price").css({}); 369 $("#smartbanner .sb-info em").css({ 370 "font-style": "normal", 371 "text-transform": "uppercase" 372 }); 373 $("#smartbanner .sb-button").css({ 374 "position": "absolute", 375 "right": "20px", 376 "top": "24px",
377 "border": "1px solid #bfbfbf", 378 "padding": "0 10px", 379 "min-width": "10%", 380 "height": "24px", 381 "font-size": "14px", 382 "line-height": "24px", 383 "text-align": "center", 384 "font-weight": "bold", 385 "color": "#6a6a6a !important", 386 "background": "#fff", 387 "text-transform": "uppercase", 388 "text-decoration": "none", 389 "text-shadow": "0 1px 0 rgba(255,255,255,0.8)", 390 "border-radius": "3px", 391 "box-shadow": "0 1px 0 rgba(255,255,255,0.6),0 1px 0 rgba(255,255,255,0.7) inset" 392 }); 393 $("#smartbanner .sb-icon.gloss:after").css({ 394 "content": "''", 395 "position": "absolute", 396 "left": "0", 397 "top": "-1px", 398 "border-top": "1px solid rgba(255,255,255,0.8)", 399 "width": "100%", 400 "height": "50%", 401 "background": "-webkit-linear-gradient(top, rgba(255,255,255,0.7) 0%,rgba(255,255,255,0.2) 100%)", 402 "border-radius": "10px 10px 12px 12px" 403 }); 404 /* iOS*/ 405 $("#smartbanner.ios .sb-icon").css({ 406 "border-radius": "9px" 407 }); 408 $("#smartbanner.ios .sb-close").css({ 409 "color": "#999 !important", 410 "padding": "7px" 411 }); 412 $("#smartbanner.ios .sb-button").css({ 413 "background-color": "#fff", 414 "color": "#007AFF !important", 415 "border": "1px solid #007AFF" 416 }); 417 /* Android */ 418 $("#smartbanner.android").css({ 419 "border-color": "#ccc", 420 "border-top": "5px solid rgb(179, 200, 51)", 421 "border-bottom": "2px solid #d6d6d6", 422 "background": "#f5f5f5", 423 "box-shadow": "none", 424 "font-family": "Roboto,Arial,sans-serif", 425 "font-size": "13px", 426 "font-weight": "normal", 427 "color": "#8d8d8d" 428 }); 429 $("#smartbanner.android .sb-close").css({ 430 "color": "#999 !important", 431 "padding": "5px" 432 }); 433 $("#smartbanner.android .sb-close:active").css({ 434 "color": "#eee" 435 }); 436 $("#smartbanner.android .sb-info").css({ 437 "text-shadow": "none", 438 "font-weight": "normal" 439 }); 440 $("#smartbanner.android .sb-info strong").css({ 441 "color": "#333" 442 }); 443 $("#smartbanner.android .sb-info .sb-price").css({ 444 "color": "#b3c833" 445 }); 446 $("#smartbanner.android .sb-button").css({ 447 "min-width": "12%", 448 "border": "2px solid transparent", 449 "padding": "0", 450 "color": "#fff !important", 451 "border-radius": "2px", 452 "box-shadow": "0 1px 0 rgba(0,0,0,.2)", 453 "background": "#b3c833" 454 }); 455 $("#smartbanner.android .sb-button span").css({ 456 "display": "block", 457 "padding": "0 10px", 458 "text-transform": "none", 459 "text-shadow": "none" 460 }); 461 $("#smartbanner.android .sb-button:active, #smartbanner.android .sb-button:hover").css({ 462 "box-shadow": "0 1px 0 rgba(0,0,0,.4)" 463 }); 464 $("#smartbanner.android .sb-button:active span, #smartbanner.android .sb-button:hover span").css({ 465 "box-shadow": "0 1px 2px rgba(0,0,0,0.05)" 466 }); 467 /* Windows RT */ 468 $("#smartbanner.windows").css({ 469 "background": "#464646", 470 "border-bottom": "8px solid #2a2a2a", 471 "font-family": "wf_SegoeUI,Segoe UI,Segoe,Segoe WP,Tahoma,Verdana,Arial,sans-serif", 472 "font-size": "14px", 473 "-webkit-font-smoothing": "antialiased" 474 }); 475 $("#smartbanner.windows .sb-container").css({ 476 "height": "100%", 477 "box-sizing": "border-box", 478 "border-bottom": "1px solid #00bcf2" 479 }); 480 $("#smartbanner.windows .sb-icon").css({ 481 "border-radius": "0px" 482 }); 483 $("#smartbanner.windows .sb-info").css({ 484 "color": "#fff", 485 "text-shadow": "none", 486 "font-weight": "normal" 487 }); 488 $("#smartbanner.windows .sb-info strong").css({ 489 "color": "#00bcf2", 490 "text-shadow": "0 0 2px #222" 491 }); 492 $("#smartbanner.windows .sb-info .sb-price").css({ 493 "color": "#00bcf2" 494 }); 495 $("smartbanner.windows .sb-button").css({ 496 "border-radius": "0", 497 "background": "#00bcf2", 498 "color": "#fff !important", 499 "border": "2px solid #00bcf2", 500 "box-shadow": "none", 501 "text-shadow": "none" 502 }); 503 $("#smartbanner.windows .sb-button:hover").css({ 504 "border": "2px solid rgba(0,0,0,0.2)" 505 }); 506 $("#smartbanner.windows .sb-close").css({ 507 "color": "#999 !important" 508 }); 509 /* Windows Phone */ 510 $("#smartbanner.windows-phone").css({ 511 "background": "#464646", 512 "border-bottom": "8px solid #2a2a2a", 513 "font-family": "wf_SegoeUI,Segoe UI,Segoe,Segoe WP,Tahoma,Verdana,Arial,sans-serif", 514 "font-size": "14px", 515 "-webkit-font-smoothing": "antialiased" 516 }); 517 $("#smartbanner.windows-phone .sb-container").css({ 518 "height": "100%", 519 "box-sizing": "border-box", 520 "border-bottom": "1px solid #9B4F96" 521 }); 522 $("#smartbanner.windows-phone .sb-icon").css({
523 "border-radius": "0px" 524 }); 525 $("#smartbanner.windows-phone .sb-info").css({ 526 "color": "#fff", 527 "text-shadow": "none", 528 "font-weight": "normal" 529 }); 530 $("#smartbanner.windows-phone .sb-info strong").css({ 531 "color": "#9B4F96", 532 "text-shadow": "0 0 2px #222" 533 }); 534 $("#smartbanner.windows-phone .sb-info .sb-price").css({ 535 "color": "#9B4F96" 536 }); 537 $("#smartbanner.windows-phone .sb-button").css({ 538 "border-radius": "0", 539 "background": "#9B4F96", 540 "color": "#fff !important", 541 "border": "2px solid #9B4F96", 542 "box-shadow": "none", 543 "text-shadow": "none" 544 }); 545 $("#smartbanner.windows-phone .sb-button:hover").css({ 546 "border": "2px solid rgba(0,0,0,0.2)" 547 }); 548 $("#smartbanner.windows-phone .sb-close").css({ 549 "color": "#999 !important" 550 }); 551});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.