/***************** jQuery Tools overlay helpers. Copyright © 2010, The Plone Foundation Licensed under the GPL, see LICENSE.txt for details. *****************/ /*jslint browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, newcap: true, immed: true, regexp: false, white:true */ /*global jQuery, ajax_noresponse_message, window */ // Name space object for pipbox var pb = {spinner: {}, overlay_counter: 1}; jQuery.tools.overlay.conf.oneInstance = false; jQuery(function ($) { pb.spinner.show = function () { $('body').css('cursor', 'wait'); }; pb.spinner.hide = function () { $('body').css('cursor', ''); }; /****** $.fn.prepOverlay jQuery plugin to inject overlay target into DOM and annotate it with the data we'll need in order to display it. ******/ $.fn.prepOverlay = function (pba) { return this.each(function () { var o, pbo, config, onBeforeLoad, onLoad, src, parts; o = $(this); // copy options so that it's not just a reference // to the parameter. pbo = $.extend(true, {}, pba); // set overlay configuration config = pbo.config || {}; // set onBeforeLoad handler onBeforeLoad = pb[pbo.subtype]; if (onBeforeLoad) { config.onBeforeLoad = onBeforeLoad; } onLoad = config.onLoad; config.onLoad = function () { if (onLoad) { onLoad.apply(this, arguments); } pb.fi_focus(this.getOverlay()); }; // be promiscuous, pick up the url from // href, src or action attributes src = o.attr('href') || o.attr('src') || o.attr('action'); // translate url with config specifications if (pbo.urlmatch) { src = src.replace(new RegExp(pbo.urlmatch), pbo.urlreplace); } if (pbo.subtype === 'inline') { // we're going to let tools' overlay do all the real // work. Just get the markers in place. src = src.replace(/^.+#/, '#'); $("[id='" + src.replace('#', '') + "']") .addClass('overlay'); o.removeAttr('href').attr('rel', src); // use overlay on the source (clickable) element o.overlay(); } else { // save various bits of information from the pbo options, // and enable the overlay. // this is not inline, so in one fashion or another // we'll be loading it via the beforeLoad callback. // create a unique id for a target element pbo.nt = 'pb_' + pb.overlay_counter; pb.overlay_counter += 1; pbo.selector = pbo.filter || pbo.selector; if (!pbo.selector) { // see if one's been supplied in the src parts = src.split(' '); src = parts.shift(); pbo.selector = parts.join(' '); } pbo.src = src; pbo.config = config; // remove any existing overlay and overlay handler pb.remove_overlay(o); // save options on trigger element o.data('pbo', pbo); // mark the source with a rel attribute so we can find // the overlay, and a special class for styling o.attr('rel', '#' + pbo.nt); o.addClass('link-overlay'); // for some subtypes, we're setting click handlers // and attaching overlay to the target element. That's // so we'll know the dimensions early. // Others, like iframe, just use overlay. switch (pbo.subtype) { case 'image': o.click(pb.image_click); break; case 'ajax': o.click(pb.ajax_click); break; case 'iframe': pb.create_content_div(pbo); o.overlay(config); break; default: throw "Unsupported overlay type"; } // in case the click source wasn't // already a link. o.css('cursor', 'pointer'); } }); }; /****** pb.remove_overlay Remove the overlay and handler associated with a jquery wrapped trigger object ******/ pb.remove_overlay = function (o) { var old_data = o.data('pbo'); if (old_data) { switch (old_data.subtype) { case 'image': o.unbind('click', pb.image_click); break; case 'ajax': o.unbind('click', pb.ajax_click); break; default: // it's probably the jqt overlay click handler, // but we don't know the handler and are forced // to do a generic unbind of click handlers. o.unbind('click'); } if (old_data.nt) { $('#' + old_data.nt).remove(); } } }; /****** pb.create_content_div create a div to act as an overlay; append it to the body; return it ******/ pb.create_content_div = function (pbo) { var content; content = $( '
' ); content.data('pbo', pbo); // if we've a width specified, set it on the overlay div if (pbo.width) { content.width(pbo.width); } // add the target element at the end of the body. content.appendTo($("body")); return content; }; /****** pb.image_click click handler for ajax sources. ******/ pb.image_click = function (event) { var ethis, content, api, img, el, pbo; ethis = $(this); pbo = ethis.data('pbo'); // find target container content = $(ethis.attr('rel')); if (!content.length) { content = pb.create_content_div(pbo); content.overlay(pbo.config); } api = content.overlay(); // is the image loaded yet? if (content.find('img').length === 0) { // load the image. if (pbo.src) { pb.spinner.show(); // create the image and stuff it // into our target img = new Image(); img.src = pbo.src; el = $(img); content.append(el.addClass('pb-image')); // Now, we'll cause the overlay to // load when the image is loaded. el.load(function () { pb.spinner.hide(); api.load(); }); } } else { api.load(); } return false; }; /****** pb.fi_focus First-input focus inside $ selection. ******/ pb.fi_focus = function (jqo) { if (! jqo.find("form div.error :input:first").focus().length) { jqo.find("form :input:visible:first").focus(); } }; /****** pb.ajax_error_recover jQuery's ajax load function does not load error responses. This routine returns the cooked error response. ******/ pb.ajax_error_recover = function (responseText, selector) { var tcontent = $('') .append(responseText.replace(/