summaryrefslogtreecommitdiff
path: root/modules/overlay/overlay-child.js
blob: 5a81de20fc27d9996aa4ff741891a5382059f90e (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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// $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 (!$.isObject(parent.Drupal) || !$.isObject(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);
      // 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(settings.args, settings.statusMessages);
        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);

    // Install onBeforeUnload callback, if module is present.
    if ($.isObject(Drupal.onBeforeUnload) && !Drupal.onBeforeUnload.callbackExists('overlayChild')) {
      Drupal.onBeforeUnload.addCallback('overlayChild', function () {
        // Tell the parent window we're unloading.
        parent.Drupal.overlay.unbindChild(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);
};

/**
 * Modify links and forms depending on their relation to the overlay.
 *
 * By default, forms and links are assumed to keep the flow in the overlay.
 * Thus their action and href attributes respectively get a ?render=overlay
 * suffix. Non-administrative links should however close the overlay and
 * redirect the parent page to the given link. This would include links in a
 * content listing, where administration options are mixed with links to the
 * actual content to be shown on the site out of the overlay.
 *
 * @see Drupal.overlay.isAdminLink()
 */
Drupal.overlayChild.behaviors.parseLinks = function (context, settings) {
  $('a:not(.overlay-exclude)', context).once('overlay').each(function () {
    // Non-admin links should close the overlay and open in the main window.
    if (!parent.Drupal.overlay.isAdminLink(this.href)) {
      $(this).click(function () {
        // We need to store the parent variable locally because it will
        // disappear as soon as we close the iframe.
        var parentWindow = parent;
        if (parentWindow.Drupal.overlay.close(false)) {
          parentWindow.Drupal.overlay.redirect($(this).attr('href'));
        }
        return false;
      });
      return;
    }
    else {
      var href = $(this).attr('href');
      if (href.indexOf('http') > 0 || href.indexOf('https') > 0) {
        $(this).attr('target', '_new');
      }
      else {
        $(this).each(function(){
          this.href = parent.Drupal.overlay.fragmentizeLink(this);
        }).click(function () {
          parent.window.location.href = this.href;
          return false;
        });
      }
    }
  });
  $('form:not(.overlay-processed)', context).addClass('overlay-processed').each(function () {
    // Obtain the action attribute of the form.
    var action = $(this).attr('action');
    if (action.indexOf('http') != 0 && action.indexOf('https') != 0) {
      // Keep internal forms in the overlay.
      action += (action.indexOf('?') > -1 ? '&' : '?') + 'render=overlay';
      $(this).attr('action', action);
    }
    else {
      $(this).attr('target', '_new');
    }
  });
};

})(jQuery);