CC-5778 : Improving Builder Rendering Time

upgrading blockUI.
check-builder-feed always caused the table to be drawn twice on first load.
moved this check to builder.js since you can add to the now playing show on the calendar page as well.
This commit is contained in:
Naomi 2014-04-07 16:47:52 -04:00
parent 58dd09f136
commit 56e299d413
3 changed files with 682 additions and 660 deletions

View File

@ -7,90 +7,77 @@ var AIRTIME = (function(AIRTIME){
$sbContent,
$sbTable,
$toolbar,
$ul,
$lib,
cursors = [],
cursorIds = [],
showInstanceIds = [],
headerFooter = [];
internalTimestamp = -1,
internalShowInstances = [],
hasGottenFirstAjax = false;
if (AIRTIME.showbuilder === undefined) {
AIRTIME.showbuilder = {};
}
mod = AIRTIME.showbuilder;
function checkError(json) {
if (json.error !== undefined) {
alert(json.error);
}
}
mod.timeout = undefined;
mod.timestamp = -1;
mod.showInstances = [];
mod.resetTimestamp = function() {
function resetTimestamp() {
mod.timestamp = -1;
};
mod.setTimestamp = function(timestamp) {
mod.timestamp = timestamp;
};
mod.updateCalendarStatusIcon = function(json) {
//make sure we are only executing this code on the calendar view, not
//the Now Playing view.
if (window.location.pathname.toLowerCase().indexOf("schedule") < 0) {
return;
internalTimestamp = -1;
}
function setTimestamp(timestamp) {
var instance_id = json.schedule[0].instance;
var lastElem = json.schedule[json.schedule.length-1];
var $elem = $("#fc-show-instance-"+instance_id);
//if the show is linked, then replace $elem to reference all linked
//instances
if ($elem.data("show-linked") == "1") {
var show_id = $elem.data("show-id");
$elem = $('*[data-show-id="'+show_id+'"]');
internalTimestamp = timestamp;
}
$elem.find(".show-empty, .show-partial-filled").remove();
if (json.schedule[1].empty) {
$elem
.find(".fc-event-inner")
.append('<span id="'+instance_id+'" title="'+$.i18n._("Show is empty")+'" class="small-icon show-empty"></span>');
} else if (lastElem["fRuntime"][0] == "-") {
$elem
.find(".fc-event-inner")
.append('<span id="'+instance_id+'" title="'+$.i18n._("Show is partially filled")+'" class="small-icon show-partial-filled"></span>');
function getTimestamp() {
return internalTimestamp;
};
function setShowInstances(showInstances) {
internalShowInstances = showInstances;
};
function getShowInstances() {
return internalShowInstances;
};
function checkScheduleUpdates() {
var data = {},
oTable = $('#show_builder_table').dataTable(),
fn = oTable.fnSettings().fnServerData,
start = fn.start,
end = fn.end;
data["format"] = "json";
data["start"] = start;
data["end"] = end;
data["timestamp"] = getTimestamp();
data["instances"] = getShowInstances();
if (fn.hasOwnProperty("ops")) {
data["myShows"] = fn.ops.myShows;
data["showFilter"] = fn.ops.showFilter;
data["showInstanceFilter"] = fn.ops.showInstanceFilter;
}
};
mod.getTimestamp = function() {
if (mod.timestamp !== undefined) {
return mod.timestamp;
$.ajax( {
"dataType" : "json",
"type" : "GET",
"url" : baseUrl+"showbuilder/check-builder-feed",
"data" : data,
"success" : function(json) {
if (json.update === true) {
console.log("need to update builder table.");
oTable.fnDraw();
}
else {
return -1;
setTimeout(checkScheduleUpdates, 5000);
}
});
}
};
mod.setShowInstances = function(showInstances) {
mod.showInstances = showInstances;
};
mod.getShowInstances = function() {
return mod.showInstances;
};
mod.refresh = function(schedId) {
mod.resetTimestamp();
resetTimestamp();
if (schedId > 0) {
oSchedTable.fnDraw();
@ -257,47 +244,12 @@ var AIRTIME = (function(AIRTIME){
$lib.unblock();
$sbContent.unblock();
//Block UI changes the postion to relative to display the messages.
$lib.css("position", "static");
$sbContent.css("position", "static");
};
mod.fnItemCallback = function(json) {
checkError(json);
mod.fnRedrawSchedule = function(json) {
mod.getSelectedCursors();
oSchedTable.fnDraw();
mod.enableUI();
//$("#library_content").find("#library_display").dataTable().fnStandingRedraw();
};
mod.getSelectedCursors = function() {
cursorIds = [];
/* We need to keep record of which show the cursor belongs to
* in the case where more than one show is displayed in the show builder
* because header and footer rows have the same id
*/
showInstanceIds = [];
/* Keeps track if the row is a footer. We need to do this because
* header and footer rows have the save cursorIds and showInstanceId
* so both will be selected in the draw callback
*/
headerFooter = [];
cursors = $(".cursor-selected-row");
for (i = 0; i < cursors.length; i++) {
cursorIds.push(($(cursors.get(i)).attr("id")));
showInstanceIds.push(($(cursors.get(i)).attr("si_id")));
if ($(cursors.get(i)).hasClass("sb-footer")) {
headerFooter.push("f");
} else {
headerFooter.push("n");
}
}
};
mod.fnAdd = function(aMediaIds, aSchedIds) {
@ -305,7 +257,7 @@ var AIRTIME = (function(AIRTIME){
$.post(baseUrl+"showbuilder/schedule-add",
{"format": "json", "mediaIds": aMediaIds, "schedIds": aSchedIds},
mod.fnItemCallback
mod.fnRedrawSchedule
);
};
@ -315,7 +267,7 @@ var AIRTIME = (function(AIRTIME){
$.post(baseUrl+"showbuilder/schedule-move",
{"format": "json", "selectedItem": aSelect, "afterItem": aAfter},
mod.fnItemCallback
mod.fnRedrawSchedule
);
};
@ -325,9 +277,10 @@ var AIRTIME = (function(AIRTIME){
if (confirm($.i18n._("Delete selected item(s)?"))) {
$.post( baseUrl+"showbuilder/schedule-remove",
{"items": aItems, "format": "json"},
mod.fnItemCallback
mod.fnRedrawSchedule
);
}else{
}
else {
mod.enableUI();
}
};
@ -349,8 +302,10 @@ var AIRTIME = (function(AIRTIME){
mod.fnServerData = function fnBuilderServerData( sSource, aoData, fnCallback ) {
aoData.push( { name: "timestamp", value: mod.getTimestamp()} );
aoData.push( { name: "instances", value: mod.getShowInstances()} );
console.log("getting builder feed.");
aoData.push( { name: "timestamp", value: getTimestamp()} );
aoData.push( { name: "instances", value: getShowInstances()} );
aoData.push( { name: "format", value: "json"} );
if (mod.fnServerData.hasOwnProperty("start")) {
@ -371,11 +326,23 @@ var AIRTIME = (function(AIRTIME){
"url": sSource,
"data": aoData,
"success": function(json) {
mod.updateCalendarStatusIcon(json)
mod.setTimestamp(json.timestamp);
mod.setShowInstances(json.instances);
mod.getSelectedCursors();
if (json.error !== undefined) {
alert(json.error);
}
else {
fnCallback(json);
setTimestamp(json.timestamp);
setShowInstances(json.instances);
if (!hasGottenFirstAjax) {
hasGottenFirstAjax = true;
//start this timeout
//check if the timeline view needs updating.
checkScheduleUpdates();
}
}
}
});
};
@ -389,13 +356,12 @@ var AIRTIME = (function(AIRTIME){
var currentTop = current.offset().top;
$scroll.scrollTop(currentTop - scrollingTop + scrolled);
}
};
mod.builderDataTable = function() {
$sbContent = $('#show_builder');
$lib = $("#library_content"),
$sbTable = $sbContent.find('table');
var isInitialized = false;
oSchedTable = $sbTable.dataTable( {
"aoColumns": [
@ -482,13 +448,18 @@ var AIRTIME = (function(AIRTIME){
$image,
$div,
headerIcon,
$wrapper;
$wrapper,
$marker;
//http://stackoverflow.com/a/6119684
$wrapper = $("<div/>", {
"class": "innerWrapper"
});
$marker = $("<div/>", {
"class": "marker"
});
$node = $(nRow.children[0]);
$node.html($wrapper);
@ -571,7 +542,9 @@ var AIRTIME = (function(AIRTIME){
//putting the cursor on the screen
if (aData.allowed && $lib.length > 0 && $lib.filter(":visible").length > 0) {
$wrapper.append('<div class="marker"></div>');
//using this input just for cursor positioning purposes.
$wrapper.append('<input type="checkbox" style="visibility:hidden" disabled="disabled"></input>');
$wrapper.append($marker);
}
sSeparatorHTML = '<span>'+$.i18n._("Show Empty")+'</span>';
@ -621,11 +594,11 @@ var AIRTIME = (function(AIRTIME){
}
if (aData.allowed === true && aData.scheduled >= 1) {
$wrapper.html('<input type="checkbox" name="'+aData.id+'"></input>');
$wrapper.append('<input type="checkbox" name="'+aData.id+'"></input>');
//putting the cursor on the screen
if ($lib.length > 0 && $lib.filter(":visible").length > 0) {
$wrapper.append('<div class="marker"></div>');
$wrapper.append($marker);
}
}
}
@ -698,59 +671,25 @@ var AIRTIME = (function(AIRTIME){
$("#draggingContainer").remove();
},
"fnDrawCallback": function fnBuilderDrawCallback(oSettings, json) {
var isInitialized = false;
//var timer1 = new Date().getTime();
if (!isInitialized) {
//when coming to 'Now Playing' page we want the page
//to jump to the current track
if ($(this).find("."+NOW_PLAYING_CLASS).length > 0) {
mod.jumpToCurrentTrack();
}
}
isInitialized = true;
var aData,
elements,
i, length, temp,
$cursorRows,
$table = $(this);
if ($(this).find("."+NOW_PLAYING_CLASS).length > 0) {
mod.jumpToCurrentTrack();
}
clearTimeout(mod.timeout);
//only create the cursor arrows if the library is on the page.
if ($lib.length > 0 && $lib.filter(":visible").length > 0) {
//$cursorRows = $sbTable.find("tbody tr.sb-future.sb-allowed:not(.sb-header, .sb-empty)");
$cursorRows = $sbTable.find("div.marker").parents("tr");
//re-highlight selected cursors before draw took place
/*
for (i = 0; i < cursorIds.length; i++) {
if (headerFooter[i] == "f") {
$tr = $table.find("tbody tr.sb-footer[id="+cursorIds[i]+"][si_id="+showInstanceIds[i]+"]");
} else {
$tr = $table.find("tr[id="+cursorIds[i]+"][si_id="+showInstanceIds[i]+"]");
}
// If the currently playing track's cursor is selected,
//and that track is deleted, the cursor position becomes
//unavailble. We have to check the position is available
// before re-highlighting it.
//
if ($tr.find(".sb-checkbox").children().hasClass("innerWrapper")) {
mod.selectCursor($tr);
// If the selected cursor is the footer row we need to
//explicitly select it because that row does not have
// innerWrapper class
//
} else if ($tr.hasClass("sb-footer")) {
mod.selectCursor($tr);
}
}
*/
//if there is only 1 cursor on the page highlight it by default.
if ($cursorRows.length === 1) {
$cursorRows.addClass("cursor-selected-row");
@ -1027,8 +966,8 @@ var AIRTIME = (function(AIRTIME){
$toolbar.append($menu);
$menu = undefined;
$('#timeline-sa').click(function(){mod.selectAll();});
$('#timeline-sn').click(function(){mod.selectNone();});
$('#timeline-sa').click(mod.selectAll);
$('#timeline-sn').click(mod.selectNone);
//cancel current show
$toolbar.find('.sb-cancel').click(function() {
@ -1167,13 +1106,13 @@ var AIRTIME = (function(AIRTIME){
}
//only show the cursor selecting options if the library is visible on the page.
if ($tr.next().find('.marker').length === 0) {
if ($tr.find('.marker').length === 0) {
delete oItems.selCurs;
delete oItems.delCurs;
}
//check to include either select or remove cursor.
else {
if ($tr.next().hasClass(cursorClass)) {
if ($tr.hasClass(cursorClass)) {
delete oItems.selCurs;
}
else {

View File

@ -130,6 +130,7 @@ AIRTIME = (function(AIRTIME) {
AIRTIME.showbuilder.fnServerData.start = oRange.start;
AIRTIME.showbuilder.fnServerData.end = oRange.end;
console.log("calling builder datatable");
AIRTIME.showbuilder.builderDataTable();
$libWrapper = $lib.find(".ui-tabs-nav");
@ -218,42 +219,6 @@ AIRTIME = (function(AIRTIME) {
showSearchSubmit();
});
function checkScheduleUpdates() {
var data = {},
oTable = $('#show_builder_table').dataTable(),
fn = oTable.fnSettings().fnServerData,
start = fn.start,
end = fn.end;
data["format"] = "json";
data["start"] = start;
data["end"] = end;
data["timestamp"] = AIRTIME.showbuilder.getTimestamp();
data["instances"] = AIRTIME.showbuilder.getShowInstances();
if (fn.hasOwnProperty("ops")) {
data["myShows"] = fn.ops.myShows;
data["showFilter"] = fn.ops.showFilter;
data["showInstanceFilter"] = fn.ops.showInstanceFilter;
}
$.ajax( {
"dataType" : "json",
"type" : "GET",
"url" : baseUrl+"showbuilder/check-builder-feed",
"data" : data,
"success" : function(json) {
if (json.update === true) {
oTable.fnDraw();
}
setTimeout(checkScheduleUpdates, 5000);
}
});
}
//check if the timeline view needs updating.
checkScheduleUpdates();
};
return AIRTIME;

View File

@ -1,10 +1,10 @@
/*!
* jQuery blockUI plugin
* Version 2.39 (23-MAY-2011)
* @requires jQuery v1.2.3 or later
* Version 2.66.0-2013.10.09
* Requires jQuery v1.7 or later
*
* Examples at: http://malsup.com/jquery/block/
* Copyright (c) 2007-2010 M. Alsup
* Copyright (c) 2007-2013 M. Alsup
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
@ -12,24 +12,21 @@
* Thanks to Amir-Hossein Sobhi for some excellent contributions!
*/
;(function($) {
/*
if (/1\.(0|1|2)\.(0|1|2)/.test($.fn.jquery) || /^1.1/.test($.fn.jquery)) {
alert('blockUI requires jQuery v1.2.3 or later! You are using v' + $.fn.jquery);
return;
}
*/
;(function() {
/*jshint eqeqeq:false curly:false latedef:false */
"use strict";
function setup($) {
$.fn._fadeIn = $.fn.fadeIn;
var noOp = function() {};
var noOp = $.noop || function() {};
// this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle
// retarded userAgent strings on Vista)
// confusing userAgent strings on Vista)
var msie = /MSIE/.test(navigator.userAgent);
var ie6 = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent);
var mode = document.documentMode || 0;
var setExpr = $.browser.msie && (($.browser.version < 8 && !mode) || mode < 8);
var ie6 = $.browser.msie && /MSIE 6.0/.test(navigator.userAgent) && !mode;
var setExpr = $.isFunction( document.createElement('div').style.setExpression );
// global $ methods for blocking/unblocking the entire page
$.blockUI = function(opts) { install(window, opts); };
@ -40,34 +37,77 @@ $.growlUI = function(title, message, timeout, onClose) {
var $m = $('<div class="growlUI"></div>');
if (title) $m.append('<h1>'+title+'</h1>');
if (message) $m.append('<h2>'+message+'</h2>');
if (timeout == undefined) timeout = 3000;
if (timeout === undefined) timeout = 3000;
// Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications
var callBlock = function(opts) {
opts = opts || {};
$.blockUI({
message: $m, fadeIn: 700, fadeOut: 1000, centerY: false,
timeout: timeout, showOverlay: false,
message: $m,
fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700,
fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000,
timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout,
centerY: false,
showOverlay: false,
onUnblock: onClose,
css: $.blockUI.defaults.growlCSS
});
};
callBlock();
var nonmousedOpacity = $m.css('opacity');
$m.mouseover(function() {
callBlock({
fadeIn: 0,
timeout: 30000
});
var displayBlock = $('.blockMsg');
displayBlock.stop(); // cancel fadeout if it has started
displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency
}).mouseout(function() {
$('.blockMsg').fadeOut(1000);
});
// End konapun additions
};
// plugin method for blocking element content
$.fn.block = function(opts) {
return this.unblock({ fadeOut: 0 }).each(function() {
if ($.css(this,'position') == 'static')
if ( this[0] === window ) {
$.blockUI( opts );
return this;
}
var fullOpts = $.extend({}, $.blockUI.defaults, opts || {});
this.each(function() {
var $el = $(this);
if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked'))
return;
$el.unblock({ fadeOut: 0 });
});
return this.each(function() {
if ($.css(this,'position') == 'static') {
this.style.position = 'relative';
if ($.browser.msie)
this.style.zoom = 1; // force 'hasLayout'
$(this).data('blockUI.static', true);
}
this.style.zoom = 1; // force 'hasLayout' in ie
install(this, opts);
});
};
// plugin method for unblocking element content
$.fn.unblock = function(opts) {
if ( this[0] === window ) {
$.unblockUI( opts );
return this;
}
return this.each(function() {
remove(this, opts);
});
};
$.blockUI.version = 2.39; // 2nd generation blocking at no extra cost!
$.blockUI.version = 2.66; // 2nd generation blocking at no extra cost!
// override these in your code to change the default behavior and style
$.blockUI.defaults = {
@ -109,6 +149,10 @@ $.blockUI.defaults = {
cursor: 'wait'
},
// style to replace wait cursor before unblocking to correct issue
// of lingering wait cursor
cursorReset: 'default',
// styles applied when using $.growlUI
growlCSS: {
width: '350px',
@ -128,6 +172,7 @@ $.blockUI.defaults = {
// IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w
// (hat tip to Jorge H. N. de Vasconcelos)
/*jshint scripturl:true */
iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank',
// force usage of iframe in non-IE browsers (handy for blocking applets)
@ -167,8 +212,12 @@ $.blockUI.defaults = {
// page blocking
focusInput: true,
// elements that can receive focus
focusableElements: ':input:enabled:visible',
// suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)
applyPlatformOpacityRules: true,
// no longer needed in 2012
// applyPlatformOpacityRules: true,
// callback method invoked when fadeIn has completed and blocking message is visible
onBlock: null,
@ -179,11 +228,18 @@ $.blockUI.defaults = {
// onUnblock(element, options)
onUnblock: null,
// callback method invoked when the overlay area is clicked.
// setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used.
onOverlayClick: null,
// don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493
quirksmodeOffsetHack: 4,
// class name of the message block
blockMsgClass: 'blockMsg'
blockMsgClass: 'blockMsg',
// if it is already blocked, then ignore it (don't unblock and reblock)
ignoreIfBlocked: false
};
// private data and functions follow...
@ -192,12 +248,20 @@ var pageBlock = null;
var pageBlockEls = [];
function install(el, opts) {
var css, themedCSS;
var full = (el == window);
var msg = opts && opts.message !== undefined ? opts.message : undefined;
var msg = (opts && opts.message !== undefined ? opts.message : undefined);
opts = $.extend({}, $.blockUI.defaults, opts || {});
if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked'))
return;
opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});
var css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
var themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {});
css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
if (opts.onOverlayClick)
opts.overlayCSS.cursor = 'pointer';
themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {});
msg = msg === undefined ? opts.message : msg;
// remove the current block (if there is one)
@ -226,27 +290,32 @@ function install(el, opts) {
// layer1 is the iframe layer which is used to supress bleed through of underlying content
// layer2 is the overlay layer which has opacity and a wait cursor (by default)
// layer3 is the message content that is displayed while blocking
var lyr1, lyr2, lyr3, s;
if (msie || opts.forceIframe)
lyr1 = $('<iframe class="blockUI" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="'+opts.iframeSrc+'"></iframe>');
else
lyr1 = $('<div class="blockUI" style="display:none"></div>');
var lyr1 = ($.browser.msie || opts.forceIframe)
? $('<iframe class="blockUI" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="'+opts.iframeSrc+'"></iframe>')
: $('<div class="blockUI" style="display:none"></div>');
if (opts.theme)
lyr2 = $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+ (z++) +';display:none"></div>');
else
lyr2 = $('<div class="blockUI blockOverlay" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>');
var lyr2 = opts.theme
? $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+ (z++) +';display:none"></div>')
: $('<div class="blockUI blockOverlay" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>');
var lyr3, s;
if (opts.theme && full) {
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:fixed">' +
'<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>' +
'<div class="ui-widget-content ui-dialog-content"></div>' +
'</div>';
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:fixed">';
if ( opts.title ) {
s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>';
}
s += '<div class="ui-widget-content ui-dialog-content"></div>';
s += '</div>';
}
else if (opts.theme) {
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:absolute">' +
'<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>' +
'<div class="ui-widget-content ui-dialog-content"></div>' +
'</div>';
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:absolute">';
if ( opts.title ) {
s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>';
}
s += '<div class="ui-widget-content ui-dialog-content"></div>';
s += '</div>';
}
else if (full) {
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage" style="z-index:'+(z+10)+';display:none;position:fixed"></div>';
@ -267,12 +336,12 @@ function install(el, opts) {
}
// style the overlay
if (!opts.theme && (!opts.applyPlatformOpacityRules || !($.browser.mozilla && /Linux/.test(navigator.platform))))
if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/)
lyr2.css(opts.overlayCSS);
lyr2.css('position', full ? 'fixed' : 'absolute');
// make iframe layer transparent in IE
if ($.browser.msie || opts.forceIframe)
if (msie || opts.forceIframe)
lyr1.css('opacity',0.0);
//$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
@ -289,28 +358,32 @@ function install(el, opts) {
}
// ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)
var expr = setExpr && (!$.boxModel || $('object,embed', full ? null : el).length > 0);
var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0);
if (ie6 || expr) {
// give body 100% height
if (full && opts.allowBodyStretch && $.boxModel)
if (full && opts.allowBodyStretch && $.support.boxModel)
$('html,body').css('height','100%');
// fix ie6 issue when blocked element has a border width
if ((ie6 || !$.boxModel) && !full) {
if ((ie6 || !$.support.boxModel) && !full) {
var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth');
var fixT = t ? '(0 - '+t+')' : 0;
var fixL = l ? '(0 - '+l+')' : 0;
}
// simulate fixed position
$.each([lyr1,lyr2,lyr3], function(i,o) {
$.each(layers, function(i,o) {
var s = o[0].style;
s.position = 'absolute';
if (i < 2) {
full ? s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"')
: s.setExpression('height','this.parentNode.offsetHeight + "px"');
full ? s.setExpression('width','jQuery.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"')
: s.setExpression('width','this.parentNode.offsetWidth + "px"');
if (full)
s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"');
else
s.setExpression('height','this.parentNode.offsetHeight + "px"');
if (full)
s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"');
else
s.setExpression('width','this.parentNode.offsetWidth + "px"');
if (fixL) s.setExpression('left', fixL);
if (fixT) s.setExpression('top', fixT);
}
@ -319,7 +392,7 @@ function install(el, opts) {
s.marginTop = 0;
}
else if (!opts.centerY && full) {
var top = (opts.css && opts.css.top) ? parseInt(opts.css.top) : 0;
var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0;
var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"';
s.setExpression('top',expression);
}
@ -336,7 +409,7 @@ function install(el, opts) {
$(msg).show();
}
if (($.browser.msie || opts.forceIframe) && opts.showOverlay)
if ((msie || opts.forceIframe) && opts.showOverlay)
lyr1.show(); // opacity is zero
if (opts.fadeIn) {
var cb = opts.onBlock ? opts.onBlock : noOp;
@ -361,7 +434,7 @@ function install(el, opts) {
if (full) {
pageBlock = lyr3[0];
pageBlockEls = $(':input:enabled:visible',pageBlock);
pageBlockEls = $(opts.focusableElements,pageBlock);
if (opts.focusInput)
setTimeout(focus, 20);
}
@ -371,14 +444,18 @@ function install(el, opts) {
if (opts.timeout) {
// auto-unblock
var to = setTimeout(function() {
full ? $.unblockUI(opts) : $(el).unblock(opts);
if (full)
$.unblockUI(opts);
else
$(el).unblock(opts);
}, opts.timeout);
$(el).data('blockUI.timeout', to);
}
};
}
// remove the block
function remove(el, opts) {
var count;
var full = (el == window);
var $el = $(el);
var data = $el.data('blockUI.history');
@ -399,21 +476,36 @@ function remove(el, opts) {
if (full) // crazy selector to handle odd field errors in ie6/7
els = $('body').children().filter('.blockUI').add('body > .blockUI');
else
els = $('.blockUI', el);
els = $el.find('>.blockUI');
// fix cursor issue
if ( opts.cursorReset ) {
if ( els.length > 1 )
els[1].style.cursor = opts.cursorReset;
if ( els.length > 2 )
els[2].style.cursor = opts.cursorReset;
}
if (full)
pageBlock = pageBlockEls = null;
if (opts.fadeOut) {
els.fadeOut(opts.fadeOut);
setTimeout(function() { reset(els,data,opts,el); }, opts.fadeOut);
count = els.length;
els.stop().fadeOut(opts.fadeOut, function() {
if ( --count === 0)
reset(els,data,opts,el);
});
}
else
reset(els, data, opts, el);
};
}
// move blocking element back into the DOM where it started
function reset(els,data,opts,el) {
var $el = $(el);
if ( $el.data('blockUI.isBlocked') )
return;
els.each(function(i,o) {
// remove via DOM calls so we don't lose event handlers
if (this.parentNode)
@ -425,12 +517,21 @@ function reset(els,data,opts,el) {
data.el.style.position = data.position;
if (data.parent)
data.parent.appendChild(data.el);
$(el).removeData('blockUI.history');
$el.removeData('blockUI.history');
}
if ($el.data('blockUI.static')) {
$el.css('position', 'static'); // #22
}
if (typeof opts.onUnblock == 'function')
opts.onUnblock(el,opts);
};
// fix issue in Safari 6 where block artifacts remain until reflow
var body = $(document.body), w = body.width(), cssW = body[0].style.width;
body.width(w-1).width(w);
body[0].style.width = cssW;
}
// bind/unbind the handler
function bind(b, el, opts) {
@ -439,44 +540,51 @@ function bind(b, el, opts) {
// don't bother unbinding if there is nothing to unbind
if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked')))
return;
if (!full)
$el.data('blockUI.isBlocked', b);
// don't bind events when overlay is not in use or if bindEvents is false
if (!opts.bindEvents || (b && !opts.showOverlay))
if (!full || !opts.bindEvents || (b && !opts.showOverlay))
return;
// bind anchors and inputs for mouse and key events
var events = 'mousedown mouseup keydown keypress';
b ? $(document).bind(events, opts, handler) : $(document).unbind(events, handler);
var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove';
if (b)
$(document).bind(events, opts, handler);
else
$(document).unbind(events, handler);
// former impl...
// var $e = $('a,:input');
// b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
};
}
// event handler to suppress keyboard/mouse events when blocking
function handler(e) {
// allow tab navigation (conditionally)
if (e.keyCode && e.keyCode == 9) {
if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) {
if (pageBlock && e.data.constrainTabKey) {
var els = pageBlockEls;
var fwd = !e.shiftKey && e.target === els[els.length-1];
var back = e.shiftKey && e.target === els[0];
if (fwd || back) {
setTimeout(function(){focus(back)},10);
setTimeout(function(){focus(back);},10);
return false;
}
}
}
var opts = e.data;
var target = $(e.target);
if (target.hasClass('blockOverlay') && opts.onOverlayClick)
opts.onOverlayClick(e);
// allow events within the message content
if ($(e.target).parents('div.' + opts.blockMsgClass).length > 0)
if (target.parents('div.' + opts.blockMsgClass).length > 0)
return true;
// allow events for content that is not being blocked
return $(e.target).parents().children().filter('div.blockUI').length == 0;
};
return target.parents().children().filter('div.blockUI').length === 0;
}
function focus(back) {
if (!pageBlockEls)
@ -484,7 +592,7 @@ function focus(back) {
var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0];
if (e)
e.focus();
};
}
function center(el, x, y) {
var p = el.parentNode, s = el.style;
@ -492,10 +600,20 @@ function center(el, x, y) {
var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth');
if (x) s.left = l > 0 ? (l+'px') : '0';
if (y) s.top = t > 0 ? (t+'px') : '0';
};
}
function sz(el, p) {
return parseInt($.css(el,p))||0;
};
return parseInt($.css(el,p),10)||0;
}
})(jQuery);
}
/*global define:true */
if (typeof define === 'function' && define.amd && define.amd.jQuery) {
define(['jquery'], setup);
} else {
setup(jQuery);
}
})();