~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/static/javascript/custom.js

  • Committer: Robey Pointer
  • Date: 2007-01-14 05:43:15 UTC
  • Revision ID: robey@lag.net-20070114054315-qorf24nc9txv1umi
new ignores

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
Y = YUI().use("base", "node", "io-base", "anim");
2
 
 
3
 
var global_timeout_id = null;
4
 
var global_search_request = null;
5
 
 
6
 
Y.on(
7
 
  'domready',
8
 
  function()
9
 
  {
10
 
    var search_box = Y.get('#q');
11
 
    if (!Y.Lang.isNull(search_box))
12
 
    {
13
 
      function get_suggestions() {
14
 
        var query = search_box.get('value');
15
 
        var url = global_path + 'search?query=' + query;
16
 
 
17
 
        if (!Y.Lang.isNull(global_search_request))
18
 
        {
19
 
          global_search_request.abort();
20
 
        }
21
 
        global_search_request = Y.io(
22
 
          url,
23
 
          {
24
 
            on: {complete: cool_search},
25
 
            arguments: [query]
26
 
          }
27
 
        );
28
 
 
29
 
        var region = search_box.get('region');
30
 
        var current_query = search_box.get('value');
31
 
 
32
 
        Y.get('#search_terms').setStyle('display', 'block');
33
 
        Y.get('#search_terms').setStyle('position', 'absolute');
34
 
        Y.get('#search_terms').setStyle('left', region.left);
35
 
        Y.get('#search_terms').setStyle('top', region.bottom);
36
 
        Y.get('#search_terms').set('innerHTML','Loading...');
37
 
      }
38
 
      search_box.on(
39
 
        "keyup",
40
 
        function(event)
41
 
        {
42
 
          if(search_box.get('value') == '')
43
 
          {
44
 
            Y.get('#search_terms').setStyle('display', 'none');
45
 
          }
46
 
          else
47
 
          {
48
 
            if (null != global_timeout_id)
49
 
            {
50
 
              clearTimeout(global_timeout_id);
51
 
            }
52
 
            global_timeout_id = setTimeout(get_suggestions, 200);
53
 
          }
54
 
        });
55
 
    }
56
 
  });
57
 
 
58
 
function cool_search(tid, response, query)
59
 
{
60
 
  var q = Y.get('#q');
61
 
  var region = q.get('region');
62
 
  var current_query = q.get('value');
63
 
  if (current_query == query)
64
 
  {
65
 
    Y.get('#search_terms').set('innerHTML', response.responseText);
66
 
    Y.get('#search_terms').setStyle('display', 'block');
67
 
    Y.get('#search_terms').setStyle('position', 'absolute');
68
 
    Y.get('#search_terms').setStyle('left', region.left);
69
 
    Y.get('#search_terms').setStyle('top', region.bottom);
70
 
  }
71
 
}
72
 
 
73
 
function hide_search()
74
 
{
75
 
  setTimeout("Y.get('#search_terms').setStyle('display','none')", 300);
76
 
}
77
 
 
78
 
function Collapsable(config)
79
 
{
80
 
  this.is_open = config.is_open;
81
 
  this.open_node = config.open_node;
82
 
  this.close_node = config.close_node;
83
 
  this.expand_icon = config.expand_icon;
84
 
  this.source = config.source;
85
 
  this.loading = config.loading;
86
 
  this.node_process = config.node_process;
87
 
  this.container = null;
88
 
  this.anim = null;
89
 
  this._loading = false;
90
 
}
91
 
 
92
 
function get_height(node) {
93
 
  node.setStyle('position', 'absolute');
94
 
  node.setStyle('top', -1000000000);
95
 
  node.setStyle('display', 'block');
96
 
  var height = node.get('region').height;
97
 
  node.setStyle('display', 'none');
98
 
  node.setStyle('position', 'static');
99
 
  node.setStyle('top', 'auto');
100
 
  return height;
101
 
}
102
 
 
103
 
Collapsable.prototype._animate = function (callback)
104
 
{
105
 
  if (this.anim) this.anim.stop();
106
 
 
107
 
  this.anim = new Y.Anim(
108
 
    {
109
 
      node: this.container,
110
 
      from: {
111
 
        marginBottom: this.container.getStyle('marginBottom')
112
 
      },
113
 
      to: {
114
 
        marginBottom: 0
115
 
      },
116
 
      duration: 0.2
117
 
    });
118
 
 
119
 
  this.anim.run();
120
 
  this.anim.on('end', this.animComplete, this, callback);
121
 
}
122
 
 
123
 
