Mercurial > defr > drupal > popups
diff popups.js @ 1:4215c43e74eb
Popups: Mise à jour en version alpha6
author | Franck Deroche <franck@defr.org> |
---|---|
date | Fri, 31 Dec 2010 13:44:00 +0100 |
parents | 76f9b43738f2 |
children | 09e998f65556 |
line wrap: on
line diff
--- a/popups.js Fri Dec 31 13:41:08 2010 +0100 +++ b/popups.js Fri Dec 31 13:44:00 2010 +0100 @@ -1,4 +1,4 @@ -// $Id: popups.js,v 1.9.8.12 2009/03/21 00:57:15 starbow Exp $ +// $Id: popups.js,v 1.9.8.19 2010/12/10 02:51:17 drewish Exp $ /** * Popup Modal Dialog API @@ -27,7 +27,7 @@ Drupal.behaviors.popups = function(context) { Popups.saveSettings(); - + var $body = $('body'); if(!$body.hasClass('popups-processed')) { $body.addClass('popups-processed'); @@ -37,19 +37,34 @@ $popit.remove(); Popups.message($popit.html()); } + + // Make note of all the CSS and JS on the page so when we load a popup we + // don't try to add them a second time. + $('link[rel="stylesheet"][href]').each(function(i, v) { + Popups.originalCSS[$(this).attr('href').replace(/^(\/.+)\?\w$/, '$1')] = 1; + }); + if (Drupal.settings.popups && Drupal.settings.popups.originalCSS) { + $.extend(Popups.originalCSS, Drupal.settings.popups.originalCSS); + } + $('script[src]').each(function(i, v) { + Popups.originalJS[$(this).attr('src').replace(/^(\/.+)\?\w$/, '$1')] = 1; + }); + if (Drupal.settings.popups && Drupal.settings.popups.originalJS) { + $.extend(Popups.originalJS, Drupal.settings.popups.originalJS); + } } - + // Add the popups-link-in-dialog behavior to links defined in Drupal.settings.popups.links array. // Get these from current Drupal.settings, not Popups.originalSettings, as each page has it's own hooks. if (Drupal.settings.popups && Drupal.settings.popups.links) { - jQuery.each(Drupal.settings.popups.links, function (link, options) { + jQuery.each(Drupal.settings.popups.links, function (link, options) { Popups.attach(context, link, Popups.options(options)); }); } - - Popups.attach(context, '.popups', Popups.options({updateMethod: 'none'})); + + Popups.attach(context, '.popups', Popups.options({updateMethod: 'none'})); Popups.attach(context, '.popups-form', Popups.options({updateMethod: 'ajax'})); // ajax reload. - Popups.attach(context, '.popups-form-reload', Popups.options({updateMethod: 'reload'})); // whole page reload. + Popups.attach(context, '.popups-form-reload', Popups.options({updateMethod: 'reload'})); // whole page reload. Popups.attach(context, '.popups-form-noupdate', Popups.options({updateMethod: 'none'})); // no reload at all. }; @@ -67,9 +82,11 @@ /** * Static variables in the Popups namespace. */ -Popups.popupStack = []; -Popups.addedCSS = []; -Popups.addedJS = []; +Popups.popupStack = []; +Popups.addedCSS = {}; +Popups.addedJS = {}; +Popups.originalCSS = {}; +Popups.originalJS = {}; Popups.originalSettings = null; // The initial popup options of the page. /** * Each popup object gets it's own set of options. @@ -79,14 +96,15 @@ doneTest: null, // null, *path*, *regexp*. how do we know when a multiform flow is done? updateMethod: 'ajax', // none, ajax, reload, *callback* updateSource: 'initial', // initial, final. Only used if updateMethod != none. - href: null, + onUpdate: '', // Only used if updateMethod == callback. + href: null, width: null, // Override the width specified in the css. targetSelectors: null, // Hash of jQuery selectors that define the content to be swapped out. titleSelectors: null, // Array of jQuery selectors to place the new page title. reloadOnError: false, // Force the entire page to reload if the popup href is unaccessable. - noMessage: false, // Don't show drupal_set_message messages. - skipDirtyCheck: false, // If true, this popup will not check for edits on the originating page. - hijackDestination: true // Use the destiination param to force a form submit to return to the originating page. + noMessage: false, // Don't show drupal_set_message messages. + skipDirtyCheck: false, // If true, this popup will not check for edits on the originating page. + hijackDestination: true // Use the destiination param to force a form submit to return to the originating page. }; // *************************************************************************** @@ -98,7 +116,7 @@ */ Popups.Popup = function() { this.id = 'popups-' + Popups.nextCounter(); - + // These properties are needed if the popup contains a form that will be ajax submitted. this.parent = null; // The popup that spawned this one. If parent is null, this popup was spawned by the original page. this.path = null; // If popup is showing content from a url, this is that path. @@ -126,7 +144,7 @@ /** * Create the jQuery wrapped html at the heart of the popup object. - * + * * @param title * String * @param body @@ -141,7 +159,7 @@ } /** - * Hide the popup by pushing it off to the side. + * Hide the popup by pushing it off to the side. * Just making it display:none causes flash in FF2. */ Popups.Popup.prototype.hide = function() { @@ -156,9 +174,9 @@ return Popups.open(this, title, body, buttons, width); }; -Popups.Popup.prototype.removePopup = function() { +Popups.Popup.prototype.removePopup = function() { Popups.removePopup(this); -}; +}; /** * Remove everything. @@ -183,7 +201,7 @@ /** * Return a selector that will find target content on the layer that spawned this popup. - * This is needed for the popup to do ajax updates. + * This is needed for the popup to do ajax updates. */ Popups.Popup.prototype.targetLayerSelector = function() { if (this.parent === null) { @@ -191,38 +209,35 @@ } else { return '#' + this.parent.id; // Select content in the parent popup. - } + } }; /** * Determine if we are at an end point of a form flow, or just moving from one popups to another. - * + * * @param path * The path of the page that the form flow has moved to. - * This path is relative to the base_path. + * This path is relative to the base_path. * Ex: node/add/story, not http://localhost/drupal6/node/add/story or drupa6/node/add/story. * @return bool - */ + */ Popups.Popup.prototype.isDone = function(path) { -// console.log("Doing isDone for popup: " + this.id + ", now at " + path ); var done; if (this.options.doneTest) { // Test if we are at the path specified by doneTest. - done = (path === this.options.doneTest || path.match(this.options.doneTest)); + done = (path === this.options.doneTest || path.match(this.options.doneTest)); } - else { + else { if (this.parent) { // Test if we are back to the parent popup's path. - done = (path === this.parent.path); -// console.log("Lookin at parent: " + this.parent.path + ". Done = " + done); + done = (path === this.parent.path); } else { // Test if we are back to the original page's path. done = (path === Popups.originalSettings.popups.originalPath); -// console.log("Lookin at original page: " + Popups.originalSettings.popups.originalPath + ". Done = " + done); } - }; - return done; + }; + return done; }; @@ -231,7 +246,7 @@ // *************************************************************************** /** - * Test if the param has been set. + * Test if the param has been set. * Used to distinguish between a value set to null or false and on not yet unset. */ Popups.isset = function(v) { @@ -264,19 +279,19 @@ /** * Build an options hash from defaults. - * + * * @param overrides * Hash of values to override the defaults. */ Popups.options = function(overrides) { var defaults = Popups.defaultOptions; - return Popups.overrideOptions(defaults, overrides); + return Popups.overrideOptions(defaults, overrides); } /** - * Build an options hash. + * Build an options hash. * Also maps deprecated options to current options. - * + * * @param defaults * Hash of default values * @param overrides @@ -289,24 +304,24 @@ if (Popups.isset(overrides[option])) { options[option] = overrides[option]; } - else { + else { options[option] = defaults[option]; } } // Map deprecated options. if (overrides['noReload'] || overrides['noUpdate']) { options['updateMethod'] = 'none'; - } + } if (overrides['reloadWhenDone']) { options['updateMethod'] = 'reload'; - } + } if (overrides['afterSubmit']) { options['updateMethod'] = 'callback'; options['onUpdate'] = overrides['afterSubmit']; - } + } if (overrides['forceReturn']) { options['doneTest'] = overrides['forceReturn']; - } + } return options; } @@ -321,31 +336,30 @@ * Hash of options associated with these links. */ Popups.attach = function(context, selector, options) { -// console.log(options); $(selector, context).not('.popups-processed').each(function() { - var $element = $(this); - - // Mark the element as processed. + var $element = $(this); + + // Mark the element as processed. $element.addClass('popups-processed'); - + // Append note to link title. var title = ''; if ($element.attr('title')) { title = $element.attr('title') + ' '; } title += Drupal.t('[Popup]'); - $element.attr('title', title); - + $element.attr('title', title); + // Attach the on-click popup behavior to the element. $element.click(function(event){ return Popups.clickPopupElement(this, options); }); }); -}; +}; /** * Respond to click by opening a popup. - * + * * @param element * The element that was clicked. * @param options @@ -353,16 +367,16 @@ */ Popups.clickPopupElement = function(element, options) { Popups.saveSettings(); - + // If the element contains a on-popups-options attribute, override default options param. if ($(element).attr('on-popups-options')) { - var overrides = Drupal.parseJson($(element).attr('on-popups-options')); + var overrides = Drupal.parseJson($(element).attr('on-popups-options')); options = Popups.overrideOptions(options, overrides); } - + // The parent of the new popup is the currently active popup. var parent = Popups.activePopup(); - + // If the option is distructive, check if the page is already modified, and offer to save. var willModifyOriginal = !(options.updateMethod === 'none' || options.skipDirtyCheck); if (willModifyOriginal && Popups.activeLayerIsEdited()) { @@ -373,7 +387,7 @@ // Page is clean, or popup is safe, so just open it. Popups.openPath(element, options, parent); } - return false; + return false; }; /** @@ -383,14 +397,14 @@ Popups.activeLayerIsEdited = function() { var layer = Popups.activePopup(); var $context = Popups.getLayerContext(layer); - // TODO: better test for edited page, maybe capture change event on :inputs. - var edited = $context.find('span.tabledrag-changed').length; + // TODO: better test for edited page, maybe capture change event on :inputs. + var edited = $context.find('span.tabledrag-changed').length; return edited; } /** * Show dialog offering to save form on parent layer. - * + * * @param element * The DOM element that was clicked. * @param options @@ -406,13 +420,13 @@ 'popup_submit': {title: Drupal.t('Continue'), func: function(){popup.removePopup(); Popups.openPath(element, options, parent);}}, 'popup_cancel': {title: Drupal.t('Cancel'), func: function(){popup.close();}} }; - popup.open(Drupal.t('Warning: Please Confirm'), body, buttons); + popup.open(Drupal.t('Warning: Please Confirm'), body, buttons); }; /** * Generic dialog builder. * Adds the newly built popup into the DOM. - * + * * TODO: capture the focus if it tabs out of the dialog. * * @param popup @@ -425,17 +439,17 @@ * Hash of button parameters. * @param width (optional) * Width of new dialog. - * + * * @return popup object */ Popups.open = function(popup, title, body, buttons, width){ Popups.addOverlay(); - + if (Popups.activePopup()) { // Hiding previously active popup. Popups.activePopup().hide(); } - + if (!popup) { // Popup object was not handed in, so create a new one. popup = new Popups.Popup(); @@ -449,9 +463,9 @@ if (width) { $popup.css('width', width); } - + // Add the new popup to the DOM. - $('body').append($popup); + $('body').append($popup); // Add button function callbacks. if (buttons) { @@ -459,7 +473,7 @@ $('#' + id).click(button.func); }); } - + // Add the default click-to-close behavior. popup.$popupClose().click(function(){ return Popups.close(popup); @@ -468,45 +482,45 @@ Popups.resizeAndCenter(popup); // Focus on the first input element in the popup window. - popup.refocus(); - + popup.refocus(); + // TODO - this isn't the place for this - should mirror addLoading calls. // Remove the loading image. Popups.removeLoading(); - + return popup; -}; +}; /** * Adjust the popup's height to fit it's content. * Move it to be centered on the screen. * This undoes the effects of popup.hide(). - * + * * @param popup */ Popups.resizeAndCenter = function(popup) { var $popup = popup.$popup(); - + // center on the screen, adding in offsets if the window has been scrolled - var popupWidth = $popup.width(); + var popupWidth = $popup.width(); var windowWidth = Popups.windowWidth(); var left = (windowWidth / 2) - (popupWidth / 2) + Popups.scrollLeft(); - + // Get popups's height on the page. $popup.css('height', 'auto'); // Reset height. - var popupHeight = $popup.height(); + var popupHeight = $popup.height(); $popup.height(popupHeight); var windowHeight = Popups.windowHeight(); - + if (popupHeight > (0.9 * windowHeight) ) { // Must fit in 90% of window. popupHeight = 0.9 * windowHeight; $popup.height(popupHeight); - } + } var top = (windowHeight / 2) - (popupHeight / 2) + Popups.scrollTop(); - $popup.css('top', top).css('left', left); // Position the popups to be visible. + $popup.css('top', top).css('left', left); // Position the popups to be visible. }; - + /** * Create and show a simple popup dialog that functions like the browser's alert box. @@ -549,7 +563,7 @@ /***************************************************************************** * Appearence Functions (overlay, loading graphic, remove popups) ********* *****************************************************************************/ - + /** * Add full page div between the page and the dialog, to make the popup modal. */ @@ -560,7 +574,7 @@ $overlay.css('opacity', '0.4'); // for ie6(?) // Doing absolute positioning, so make overlay's size equal the entire body. var $doc = $(document); - $overlay.width($doc.width()).height($doc.height()); + $overlay.width($doc.width()).height($doc.height()); $overlay.click(function(){Popups.close();}); $('body').prepend($overlay); } @@ -596,20 +610,15 @@ }; // Should I fold this function into Popups.pop? -Popups.removePopup = function(popup) { -// console.log("Popups.removePopup: " + popup); +Popups.removePopup = function(popup) { if (!Popups.isset(popup)) { popup = Popups.activePopup(); } if (popup) { -// console.log('removing '+popup.id); popup.$popup().remove(); - Popups.popupStack.splice(Popups.popupStack.indexOf(popup), 1); // Remove popup from stack. Probably should rework into .pop() - } -// else { -// console.log("Popups.removePopup - there is no popup to remove."); -// } -}; + Popups.popupStack.splice(jQuery.inArray(popup,Popups.popupStack), 1); // Remove popup from stack. Probably should rework into .pop() + } +}; /** * Remove everything. @@ -644,7 +653,7 @@ * Restore the page's original Drupal.settings. */ Popups.restoreSettings = function() { - Drupal.settings = Popups.originalSettings; + Drupal.settings = Popups.originalSettings; }; /** @@ -653,9 +662,8 @@ Popups.restorePage = function() { Popups.restoreSettings(); // Remove the CSS files that were jit loaded for popup. - for (var i in Popups.addedCSS) { - var link = Popups.addedCSS[i]; - $('link[href='+ $(link).attr('href') + ']').remove(); + for (var i in Popups.addedCSS) if (Popups.addedCSS.hasOwnProperty(i)) { + $('link[href='+ Popups.addedCSS[i] + ']').remove(); } Popups.addedCSS = []; }; @@ -684,7 +692,7 @@ * Fixes jQuery & Opera bug - http://drupal.org/node/366093 */ Popups.windowHeight = function() { - if ($.browser.opera && $.browser.version > "9.5" && $.fn.jquery <= "1.2.6") { + if ($.browser.opera && $.browser.version > "9.5" && $.fn.jquery <= "1.2.6") { return document.documentElement.clientHeight; } return $(window).height(); @@ -695,7 +703,7 @@ * Fixes jQuery & Opera bug - http://drupal.org/node/366093 */ Popups.windowWidth = function() { - if ($.browser.opera && $.browser.version > "9.5" && $.fn.jquery <= "1.2.6") { + if ($.browser.opera && $.browser.version > "9.5" && $.fn.jquery <= "1.2.6") { return document.documentElement.clientWidth; } return $(window).width(); @@ -720,13 +728,14 @@ */ Popups.addCSS = function(css) { Popups.addedCSS = []; - for (var type in css) { - for (var file in css[type]) { + for (var type in css) if (css.hasOwnProperty(type)) { + for (var file in css[type]) if (css[type].hasOwnProperty(file)) { var link = css[type][file]; + var href = $(link).attr('href'); // Does the page already contain this stylesheet? - if (!$('link[href='+ $(link).attr('href') + ']').length) { + if (!Popups.originalCSS[href.replace(/^(\/.+)\?\w$/, '$1')] && !Popups.addedCSS[href]) { $('head').append(link); - Popups.addedCSS.push(link); // Keep a list, so we can remove them later. + Popups.addedCSS[href] = 1; // Keep a list, so we can remove them later. } } } @@ -739,14 +748,29 @@ // Parse the json info about the new context. var scripts = []; var inlines = []; - for (var type in js) { + var src; + for (var type in js) if (js.hasOwnProperty(type)) { if (type != 'setting') { - for (var file in js[type]) { + for (var file in js[type]) if (js[type].hasOwnProperty(file)) { if (type == 'inline') { inlines.push($(js[type][file]).text()); } else { - scripts.push($(js[type][file]).attr('src')); + src = $(js[type][file]).attr('src'); + if (!Popups.originalJS[src.replace(/^(\/.+)\?\w$/, '$1')] && !Popups.addedJS[src]) { + // Get the script from the server and execute it. + $.ajax({ + type: 'GET', + url: src, + dataType: 'script', + async : false, + success: function(script) { + eval(script); + } + }); + // Mark the js as added to the underlying page. + Popups.addedJS[src] = 1; + } } } } @@ -754,26 +778,6 @@ // Add new JS settings to the page, needed for #ahah properties to work. Drupal.settings = js.setting; -// console.log('js.setting...'); -// console.log(js.setting); - - for (var i in scripts) { - var src = scripts[i]; - if (!$('script[src='+ src + ']').length && !Popups.addedJS[src]) { - // Get the script from the server and execute it. - $.ajax({ - type: 'GET', - url: src, - dataType: 'script', - async : false, - success: function(script) { - eval(script); - } - }); - // Mark the js as added to the underlying page. - Popups.addedJS[src] = true; - } - } return inlines; }; @@ -781,7 +785,7 @@ /** * Execute the jit loaded inline scripts. * Q: Do we want to re-excute the ones already in the page? - * + * * @param inlines * Array of inline scripts. */ @@ -789,9 +793,9 @@ // Load the inlines into the page. for (var n in inlines) { // If the script is not already in the page, execute it. - if (!$('script:not([src]):contains(' + inlines[n] + ')').length) { + //if (!$('script:not([src]):contains(' + inlines[n] + ')').length) { eval(inlines[n]); - } + //} } }; @@ -827,31 +831,28 @@ // Let the user know something is happening. $('body').css("cursor", "wait"); - + // TODO - get nonmodal working. if (!options.nonModal) { - Popups.addOverlay(); + Popups.addOverlay(); } Popups.addLoading(); - + var href = options.href ? options.href : element.href; $(document).trigger('popups_open_path', [element, href]); // Broadcast Popup Open Path event. - - var params = {}; + + var params = {}; // Force the popups to return back to the orignal page when forms are done, unless hijackDestination option is set to FALSE. - if (options.hijackDestination) { + if (options.hijackDestination) { var returnPath; if (parent) { returnPath = parent.path; -// console.log('Popup parent is ...'); -// console.log(parent); } else { // No parent, so bring flow back to original page. returnPath = Popups.originalSettings.popups.originalPath; - } + } href = href.replace(/destination=[^;&]*[;&]?/, ''); // Strip out any existing destination param. -// console.log("Hijacking destination to " + returnPath); - params.destination = returnPath; // Set the destination to return to the parent's path. + params.destination = returnPath; // Set the destination to return to the parent's path. } var ajaxOptions = { @@ -859,17 +860,17 @@ dataType: 'json', data: params, beforeSend: Popups.beforeSend, - success: function(json) { + success: function(json) { // Add additional CSS to the page. Popups.addCSS(json.css); var inlines = Popups.addJS(json.js); var popup = Popups.openPathContent(json.path, json.title, json.messages + json.content, element, options, parent); - Popups.addInlineJS(inlines); + Popups.addInlineJS(inlines); // Broadcast an event that the path was opened. - $(document).trigger('popups_open_path_done', [element, href, popup]); + $(document).trigger('popups_open_path_done', [element, href, popup]); }, complete: function() { - $('body').css("cursor", "auto"); // Return the cursor to normal state. + $('body').css("cursor", "auto"); // Return the cursor to normal state. } }; @@ -877,7 +878,7 @@ if (options.reloadOnError) { ajaxOptions.error = function() { location.reload(); // Reload on error. Is this working? - }; + }; } else { ajaxOptions.error = function() { @@ -885,8 +886,8 @@ }; } $.ajax(ajaxOptions); - - return false; + + return false; }; /** @@ -897,24 +898,23 @@ * @param content * HTML to show in the popups. * @param element - * A DOM object containing the element that was clicked to initiate the popup. + * A DOM object containing the element that was clicked to initiate the popup. * @param options * Hash of options controlling how the popups interacts with the underlying page. * @param parent - * Spawning popup, or null if spawned from original page. + * Spawning popup, or null if spawned from original page. */ -Popups.openPathContent = function(path, title, content, element, options, parent) { +Popups.openPathContent = function(path, title, content, element, options, parent) { var popup = new Popups.Popup(); - Popups.open(popup, title, content, null, options.width); + Popups.open(popup, title, content, null, options.width); - // Set properties on new popup. + // Set properties on new popup. popup.parent = parent; popup.path = path; -// console.log("Setting popup " + popup.id + " originalPath to " + path); popup.options = options; popup.element = element; - // Add behaviors to content in popups. + // Add behaviors to content in popups. delete Drupal.behaviors.tableHeader; // Work-around for bug in tableheader.js (http://drupal.org/node/234377) delete Drupal.behaviors.teaser; // Work-around for bug in teaser.js (sigh). Drupal.attachBehaviors(popup.$popupBody()); @@ -924,8 +924,8 @@ // If the popups contains a form, capture submits. var $form = $('form', popup.$popupBody()); if ($form.length) { - $form.ajaxForm({ - dataType: 'json', + $form.ajaxForm({ + dataType: 'json', beforeSubmit: Popups.beforeSubmit, beforeSend: Popups.beforeSend, success: function(json, status) { @@ -943,13 +943,13 @@ * The form in the popups was successfully submitted * Update the originating page. * Show any messages in a popups. - * + * * @param popup * The popup object that contained the form that was just submitted. * @param data * JSON object from server with status of form submission. */ -Popups.formSuccess = function(popup, data) { +Popups.formSuccess = function(popup, data) { // Determine if we are at an end point, or just moving from one popups to another. var done = popup.isDone(data.path); if (!done) { // Not done yet, so show new page in new popups. @@ -958,7 +958,7 @@ } else { // We are done with popup flow. // Execute the onUpdate callback if available. - if (popup.options.updateMethod === 'callback' && popup.options.onUpdate) { + if (popup.options.updateMethod === 'callback' && popup.options.onUpdate) { var result = eval(popup.options.onUpdate +'(data, popup.options, popup.element)'); if (result === false) { // Give onUpdate callback a chance to skip normal processing. return; @@ -970,19 +970,27 @@ location.href = Drupal.settings.basePath + data.path; // TODO: Need to test this. } else { // Reload originating page. - location.reload(); + location.reload(); } } else { // Normal, targeted ajax, reload behavior. + var showingMessagePopup = false; // Show messages in dialog and embed the results in the original page. - var showMessage = data.messages.length && !popup.options.noMessage; - if (showMessage) { - var messagePopup = Popups.message(data.messages); // Popup message. - if (Popups.originalSettings.popups.autoCloseFinalMessage) { - setTimeout(function(){Popups.close(messagePopup);}, 2500); // Autoclose the message box in 2.5 seconds. + // TODO - should seperate these two functions. +// var showMessage = data.messages.length && !popup.options.noMessage; + if (data.messages.length) { + // If we just dismissed the last popup dialog. + if (!Popups.activePopup() && !popup.options.noMessage) { + // Show drupal_set_message in message popup. + var messagePopup = Popups.message(data.messages); + if (Popups.originalSettings.popups.autoCloseFinalMessage) { + setTimeout(function(){Popups.close(messagePopup);}, 2500); // Autoclose the message box in 2.5 seconds. + } + showingMessagePopup = true; } - - // Insert the message into the page above the content. + + + // Insert the message into the parent layer, above the content. // Might not be the standard spot, but it is the easiest to find. var $next; if (popup.targetLayerSelector() === 'body') { @@ -994,21 +1002,18 @@ $next.parent().find('div.messages').remove(); // Remove the existing messages. $next.before(data.messages); // Insert new messages. } - + // Update the content area (defined by 'targetSelectors'). - if (popup.options.updateMethod !== 'none') { + if (popup.options.updateMethod !== 'none') { Popups.testContentSelector(); // Kick up warning message if selector is bad. - Popups.restoreSettings(); // Need to restore original Drupal.settings.popups.links before running attachBehaviors. This probably has CSS side effects! + Popups.restoreSettings(); // Need to restore original Drupal.settings.popups.links before running attachBehaviors. This probably has CSS side effects! if (popup.options.targetSelectors) { // Pick and choose what returned content goes where. jQuery.each(popup.options.targetSelectors, function(t_new, t_old) { if(!isNaN(t_new)) { t_new = t_old; // handle case where targetSelectors is an array, not a hash. } -// console.log("Updating target " + t_old + ' with ' + t_new); var new_content = $(t_new, data.content); -// console.log("new content... "); -// console.log(new_content); var $c = $(popup.targetLayerSelector()).find(t_old).html(new_content); // Inject the new content into the original page. Drupal.attachBehaviors($c); @@ -1016,31 +1021,32 @@ } else { // Put the entire new content into default content area. var $c = $(popup.targetLayerSelector()).find(Popups.originalSettings.popups.defaultTargetSelector).html(data.content); -// console.log("updating entire content area.") - Drupal.attachBehaviors($c); + Drupal.attachBehaviors($c); } } - + // Update the title of the page. if (popup.options.titleSelectors) { jQuery.each(popup.options.titleSelectors, function() { $(''+this).html(data.title); }); } - + // Done with changes to the original page, remove effects. Popups.removeLoading(); - if (!showMessage) { - // If there is not a messages popups, close current layer. - Popups.close(); + if (!showingMessagePopup) { + // If there is not a messages popups, pop the stack. + // Sending in null to Popups.close reveales the next popup in the stack. + // If the stack is empty, it will remove the overlay. + Popups.close(null); } } - + // Broadcast an event that popup form was done and successful. $(document).trigger('popups_form_success', [popup]); - + } // End of updating spawning layer. -}; +}; /** @@ -1048,7 +1054,7 @@ * @param layer * Either a popup, or null to signify the original page. */ -Popups.getLayerContext = function(layer) { +Popups.getLayerContext = function(layer) { var $context; if (!layer) { $context = $('body').find(Popups.originalSettings.popups.defaultTargetSelector); @@ -1067,24 +1073,24 @@ * @param options * Hash of options controlling how the popups interacts with the underlying page. * @param layer - * Popup with form to save, or null if form is on original page. + * Popup with form to save, or null if form is on original page. */ Popups.saveFormOnLayer = function(element, options, layer) { var $context = Popups.getLayerContext(layer); var $form = $context.find('form'); var ajaxOptions = { dataType: 'json', - beforeSubmit: Popups.beforeSubmit, + beforeSubmit: Popups.beforeSubmit, beforeSend: Popups.beforeSend, - success: function(response, status) { + success: function(response, status) { // Sync up the current page contents with the submit. var $c = $context.html(response.content); // Inject the new content into the page. Drupal.attachBehaviors($c); // The form has been saved, the page reloaded, now safe to show the triggering link in a popup. - Popups.openPath(element, options, layer); - } + Popups.openPath(element, options, layer); + } }; - $form.ajaxSubmit(ajaxOptions); // Submit the form. + $form.ajaxSubmit(ajaxOptions); // Submit the form. }; /** @@ -1102,7 +1108,7 @@ else if (hits > 1) { msg += Drupal.t('There are multiple elements that match: ') + '"' + target + '"\n'; } - msg += Drupal.t('Go to admin/build/themes/settings, select your theme, and edit the "Content Selector" field'); + msg += Drupal.t('Go to admin/build/themes/settings, select your theme, and edit the "Content Selector" field'); alert(msg); } }; @@ -1130,14 +1136,14 @@ Drupal.theme.prototype.popupDialog = function(popupId, title, body, buttons) { var template = Drupal.theme('popupTemplate', popupId); var popups = template.replace('%title', title).replace('%body', body); - + var themedButtons = ''; if (buttons) { - jQuery.each(buttons, function (id, button) { + jQuery.each(buttons, function (id, button) { themedButtons += Drupal.theme('popupButton', button.title, id); - }); - } - popups = popups.replace('%buttons', themedButtons); + }); + } + popups = popups.replace('%buttons', themedButtons); return popups; }; @@ -1155,4 +1161,3 @@ template += '</div>'; return template; }; -