PageSourceSearch

https://cdnazure.infoempleo.com/infoempleo/assets/vendor/smartbanner/jquery.smartbanner.js

js infoempleo.com collected 2026-09-24 09:10:24 UTC 16,123 bytes, 451 lines download raw bytes

1/*!
2 * jQuery Smart Banner
3 * Copyright (c) 2012 Arnold Daniels <[email protected]>
4 * Based on 'jQuery Smart Web App Banner' by Kurt Zenisek @ kzeni.com
5 */
6(function(root, factory) {
7  if (typeof define == 'function' && define.amd) {
8    define(['jquery'], factory);
9  } else {
10    factory(root.jQuery);
11  }
12})(this, function($) {
13  var UA = navigator.userAgent;
14  var isEdge = /Edge/i.test(UA);
15
16  var SmartBanner = function(options) {
17    // Get the original margin-top of the HTML element so we can take that into account.
18    this.origHtmlMargin = parseFloat($('html').css('margin-top'));
19    this.options = $.extend({}, $.smartbanner.defaults, options);
20
21    // Check if it's already a standalone web app or running within a webui view of an app (not mobile safari).
22    var standalone = navigator.standalone;
23
24    // Detect banner type (iOS or Android).
25    if (this.options.force) {
26      this.type = this.options.force;
27    }
28    else if (UA.match(/Windows Phone/i) !== null && UA.match(/Edge|Touch/i) !== null) {
29      this.type = 'windows';
30    }
31    else if (UA.match(/iPhone|iPod/i) !== null || (UA.match(/iPad/) && this.options.iOSUniversalApp)) {
32      if (UA.match(/Safari/i) !== null &&
33          (UA.match(/CriOS/i) !== null ||
34           UA.match(/FxiOS/i) != null ||
35            window.Number(UA.substr(UA.indexOf('OS ') + 3, 3).replace('_', '.')) < 6)) {
36        // Check webview and native smart banner support (iOS 6+).
37        this.type = 'ios';
38      }
39    }
40    else if (UA.match(/\bSilk\/(.*\bMobile Safari\b)?/) || UA.match(/\bKF\w/) || UA.match('Kindle Fire')) {
41      this.type = 'kindle';
42    }
43    else if (UA.match(/Android/i) !== null) {
44      this.type = 'android';
45    }
46    // Don't show banner if device isn't iOS or Android, website is loaded in app or user dismissed banner.
47    if (!this.type || standalone || this.getCookie('sb-closed') || this.getCookie('sb-installed')) {
48      return;
49    }
50    // Calculate scale.
51    this.scale = this.options.scale == 'auto' ? $(window).width() / window.screen.width : this.options.scale;
52    if (this.scale < 1) {
53      this.scale = 1;
54    }
55    // Get info from meta data.
56    var meta = $(
57      this.type == 'android'
58        ? 'meta[name="google-play-app"]'
59        : (this.type == 'ios'
60            ? 'meta[name="apple-itunes-app"]'
61            : (this.type == 'kindle'
62                ? 'meta[name="kindle-fire-app"]'
63                : 'meta[name="msApplication-ID"]'
64              )
65          )
66    );
67
68    if (!meta.length) {
69      return;
70    }
71    // For Windows Store apps, get the PackageFamilyName for protocol launch.
72    if (this.type == 'windows') {
73      if (isEdge) {
74        this.appId = $('meta[name="msApplication-PackageEdgeName"]').attr('content');
75      }
76      if (!this.appId) {
77        this.appId = $('meta[name="msApplication-PackageFamilyName"]').attr('content');
78      }
79    }
80    else {
81      // Try to pull the appId out of the meta tag and store the result.
82      var parsedMetaContent = /app-id=([^\s,]+)/.exec(meta.attr('content'));
83      if (parsedMetaContent) {
84        this.appId = parsedMetaContent[1];
85      } else {
86        return;
87      }
88    }
89    this.title = this.options.title
90      ? this.options.title
91      : (meta.data('title') || $('title').text().replace(/\s*[|\-·].*$/, ''));
92
93    this.author = this.options.author
94      ? this.options.author
95      : (meta.data('author') || ($('meta[name="author"]').length ? $('meta[name="author"]').attr('content') : window.location.hostname));
96
97    this.iconUrl = meta.data('icon-url');
98    this.price = meta.data('price');
99
100    // Set default onInstall callback if not set in options.
101    if (typeof this.options.onInstall == 'function') {
102      this.options.onInstall = this.options.onInstall;
103    } else {
104      this.options.onInstall = function() {};
105    }
106    // Set default onClose callback if not set in options.
107    if (typeof this.options.onClose == 'function') {
108      this.options.onClose = this.options.onClose;
109    } else {
110      this.options.onClose = function() {};
111    }
112    // Create banner.
113    this.create();
114    this.show();
115    this.listen();
116  };
117
118  SmartBanner.prototype = {
119
120    constructor: SmartBanner,
121
122    create: function() {
123      var iconURL;
124      var price = this.price || this.options.price;
125
126      var link = this.options.url || (function() {
127        switch (this.type) {
128          case 'android':
129            return 'market://details?id=';
130          case 'kindle':
131            return 'amzn://apps/android?asin=';
132          case 'windows':
133            return isEdge
134              ? 'ms-windows-store://pdp/?productid='
135              : 'ms-windows-store:navigate?appid=';
136        }
137        return 'https://itunes.apple.com/' + this.options.appStoreLanguage + '/app/id';
138      }.call(this) + this.appId);
139
140      var inStore = !price ? '' : (function() {
141        var result = price + ' - ';
142        switch (this.type) {
143          case 'android':
144            return result + this.options.inGooglePlay;
145          case 'kindle':
146            return result + this.options.inAmazonAppStore;
147          case 'windows':
148            return result + this.options.inWindowsStore;
149        }
150        return result + this.options.inAppStore
151      }.call(this));
152
153      var gloss = this.options.iconGloss == null
154        ? (this.type=='ios')
155        : this.options.iconGloss;
156
157      if (this.type == 'android' && this.options.GooglePlayParams) {
158        link += '&referrer=' + this.options.GooglePlayParams;
159      }
160      var banner = (
161        '<div id="smartbanner" class="' + this.type + '">' +
162          '<div class="sb-container">' +
163            '<a href="#" class="sb-close">&times;</a>' +
164            '<span class="sb-icon"></span>' +
165            '<div class="sb-info">' +
166              '<strong>' + this.title + '</strong>' +
167              '<span>' + this.author + '</span>' +
168              '<span>' + inStore + '</span>' +
169            '</div>' +
170            '<a href="' + link + '" class="sb-button">' +
171              '<span>' + this.options.button + '</span>' +
172            '</a>' +
173          '</div>' +
174        '</div>'
175      );
176      if (this.options.layer) {
177        $(this.options.appendToSelector).append(banner);
178      } else {
179        $(this.options.appendToSelector).prepend(banner);
180      }
181      if (this.options.icon) {
182        iconURL = this.options.icon;
183      } else if(this.iconUrl) {
184        iconURL = this.iconUrl;
185      } else if ($('link[rel="apple-touch-icon-precomposed"]').length > 0) {
186        iconURL = $('link[rel="apple-touch-icon-precomposed"]').attr('href');
187        if (this.options.iconGloss == null) {
188          gloss = false;
189        }
190      } else if ($('link[rel="apple-touch-icon"]').length > 0) {
191        iconURL = $('link[rel="apple-touch-icon"]').attr('href');
192      } else if ($('meta[name="msApplication-TileImage"]').length > 0) {
193        iconURL = $('meta[name="msApplication-TileImage"]').attr('content');
194      } else if ($('meta[name="msapplication-TileImage"]').length > 0) {
195        // Redundant because ms docs show two case usages.
196        iconURL = $('meta[name="msapplication-TileImage"]').attr('content');
197      }
198      if (iconURL) {
199        $('#smartbanner .sb-icon').css('background-image', 'url(' + iconURL + ')');
200        if (gloss) {
201          $('#smartbanner .sb-icon').addClass('gloss');
202        }
203      } else{
204        $('#smartbanner').addClass('no-icon');
205      }
206      this.bannerHeight = $('#smartbanner').outerHeight() + 2;
207
208      if (this.scale > 1) {
209        $('#smartbanner')
210          .css('top', parseFloat($('#smartbanner').css('top')) * this.scale)
211          .css('height', parseFloat($('#smartbanner').css('height')) * this.scale)
212          .hide();
213        $('#smartbanner .sb-container')
214          .css('-webkit-transform', 'scale(' + this.scale + ')')
215          .css('-msie-transform', 'scale(' + this.scale + ')')
216          .css('-moz-transform', 'scale(' + this.scale + ')')
217          .css('width', $(window).width() / this.scale);
218      }
219      $('#smartbanner')
220        .css('position', this.options.layer ? 'absolute' : 'static');
221    },
222
223    listen: function() {
224      $('#smartbanner .sb-close').on('click', $.proxy(this.close, this));
225      $('#smartbanner .sb-button').on('click', $.proxy(this.install, this));
226    },
227
228    show: function(callback) {
229      var banner = $('#smartbanner');
230      banner.stop();
231
232      if (this.options.layer) {
233        banner
234          .animate({ top: 0, display: 'block' }, this.options.speedIn)
235          .addClass('shown')
236          .show();
237        $(this.pushSelector)
238          .animate({
239            paddingTop: this.origHtmlMargin + (this.bannerHeight * this.scale)
240          }, this.options.speedIn, 'swing', callback);
241      }
242      else {
243        if ($.support.transition) {
244          banner.animate({ top: 0 }, this.options.speedIn).addClass('shown');
245          var transitionCallback = function() {
246            $('html').removeClass('sb-animation');
247            if (callback) {
248              callback();
249            }
250          };
251          $(this.pushSelector)
252            .addClass('sb-animation')
253            .one($.support.transition.end, transitionCallback)
254            .emulateTransitionEnd(this.options.speedIn)
255            .css('margin-top', this.origHtmlMargin + (this.bannerHeight * this.scale));
256        }
257        else {
258          banner
259            .slideDown(this.options.speedIn)
260            .addClass('shown');
261        }
262      }
263    },
264
265    hide: function(callback) {
266      var banner = $('#smartbanner');
267      banner.stop();
268
269      if (this.options.layer) {
270        banner.animate({
271          top: -1 * this.bannerHeight * this.scale,
272          display: 'block'
273        }, this.options.speedIn)
274        .removeClass('shown');
275
276        $(this.pushSelector)
277          .animate({
278            paddingTop: this.origHtmlMargin
279          }, this.options.speedIn, 'swing', callback);
280      }
281      else {
282        if ($.support.transition) {
283          if (this.type !== 'android') {
284            banner
285              .css('top', -1 * this.bannerHeight * this.scale)
286              .removeClass('shown');
287          }
288          else {
289            banner
290              .css({display:'none'})
291              .removeClass('shown');
292          }
293          var transitionCallback = function() {
294            $('html').removeClass('sb-animation');
295            if (callback) {
296              callback();
297            }
298          };
299          $(this.pushSelector)
300            .addClass('sb-animation')
301            .one($.support.transition.end, transitionCallback)
302            .emulateTransitionEnd(this.options.speedOut)
303            .css('margin-top', this.origHtmlMargin);
304        }
305        else {
306          banner.slideUp(this.options.speedOut).removeClass('shown');
307        }
308      }
309    },
310
311    close: function(e) {
312      e.preventDefault();
313      this.hide();
314      this.setCookie('sb-closed', 'true', this.options.daysHidden);
315      this.options.onClose(e);
316    },
317
318    install: function(e) {
319      if (this.options.hideOnInstall) {
320        this.hide();
321      }
322      this.setCookie('sb-installed', 'true', this.options.daysReminder);
323      this.options.onInstall(e);
324    },
325
326    setCookie: function(name, value, exdays) {
327      var exdate = new Date();
328      exdate.setDate(exdate.getDate() + exdays);
329      value = encodeURI(value) + ((exdays == null) ? '' : '; expires=' + exdate.toUTCString());
330      document.cookie = name + '=' + value + '; path=/;';
331    },
332
333    getCookie: function(name) {
334      var i, x, y, ARRcookies = document.cookie.split(';');
335      for (i = 0; i < ARRcookies.length; i++) {
336        x = ARRcookies[i].substr(0, ARRcookies[i].indexOf('='));
337        y = ARRcookies[i].substr(ARRcookies[i].indexOf('=') + 1);
338        x = x.replace(/^\s+|\s+$/g, '');
339        if (x == name) {
340          return decodeURI(y);
341        }
342      }
343      return null;
344    },
345
346    // Demo only.
347    switchType: function() {
348      var that = this;
349
350      this.hide(function() {
351        that.type = that.type == 'android' ? 'ios' : 'android';
352        var meta = $(that.type == 'android' ? 'meta[name="google-play-app"]' : 'meta[name="apple-itunes-app"]').attr('content');
353        that.appId = /app-id=([^\s,]+)/.exec(meta)[1];
354
355        $('#smartbanner').detach();
356        that.create();
357        that.show();
358      });
359    }
360  };
361
362  $.smartbanner = function(option) {
363    var $window = $(window);
364    var data = $window.data('smartbanner');
365    var options = typeof option == 'object' && option;
366    if (!data) {
367      $window.data('smartbanner', (data = new SmartBanner(options)));
368    }
369    if (typeof option == 'string') {
370      data[option]();
371    }
372  };
373
374  // override these globally if you like (they are all optional)
375  $.smartbanner.defaults = {
376    title: null, // What the title of the app should be in the banner (defaults to <title>)
377    author: null, // What the author of the app should be in the banner (defaults to <meta name="author"> or hostname)
378    price: 'FREE', // Price of the app
379    appStoreLanguage: 'us', // Language code for App Store
380    inAppStore: 'On the App Store', // Text of price for iOS
381    inGooglePlay: 'In Google Play', // Text of price for Android
382    inAmazonAppStore: 'In the Amazon Appstore',
383    inWindowsStore: 'In the Windows Store', //Text of price for Windows
384    GooglePlayParams: null, // Aditional parameters for the market
385    icon: null, // The URL of the icon (defaults to <meta name="apple-touch-icon">)
386    iconGloss: null, // Force gloss effect for iOS even for precomposed
387    button: 'VIEW', // Text for the install button
388    url: null, // The URL for the button. Keep null if you want the button to link to the app store.
389    scale: 'auto', // Scale based on viewport size (set to 1 to disable)
390    speedIn: 300, // Show animation speed of the banner
391    speedOut: 400, // Close animation speed of the banner
392    daysHidden: 15, // Duration to hide the banner after being closed (0 = always show banner)
393    daysReminder: 90, // Duration to hide the banner after "VIEW" is clicked *separate from when the close button is clicked* (0 = always show banner)
394    force: null, // Choose 'ios', 'android' or 'windows'. Don't do a browser check, just always show this banner
395    hideOnInstall: true, // Hide the banner after "VIEW" is clicked.
396    layer: false, // Display as overlay layer or slide down the page
397    iOSUniversalApp: true, // If the iOS App is a universal app for both iPad and iPhone, display Smart Banner to iPad users, too.
398    appendToSelector: 'body', //Append the banner to a specific selector
399    pushSelector: 'html' // What element is going to push the site content down; this is where the banner append animation will start.
400  };
401
402  $.smartbanner.Constructor = SmartBanner;
403
404  // ============================================================
405  // Bootstrap transition
406  // Copyright 2011-2014 Twitter, Inc.
407  // Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
408
409  function transitionEnd () {
410    var el = document.createElement('smartbanner');
411
412    var transEndEventNames = {
413      WebkitTransition: 'webkitTransitionEnd',
414      MozTransition: 'transitionend',
415      OTransition: 'oTransitionEnd otransitionend',
416      transition: 'transitionend'
417    };
418
419    for (var name in transEndEventNames) {
420      if (el.style[name] !== undefined) {
421        return {end: transEndEventNames[name]};
422      }
423    }
424    // Explicit for ie8.
425    return false;
426  }
427  if ($.support.transition !== undefined) {
428    // Prevent conflict with Twitter Bootstrap.
429    return;
430  }
431
432  // http://blog.alexmaccaw.com/css-transitions
433  $.fn.emulateTransitionEnd = function(duration) {
434    var called = false, $el = this;
435    $(this).one($.support.transition.end, function() {
436      called = true;
437    });
438    var callback = function() {
439      if (!called) {
440        $($el).trigger($.support.transition.end);
441      }
442    };
443    setTimeout(callback, duration);
444    return this;
445  };
446
447  $(function() {
448    $.support.transition = transitionEnd();
449  });
450  // ============================================================
451});

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.