Collapsable.prototype._load_finished = function(tid, res, args)
124
 
{
125
 
  var l = res.responseText.split('\n');
126
 
  l.splice(0, 1);
127
 
  var newNode = Y.Node.create(l.join(''));
128
 
  if (this.node_process)
129
 
    this.node_process(newNode);
130
 
  this.source = null;
131
 
  newNode.setStyle('display', 'none');
132
 
  this.loading.ancestor().insertBefore(newNode, this.loading);
133
 
  var delta = this.loading.get('region').height - get_height(newNode);
134
 
  newNode.setStyle('display', 'block');
135
 
  this.container.setStyle('marginBottom', parseFloat(this.container.getStyle('marginBottom')) + delta);
136
 
  this.loading.ancestor().removeChild(this.loading);
137
 
  this._animate(args[0]);
138
 
};
139
 
 
140
 
Collapsable.prototype._ensure_container = function(callback)
141
 
{
142
 
  if (this.container == null) {
143
 
    this.container = Y.Node.create('<div></div>');
144
 
    if (this.closed_node) {
145
 
      this.closed_node.ancestor().replaceChild(
146
 
        this.container, this.closed_node);
147
 
      this.container.appendChild(this.closed_node);
148
 
      if (this.open_node) {
149
 
        this.container.appendChild(this.open_node);
150
 
      }
151
 
    }
152
 
    else {
153
 
      this.open_node.ancestor().replaceChild(
154
 
        this.container, this.open_node);
155
 
      this.container.appendChild(this.open_node);
156
 
    }
157
 
    var outer = Y.Node.create('<div style="overflow:hidden;"></div>');
158
 
    this.container.ancestor().replaceChild(outer, this.container);
159
 
    outer.appendChild(this.container);
160
 
  }
161
 
}
162
 
 
163
 
/* What happens when you click open.
164
 
 *
165
 
 * 1. The arrow flips to the expanded position.
166
 
 *
167
 
 * 2. If necessary, the div which will be running the animation is
168
 
 * created and the open/closed content stuffed into it (and has height
169
 
 * set to the height of the closed content).
170
 
 *
171
 
 * 3. The open content is shown and the closed content is closed.
172
 
 *
173
 
 * 4. The animation to expose all of the open content is started.
174
 
 *
175
 
 * 5. If we have to do ajax to load content, start the request.
176
 
 *
177
 
 * 6. When the request completes, parse the content into a node, run
178
 
 * the node_process callback over it and replace the spinner (assumed
179
 
 * to be appropriately contained in the open node) with the new node.
180
 
 *
181
 
 * 7. If the animation showing the open content has not completed,
182
 
 * stop it.
183
 
 *
184
 
 * 8. Start a new animation to show the rest of the new content.
185
 
 */
186
 
 
187
 
Collapsable.prototype.open = function(callback)
188
 
{
189
 
  this.expand_icon.set('src', expanded_icon_path);
190
 
 
191
 
  this._ensure_container();
192
 
 
193
 
  var open_height = get_height(this.open_node);
194
 
 
195
 
  var close_height;
196
 
  if (this.close_node) {
197
 
    close_height = this.close_node.get('region').height;
198
 
  }
199
 
  else {
200
 
    close_height = 0;
201
 
  }
202
 
 
203
 
  this.container.setStyle('marginBottom', close_height - open_height);
204
 
  if (this.close_node) {
205
 
    this.close_node.setStyle('display', 'none');
206
 
  }
207
 
  this.open_node.setStyle('display', 'block');
208
 
 
209
 
  this._animate(callback);
210
 
 
211
 
  if (this.source) {
212
 
    Y.io(
213
 
      this.source,
214
 
      {
215
 
        on: {complete: this._load_finished},
216
 
        arguments: [callback],
217
 
        context: this
218
 
      });
219
 
    return;
220
 
  }
221
 
 
222
 
};
223
 
 
224
 
Collapsable.prototype.animComplete = function(evt, callback)
225
 
{
226
 
  this.anim = null;
227
 
  if (this._loading) return;
228
 
  if (callback) callback();
229
 
  this.is_open = true;
230
 
};
231
 
 
232
 
Collapsable.prototype.close = function()
233
 
