overlay-child.js 6.5 KB

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