~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

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

  • Committer: John Arbash Meinel
  • Date: 2011-03-15 10:24:40 UTC
  • mfrom: (432.1.3 loggerhead)
  • Revision ID: john@arbash-meinel.com-20110315102440-n4zr988738z125cd
Merge fix for bug #569358. Redirect requests so people can URL hack.

If you edit /files/directory to become /files/directory/filename, redirect it to
the /view/directory/filename, and conversly if you go to /view/directory redirect
it to /files/directory. This way people can edit the URL in a logical way
and still get the view they are expecting.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Y = YUI().use("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