summaryrefslogtreecommitdiff
path: root/modules/overlay/overlay-child.js
blob: 8e526b8a3902d1dc4a142faca06da5544fa30711 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// $Id$

(function ($) {

/**
 * Overlay object for child windows.
 */
Drupal.overlayChild = Drupal.overlayChild || { processed: false, behaviors: {} };

/**
 * Attach the child dialog behavior to new content.
 */
Drupal.behaviors.overlayChild = {
  attach: function (context, settings) {
    var self = Drupal.overlayChild;
    var settings = settings.overlayChild || {};

    // Make sure this behavior is not processed more than once.
    if (self.processed) {
      return;
    }
    self.processed = true;

    // If we cannot reach the parent window, then we have nothing else to do
    // here.
    if (!$.isPlainObject(parent.Drupal) || !$.isPlainObject(parent.Drupal.overlay)) {
      return;
    }

    // If a form has been submitted successfully, then the server side script
    // may have decided to tell us the parent window to close the popup dialog.
    if (settings.closeOverlay) {
      parent.Drupal.overlay.bindChild(window, true);
      // Use setTimeout to close the child window from a separate thread,
      // because the current one is busy processing Drupal behaviors.
      setTimeout(function () {
        // We need to store the parent variable locally because it will
        // disappear as soon as we close the iframe.
        var p = parent;
        p.Drupal.overlay.close();
        if (typeof settings.redirect == 'string') {
          p.Drupal.overlay.redirect(settings.redirect);
        }
      }, 1);
      return;
    }

    // If one of the regions displaying outside the overlay needs to be
    // reloaded, let the parent window know.
    if (settings.refreshRegions) {
      parent.Drupal.overlay.refreshRegions(settings.refreshRegions);
    }

    // Ok, now we can tell the parent window we're ready.
    parent.Drupal.overlay.bindChild(window);

    // Attach child related behaviors to the iframe document.
    self.attachBehaviors(context, settings);
  }
};

/**
 * Attach child related behaviors to the iframe document.
 */
Drupal.overlayChild.attachBehaviors = function (context, settings) {
  $.each(this.behaviors, function () {
    this(context, settings);
  });
};

/**
 * Scroll to the top of the page.
 *
 * This makes the overlay visible to users even if it is not as tall as the
 * previously shown overlay was.
 */
Drupal.overlayChild.behaviors.scrollToTop = function (context, settings) {
  window.scrollTo(0, 0);
};

/**
 * Capture and handle clicks.
 *
 * Instead of binding a click event handler to every link we bind one to the
 * document and handle events that bubble up. This also allows other scripts
 * to bind their own handlers to links and also to prevent overlay's handling.
 */
Drupal.overlayChild.behaviors.addClickHandler = function (context, settings) {
  $(document).bind('click.overlay-event', parent.Drupal.overlay.clickHandler);
};

/**
 * Modify forms depending on their relation to the overlay.
 *
 * By default, forms are assumed to keep the flow in the overlay. Thus their
 * action attribute get a ?render=overlay suffix.
 */
Drupal.overlayChild.behaviors.parseForms = function (context, settings) {
  $('form', context).once('overlay', function () {
    // Obtain the action attribute of the form.
    var action = $(this).attr('action');
    // Keep internal forms in the overlay.
    if (action == undefined || (action.indexOf('http') != 0 && action.indexOf('https') != 0)) {
      action += (action.indexOf('?') > -1 ? '&' : '?') + 'render=overlay';
      $(this).attr('action', action);
    }
    // Submit external forms into a new window.
    else {
      $(this).attr('target', '_new');
    }
  });
};

})(jQuery);