/*!
* bauer.ui.js
* ===========================================
* Copyright (c) 2015 Bauer Consumer Media Ltd
*
* Version: 2.0.0
* -------------------------------------------
* bui.cookie: Modified from jQuery Cookie plugin, (c) Klaus Hartl 2006 (stilbuero.de), MIT and GPL licenses
* bui.datetime: Modified from Date Format 1.2.3, (c) Steven Levithan 2007-2009 (stevenlevithan.com), MIT license
* bui.images.onLoad: Modified from jQuery imagesLoaded v2, (c) Paul Irish 2012 (github.com/desandro/imagesloaded), MIT license
* bui.images.pngFix: Modified from jQuery pngFix plugin, (c) Andreas Eberhard 2007 (jquery.andreaseberhard.de), GPL license
* bui.json: Modified from JSON2, (c) Douglas Crockford (json.org)
*
* GPL License (http://www.opensource.org/licenses/gpl-license.php)
* MIT License (http://www.opensource.org/licenses/mit-license.php)
* -------------------------------------------
*/
(function ($) {
var bui = function (o, prefix) {
if (!o) { return; }
o = bui.test.isType(o, 'string') ? $('#' + (prefix ? prefix + '_' : '') + o.trimLeft('#')) : $(o);
if (o.length > 1) { o = $(o[0]); }
return o;
};
$.extend(bui, {
debug: false,
defaults: {
accessKeys: true,
bookmark: true,
social: false,
string: true,
window: true
},
jqueryVersion: {},
libs: {},
loaded: false,
options: {},
ready: false,
vars: {},
version: '[[AssemblyVersionMajor]].[[AssemblyVersionMinor]].[[AssemblyVersionBuild]]',
// #region Initialisation
// ==================================
init: function (options, context) {
// context is the jquery selector/object to start from
if (options.debug !== undefined) {
bui.debug = options.debug;
}
var opts = $.extend(bui.options, bui.defaults, options);
// priority: 1
bui.browser.init();
if (bui.libs.mobile) { bui.mobile.init(opts, context); }
if (bui.libs.visual) { bui.visual.init(opts, context); }
if (bui.libs.widgets) { bui.widgets.init(opts, context); }
if (bui.libs.googleApi) { bui.googleApi.init(opts, context); }
// priority: 2
if (opts.string) { bui.string.init(context); }
if (opts.window) { bui.window.init(context); }
if (bui.libs.forms) { bui.forms.init(opts, context); }
// priority: 3
if (opts.accessKeys) { bui.accessKeys.init(context); }
if (opts.bookmark) { bui.bookmark.init(context); }
if (opts.social) { bui.social.init(context); }
$(document).bind('dragstart', function (e) {
var o = $(e.target);
if (bui.controls.isImage(o) || o.css('backgroundImage') !== '') { return false; }
});
},
// #endregion
// #region Core
// ==================================
clone: function (o, deep) {
return deep ? $.extend(true, {}, o) : $.extend({}, o);
},
getType: function (o) {
// deprecated: use $.type instead
return $.type(o);
},
log: function (s) {
if (!bui.debug) { return; }
if (window.console && window.console.log) { window.console.log(s); }
if (window.opera) { window.opera.postError(s); }
if (window.debugService) { window.debugService.trace(s); }
},
onLoad: function (func, delay) {
if ($.isFunction(func)) {
if (bui.loaded) {
func();
} else if (delay && delay > 0) {
$(window).load(function () {
window.setTimeout(func, delay);
});
} else {
$(window).load(func);
}
}
},
preventDefault: function (e) {
e.preventDefault();
},
safeEval: function (o) {
// note: only use with native objects or simple JSON strings, some characters get escaped for security
if (!bui.test.isType(o, 'string')) { return o; }
o = bui.string.trim(o).replace('(', '\\(').replace(')', '\\)').replace(';', '\\;');
if (!o.match(/^((\d+(\.\d+)?)|(true)|(false))$/i) && !o.match(/^[\[{]/)) { return String(o); }
return eval('(' + o + ')');
},
sleep: function (ms) {
var dt = new Date(), dt2 = new Date();
dt2.setTime(dt.getTime() + ms);
while (dt.getTime() < dt2.getTime()) {
$.noop();
}
},
speed: function (n, defaultValue) {
defaultValue = defaultValue || 0;
if (!n && n !== 0) {
n = defaultValue;
}
if (n && bui.test.isType(n, 'string')) {
if (n === 'fast') {
n = 200;
} else if (n === 'slow') {
n = 600;
} else {
n = 400;
}
}
return Number(n);
},
write: function (s, o) {
if (o) {
o = bui(o);
if (bui.controls.isInput(o)) {
o.val(s);
} else {
o.html(s);
}
} else {
document.write(s);
}
},
// #endregion
// #region Access Keys
// ==================================
accessKeys: {
init: function (context) {
var b = false;
$('a[accesskey]', context).each(function () {
b = true;
var o = $(this);
if (o.attr('accesskey') === '') { return; }
var em = bui.accessKeys.createTag(o.attr('accesskey'), 'link');
o.prepend(em);
});
$('input[accesskey]', context).each(function () {
b = true;
var o = $(this);
if (o.attr('accesskey') === '') { return; }
var em = bui.accessKeys.createTag(o.attr('accesskey'), 'input');
em.insertBefore(o);
});
$('label[accesskey]', context).each(function () {
b = true;
var o = $(this);
if (o.attr('accesskey') === '' || o.attr('for') === '') { return; }
// move access key to input control
var k = o.attr('accesskey');
var i = $('#' + o.attr('for'));
if (i.length === 0) { return; }
o.removeAttr('accesskey');
i.attr('accesskey', k);
var em = bui.accessKeys.createTag(k, 'label');
o.prepend(em);
});
if (b && !bui.vars.hasAccessKeys) {
bui.vars.hasAccessKeys = true;
$(document).bind('keydown.accesskeys', function (e) {
var ff = $.browser.mozilla;
if (!e.which && ((e.charCode || e.charCode === 0) ? e.charCode : e.keyCode)) {
e.which = e.charCode || e.keyCode;
}
if ((!ff && e.which === 18) || (ff && ((e.altKey && e.which === 16) || (e.shiftKey && e.which === 18)))) {
bui.accessKeys.show();
}
});
$(document).bind('keyup.accesskeys', bui.accessKeys.hide);
$(window).bind('resize.accesskeys', bui.accessKeys.hide);
$(window).bind('blur.accesskeys', bui.accessKeys.hide);
$(window).bind('focus.accesskeys', bui.accessKeys.hide);
$(window).unload(function () {
$(document).unbind('.accesskeys');
$(window).unbind('.accesskeys');
});
}
},
createTag: function (k, type) {
var o = $('').html(k.toUpperCase()).hide();
if (type && type !== '') {
o.addClass('bui-accesskeys-' + type);
}
return o;
},
hide: function () {
if (bui.accessKeys.visible()) {
$('em.bui-accesskeys').hide();
$('body').removeClass('bui-accesskeys-visible');
}
},
show: function () {
if (!bui.accessKeys.visible()) {
$('em.bui-accesskeys').show();
$('body').addClass('bui-accesskeys-visible');
if (window.opera) { window.setTimeout(bui.accessKeys.hide, 10000); }
}
},
visible: function () {
return $('body').hasClass('bui-accesskeys-visible');
}
},
// #endregion
// #region Arrays
// ==================================
array: {
clone: function (a) {
if (!bui.test.isArray(a)) { return null; }
return a.slice(0);
},
contains: function (a, item) {
if (!bui.test.isArray(a)) { return null; }
return a.indexOf(item) > -1;
},
containsAnyValue: function (a, values, valueDelimiter) {
// returns true if any of the values appear in the array
if (!bui.test.isArray(a)) { return null; }
var i, v;
if (!bui.test.isArray(values)) {
valueDelimiter = valueDelimiter || ',';
v = [];
if (bui.test.isType(values, 'string')) {
v = values.split(valueDelimiter);
} else {
v.push(values);
}
values = v;
}
for (i = 0; i < values.length; i++) {
v = values[i];
if (bui.test.isType(v, 'string')) {
v = bui.string.trim(v);
}
if (a.contains(v)) {
return true;
}
}
return false;
},
indexOf: function (a, item, start) {
if (!bui.test.isArray(a)) { return null; }
var i, result = -1;
for (i = Math.max(Math.min(start, a.length), 0) || 0; i < a.length; i++) {
if (a[i] === item) {
result = i;
break;
}
}
return result;
},
lastIndexOf: function (a, item, start) {
if (!bui.test.isArray(a)) { return null; }
var i, result = -1;
for (i = Math.max(Math.min(start || a.length, a.length), 0); i >= 0; i--) {
if (a[i] === item) {
result = i;
break;
}
}
return result;
}
},
// #endregion
// #region Bookmarks
// ==================================
bookmark: {
init: function (context) {
$('a.bui-bookmark', context).unbind('click.bookmark').bind('click.bookmark', function (e) {
var a = $(this);
var b = bui.bookmark.add(a);
if (!b) { e.preventDefault(); }
});
},
add: function (o, url, title) {
o = bui(o);
var r = false;
if (o.length > 0) {
var href = o.attr('href');
if (href === '#') { href = ''; }
url = url || href || window.location.href;
title = title || o.attr('title') || document.title;
if (window.sidebar && window.sidebar.addPanel) {
window.sidebar.addPanel(title, url, '');
} else if (window.external) {
window.external.AddFavorite(url, title);
} else if (window.opera && window.print) {
o.attr('href', url);
o.attr('title', title);
o.attr('rel', 'sidebar');
o.attr('onclick', '');
r = true;
} else {
alert('Sorry, your web browser won\'t allow us to add a bookmark.');
}
}
return r;
}
},
// #endregion
// #region Browsers
// ==================================
browser: {
init: function () {
var body = $('body');
if ($.browser.mozilla) { body.addClass('moz'); }
if ($.browser.msie) { body.addClass('ie'); }
if ($.browser.opera) { body.addClass('opera'); }
if ($.browser.safari) { body.addClass('safari'); }
if ($.browser.webkit) { body.addClass('webkit'); }
if (!bui.libs.mobile) {
if (navigator.platform.indexOf('iPhone') > -1 || navigator.platform.indexOf('iPod') > -1) {
body.addClass('iphone');
}
if (navigator.platform.indexOf('iPad') > -1) {
body.addClass('ipad');
}
}
if (bui.options.secureAjax) {
body.bind('ajaxSend', function (e, xhr, options) {
bui.browser.request.onAjaxSend(xhr, options);
});
}
},
isIE: function (ver) {
var b;
if (ver) {
b = ($.browser.msie && bui.string.startsWith($.browser.version, ver));
} else {
b = $.browser.msie;
}
return b;
},
isOldIE: function () {
return bui.browser.isIE(6) || bui.browser.isIE(7) || bui.browser.isIE(8);
},
request: {
onAjaxSend: function (xhr, options) {
if (options.type.toUpperCase() === 'POST') {
var key = options.url.replace(/[^\w]+/ig, '_').toLowerCase();
var tokens = bui.vars.ajaxTok || {};
if (!tokens[key]) {
var ticket = bui.vars.ajaxTkt || '';
var url = options.url;
if (bui.string.startsWith(url, '/')) {
url = bui.url.host() + url;
}
tokens[key] = bui.utils.hash((url + ticket).toLowerCase(), true);
bui.vars.ajaxTok = tokens;
}
xhr.setRequestHeader(('\\x58\\x2D\\x41\\x6A\\x61\\x78\\x2D\\x54\\x6F\\x6B\\x65\\x6E').hexDecode(), tokens[key] || 'error');
}
}
}
},
// #endregion
// #region Cookies
// ==================================
cookie: {
get: function (name) {
var c, ca, cv, i;
if (name && document.cookie && document.cookie !== '') {
ca = document.cookie.split(';');
for (i = 0; i < ca.length; i++) {
c = bui.string.trim(ca[i]);
if (c.substring(0, name.length + 1) === (name + '=')) {
cv = bui.url.decode(c.substring(name.length + 1));
break;
}
}
}
return cv;
},
remove: function (name) {
bui.cookie.set(name);
},
set: function (name, value, options) {
if (name) {
value = value || '';
options = options || {};
if (value === '') { options.expires = -1; }
var expires = '';
if (options.expires && (bui.test.isType(options.expires, 'number') || options.expires.toUTCString)) {
var date;
if (bui.test.isType(options.expires, 'number')) {
date = new Date();
date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
} else {
date = options.expires;
}
expires = '; expires=' + date.toUTCString();
}
var path = '; path=' + (options.path || '/');
var domain = options.domain ? '; domain=' + (options.domain) : '';
var secure = options.secure ? '; secure' : '';
document.cookie = [name, '=', bui.url.encode(value), expires, path, domain, secure].join('');
}
}
},
// #endregion
// #region Controls
// ==================================
controls: {
disable: function (o) {
o = bui(o);
o.addClass('disabled');
if (bui.controls.isInput(o) || bui.controls.isDropDownOption(o)) {
o.attr('disabled', 'disabled');
if (bui.libs.forms && bui.controls.isCheckable(o)) {
bui.forms.enhance.customCheckbox.update(o);
bui.forms.enhance.customRadioButton.update(o);
}
if (bui.controls.isInput(o) && o.attr('id')) {
$('label[for="' + o.attr('id') + '"]').addClass('disabled');
}
} else if (bui.controls.isLink(o)) {
if (!o.data('href')) {
o.data('href', o.attr('href'));
}
o.attr('href', '#');
}
},
enable: function (o) {
o = bui(o);
o.removeClass('disabled');
if (bui.controls.isInput(o) || bui.controls.isDropDownOption(o)) {
o.removeAttr('disabled');
if (bui.libs.forms && bui.controls.isCheckable(o)) {
bui.forms.enhance.customCheckbox.update(o);
bui.forms.enhance.customRadioButton.update(o);
}
if (bui.controls.isInput(o) && o.attr('id')) {
$('label[for="' + o.attr('id') + '"]').removeClass('disabled');
}
} else if (bui.controls.isLink(o) && o.data('href')) {
o.attr('href', o.data('href'));
}
},
isCheckable: function (o) {
o = bui(o);
var b = false;
if (bui.controls.isInput(o)) {
var t = (o.attr('type') || 'text').toLowerCase();
b = (t === 'checkbox' || t === 'radio');
}
return b;
},
isDropDown: function (o) {
o = bui(o);
return o[0].tagName === 'SELECT';
},
isDropDownOption: function (o) {
o = bui(o);
return o[0].tagName === 'OPTION';
},
isImage: function (o) {
o = bui(o);
return (o[0].tagName === 'IMG');
},
isInput: function (o) {
o = bui(o);
return (o[0].tagName === 'INPUT' || o[0].tagName === 'SELECT' || o[0].tagName === 'TEXTAREA');
},
isLink: function (o) {
o = bui(o);
return (o[0].tagName === 'A');
},
isTag: function (o, tag) {
o = bui(o);
return (o[0].tagName === tag.toUpperCase());
}
},
// #endregion
// #region Data Storage
// ==================================
data: {
extend: function (o, defaults, options, metadataKey) {
var md;
if (metadataKey && metadataKey !== '') {
md = bui.metadata.get(o, metadataKey);
}
return $.extend({}, defaults, options, md);
},
get: function (o, key) {
o = bui(o);
if (o.length > 0) { return o.data(key); }
},
set: function (o, key, data) {
o = bui(o);
if (o.length > 0) { o.data(key, data); }
}
},
// #endregion
// #region DateTime
// ==================================
datetime: {
dateFormats: {
_default: 'dd/MM/yyyy HH:mm:ss',
shortDate: 'dd/MM/yyyy',
longDate: 'dd MMMM yyyy',
fullDate: 'dddd, dd MMMM, yyyy',
shortTime: 'HH:mm',
longTime: 'HH:mm:ss',
isoDate: 'yyyy-MM-dd',
isoTime: 'HH:mm:ss',
isoDateTime: 'yyyy-MM-dd"T"HH:mm:ss',
isoUtcDateTime: 'UTC:yyyy-MM-dd"T"HH:mm:ss"Z"'
},
dateNames: {
longDay: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
longMonth: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
shortDay: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
shortMonth: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
diff: function (date1, date2) {
// returns difference in seconds
date1 = date1 ? (bui.test.isType(date1, 'Date') ? date1 : bui.datetime.parse(date1)) : null;
date2 = date2 ? (bui.test.isType(date2, 'Date') ? date2 : bui.datetime.parse(date2)) : null;
if (date1 && date2) {
var t = date2.getTime() - date1.getTime();
return t / 1000;
}
return 0;
},
format: function (date, mask, utc) {
date = date ? (bui.test.isType(date, 'Date') ? date : bui.datetime.parse(date)) : new Date();
if (!mask || mask === '') { mask = '_default'; }
mask = String(bui.datetime.dateFormats[mask] || mask);
utc = utc || false;
var df = bui.datetime.dateNames;
var dl = df.longDay, ds = df.shortDay, ml = df.longMonth, ms = df.shortMonth;
var pad = bui.string.pad;
var tkn = /d{1,4}|M{1,4}|yy(?:yy)?|([HhmsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g;
var tz = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[\-+]\d{4})?)\b/g;
var tzc = /[^\-+\dA-Z]/g;
// allow setting of utc via the mask
if (mask.slice(0, 4).toUpperCase() === 'UTC:') {
mask = mask.slice(4);
utc = true;
}
var get = utc ? 'getUTC' : 'get',
d = date[get + 'Date'](),
D = date[get + 'Day'](),
M = date[get + 'Month'](),
y = date[get + 'FullYear'](),
H = date[get + 'Hours'](),
m = date[get + 'Minutes'](),
s = date[get + 'Seconds'](),
L = date[get + 'Milliseconds'](),
o = utc ? 0 : date.getTimezoneOffset(),
flags = {
d: d,
dd: pad(d),
ddd: ds[D],
dddd: dl[D],
M: M + 1,
MM: pad(M + 1),
MMM: ms[M],
MMMM: ml[M],
yy: String(y).slice(2),
yyyy: y,
h: H % 12 || 12,
hh: pad(H % 12 || 12),
H: H,
HH: pad(H),
m: m,
mm: pad(m),
s: s,
ss: pad(s),
l: pad(L, 3),
L: pad(L > 99 ? Math.round(L / 10) : L),
t: H < 12 ? 'a' : 'p',
tt: H < 12 ? 'am' : 'pm',
T: H < 12 ? 'A' : 'P',
TT: H < 12 ? 'AM' : 'PM',
Z: utc ? 'UTC' : (String(date).match(tz) || ['']).pop().replace(tzc, ''),
o: (o > 0 ? '-' : '+') + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
S: ['th', 'st', 'nd', 'rd'][d % 10 > 3 ? 0 : (d % 100 - d % 10 !== 10) * d % 10]
};
return mask.replace(tkn, function (m) {
return flags[m] !== undefined ? flags[m] : m.slice(1, m.length - 1);
});
},
getDayName: function (dt) {
if (bui.test.isType(dt, 'Date')) {
return bui.datetime.dateNames.longDay[dt.getDay()];
}
},
getMonthName: function (dt) {
if (bui.test.isType(dt, 'Date')) {
return bui.datetime.dateNames.longMonth[dt.getMonth()];
}
},
parse: function (s) {
// returns UTC if time specified, accepts formats 'yyyy-MM-dd', 'yyyy-MM-dd ((HH:mm):ss)', 'yyyy-MM-dd ((HH:mm):ss)+0100' etc
if (bui.test.isType(s, 'Date')) { return s; }
s = String(s);
var d, m = s.match(/^(\d{4})\-(\d{2})\-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2}(?:\.\d+)?)(?:(Z|( ?([+\-])(\d{2}):?(\d{2}))))?)?)?$/i);
if (m) {
if (m[7]) {
d = new Date(Date.UTC(m[1], m[2] - 1, m[3], m[4] || 0, m[5] || 0, m[6] || 0, (m[6] * 1000 - ((m[6] || 0) * 1000)) || 0, m[7]) + (m[7].toUpperCase() === 'Z' ? 0 : (m[10] * 3600 + m[11] * 60) * (m[9] === '-' ? 1000 : -1000)));
} else {
d = new Date(Date.UTC(m[1], m[2] - 1, m[3], m[4] || 0, m[5] || 0, m[6] || 0, (m[6] * 1000 - ((m[6] || 0) * 1000)) || 0));
}
}
if (!d || isNaN(d)) {
throw new SyntaxError('Error parsing date: not a valid datetime.');
}
return d;
},
today: function () {
var dt = new Date();
dt.setUTCHours(0, 0, 0, 0);
return dt;
}
},
// #endregion
// #region History
// ==================================
history: {
back: function () {
window.history.go(-1);
return false;
},
forward: function () {
window.history.go(1);
return false;
}
},
// #endregion
// #region HTML Helpers
// ==================================
html: {
createLinkTag: function (href, rel, type, insertIntoHead) {
rel = rel || 'stylesheet';
type = type || 'text/css';
var s = document.createElement('link');
s.rel = rel;
s.type = type;
s.href = href;
if (insertIntoHead) {
var h = document.getElementsByTagName('head')[0];
h.appendChild(s);
} else {
var c = document.createElement('code');
c.appendChild(s);
return c.innerHTML;
}
},
createScriptTag: function (src, async, insertIntoHead) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = src;
if (async) {
s.async = 'true';
}
if (insertIntoHead) {
var h = document.getElementsByTagName('head')[0];
h.appendChild(s);
} else {
var c = document.createElement('code');
c.appendChild(s);
return c.innerHTML;
}
},
decode: function (s) {
if (!s) { return ''; }
return $('').html(s).text();
},
encode: function (s) {
var a, i;
if (!s) { return ''; }
a = bui.string.trim(s).split(/\r\n|\r|\n/);
if (a.length > 1) {
for (i = 0; i < a.length; i++) {
a[i] = bui.html.encode(a[i]);
}
return a.join('\n');
}
return $('
').text(bui.string.trim(s)).html();
},
highlightText: function (div, text, className) {
div = bui(div);
if (!text) { return; }
className = className || 'highlight';
var re = new RegExp(text, 'ig');
div.contents().filter(function () {
return this.nodeType === 3 && re.test(this.nodeValue);
}).replaceWith(function () {
return (this.nodeValue || '').replace(re, function (match) {
return '' + match + '';
});
});
}
},
// #endregion
// #region Images
// ==================================
images: {
cache: [],
cons: {
// the pixel image is actually used to store strings used by the Secrets region
blankImage: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==',
pixelImage: 'data:image/gif;base64,62726F77736572//72657175657374//6F6E416A617853656E64//68617368436F6465//39333436396530372D306633362D346233332D393331312D353761386430373865643831//=='
},
settings: {
blankGif: '/static/images/pixel.trans.gif',
pngSuffix: '.trans.png'
},
getResizedUrl: function (url, width, height) {
var lastSlash = url.lastIndexOf('/');
var path = url.substring(0, lastSlash + 1);
var file = url.substring(lastSlash);
return path + width + 'x' + height + file;
},
onLoad: function ($this, callback) {
var namespace = 'buiImagesLoaded';
var deferred = $.isFunction($.Deferred) ? $.Deferred() : 0,
hasNotify = $.isFunction(deferred.notify),
$images = $this.find('img').add($this.filter('img')),
loaded = [],
proper = [],
broken = [];
function doneLoading() {
var $proper = $(proper),
$broken = $(broken);
if (deferred) {
if (broken.length) {
deferred.reject($images, $proper, $broken);
} else {
deferred.resolve($images);
}
}
if ($.isFunction(callback)) {
callback.call($this, $images, $proper, $broken);
}
}
function imgLoaded(img, isBroken) {
if (img.src === bui.images.cons.blankImage || loaded.contains(img)) { return; }
loaded.push(img);
if (isBroken) {
broken.push(img);
} else {
proper.push(img);
}
$.data(img, namespace, { isBroken: isBroken, src: img.src });
if (hasNotify) {
deferred.notifyWith($(img), [isBroken, $images, $(proper), $(broken)]);
}
if ($images.length === loaded.length) {
window.setTimeout(doneLoading);
$images.unbind('.' + namespace);
}
}
if ($images.length === 0) {
doneLoading();
} else {
$images.bind('load.' + namespace + ' error.' + namespace, function (e) {
imgLoaded(e.target, e.type === 'error');
}).each(function (i, el) {
var src = el.src;
var cached = $.data(el, namespace);
if (cached && cached.src === src) {
imgLoaded(el, cached.isBroken);
return;
}
if (el.complete && el.naturalWidth !== undefined) {
imgLoaded(el, el.naturalWidth === 0 || el.naturalHeight === 0);
return;
}
if (el.readyState || el.complete) {
el.src = bui.images.cons.blankImage;
el.src = src;
}
});
}
return deferred ? deferred.promise($this) : $this;
},
pngFix: function (context, settings) {
if (bui.browser.isIE('5.5') || bui.browser.isIE('6')) {
settings = $.extend({}, bui.images.settings, settings);
var alpha = 'progid:DXImageTransform.Microsoft.AlphaImageLoader';
// fix images with png source
$(context).find('img[src$=' + settings.pngSuffix + ']').each(function () {
var img = $(this);
img.attr('width', img.width());
img.attr('height', img.height());
var imgId = (img.attr('id')) ? 'id="' + img.attr('id') + '" ' : '';
var imgClass = (img.attr('class')) ? 'class="' + img.attr('class') + '" ' : '';
var imgTitle = (img.attr('title')) ? 'title="' + img.attr('title') + '" ' : '';
var imgAlt = (img.attr('alt')) ? 'alt="' + img.attr('alt') + '" ' : '';
var imgAlign = (img.attr('align')) ? 'float:' + img.attr('align') + ';' : '';
var imgHand = (img.parent().attr('href')) ? 'cursor:pointer;' : '';
var html = '';
var prevStyle = '';
if (this.style.border) {
prevStyle += 'border:' + this.style.border + ';';
this.style.border = '';
}
if (this.style.padding) {
prevStyle += 'padding:' + this.style.padding + ';';
this.style.padding = '';
}
if (this.style.margin) {
prevStyle += 'margin:' + this.style.margin + ';';
this.style.margin = '';
}
html += '';
if (prevStyle !== '') {
html = '' + html + '';
}
img.hide();
img.after(html);
});
// fix css background pngs
$(context).find('*').each(function () {
var o = $(this);
if (o.css('filter') === '' || o.css('filter') === 'auto') {
var bg = o.css('backgroundImage');
if (bg.indexOf(settings.pngSuffix) > -1) {
bg = bg.split('url("')[1].split('")')[0];
o.css('backgroundImage', 'none');
o.get(0).runtimeStyle.filter = alpha + '(src=\'' + bg + '\', sizingMethod=\'image\')';
}
}
});
// fix input with png source
$(context).find('input[src$=' + settings.pngSuffix + ']').each(function () {
var o = $(this);
if (o.css('filter') === '' || o.css('filter') === 'auto') {
var bg = o.attr('src');
o.get(0).runtimeStyle.filter = alpha + '(src=\'' + bg + '\', sizingMethod=\'image\');';
o.attr('src', settings.blankGif);
}
});
}
},
preload: function () {
var i, img;
for (i = 0; i < arguments.length; i++) {
img = document.createElement('img');
img.src = arguments[i];
bui.images.cache.push(img);
}
}
},
// #endregion
// #region JSON
// ==================================
json: {
fetch: function (url, params, options) {
params = params || '';
options = options || {};
return $.ajax({
type: options.method || 'POST',
url: url,
cache: options.cache || true,
timeout: options.timeout || 30000,
dataType: 'json',
data: params,
beforeSend: function (xhr) {
if ($.isFunction(options.onBeforeSend)) { options.onBeforeSend(); }
},
complete: function (xhr, status) {
if ($.isFunction(options.onComplete)) { options.onComplete(status); }
},
success: function (data, status, xhr) {
if ($.isFunction(options.onSuccess)) { options.onSuccess(data, status); }
},
error: function (xhr, status, err) {
if ($.isFunction(options.onError)) {
options.onError(status, err);
} else if (bui.debug || options.debug) {
switch (status) {
case 'error':
if (err) {
alert('Error: ' + err.message);
} else {
alert('Error: Invalid response received from server');
}
break;
case 'timeout':
alert('Error: No response received from server');
break;
default:
alert('Error: ' + status + ' - ' + err.message);
break;
}
}
}
});
},
parse: function (o) {
// note: only supports strict JSON format
if (bui.support.hasJsonParse()) { return JSON.nativeParse(o); }
window.JSON.parse = null;
o = $.parseJSON(o);
window.JSON.parse = bui.json.parse;
return o;
},
safeString: function (s) {
var esc = /[\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff\"\\]/g;
var rpl = { '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"': '\\"', '\\': '\\\\' };
if (s.match(esc)) {
return '"' + s.replace(esc, function (a) {
var c = rpl[a];
if (bui.test.isType(c, 'string')) { return c; }
c = a.charCodeAt();
return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
}) + '"';
}
return '"' + s + '"';
},
stringify: function (o) {
if (bui.support.hasJsonStringify()) { return JSON.nativeStringify(o); }
var t = typeof o;
if (o === null) { return '{}'; }
if (t === 'boolean' || t === 'number') { return String(o); }
if (t === 'string') { return bui.json.safeString(o); }
if (t === 'object') {
if ($.isFunction(o.toJSON)) { return bui.json.stringify(o.toJSON()); }
if (o.constructor === Date) { return '"' + bui.datetime.format(o, 'isoUtcDateTime') + '"'; }
if (o.constructor === Array) {
var i, ret = [];
for (i = 0; i < o.length; i++) {
ret.push(bui.json.stringify(o[i]) || 'null');
}
return '[' + ret.join(',') + ']';
}
var val, pairs = [];
for (val in o) {
var s, v;
t = typeof val;
if (t === 'number') {
s = '"' + val + '"';
} else if (t === 'string') {
s = bui.json.safeString(val);
}
if (s !== undefined) {
v = bui.json.stringify(o[val]);
pairs.push(s + ':' + v);
}
}
return '{' + pairs.join(', ') + '}';
}
}
},
// #endregion
// #region Metadata
// ==================================
metadata: {
get: function (o, key, refresh) {
o = bui(o);
if (!key || key === '') { key = 'bui'; }
refresh = refresh || false;
var obj, data = o.data('metadata-' + key);
if (!refresh && data) { return data; }
if (o.hasAttr('data-' + key)) {
obj = bui.safeEval(o.attr('data-' + key));
} else if (o.hasAttr('data-bui')) {
obj = bui.safeEval(o.attr('data-bui'))[key];
}
if (!obj && o.hasAttr('class')) {
var m = /(\{.*\})/.exec(o.attr('class'));
if (m) {
data = m[1];
data = data.indexOf('{') < 0 ? '{' + data + '}' : data;
obj = bui.safeEval(data);
if (key !== 'bui') { obj = obj[key]; }
}
}
if (!refresh && obj) {
o.data('metadata-' + key, obj);
}
return obj;
}
},
// #endregion
// #region Numbers
// ==================================
number: {
addCommas: function (n) {
n = bui.string.replace(n, '[^\\d\\.]');
var x = n.split('.');
var x1 = x[0];
var x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
},
round: function (n, digits) {
n = Number(n);
if (!digits || digits <= 0) {
n = Math.round(n);
} else {
var m = Math.pow(10, digits);
n = (Math.round(n * m) / m).toFixed(digits);
}
return n;
}
},
// #endregion
// #region Printing
// ==================================
printing: {
print: function (close) {
window.print();
if (close) { window.close(); }
return false;
}
},
// #endregion
// #region QueryStrings
// ==================================
query: {
get: function (key) {
return bui.url.queryGet(key, window.location.href);
}
},
// #endregion
// #region Social
// ==================================
social: {
events: {
onShare: null // function (source, action)
},
init: function (context) {
bui.social.facebook.init(context);
bui.social.googlePlus.init(context);
bui.social.twitter.init(context);
},
facebook: {
init: function (context) {
$('a.bui-facebook-share', context).each(function () {
var lnk = $(this);
var url = lnk.attr('data-social-url') || window.location.href;
lnk.attr('href', 'http://www.facebook.com/share.php?u=' + bui.url.encode(url));
lnk.attr('target', '_blank');
if (!lnk.hasAttr('title') && lnk.text().trim() === '') {
lnk.attr('title', 'Share this page on Facebook');
}
}).unbind('click.social').bind('click.social', function (e) {
e.preventDefault();
var lnk = $(this);
bui.social.facebook.share(lnk.attr('data-share-url'), lnk.attr('data-share-title'));
if ($.isFunction(bui.social.events.onShare)) {
bui.social.events.onShare('Facebook', 'Share');
}
});
},
share: function (title, url) {
title = title || document.title;
url = url || window.location.href;
return bui.window.open('http://www.facebook.com/sharer.php?u=' + bui.url.encode(url) + '&t=' + bui.url.encode(title), 'bui-facebook-share', { width: 650, height: 400 }, true);
}
},
googlePlus: {
init: function (context) {
$('a.bui-googleplus-share', context).each(function () {
var lnk = $(this);
var url = lnk.attr('data-share-url') || window.location.href;
lnk.attr('href', 'https://plus.google.com/share?url=' + bui.url.encode(url));
lnk.attr('target', '_blank');
if (!lnk.hasAttr('title') && lnk.text().trim() === '') {
lnk.attr('title', 'Share this page on Google+');
}
}).unbind('click.social').bind('click.social', function (e) {
e.preventDefault();
var lnk = $(this);
bui.social.googlePlus.share(lnk.attr('data-share-url'));
if ($.isFunction(bui.social.events.onShare)) {
bui.social.events.onShare('GooglePlus', 'Share');
}
});
},
share: function (url) {
url = url || window.location.href;
return bui.window.open('https://plus.google.com/share?url=' + bui.url.encode(url), 'bui-googleplus-share', { width: 1000, height: 800 }, true);
}
},
twitter: {
init: function (context) {
$('a.bui-twitter-tweet', context).each(function () {
var lnk = $(this);
var url = bui.social.twitter.getTweetUrl(lnk.attr('data-tweet'), lnk.attr('data-share-title'), lnk.attr('data-share-url'));
lnk.attr('href', url);
lnk.attr('target', '_blank');
if (!lnk.hasAttr('title') && lnk.text().trim() === '') {
lnk.attr('title', 'Tweet this page on Twitter');
}
}).unbind('click.social').bind('click.social', function (e) {
e.preventDefault();
var lnk = $(this);
if (lnk.attr('data-tweet') !== '') {
bui.social.twitter.tweet(lnk.attr('data-tweet'));
} else {
bui.social.twitter.tweet(null, lnk.attr('data-share-title'), lnk.attr('data-share-url'));
}
});
if (window.twttr && twttr.events && twttr.events.bind) {
twttr.events.bind('tweet', function (e) {
if ($.isFunction(bui.social.events.onShare)) {
bui.social.events.onShare('Twitter', 'Tweet');
}
});
}
},
getTweetUrl: function (status, title, url) {
title = title || document.title;
url = url || window.location.href;
status = status || (title + ' ' + url);
return 'http://twitter.com/home?status=' + bui.url.encode(status);
},
tweet: function (status, title, url) {
return bui.window.open(bui.social.twitter.getTweetUrl(status, title, url), 'bui-twitter-tweet', { width: 900, height: 700, scrollbars: 1 }, true);
}
}
},
// #endregion
// #region Strings
// ==================================
string: {
init: function (context) {
var c = context;
$('.bui-cap', c).cap();
$('.bui-cap-strict', c).cap(true);
$('.bui-capall', c).capAll();
$('.bui-capall-strict', c).capAll(true);
$('.bui-lower', c).lower();
$('.bui-striphtml', c).stripHtml();
$('.bui-trim', c).trim();
$('.bui-upper', c).upper();
},
addFullStop: function (s) {
s = String(s);
if (!s) { return ''; }
s = bui.string.trim(s);
if (s !== '' && s.indexOf(' ') > -1 && !bui.test.match(s, '.*[\\.\\?\\!]$')) {
s += '.';
}
return s;
},
cap: function (s, strict) {
s = bui.string.trim(s);
if (!s) { return ''; }
if (!strict && s.length > 1 && s.indexOf(' ') > -1 && bui.test.match(bui.string.replace(s, '\\W'), '^[A-Z]+$', '')) {
// assume caps lock on, make the rest lowercase
strict = true;
}
var fc, rc;
fc = s.substring(0, 1).toUpperCase();
rc = strict ? s.substring(1).toLowerCase() : s.substring(1);
return fc + rc;
},
capAll: function (s, strict) {
s = bui.string.trim(s);
if (!s) { return ''; }
if (!strict && s.length > 1 && s.indexOf(' ') > -1 && bui.test.match(bui.string.replace(s, '\\W'), '^[A-Z]+$', '')) {
// assume caps lock on, make the rest lowercase
strict = true;
}
var i, t = '';
var words = s.split(/[ \'\-]/);
var exc = ['ab', 'al', 'ap', 'at', 'bin', 'bint', 'd', 'da', 'de', 'del', 'dela', 'den', 'di', 'dit', 'du', 'ibn', 'l', 'la', 'le', 'lo', 'och', 'om', 'st', 'te', 'van', 'von'];
for (i = 0; i < words.length; i++) {
if (bui.utils.inArray(exc, words[i].toLowerCase())) {
// special names to exclude, except when caps lock on
if (words[i].length > 1 && bui.test.match(words[i], '^[A-Z]+$', '')) {
words[i] = bui.string.cap(words[i], true);
}
} else {
if (words[i].length > 2 && bui.test.match(words[i], '[a-z][A-Z][a-z]', '')) {
// mixed case names like McDonald
words[i] = bui.string.cap(words[i], false);
} else {
words[i] = bui.string.cap(words[i], strict);
}
}
if (i > 0) {
// prepend original character separator
t += s.substring(t.length, t.length + 1);
}
t += words[i];
}
return t;
},
endsWith: function (s, suffix) {
s = String(s);
suffix = String(suffix);
if (!s || !suffix) { return false; }
return (s.substr(s.length - suffix.length) === suffix);
},
format: function (s) {
s = String(s);
if (!s) { return ''; }
var args = arguments, i, start = 1;
if (arguments.length > 1 && bui.test.isType(arguments[1], 'object')) {
// came from String.format prototype
args = arguments[1];
start = 0;
}
for (i = start; i < args.length; i++) {
s = s.replace('{' + (i - start) + '}', args[i]);
}
return s;
},
pad: function (s, len, prefix) {
s = String(s);
len = len || 2;
prefix = prefix || '0';
if (prefix.length > 1) { prefix = prefix.substr(0, 1); }
while (s.length < len) { s = prefix + s; }
return s;
},
padRight: function (s, len, suffix) {
s = String(s);
len = len || 2;
suffix = suffix || '0';
if (suffix.length > 1) { suffix = suffix.substr(0, 1); }
while (s.length < len) { s += suffix; }
return s;
},
replace: function (s, pattern, replaceWith, modifiers) {
s = String(s);
if (!s) { return ''; }
if (!pattern || pattern === '') { return s; }
if (!replaceWith) { replaceWith = ''; }
if (!modifiers) { modifiers = 'ig'; }
var re = new RegExp(pattern, modifiers);
return s.replace(re, replaceWith);
},
startsWith: function (s, prefix) {
s = String(s);
prefix = String(prefix);
if (!s || !prefix) { return false; }
return (s.substr(0, prefix.length) === prefix);
},
stripExtraWhitespace: function (s, stripLineBreaks) {
s = String(s);
if (!s) { return ''; }
if (stripLineBreaks) {
s = s.trim().replace(/\n+/g, ' ');
} else {
s = s.trim().replace(/\n{3,}/g, '\n\n');
}
return s.replace(/[ \t]{2,}/g, ' ');
},
stripHtml: function (s) {
s = String(s);
if (!s) { return ''; }
return $('