1
Y = YUI().use("base", "node", "io-base", "anim");
3
var global_timeout_id = null;
4
var global_search_request = null;
10
var search_box = Y.get('#q');
11
if (!Y.Lang.isNull(search_box))
13
function get_suggestions() {
14
var query = search_box.get('value');
15
var url = global_path + 'search?query=' + query;
17
if (!Y.Lang.isNull(global_search_request))
19
global_search_request.abort();
21
global_search_request = Y.io(
24
on: {complete: cool_search},
29
var region = search_box.get('region');
30
var current_query = search_box.get('value');
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...');
42
if(search_box.get('value') == '')
44
Y.get('#search_terms').setStyle('display', 'none');
48
if (null != global_timeout_id)
50
clearTimeout(global_timeout_id);
52
global_timeout_id = setTimeout(get_suggestions, 200);
58
function cool_search(tid, response, query)
61
var region = q.get('region');
62
var current_query = q.get('value');
63
if (current_query == query)
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);
73
function hide_search()
75
setTimeout("Y.get('#search_terms').setStyle('display','none')", 300);
78
function Collapsable(config)
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;
89
this._loading = false;
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');
103
Collapsable.prototype._animate = function (callback)
105
if (this.anim) this.anim.stop();
107
this.anim = new Y.Anim(
109
node: this.container,
111
marginBottom: this.container.getStyle('marginBottom')
120
this.anim.on('end', this.animComplete, this, callback);
123
Collapsable.prototype._load_finished = function(tid, res, args)
125
var l = res.responseText.split('\n');
127
var newNode = Y.Node.create(l.join(''));
128
if (this.node_process)
129
this.node_process(newNode);
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]);
140
Collapsable.prototype._ensure_container = function(callback)
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);
153
this.open_node.ancestor().replaceChild(
154
this.container, this.open_node);
155
this.container.appendChild(this.open_node);
157
var outer = Y.Node.create('<div style="overflow:hidden;"></div>');
158
this.container.ancestor().replaceChild(outer, this.container);
159
outer.appendChild(this.container);
163
/* What happens when you click open.
165
* 1. The arrow flips to the expanded position.
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).
171
* 3. The open content is shown and the closed content is closed.
173
* 4. The animation to expose all of the open content is started.
175
* 5. If we have to do ajax to load content, start the request.
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.
181
* 7. If the animation showing the open content has not completed,
184
* 8. Start a new animation to show the rest of the new content.
187
Collapsable.prototype.open = function(callback)
189
this.expand_icon.set('src', expanded_icon_path);
191
this._ensure_container();
193
var open_height = get_height(this.open_node);
196
if (this.close_node) {
197
close_height = this.close_node.get('region').height;
203
this.container.setStyle('marginBottom', close_height - open_height);
204
if (this.close_node) {
205
this.close_node.setStyle('display', 'none');
207
this.open_node.setStyle('display', 'block');
209
this._animate(callback);
215
on: {complete: this._load_finished},
216
arguments: [callback],
224
Collapsable.prototype.animComplete = function(evt, callback)
227
if (this._loading) return;
228
if (callback) callback();
232
Collapsable.prototype.close = function()
234
this._ensure_container();
236
var open_height = this.open_node.get('region').height;
239
if (this.close_node) {
240
close_height = get_height(this.close_node);
246
var anim = new Y.Anim(
248
node: this.container,
253
marginBottom: close_height - open_height
257
anim.on("end", this.closeComplete, this);
261
Collapsable.prototype.closeComplete = function () {
262
this.open_node.setStyle('display', 'none');
263
if (this.close_node) {
264
this.close_node.setStyle('display', 'block');
266
this.container.setStyle('marginBottom', 0);
267
this.expand_icon.set('src', collapsed_icon_path);
268
this.is_open = false;
271
Collapsable.prototype.toggle = function()
283
var notification_node = null;
285
* Display privacy notifications
287
* This should be called after the page has loaded e.g. on 'domready'.
289
function setup_privacy_notification(config) {
290
if (notification_node !== null) {
293
var notification_text = 'The information on this page is private';
295
var target_id = "loggerheadCont";
296
if (config !== undefined) {
297
if (config.notification_text !== undefined) {
298
notification_text = config.notification_text;
300
if (config.hidden !== undefined) {
301
hidden = config.hidden;
303
if (config.target_id !== undefined) {
304
target_id = config.target_id;
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');
312
notification_node.addClass('hidden');
314
var notification_span = Y.Node.create('<span></span>')
316
.addClass('notification-private');
317
notification_node.set('innerHTML', notification_text);
318
main.appendChild(notification_node);
319
notification_node.appendChild(notification_span);
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
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');
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');
338
var fade_in = new Y.Anim({
339
node: global_notification,
343
var body_space = new Y.Anim({
345
to: {'paddingTop': '40px'},
347
easing: Y.Easing.easeOut
349
var black_link_space = new Y.Anim({
353
easing: Y.Easing.easeOut
358
black_link_space.run();
362
Y.on('domready', function() {
363
var body = Y.get('body');
364
if (body.hasClass('private')) {
365
setup_privacy_notification();
366
display_privacy_notification();