overlay-child.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /**
  2. * @file
  3. * Attaches the behaviors for the Overlay child pages.
  4. */
  5. (function ($) {
  6. /**
  7. * Attach the child dialog behavior to new content.
  8. */
  9. Drupal.behaviors.overlayChild = {
  10. attach: function (context, settings) {
  11. // Make sure this behavior is not processed more than once.
  12. if (this.processed) {
  13. return;
  14. }
  15. this.processed = true;
  16. // If we cannot reach the parent window, break out of the overlay.
  17. if (!parent.Drupal || !parent.Drupal.overlay) {
  18. window.location = window.location.href.replace(/([?&]?)render=overlay&?/g, '$1').replace(/\?$/, '');
  19. }
  20. var settings = settings.overlayChild || {};
  21. // If the entire parent window should be refreshed when the overlay is
  22. // closed, pass that information to the parent window.
  23. if (settings.refreshPage) {
  24. parent.Drupal.overlay.refreshPage = true;
  25. }
  26. // If a form has been submitted successfully, then the server side script
  27. // may have decided to tell the parent window to close the popup dialog.
  28. if (settings.closeOverlay) {
  29. parent.Drupal.overlay.bindChild(window, true);
  30. // Use setTimeout to close the child window from a separate thread,
  31. // because the current one is busy processing Drupal behaviors.
  32. setTimeout(function () {
  33. if (typeof settings.redirect == 'string') {
  34. parent.Drupal.overlay.redirect(settings.redirect);
  35. }
  36. else {
  37. parent.Drupal.overlay.close();
  38. }
  39. }, 1);
  40. return;
  41. }
  42. // If one of the regions displaying outside the overlay needs to be
  43. // reloaded immediately, let the parent window know.
  44. if (settings.refreshRegions) {
  45. parent.Drupal.overlay.refreshRegions(settings.refreshRegions);
  46. }
  47. // Ok, now we can tell the parent window we're ready.
  48. parent.Drupal.overlay.bindChild(window);
  49. // IE8 crashes on certain pages if this isn't called; reason unknown.
  50. window.scrollTo(window.scrollX, window.scrollY);
  51. // Attach child related behaviors to the iframe document.
  52. Drupal.overlayChild.attachBehaviors(context, settings);
  53. // There are two links within the message that informs people about the
  54. // overlay and how to disable it. Make sure both links are visible when
  55. // either one has focus and add a class to the wrapper for styling purposes.
  56. $('#overlay-disable-message', context)
  57. .focusin(function () {
  58. $(this).addClass('overlay-disable-message-focused');
  59. $('a.element-focusable', this).removeClass('element-invisible');
  60. })
  61. .focusout(function () {
  62. $(this).removeClass('overlay-disable-message-focused');
  63. $('a.element-focusable', this).addClass('element-invisible');
  64. });
  65. }
  66. };
  67. /**
  68. * Overlay object for child windows.
  69. */
  70. Drupal.overlayChild = Drupal.overlayChild || {
  71. behaviors: {}
  72. };
  73. Drupal.overlayChild.prototype = {};
  74. /**
  75. * Attach child related behaviors to the iframe document.
  76. */
  77. Drupal.overlayChild.attachBehaviors = function (context, settings) {
  78. $.each(this.behaviors, function () {
  79. this(context, settings);
  80. });
  81. };
  82. /**
  83. * Capture and handle clicks.
  84. *
  85. * Instead of binding a click event handler to every link we bind one to the
  86. * document and handle events that bubble up. This also allows other scripts
  87. * to bind their own handlers to links and also to prevent overlay's handling.
  88. */
  89. Drupal.overlayChild.behaviors.addClickHandler = function (context, settings) {
  90. $(document).bind('click.drupal-overlay mouseup.drupal-overlay', $.proxy(parent.Drupal.overlay, 'eventhandlerOverrideLink'));
  91. };
  92. /**
  93. * Modify forms depending on their relation to the overlay.
  94. *
  95. * By default, forms are assumed to keep the flow in the overlay. Thus their
  96. * action attribute get a ?render=overlay suffix.
  97. */
  98. Drupal.overlayChild.behaviors.parseForms = function (context, settings) {
  99. $('form', context).once('overlay', function () {
  100. // Obtain the action attribute of the form.
  101. var action = $(this).attr('action');
  102. // Keep internal forms in the overlay.
  103. if (action == undefined || (action.indexOf('http') != 0 && action.indexOf('https') != 0)) {
  104. action += (action.indexOf('?') > -1 ? '&' : '?') + 'render=overlay';
  105. $(this).attr('action', action);
  106. }
  107. // Submit external forms into a new window.
  108. else {
  109. $(this).attr('target', '_new');
  110. }
  111. });
  112. };
  113. /**
  114. * Replace the overlay title with a message while loading another page.
  115. */
  116. Drupal.overlayChild.behaviors.loading = function (context, settings) {
  117. var $title;
  118. var text = Drupal.t('Loading');
  119. var dots = '';
  120. $(document).bind('drupalOverlayBeforeLoad.drupal-overlay.drupal-overlay-child-loading', function () {
  121. $title = $('#overlay-title').text(text);
  122. var id = setInterval(function () {
  123. dots = (dots.length > 10) ? '' : dots + '.';
  124. $title.text(text + dots);
  125. }, 500);
  126. });
  127. };
  128. /**
  129. * Switch active tab immediately.
  130. */
  131. Drupal.overlayChild.behaviors.tabs = function (context, settings) {
  132. var $tabsLinks = $('#overlay-tabs > li > a');
  133. $('#overlay-tabs > li > a').bind('click.drupal-overlay', function () {
  134. var active_tab = Drupal.t('(active tab)');
  135. $tabsLinks.parent().siblings().removeClass('active').find('element-invisible:contains(' + active_tab + ')').appendTo(this);
  136. $(this).parent().addClass('active');
  137. });
  138. };
  139. /**
  140. * If the shortcut add/delete button exists, move it to the overlay titlebar.
  141. */
  142. Drupal.overlayChild.behaviors.shortcutAddLink = function (context, settings) {
  143. // Remove any existing shortcut button markup from the titlebar.
  144. $('#overlay-titlebar').find('.add-or-remove-shortcuts').remove();
  145. // If the shortcut add/delete button exists, move it to the titlebar.
  146. var $addToShortcuts = $('.add-or-remove-shortcuts');
  147. if ($addToShortcuts.length) {
  148. $addToShortcuts.insertAfter('#overlay-title');
  149. }
  150. $(document).bind('drupalOverlayBeforeLoad.drupal-overlay.drupal-overlay-child-loading', function () {
  151. $('#overlay-titlebar').find('.add-or-remove-shortcuts').remove();
  152. });
  153. };
  154. /**
  155. * Use displacement from parent window.
  156. */
  157. Drupal.overlayChild.behaviors.alterTableHeaderOffset = function (context, settings) {
  158. if (Drupal.settings.tableHeaderOffset) {
  159. Drupal.overlayChild.prevTableHeaderOffset = Drupal.settings.tableHeaderOffset;
  160. }
  161. Drupal.settings.tableHeaderOffset = 'Drupal.overlayChild.tableHeaderOffset';
  162. };
  163. /**
  164. * Callback for Drupal.settings.tableHeaderOffset.
  165. */
  166. Drupal.overlayChild.tableHeaderOffset = function () {
  167. var topOffset = Drupal.overlayChild.prevTableHeaderOffset ? eval(Drupal.overlayChild.prevTableHeaderOffset + '()') : 0;
  168. return topOffset + parseInt($(document.body).css('marginTop'));
  169. };
  170. })(jQuery);