{
234
 
  this._ensure_container();
235
 
 
236
 
  var open_height = this.open_node.get('region').height;
237
 
 
238
 
  var close_height;
239
 
  if (this.close_node) {
240
 
    close_height = get_height(this.close_node);
241
 
  }
242
 
  else {
243
 
    close_height = 0;
244
 
  }
245
 
 
246
 
  var anim = new Y.Anim(
247
 
    {
248
 
      node: this.container,
249
 
      from: {
250
 
        marginBottom: 0
251
 
      },
252
 
      to: {
253
 
        marginBottom: close_height - open_height
254
 
      },
255
 
      duration: 0.2
256
 
    });
257
 
  anim.on("end", this.closeComplete, this);
258
 
  anim.run();
259
 
};
260
 
 
261
 
Collapsable.prototype.closeComplete = function () {
262
 
  this.open_node.setStyle('display', 'none');
263
 
  if (this.close_node) {
264
 
    this.close_node.setStyle('display', 'block');
265
 
  }
266
 
  this.container.setStyle('marginBottom', 0);
267
 
  this.expand_icon.set('src', collapsed_icon_path);
268
 
  this.is_open = false;
269
 
};
270
 
 
271
 
Collapsable.prototype.toggle = function()
272
 
{
273
 
  if (this.is_open)
274
 
  {
275
 
    this.close();
276
 
  }
277
 
  else
278
 
  {
279
 
    this.open();
280
 
  }
281
 
};
282
 
 
283
 
var notification_node = null;
284
 
/*
285
 
 * Display privacy notifications
286
 
 *
287
 
 * This should be called after the page has loaded e.g. on 'domready'.
288
 
 */
289
 
function setup_privacy_notification(config) {
290
 
    if (notification_node !== null) {
291
 
        return;
292
 
    }
293
 
    var notification_text = 'The information on this page is private';
294
 
    var hidden = true;
295
 
    var target_id = "loggerheadCont";
296
 
    if (config !== undefined) {
297
 
        if (config.notification_text !== undefined) {
298
 
            notification_text = config.notification_text;
299
 
        }
300
 
        if (config.hidden !== undefined) {
301
 
            hidden = config.hidden;
302
 
        }
303
 
        if (config.target_id !== undefined) {
304
 
            target_id = config.target_id;
305
 
        }
306
 
    }
307
 
    var id_selector = "#" + target_id;
308
 
    var main = Y.get(id_selector);
309
 
    notification_node = Y.Node.create('<div></div>')
310
 
        .addClass('global-notification');
311
 
    if (hidden) {
312
 
        notification_node.addClass('hidden');
313
 
    }
314
 
    var notification_span = Y.Node.create('<span></span>')
315
 
        .addClass('sprite')
316
 
        .addClass('notification-private');
317
 
    notification_node.set('innerHTML', notification_text);
318
 
    main.appendChild(notification_node);
319
 
    notification_node.appendChild(notification_span);
320
 
};
321
 
 
322
 
function display_privacy_notification() {
323
 
    /* Set a temporary class on the body for the feature flag,
324
 
     this is because we have no way to use feature flags in
325
 
     css directly. This should be removed if the feature
326
 
     is accepted. */
327
 
    var body = Y.get('body');
328
 
    body.addClass('feature-flag-bugs-private-notification-enabled');
329
 
    // Set the visible flag so that the content moves down.
330
 
    body.addClass('global-notification-visible');
331
 
 
332
 
    setup_privacy_notification();
333
 
    var global_notification = Y.get('.global-notification');
334
 
    if (global_notification.hasClass('hidden')) {
335
 
        global_notification.addClass('transparent');
336
 
        global_notification.removeClass('hidden');
337
 
 
338
 
        var fade_in = new Y.Anim({
339
 
            node: global_notification,
340
 
            to: {opacity: 1},
341
 
            duration: 0.3
342
 
        });
343
 
        var body_space = new Y.Anim({
344
 
            node: 'body',
345
 
            to: {'paddingTop': '40px'},
346
 
            duration: 0.2,
347
 
            easing: Y.Easing.easeOut
348
 
        });
349
 
        var black_link_space = new Y.Anim({
350
 
            node: '.black-link',
351
 
            to: {'top': '45px'},
352
 
            duration: 0.2,
353
 
            easing: Y.Easing.easeOut
354
 
        });
355
 
 
356
 
        fade_in.run();
357
 
        body_space.run();
358
 
        black_link_space.run();
359
 
    }
360
 
};
361
 
 
362
 
Y.on('domready', function() {
363
 
    var body = Y.get('body');
364
 
    if (body.hasClass('private')) {
365
 
        setup_privacy_notification();
366
 
        display_privacy_notification();
367
 
    }
368
 
});