Merge lp:~xmo-deactivatedaccount/openobject-client-web/iframe-resize-events into lp:~openerp-dev/openobject-client-web/trunk-dev-web

Proposed by Xavier (Open ERP)
Status: Superseded
Proposed branch: lp:~xmo-deactivatedaccount/openobject-client-web/iframe-resize-events
Merge into: lp:~openerp-dev/openobject-client-web/trunk-dev-web
Diff against target: 2463 lines (+850/-761)
10 files modified
addons/openerp/controllers/templates/menu.mako (+38/-52)
addons/openerp/static/javascript/ajax_stat.js (+0/-1)
addons/openerp/static/javascript/form.js (+1/-0)
addons/openerp/static/javascript/listgrid.js (+196/-201)
addons/openerp/static/javascript/menubar.js (+0/-29)
addons/openerp/static/javascript/notebook/notebook.js (+16/-0)
addons/openerp/static/javascript/openerp/openerp.ui.textarea.js (+31/-27)
addons/openerp/static/javascript/search.js (+367/-350)
addons/openerp/static/javascript/treegrid.js (+96/-78)
openobject/static/javascript/openobject/openobject.base.js (+105/-23)
To merge this branch: bzr merge lp:~xmo-deactivatedaccount/openobject-client-web/iframe-resize-events
Reviewer Review Type Date Requested Status
OpenERP R&D Web Team Pending
Review via email: mp+22862@code.launchpad.net

This proposal supersedes a proposal from 2010-04-02.

This proposal has been superseded by a proposal from 2010-04-08.

Description of the change

Currently, the iframe is resized based on a timer which, every 10mn, does a full pass to re-set the height of #appFrame to ensure the scrollbar is on the page itself, not in the iframe.

This poses performance problems as the resizing operations are fairly expensive and restarted very often.

The current branch tries to fix that by hooking into specific events (which can change the size of the iframe's content and therefore require that the iframe element itself be resized to match) and removes the timer.

Could you:
* Check that I didn't introduce any outstanding bug (and review as "needs-fixing")
* See if you find obvious cases that I missed, and report them (and review as "needs-fixing")

To post a comment you must log in.
Revision history for this message
Sananaz (Open ERP) (sma-tiny) wrote : Posted in a previous version of this proposal

Fixed iframe resizing problem.

review: Approve

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'addons/openerp/controllers/templates/menu.mako'
2--- addons/openerp/controllers/templates/menu.mako 2010-04-06 09:51:49 +0000
3+++ addons/openerp/controllers/templates/menu.mako 2010-04-06 12:34:17 +0000
4@@ -2,53 +2,39 @@
5
6 <%def name="header()">
7 <title>OpenERP</title>
8-
9+
10 <link href="/openerp/static/css/accordion.css" rel="stylesheet" type="text/css"/>
11 <link href="/openerp/static/css/treegrid.css" rel="stylesheet" type="text/css"/>
12 <link href="/openerp/static/css/notebook.css" rel="stylesheet" type="text/css"/>
13-
14- <script type="text/javascript" src="/openerp/static/javascript/menubar.js"></script>
15+
16 <script type="text/javascript" src="/openerp/static/javascript/accordion.js"></script>
17 <script type="text/javascript" src="/openerp/static/javascript/treegrid.js"></script>
18 <script type="text/javascript" src="/openerp/static/javascript/notebook/notebook.js"></script>
19-
20- <script type="text/javascript">
21-
22- // call adjustAppFrame every 0.5 second
23- function adjustFrame(wait) {
24- try {
25- adjustAppFrame();
26- } catch(e){}
27- setTimeout(adjustFrame, wait);
28- }
29- adjustFrame(0.5);
30-
31-</script>
32-
33- <style>
34+
35+ <style type="text/css">
36 .accordion-content {
37 }
38-
39+
40 .accordion {
41 border: none;
42 }
43-
44+
45 .accordion-title {
46 padding: 2px;
47 }
48-
49+
50 #menubar_container {
51 overflow: auto;
52- border: 1px solid black;
53+ border: 1px solid black;
54 }
55-
56+
57 #content_iframe {
58- overflow-x: auto;
59- overflow-y: hidden;
60+ overflow-x: auto;
61+ overflow-y: hidden;
62 }
63-
64+
65 </style>
66-
67+
68 </%def>
69
70 <%def name="content()">
71@@ -57,39 +43,39 @@
72
73 <div id="menutabs" class="notebook menu-tabs">
74 %for parent in parents:
75- <div id="${parent['id']}" title="${parent['name']}"></div>
76+ <div id="${parent['id']}" title="${parent['name']}"></div>
77 %endfor
78 </div>
79
80 <script type="text/javascript">
81-
82+
83 var nb = new Notebook('menutabs', {
84 'closable': false,
85 'scrollable': true
86 });
87-
88- MochiKit.Signal.connect(nb, 'click', function(nb, tab){
89+
90+ MochiKit.Signal.connect(nb, 'click', function(nb, tab) {
91 window.location.href = openobject.http.getURL("/menu", {active: tab.id});
92 });
93-
94+
95 </script>
96-
97+
98 <table id="contents" width="100%">
99 <tr>
100 <td width="250" valign="top">
101 <div id="menubar" class="accordion">
102 % for tool in tools:
103- <div class="accordion-block">
104- <table class="accordion-title">
105- <tr>
106- <td><img src="${tool['icon']}" width="16" height="16" align="left"/></td>
107- <td>${tool['name']}</td>
108- </tr>
109- </table>
110- <div class="accordion-content">
111- ${tool['tree'].display()}
112+ <div class="accordion-block">
113+ <table class="accordion-title">
114+ <tr>
115+ <td><img alt="" src="${tool['icon']}" width="16" height="16" align="left"/></td>
116+ <td>${tool['name']}</td>
117+ </tr>
118+ </table>
119+ <div class="accordion-content">
120+ ${tool['tree'].display()}
121+ </div>
122 </div>
123- </div>
124 % endfor
125 </div>
126 <script type="text/javascript">
127@@ -97,16 +83,16 @@
128 </script>
129 </td>
130 <td valign="top">
131- % if setup:
132- <iframe id="appFrame" width="100%"
133- scrolling="no"
134- frameborder="0"
135- name="appFrame" src="${py.url('/home')}"></iframe>
136+ % if setup:
137+ <iframe id="appFrame" width="100%"
138+ scrolling="no"
139+ frameborder="0"
140+ name="appFrame" src="${py.url('/home')}"></iframe>
141 % else:
142- <iframe id="appFrame" width="100%"
143- scrolling="no"
144- frameborder="0"
145- name="appFrame"></iframe>
146+ <iframe id="appFrame" width="100%"
147+ scrolling="no"
148+ frameborder="0"
149+ name="appFrame"></iframe>
150 % endif
151 </td>
152 </tr>
153
154=== modified file 'addons/openerp/static/javascript/ajax_stat.js'
155--- addons/openerp/static/javascript/ajax_stat.js 2010-04-06 09:51:49 +0000
156+++ addons/openerp/static/javascript/ajax_stat.js 2010-04-06 12:34:17 +0000
157@@ -79,7 +79,6 @@
158
159 MochiKit.Signal.connect(window, "onresize", onAjaxStatPosition);
160 MochiKit.Signal.connect(window, "onscroll", onAjaxStatPosition);
161-
162 onAjaxStatPosition();
163 });
164
165
166=== modified file 'addons/openerp/static/javascript/form.js'
167--- addons/openerp/static/javascript/form.js 2010-04-06 09:51:49 +0000
168+++ addons/openerp/static/javascript/form.js 2010-04-06 12:34:17 +0000
169@@ -593,6 +593,7 @@
170 }
171
172 MochiKit.Signal.signal(fld, 'onchange');
173+ MochiKit.Signal.signal(window.document, 'onfieldchange', fld);
174 }
175
176 fld.__lock_onchange = false;
177
178=== modified file 'addons/openerp/static/javascript/listgrid.js'
179--- addons/openerp/static/javascript/listgrid.js 2010-04-06 09:51:49 +0000
180+++ addons/openerp/static/javascript/listgrid.js 2010-04-06 12:34:17 +0000
181@@ -40,11 +40,11 @@
182 }
183
184 this.__init__(name);
185-}
186+};
187
188 ListView.prototype = {
189
190- __init__: function(name){
191+ __init__: function(name) {
192
193 var prefix = name == '_terp_list' ? '' : name + '/';
194
195@@ -69,130 +69,125 @@
196 openobject.dom.get(name).__listview = this;
197 },
198
199- checkAll: function(clear){
200+ checkAll: function(clear) {
201
202 clear = clear ? false : true;
203
204 boxes = openobject.dom.get(this.name).getElementsByTagName('input');
205- forEach(boxes, function(box){
206+ forEach(boxes, function(box) {
207 box.checked = clear;
208 });
209 },
210
211 getRecords: function() {
212- var records = map(function(row){
213+ var records = map(function(row) {
214 return parseInt(getNodeAttribute(row, 'record')) || 0;
215 }, openobject.dom.select('tr.grid-row', this.name));
216
217- return filter(function(rec){
218+ return filter(function(rec) {
219 return rec;
220 }, records);
221 },
222
223 getSelectedRecords: function() {
224- return map(function(box){
225+ return map(function(box) {
226 return box.value;
227 }, this.getSelectedItems());
228 },
229
230 getSelectedItems: function() {
231- return filter(function(box){
232+ return filter(function(box) {
233 return box.id && box.checked;
234 }, openobject.dom.select('input.grid-record-selector', this.name));
235 },
236
237- getColumns: function(dom){
238+ getColumns: function(dom) {
239 dom = dom || this.name;
240 var header = openobject.dom.select('tr.grid-header', dom)[0];
241
242- return filter(function(c){
243+ return filter(function(c) {
244 return c.id ? true : false;
245 }, openobject.dom.select('th.grid-cell', header));
246 },
247-
248- makeArgs: function(){
249
250+ makeArgs: function() {
251 var args = {};
252- var name = '/' + this.name;
253- var names = name.split('/');
254+ var names = ('/' + this.name).split('/');
255
256 var prefix = '';
257 var items = openobject.dom.select('input');
258
259- while(names.length) {
260+ while (names.length) {
261
262 var name = names.shift();
263 prefix = prefix + (name ? name + '/' : '');
264
265- var patern = prefix + '_terp_';
266+ var pattern = prefix + '_terp_';
267
268- forEach(items, function(item){
269- if(item.name.match("^"+ patern) == patern && !item.name.match('^_terp_listfields/')) {
270- args[item.name] = item.value;
271+ forEach(items, function(item) {
272+ if (item.name.match("^" + pattern) == pattern && !item.name.match('^_terp_listfields/')) {
273+ args[item.name] = item.value;
274 }
275 });
276 }
277
278 return args;
279 }
280-}
281+};
282
283 // inline editor related functions
284 MochiKit.Base.update(ListView.prototype, {
285
286- adjustEditors: function(newlist){
287+ adjustEditors: function(newlist) {
288
289 var editors = this.getEditors(false, newlist);
290-
291 forEach(editors, function(e) {
292 // disable autocomplete (Firefox < 2.0 focus bug)
293 setNodeAttribute(e, 'autocomplete', 'OFF');
294 });
295
296- if (/MSIE/.test(navigator.userAgent)){
297+ if (/MSIE/.test(navigator.userAgent)) {
298 return editors;
299 }
300
301- var widths = {};
302-
303+ var columnWidths = {};
304 // set the column widths of the newlist
305- forEach(this.getColumns(), function(c){
306- widths[c.id] = parseInt(c.offsetWidth) - 8;
307- });
308-
309- forEach(this.getColumns(newlist), function(c){
310- c.style.width = widths[c.id] + 'px';
311- });
312-
313- var widths = {};
314- forEach(this.getEditors(), function(e){
315- widths[e.id] = parseInt(e.offsetWidth);
316+ forEach(this.getColumns(), function(c) {
317+ columnWidths[c.id] = parseInt(c.offsetWidth) - 8;
318+ });
319+
320+ forEach(this.getColumns(newlist), function(c) {
321+ c.style.width = columnWidths[c.id] + 'px';
322+ });
323+
324+ var editorWidths = {};
325+ forEach(this.getEditors(), function(e) {
326+ editorWidths[e.id] = parseInt(e.offsetWidth);
327 });
328
329 return editors;
330 },
331
332- bindKeyEventsToEditors: function(editors){
333+ bindKeyEventsToEditors: function(editors) {
334 var self = this;
335- var editors = filter(function(e){
336+ var enabledEditors = filter(function(e) {
337 return e.type != 'hidden' && !e.disabled
338 }, editors);
339
340- forEach(editors, function(e){
341+ forEach(enabledEditors, function(e) {
342 connect(e, 'onkeydown', self, self.onKeyDown);
343 addElementClass(e, 'listfields');
344 });
345 },
346
347- getEditors: function(named, dom){
348- var editors = [];
349+ getEditors: function(named, dom) {
350 var dom = dom ? dom : this.name;
351
352- editors = openobject.dom.select("input, select, textarea", dom);
353+ var editors = openobject.dom.select("input, select, textarea", dom);
354
355- return filter(function(e){
356+ return filter(function(e) {
357 name = named ? e.name : e.id;
358- return name && name.indexOf('_terp_listfields') == 0;
359+ return name && name.indexOf('_terp_listfields') == 0;
360 }, editors);
361 }
362
363@@ -200,49 +195,49 @@
364
365 // pagination & reordering
366 MochiKit.Base.update(ListView.prototype, {
367- sort_by_order: function(id) {
368- var self = this
369- var domain = [];
370- var args = {}
371- if(getElement('_'+this.name+'_button1'))
372- domain = getNodeAttribute(getElement('_'+this.name+'_button1'),'domain')
373-
374- args['_terp_model'] = this.model
375- args['_terp_sort_order'] = id
376- args['_terp_sort_domain'] = domain
377- var _terp_id = openobject.dom.get(self.name + '/_terp_id') || openobject.dom.get('_terp_id');
378+ sort_by_order: function(id) {
379+ var self = this;
380+ var domain = [];
381+ var args = {};
382+ if (getElement('_' + this.name + '_button1')) {
383+ domain = getNodeAttribute(getElement('_' + this.name + '_button1'), 'domain');
384+ }
385+
386+ args['_terp_model'] = this.model;
387+ args['_terp_sort_order'] = id;
388+ args['_terp_sort_domain'] = domain;
389+ var _terp_id = openobject.dom.get(self.name + '/_terp_id') || openobject.dom.get('_terp_id');
390 var _terp_ids = openobject.dom.get(self.name + '/_terp_ids') || openobject.dom.get('_terp_ids');
391-
392- if(this.ids!='[]')
393- {
394- var req = openobject.http.postJSON('/listgrid/sort_by_order', args);
395- req.addCallback(function(obj) {
396- if(obj.ids) {
397- _terp_ids.value = '[' + obj.ids.join(',') + ']';
398- self.reload();
399- }
400- else
401- alert(obj.error)
402- })
403- }
404- },
405-
406- dragRow: function(drag,drop,event) {
407- var args = {}
408- var _list_view = new ListView(drag.parentNode.parentNode.id.split("_grid")[0]);
409- var _terp_model = getElement(drag.parentNode.parentNode.id.split("_grid")[0]+'/_terp_model') || getElement('_terp_model')
410- args['_terp_model'] = _terp_model.value
411- var _terp_ids = getElement(drag.parentNode.parentNode.id.split("_grid")[0]+'/_terp_ids') || getElement('_terp_ids')
412- args['_terp_ids'] = _terp_ids.value
413- args['_terp_id'] = getNodeAttribute(drag,'record')
414- args['_terp_swap_id'] = getNodeAttribute(drop,'record')
415-
416- var req = openobject.http.postJSON('/listgrid/dragRow', args);
417- req.addCallback(function() {
418- _list_view.reload()
419- })
420- },
421-
422+
423+ if (this.ids != '[]') {
424+ var req = openobject.http.postJSON('/listgrid/sort_by_order', args);
425+ req.addCallback(function(obj) {
426+ if (obj.ids) {
427+ _terp_ids.value = '[' + obj.ids.join(',') + ']';
428+ self.reload();
429+ } else {
430+ alert(obj.error);
431+ }
432+ })
433+ }
434+ },
435+
436+ dragRow: function(drag, drop, event) {
437+ var args = {};
438+ var _list_view = new ListView(drag.parentNode.parentNode.id.split("_grid")[0]);
439+ var _terp_model = getElement(drag.parentNode.parentNode.id.split("_grid")[0] + '/_terp_model') || getElement('_terp_model');
440+ args['_terp_model'] = _terp_model.value;
441+ var _terp_ids = getElement(drag.parentNode.parentNode.id.split("_grid")[0] + '/_terp_ids') || getElement('_terp_ids');
442+ args['_terp_ids'] = _terp_ids.value;
443+ args['_terp_id'] = getNodeAttribute(drag, 'record');
444+ args['_terp_swap_id'] = getNodeAttribute(drop, 'record');
445+
446+ var req = openobject.http.postJSON('/listgrid/dragRow', args);
447+ req.addCallback(function() {
448+ _list_view.reload();
449+ })
450+ },
451+
452 moveUp: function(id) {
453
454 var self = this;
455@@ -250,11 +245,11 @@
456
457 args['_terp_model'] = this.model;
458 args['_terp_ids'] = this.ids;
459-
460+
461 args['_terp_id'] = id;
462
463 var req = openobject.http.postJSON('/listgrid/moveUp', args);
464- req.addCallback(function(){
465+ req.addCallback(function() {
466 self.reload();
467 });
468 },
469@@ -262,14 +257,14 @@
470 moveDown: function(id) {
471
472 var self = this;
473- var args = {};
474-
475- args['_terp_model'] = this.model;
476- args['_terp_ids'] = this.ids;
477- args['_terp_id'] = id;
478+ var args = {
479+ '_terp_model': this.model,
480+ '_terp_ids': this.ids,
481+ '_terp_id': id
482+ };
483
484 var req = openobject.http.postJSON('/listgrid/moveDown', args);
485- req.addCallback(function(){
486+ req.addCallback(function() {
487 self.reload();
488 });
489 }
490@@ -278,7 +273,7 @@
491 // event handlers
492 MochiKit.Base.update(ListView.prototype, {
493
494- onKeyDown: function(evt){
495+ onKeyDown: function(evt) {
496 var key = evt.key();
497 var src = evt.src();
498
499@@ -286,19 +281,19 @@
500 return;
501 }
502
503- if (key.string == "KEY_ESCAPE"){
504+ if (key.string == "KEY_ESCAPE") {
505 evt.stop();
506 return this.reload();
507 }
508
509- if (key.string == "KEY_ENTER"){
510+ if (key.string == "KEY_ENTER") {
511
512- if (hasElementClass(src, "m2o")){
513+ if (hasElementClass(src, "m2o")) {
514
515 var k = src.id;
516 k = k.slice(0, k.length - 5);
517
518- if (src.value && !openobject.dom.get(k).value){
519+ if (src.value && !openobject.dom.get(k).value) {
520 return;
521 }
522 }
523@@ -311,21 +306,21 @@
524 return this.save(this.current_record);
525 }
526
527- var editors = openobject.dom.select('listfields',this.name);
528+ var editors = openobject.dom.select('listfields', this.name);
529
530 var first = editors.shift();
531 var last = editors.pop();
532
533- if (src == last){
534+ if (src == last) {
535 evt.stop();
536 first.focus();
537 first.select();
538 }
539 },
540
541- onButtonClick: function(name, btype, id, sure, context){
542+ onButtonClick: function(name, btype, id, sure, context) {
543
544- if (sure && !confirm(sure)){
545+ if (sure && !confirm(sure)) {
546 return;
547 }
548
549@@ -334,15 +329,15 @@
550
551 if (btype == "open") {
552 return window.open(get_form_action('/form/edit', {
553- id: id,
554- ids: openobject.dom.get(prefix + '_terp_ids').value,
555- model: openobject.dom.get(prefix + '_terp_model').value,
556- view_ids: openobject.dom.get(prefix + '_terp_view_ids').value,
557- domain: openobject.dom.get(prefix + '_terp_domain').value,
558- context: openobject.dom.get(prefix + '_terp_context').value,
559- limit: openobject.dom.get(prefix + '_terp_limit').value,
560- offset: openobject.dom.get(prefix + '_terp_offset').value,
561- count: openobject.dom.get(prefix + '_terp_count').value}));
562+ id: id,
563+ ids: openobject.dom.get(prefix + '_terp_ids').value,
564+ model: openobject.dom.get(prefix + '_terp_model').value,
565+ view_ids: openobject.dom.get(prefix + '_terp_view_ids').value,
566+ domain: openobject.dom.get(prefix + '_terp_domain').value,
567+ context: openobject.dom.get(prefix + '_terp_context').value,
568+ limit: openobject.dom.get(prefix + '_terp_limit').value,
569+ offset: openobject.dom.get(prefix + '_terp_offset').value,
570+ count: openobject.dom.get(prefix + '_terp_count').value}));
571 }
572
573 name = name.split('.').pop();
574@@ -352,14 +347,14 @@
575 _terp_id : id,
576 _terp_button_name : name,
577 _terp_button_type : btype
578- }
579+ };
580
581 var req = eval_domain_context_request({source: this.name, context : context || '{}'});
582- req.addCallback(function(res){
583+ req.addCallback(function(res) {
584 params['_terp_context'] = res.context;
585 var req = openobject.http.postJSON('/listgrid/button_action', params);
586- req.addCallback(function(obj){
587- if (obj.error){
588+ req.addCallback(function(obj) {
589+ if (obj.error) {
590 return alert(obj.error);
591 }
592
593@@ -369,8 +364,9 @@
594
595 if (obj.reload) {
596 window.location.reload();
597- } else
598+ } else {
599 self.reload();
600+ }
601 });
602 });
603 }
604@@ -379,15 +375,15 @@
605 // standard actions
606 MochiKit.Base.update(ListView.prototype, {
607
608- create: function(default_get_ctx){
609+ create: function(default_get_ctx) {
610 this.edit(-1, default_get_ctx);
611 },
612
613- edit: function(edit_inline, default_get_ctx){
614+ edit: function(edit_inline, default_get_ctx) {
615 this.reload(edit_inline, null, default_get_ctx);
616 },
617
618- save: function(id){
619+ save: function(id) {
620
621 if (openobject.http.AJAX_COUNT > 0) {
622 return callLater(1, bind(this.save, this), id);
623@@ -397,7 +393,7 @@
624 var data = getFormData(true);
625 var args = getFormParams('_terp_concurrency_info');
626
627- for(var k in data) {
628+ for (var k in data) {
629 if (k.indexOf(this.name + '/') == 0 || this.name == '_terp_list') {
630 args[k] = data[k];
631 }
632@@ -409,7 +405,7 @@
633 args['_terp_ids'] = openobject.dom.get(prefix + '_terp_ids').value;
634 args['_terp_model'] = this.model;
635
636- if (parent_field.length > 0){
637+ if (parent_field.length > 0) {
638 parent_field.pop();
639 }
640
641@@ -422,17 +418,18 @@
642 args['_terp_source'] = this.name;
643
644 var self = this;
645- var req= openobject.http.postJSON('/listgrid/save', args);
646+ var req = openobject.http.postJSON('/listgrid/save', args);
647
648- req.addCallback(function(obj){
649- if (obj.error){
650+ req.addCallback(function(obj) {
651+ if (obj.error) {
652 alert(obj.error);
653
654 if (obj.error_field) {
655 var fld = openobject.dom.get('_terp_listfields/' + obj.error_field);
656
657- if (fld && getNodeAttribute(fld, 'kind') == 'many2one')
658+ if (fld && getNodeAttribute(fld, 'kind') == 'many2one') {
659 fld = openobject.dom.get(fld.id + '_text');
660+ }
661
662 if (fld) {
663 fld.focus();
664@@ -445,26 +442,26 @@
665 openobject.dom.get(prefix + '_terp_ids').value = obj.ids;
666
667 self.reload(id > 0 ? null : -1, prefix ? 1 : 0);
668- }
669- });
670+ }
671+ });
672 },
673
674- remove: function(ids){
675+ remove: function(ids) {
676
677 var self = this;
678- var args = getFormParams('_terp_concurrency_info');;
679-
680- if(!ids) {
681+ var args = getFormParams('_terp_concurrency_info');
682+
683+
684+ if (!ids) {
685 var ids = this.getSelectedRecords();
686- if(ids.length > 0){
687+ if (ids.length > 0) {
688 ids = '[' + ids.join(', ') + ']';
689 }
690 }
691
692 if (ids.length == 0) {
693 return alert(_('You must select at least one record.'));
694- }
695- else if (!confirm(_('Do you really want to delete selected record(s) ?'))) {
696+ } else if (!confirm(_('Do you really want to delete selected record(s) ?'))) {
697 return false;
698 }
699
700@@ -473,8 +470,8 @@
701
702 var req = openobject.http.postJSON('/listgrid/remove', args);
703
704- req.addCallback(function(obj){
705- if (obj.error){
706+ req.addCallback(function(obj) {
707+ if (obj.error) {
708 alert(obj.error);
709 } else {
710 self.reload();
711@@ -482,9 +479,9 @@
712 });
713 },
714
715- go: function(action){
716+ go: function(action) {
717
718- if (openobject.http.AJAX_COUNT > 0){
719+ if (openobject.http.AJAX_COUNT > 0) {
720 return;
721 }
722
723@@ -498,7 +495,7 @@
724 var lv = l.value ? parseInt(l.value) : 0;
725 var cv = c.value ? parseInt(c.value) : 0;
726
727- switch(action) {
728+ switch (action) {
729 case 'next':
730 o.value = ov + lv;
731 break;
732@@ -516,7 +513,7 @@
733 this.reload();
734 },
735
736- reload: function(edit_inline, concurrency_info, default_get_ctx){
737+ reload: function(edit_inline, concurrency_info, default_get_ctx) {
738
739 if (openobject.http.AJAX_COUNT > 0) {
740 return callLater(1, bind(this.reload, this), edit_inline, concurrency_info);
741@@ -524,7 +521,7 @@
742
743 var self = this;
744 var args = this.makeArgs();
745-
746+
747 // add args
748 args['_terp_source'] = this.name;
749 args['_terp_edit_inline'] = edit_inline;
750@@ -537,15 +534,15 @@
751 args['_terp_search_data'] = openobject.dom.get('_terp_search_data').value;
752 args['_terp_filter_domain'] = openobject.dom.get('_terp_filter_domain').value;
753 }
754-
755+
756 var req = openobject.http.postJSON('/listgrid/get', args);
757- req.addCallback(function(obj){
758+ req.addCallback(function(obj) {
759
760 var _terp_id = openobject.dom.get(self.name + '/_terp_id') || openobject.dom.get('_terp_id');
761 var _terp_ids = openobject.dom.get(self.name + '/_terp_ids') || openobject.dom.get('_terp_ids');
762 var _terp_count = openobject.dom.get(self.name + '/_terp_count') || openobject.dom.get('_terp_count');
763
764- if(obj.ids) {
765+ if (obj.ids) {
766 _terp_id.value = obj.ids.length ? obj.ids[0] : 'False';
767 _terp_ids.value = '[' + obj.ids.join(',') + ']';
768 _terp_count.value = obj.count;
769@@ -557,8 +554,9 @@
770 var newlist = d.getElementsByTagName('table')[0];
771 var editors = self.adjustEditors(newlist);
772
773- if (editors.length > 0)
774+ if (editors.length > 0) {
775 self.bindKeyEventsToEditors(editors);
776+ }
777
778 self.current_record = edit_inline;
779
780@@ -571,20 +569,21 @@
781 if ((navigator.appName != 'Netscape') || (ua.indexOf('safari') != -1)) {
782 // execute JavaScript
783 var scripts = openobject.dom.select('script', newlist);
784- forEach(scripts, function(s){
785+ forEach(scripts, function(s) {
786 eval(s.innerHTML);
787 });
788 }
789
790 // update concurrency info
791- for(var key in obj.info) {
792+ for (var key in obj.info) {
793 try {
794 var items = openobject.dom.select("[name=_terp_concurrency_info][value*=" + key + "]")
795 var value = "('" + key + "', '" + obj.info[key] + "')";
796- for(var i=0; i<items.length;i++) {
797+ for (var i = 0; i < items.length; i++) {
798 items[i].value = value;
799 }
800- }catch(e){}
801+ } catch(e) {
802+ }
803 }
804
805 // set focus on the first field
806@@ -596,7 +595,7 @@
807
808 // call on_change for default values
809 if (editors.length && edit_inline == -1) {
810- forEach(editors, function(e){
811+ forEach(editors, function(e) {
812 if (e.value && getNodeAttribute(e, 'callback')) {
813 MochiKit.Signal.signal(e, 'onchange');
814 }
815@@ -612,7 +611,7 @@
816 // export/import functions
817 MochiKit.Base.update(ListView.prototype, {
818
819- exportData: function(){
820+ exportData: function() {
821
822 var ids = this.getSelectedRecords();
823
824@@ -623,69 +622,65 @@
825 ids = '[' + ids.join(',') + ']';
826
827 openobject.tools.openWindow(openobject.http.getURL('/impex/exp', {_terp_model: this.model,
828- _terp_source: this.name,
829- _terp_search_domain: openobject.dom.get('_terp_search_domain').value,
830- _terp_ids: ids,
831- _terp_view_ids : this.view_ids,
832- _terp_view_mode : this.view_mode}));
833+ _terp_source: this.name,
834+ _terp_search_domain: openobject.dom.get('_terp_search_domain').value,
835+ _terp_ids: ids,
836+ _terp_view_ids : this.view_ids,
837+ _terp_view_mode : this.view_mode}));
838 },
839
840- importData: function(){
841+ importData: function() {
842 openobject.tools.openWindow(openobject.http.getURL('/impex/imp', {_terp_model: this.model,
843- _terp_source: this.name,
844- _terp_view_ids : this.view_ids,
845- _terp_view_mode : this.view_mode}));
846+ _terp_source: this.name,
847+ _terp_view_ids : this.view_ids,
848+ _terp_view_mode : this.view_mode}));
849 }
850 });
851
852 var toggle_group_data = function(id) {
853-
854- img = openobject.dom.get('img_'+id);
855- rows = openobject.dom.select('tr.'+id);
856-
857- forEach(rows, function(rw){
858- if (rw.style.display == 'none') {
859- rw.style.display = '';
860- setNodeAttribute(img, 'src', '/openerp/static/images/treegrid/collapse.gif');
861- }
862- else {
863- rw.style.display = 'none';
864- setNodeAttribute(img, 'src', '/openerp/static/images/treegrid/expand.gif');
865- }
866- });
867-}
868+
869+ img = openobject.dom.get('img_' + id);
870+ rows = openobject.dom.select('tr.' + id);
871+
872+ forEach(rows, function(rw) {
873+ if (rw.style.display == 'none') {
874+ rw.style.display = '';
875+ setNodeAttribute(img, 'src', '/openerp/static/images/treegrid/collapse.gif');
876+ }
877+ else {
878+ rw.style.display = 'none';
879+ setNodeAttribute(img, 'src', '/openerp/static/images/treegrid/expand.gif');
880+ }
881+ });
882+};
883
884 var row_edit = function(evt) {
885- var row = [];
886- row = getElementsByTagAndClassName('tr', 'grid-row');
887-
888- forEach(row, function(e){
889- MochiKit.Signal.connect(e, 'ondblclick', e, select_row_edit);
890+ var row = getElementsByTagAndClassName('tr', 'grid-row');
891+
892+ forEach(row, function(e) {
893+ MochiKit.Signal.connect(e, 'ondblclick', e, select_row_edit);
894 });
895-}
896+};
897
898-var select_row_edit = function(e){
899- src = e.src();
900- src_record = getNodeAttribute(src, 'record');
901- target = e.target();
902- target_class = getNodeAttribute(target,'class');
903+var select_row_edit = function(e) {
904+ src = e.src();
905+ src_record = getNodeAttribute(src, 'record');
906+ target = e.target();
907+ target_class = getNodeAttribute(target, 'class');
908
909 var view_type = getElement('_terp_view_type').value;
910 var editable = getElement('_terp_editable').value;
911
912- if (!(target_class == 'checkbox grid-record-selector' || target_class == 'listImage')) {
913- if ((view_type == 'tree' && editable != 'True')) {
914- do_select(src_record);
915- }
916- if ((view_type == 'tree' && editable == 'True')){
917- editRecord(src_record);
918- }
919- }
920-}
921+ if (!(target_class == 'checkbox grid-record-selector' || target_class == 'listImage')) {
922+ if ((view_type == 'tree' && editable != 'True')) {
923+ do_select(src_record);
924+ }
925+ if ((view_type == 'tree' && editable == 'True')) {
926+ editRecord(src_record);
927+ }
928+ }
929+};
930
931-MochiKit.DOM.addLoadEvent(function(evt){
932- row_edit(evt);
933+MochiKit.DOM.addLoadEvent(function(evt) {
934+ row_edit(evt);
935 });
936-
937-// vim: ts=4 sts=4 sw=4 si et
938-
939
940=== removed file 'addons/openerp/static/javascript/menubar.js'
941--- addons/openerp/static/javascript/menubar.js 2010-04-06 09:51:49 +0000
942+++ addons/openerp/static/javascript/menubar.js 1970-01-01 00:00:00 +0000
943@@ -1,29 +0,0 @@
944-/**
945- * Allowable width for the left-hand menu (for the current application)
946- */
947-var MENU_WIDTH = 250;
948-/**
949- * Tries to fit the size of the #appFrame frame to better fit its current
950- * content.extend
951- * Has to be called from the document outside of the frame itself.
952- *
953- * Probably won't get it exactly right, you might want to call it
954- * several times
955- */
956-function adjustAppFrame() {
957- var frameHeight = jQuery("#appFrame").contents().find("body").height();
958- var frameWidth = jQuery("#appFrame").contents().width();
959-
960- jQuery("#menubar").width(MENU_WIDTH);
961- jQuery("#appFrame").height(Math.max(0, frameHeight));
962-
963- var menuWidth = jQuery("#menubar").height();
964- var windowWidth = jQuery(window).width();
965- var totalWidth = jQuery("#menubar").width() + frameWidth;
966- var rw = windowWidth - jQuery("#menubar").width();
967-
968- var newWidth = totalWidth > windowWidth ? frameWidth : rw - 16;
969-
970- jQuery("#appFrame").width(Math.max(0, newWidth));
971- jQuery("table#contents").height(Math.max(frameHeight, menuWidth));
972-}
973
974=== modified file 'addons/openerp/static/javascript/notebook/notebook.js'
975--- addons/openerp/static/javascript/notebook/notebook.js 2010-04-06 09:51:49 +0000
976+++ addons/openerp/static/javascript/notebook/notebook.js 2010-04-06 12:34:17 +0000
977@@ -27,6 +27,22 @@
978 //
979 ////////////////////////////////////////////////////////////////////////////////
980
981+/**
982+ *
983+ * @event show triggered when a tab of the notebook is displayed
984+ * @argument notebook the notebook instance this
985+ * event was triggered from
986+ * @argument tab the (DOM element) tab being showed
987+ * @event hide triggered when a tab of the notebook is hidden
988+ * @arguments 'see show'
989+ * @event activate triggered when a tab is set as the active tab
990+ * @arguments 'see show'
991+ * @event remove triggered when a tab is removed from the notebook
992+ * @arguments 'see show'
993+ * @event click triggered when the notebook's tab bar is clicked
994+ * @arguments 'see show'
995+ *
996+ */
997 var Notebook = function(element, options) {
998
999 var cls = arguments.callee;
1000
1001=== modified file 'addons/openerp/static/javascript/openerp/openerp.ui.textarea.js'
1002--- addons/openerp/static/javascript/openerp/openerp.ui.textarea.js 2010-04-06 09:51:49 +0000
1003+++ addons/openerp/static/javascript/openerp/openerp.ui.textarea.js 2010-04-06 12:34:17 +0000
1004@@ -32,55 +32,59 @@
1005 throw "openerp.ui is required by 'openerp.ui.textarea'.";
1006 }
1007
1008-openerp.ui.TextArea = function(ta){
1009+/**
1010+ * @event onresize triggered when the widget's grip is moved (to resize the text area)
1011+ * @parameter 'the TextArea instance'
1012+ */
1013+openerp.ui.TextArea = function(ta) {
1014 this.__init__(ta);
1015-}
1016+};
1017
1018 openerp.ui.TextArea.prototype = {
1019-
1020- __init__ : function(ta){
1021+
1022+ __init__ : function(ta) {
1023 this.textarea = openobject.dom.get(ta);
1024 this.gripper = DIV({'class' : 'grip'});
1025-
1026+
1027 this.ta = this.textarea.cloneNode(true);
1028-
1029- MochiKit.DOM.swapDOM(this.textarea, DIV({'class' : 'resizable-textarea'}, this.ta, this.gripper));
1030-
1031- this.textarea = openobject.dom.get(this.ta);
1032+
1033+ MochiKit.DOM.swapDOM(this.textarea,
1034+ DIV({'class' : 'resizable-textarea'},
1035+ this.ta, this.gripper)).textarea = this;
1036+
1037+ this.textarea = openobject.dom.get(this.ta);
1038 this.draggin = false;
1039-
1040+
1041 this.evtMouseDn = MochiKit.Signal.connect(this.gripper, 'onmousedown', this, "dragStart");
1042 },
1043-
1044- __delete__ : function(){
1045+
1046+ __delete__ : function() {
1047 MochiKit.Signal.disconnect(this.evtMouseDn);
1048 },
1049-
1050- dragStart : function(evt){
1051-
1052- if (!evt.mouse().button.left)
1053+
1054+ dragStart : function(evt) {
1055+ if (!evt.mouse().button.left) {
1056 return;
1057+ }
1058
1059 this.offset = openobject.dom.height(this.textarea) - evt.mouse().page.y;
1060-
1061+
1062 this.evtMouseMv = MochiKit.Signal.connect(document, 'onmousemove', this, "dragUpdate");
1063 this.evtMouseUp = MochiKit.Signal.connect(document, 'onmouseup', this, "dragStop");
1064 },
1065-
1066- dragUpdate : function(evt){
1067+
1068+ dragUpdate : function(evt) {
1069 var h = Math.max(32, this.offset + evt.mouse().page.y);
1070 this.textarea.style.height = h + 'px';
1071- evt.stop();
1072+ MochiKit.Signal.signal(this, 'onresize', this);
1073+ evt.stop();
1074 },
1075-
1076- dragStop : function(evt){
1077+
1078+ dragStop : function(evt) {
1079 //MochiKit.Signal.disconnect(this.evtMouseMv);
1080 //MochiKit.Signal.disconnect(this.evtMouseUp);
1081 MochiKit.Signal.disconnectAll(document, 'onmousemove', this, "dragUpdate");
1082 MochiKit.Signal.disconnectAll(document, 'onmouseup', this, "dragStop");
1083- evt.stop();
1084+ evt.stop();
1085 }
1086-}
1087-
1088-// vim: ts=4 sts=4 sw=4 si et
1089-
1090+};
1091
1092=== modified file 'addons/openerp/static/javascript/search.js'
1093--- addons/openerp/static/javascript/search.js 2010-04-06 11:03:33 +0000
1094+++ addons/openerp/static/javascript/search.js 2010-04-06 12:34:17 +0000
1095@@ -26,363 +26,380 @@
1096 // You can see the MPL licence at: http://www.mozilla.org/MPL/MPL-1.1.html
1097 //
1098 ////////////////////////////////////////////////////////////////////////////////
1099-
1100-var add_filter_row = function() {
1101-
1102- var filter_table = $('filter_table');
1103- var vals = [];
1104- var row_id = 1;
1105-
1106- var first_row = $('filter_row/0');
1107- var trs = MochiKit.DOM.getElementsByTagAndClassName('tr', null, filter_table)
1108-
1109- if (filter_table.style.display == 'none') {
1110- filter_table.style.display = '';
1111- }
1112-
1113- else if (first_row.style.display == 'none' && trs.length <= 1) {
1114- MochiKit.DOM.getFirstElementByTagAndClassName('select', 'filter_fields', first_row).selectedIndex = 0;
1115- MochiKit.DOM.getFirstElementByTagAndClassName('select', 'expr', first_row).selectedIndex = 0;
1116- var old_qstring = MochiKit.DOM.getFirstElementByTagAndClassName('input', 'qstring', first_row);
1117- old_qstring.value = '';
1118- old_qstring.style.background = '#FFFFFF';
1119- first_row.style.display = ''
1120- }
1121-
1122- else{
1123-
1124- var old_tr = trs[trs.length-1]
1125- var old_qstring = MochiKit.DOM.getFirstElementByTagAndClassName('input', 'qstring', old_tr);
1126- old_qstring.style.background = '#FFFFFF';
1127-
1128- var new_tr = old_tr.cloneNode(true);
1129- keys = new_tr.id.split('/');
1130- id = parseInt(keys[1], 0);
1131- row_id = id + row_id
1132- new_tr.id = keys[0] +'/'+ row_id;
1133- var filter_column = MochiKit.DOM.getFirstElementByTagAndClassName('td', 'filter_column', new_tr);
1134-
1135- var filter_fields = MochiKit.DOM.getFirstElementByTagAndClassName('select', 'filter_fields', new_tr);
1136- var expr = MochiKit.DOM.getFirstElementByTagAndClassName('select', 'expr', new_tr);
1137- var qstring = MochiKit.DOM.getFirstElementByTagAndClassName('input', 'qstring', new_tr);
1138-
1139- filter_column.id = filter_column.id.split('/')[0] + '/' + row_id;
1140- filter_fields.id = filter_fields.id.split('/')[0] + '/' + row_id;
1141- expr.id = expr.id.split('/')[0] + '/' + row_id;
1142- qstring.id = qstring.id.split('/')[0] + '/' + row_id;
1143- qstring.style.background = '#FFFFFF';
1144- qstring.value = '';
1145-
1146- var image_col = MochiKit.DOM.getFirstElementByTagAndClassName('td', 'image_col', new_tr);
1147- image_col.id = 'image_col/' + row_id
1148-
1149- var and_or = MochiKit.DOM.getFirstElementByTagAndClassName('td', 'and_or', new_tr);
1150- if (and_or){removeElement(and_or); }
1151-
1152- var and_or = MochiKit.DOM.createDOM('td');
1153- and_or.id = 'and_or/' + id;
1154- and_or.className = 'and_or';
1155-
1156- var select_andor = MochiKit.DOM.createDOM('select');
1157- select_andor.id = 'select_andor/' + id;
1158- select_andor.className = 'select_andor';
1159-
1160- var option = MochiKit.DOM.createDOM('option');
1161-
1162- vals.push('AND');
1163- vals.push('OR');
1164-
1165- option = map(function(x){return OPTION({'value': x}, x)}, vals);
1166- image_replace = openobject.dom.get('image_col/'+ id);
1167- if(MochiKit.DOM.getFirstElementByTagAndClassName('td', 'and_or', old_tr) == null){
1168- insertSiblingNodesBefore(image_replace, and_or)
1169- }
1170-
1171- appendChildNodes(select_andor, option);
1172- appendChildNodes(and_or, select_andor);
1173- insertSiblingNodesAfter(old_tr, new_tr);
1174- }
1175+/**
1176+ * @event onaddfilter triggered when adding a filter row
1177+ * @target #filter_table the element holding the filter rows
1178+ * @argument 'the newly added (or showed for first row?) filter row'
1179+ */
1180+function add_filter_row() {
1181+ var filter_table = $('filter_table');
1182+ var vals = [];
1183+ var row_id = 1;
1184+
1185+ var first_row = $('filter_row/0');
1186+ var trs = MochiKit.DOM.getElementsByTagAndClassName('tr', null, filter_table);
1187+ var old_qstring;
1188+
1189+ if (filter_table.style.display == 'none') {
1190+ filter_table.style.display = '';
1191+ } else if (first_row.style.display == 'none' && trs.length <= 1) {
1192+ MochiKit.DOM.getFirstElementByTagAndClassName('select', 'filter_fields', first_row).selectedIndex = 0;
1193+ MochiKit.DOM.getFirstElementByTagAndClassName('select', 'expr', first_row).selectedIndex = 0;
1194+ old_qstring = MochiKit.DOM.getFirstElementByTagAndClassName('input', 'qstring', first_row);
1195+ old_qstring.value = '';
1196+ old_qstring.style.background = '#FFFFFF';
1197+ first_row.style.display = ''
1198+ } else {
1199+ var old_tr = trs[trs.length - 1];
1200+ old_qstring = MochiKit.DOM.getFirstElementByTagAndClassName('input', 'qstring', old_tr);
1201+ old_qstring.style.background = '#FFFFFF';
1202+
1203+ var new_tr = old_tr.cloneNode(true);
1204+ keys = new_tr.id.split('/');
1205+ id = parseInt(keys[1], 0);
1206+ row_id = id + row_id;
1207+
1208+ new_tr.id = keys[0] + '/' + row_id;
1209+ var filter_column = MochiKit.DOM.getFirstElementByTagAndClassName('td', 'filter_column', new_tr);
1210+
1211+ var filter_fields = MochiKit.DOM.getFirstElementByTagAndClassName('select', 'filter_fields', new_tr);
1212+ var expr = MochiKit.DOM.getFirstElementByTagAndClassName('select', 'expr', new_tr);
1213+ var qstring = MochiKit.DOM.getFirstElementByTagAndClassName('input', 'qstring', new_tr);
1214+
1215+ filter_column.id = filter_column.id.split('/')[0] + '/' + row_id;
1216+ filter_fields.id = filter_fields.id.split('/')[0] + '/' + row_id;
1217+ expr.id = expr.id.split('/')[0] + '/' + row_id;
1218+ qstring.id = qstring.id.split('/')[0] + '/' + row_id;
1219+ qstring.style.background = '#FFFFFF';
1220+ qstring.value = '';
1221+
1222+ var image_col = MochiKit.DOM.getFirstElementByTagAndClassName('td', 'image_col', new_tr);
1223+ image_col.id = 'image_col/' + row_id;
1224+
1225+ var old_and_or = MochiKit.DOM.getFirstElementByTagAndClassName('td', 'and_or', new_tr);
1226+ if (old_and_or) {
1227+ removeElement(old_and_or);
1228+ }
1229+
1230+ var and_or = MochiKit.DOM.createDOM('td');
1231+ and_or.id = 'and_or/' + id;
1232+ and_or.className = 'and_or';
1233+
1234+ var select_andor = MochiKit.DOM.createDOM('select');
1235+ select_andor.id = 'select_andor/' + id;
1236+ select_andor.className = 'select_andor';
1237+
1238+ var option = MochiKit.DOM.createDOM('option');
1239+
1240+ vals.push('AND');
1241+ vals.push('OR');
1242+
1243+ var options = map(function(x) {
1244+ return OPTION({'value': x}, x)
1245+ }, vals);
1246+ image_replace = openobject.dom.get('image_col/' + id);
1247+ if (MochiKit.DOM.getFirstElementByTagAndClassName('td', 'and_or', old_tr) == null) {
1248+ insertSiblingNodesBefore(image_replace, and_or)
1249+ }
1250+
1251+ appendChildNodes(select_andor, options);
1252+ appendChildNodes(and_or, select_andor);
1253+ insertSiblingNodesAfter(old_tr, new_tr);
1254+ }
1255+ MochiKit.Signal.signal(filter_table, 'onaddfilter', new_tr || first_row);
1256 }
1257
1258-var remove_row = function(id) {
1259-
1260- var filter_table = $('filter_table');
1261-
1262- node = MochiKit.DOM.getFirstParentByTagAndClassName(id, 'tr', 'filter_row_class');
1263-
1264- if (node.id != 'filter_row/0') {
1265- removeElement(node);
1266- }
1267- else {
1268- node.style.display = 'none';
1269- if ($('and_or/0'))
1270- removeElement($('and_or/0'));
1271- $('qstring/0').value = '';
1272- $('qstring/0').style.background = '#FFFFFF';
1273- }
1274+/**
1275+ * @event onremovefilter triggered when removing a filter row
1276+ * @target #filter_table the element holding the filter rows
1277+ * @argument 'the removed (or hidden) filter row'
1278+ */
1279+function remove_row(id) {
1280+ var filter_table = $('filter_table');
1281+
1282+ var node = MochiKit.DOM.getFirstParentByTagAndClassName(id, 'tr', 'filter_row_class');
1283+
1284+ if (node.id != 'filter_row/0') {
1285+ removeElement(node);
1286+ } else {
1287+ node.style.display = 'none';
1288+ if ($('and_or/0')) {
1289+ removeElement($('and_or/0'));
1290+ }
1291+ $('qstring/0').value = '';
1292+ $('qstring/0').style.background = '#FFFFFF';
1293+ }
1294+ MochiKit.Signal.signal(filter_table, 'onremovefilter', node);
1295 }
1296 // Direct click on icon.
1297-var search_image_filter = function(src, id) {
1298- domain = getNodeAttribute(id, 'value');
1299- search_filter(src);
1300+function search_image_filter(src, id) {
1301+ domain = getNodeAttribute(id, 'value');
1302+ search_filter(src);
1303 }
1304
1305-var onKey_Event = function(evt) {
1306-
1307- dom = $('search_filter_data');
1308-
1309- var editors = [];
1310-
1311- editors = editors.concat(getElementsByTagAndClassName('input', null, dom));
1312- editors = editors.concat(getElementsByTagAndClassName('select', null, dom));
1313- editors = editors.concat(getElementsByTagAndClassName('textarea', null, dom));
1314-
1315- var editors = filter(function(e){
1316+function onKey_Event() {
1317+ var search_filter = $('search_filter_data');
1318+
1319+ var editors = [];
1320+
1321+ editors = editors.concat(getElementsByTagAndClassName('input', null, search_filter));
1322+ editors = editors.concat(getElementsByTagAndClassName('select', null, search_filter));
1323+ editors = editors.concat(getElementsByTagAndClassName('textarea', null, search_filter));
1324+
1325+ var active_editors = filter(function(e) {
1326 return e.type != 'hidden' && !e.disabled
1327 }, editors);
1328
1329- forEach(editors, function(e){
1330- connect(e, 'onkeydown', self, onKeyDown_search);
1331- });
1332-}
1333-
1334-var onKeyDown_search = function(evt) {
1335- var key = evt.key();
1336- var src = evt.src();
1337-
1338- if (key.string == "KEY_ENTER"){
1339- search_filter();
1340- }
1341-}
1342-
1343-var search_filter = function(src, id) {
1344- all_domains = {};
1345- check_domain = 'None';
1346- domains = {};
1347- search_context = {};
1348- var group_by_ctx = [];
1349-
1350- domain = 'None';
1351- if(src) {
1352- if(src.checked==false) {
1353- src.checked = true
1354- id.className = 'active_filter';
1355- }
1356- else {
1357- src.checked = false
1358- id.className = 'inactive_filter';
1359- }
1360- }
1361- var filter_table = $('filter_table');
1362- datas = $$('[name]', 'search_filter_data');
1363-
1364- forEach(datas, function(d) {
1365- if (d.type != 'checkbox' && d.name && d.value && d.name.indexOf('_terp_') == -1 && d.name != 'filter_list') {
1366- value = d.value;
1367- if (getNodeAttribute(d, 'kind') == 'selection') {
1368- value = parseInt(d.value);
1369- if(getNodeAttribute(d, 'search_context')) {
1370- search_context['context'] = getNodeAttribute(d, 'search_context');
1371- search_context['value'] = value;
1372- }
1373- }
1374- domains[d.name] = value;
1375- }
1376- });
1377-
1378- domains = serializeJSON(domains);
1379- all_domains['domains'] = domains;
1380- all_domains['search_context'] = search_context;
1381- selected_boxes = getElementsByTagAndClassName('input', 'grid-domain-selector');
1382-
1383- all_boxes = [];
1384-
1385- forEach(selected_boxes, function(box){
1386- if (box.id && box.checked && box.value != '[]') {
1387- all_boxes = all_boxes.concat(box.value);
1388- }
1389- if (box.id && box.checked && getNodeAttribute(box, 'group_by_ctx').length > 0) {
1390- group = getNodeAttribute(box, 'group_by_ctx');
1391- group_by_ctx = group_by_ctx.concat(group);
1392- }
1393- });
1394-
1395- openobject.dom.get('_terp_group_by_ctx').value = group_by_ctx;
1396-
1397- checked_button = all_boxes.toString();
1398-
1399- if (checked_button.length > 0) {
1400- check_domain = checked_button.replace(/(]\,\[)/g, ', ');
1401- }
1402- else {
1403- check_domain = 'None';
1404- }
1405-
1406- all_domains['check_domain'] = check_domain;
1407-
1408- var selection_domain = $('filter_list').value;
1409-
1410- if (selection_domain) {
1411- all_domains['selection_domain'] = selection_domain;
1412- }
1413-
1414- if(openobject.dom.get('_terp_filter_domain').value != '[]') {
1415-
1416- var params = {};
1417- var record = {};
1418-
1419- filter_table.style.display = ''
1420-
1421- children = MochiKit.DOM.getElementsByTagAndClassName('tr', 'filter_row_class', filter_table);
1422- forEach(children, function(ch){
1423-
1424- var ids = ch['id']; // row id...
1425- var id = ids.split('/')[1];
1426- var qid = 'qstring/' + id;
1427- var fid = 'filter_fields/' + id;
1428- var eid = 'expr/' + id;
1429- if ($(qid) && $(qid).value) {
1430- var rec = {};
1431- rec[$(fid).value] = $(qid).value;
1432- params['_terp_model'] = openobject.dom.get('_terp_model').value;
1433- }
1434- if (rec) {
1435- record[ids] = rec;
1436- }
1437- });
1438-
1439- record = serializeJSON(record);
1440- params['record'] = record;
1441-
1442- var search_req = openobject.http.postJSON('/search/get', params);
1443-
1444- var custom_domain = [];
1445- search_req.addCallback(function(obj){
1446- if (obj.error) {
1447- forEach(children, function(child){
1448- var cids = child['id']
1449- var id = cids.split('/')[1];
1450- var fid = 'filter_fields/' + id;
1451- if ($(fid).value == obj.error_field) {
1452- f = fid.split('/')[1];
1453- $('qstring/'+f).style.background = '#FF6666';
1454- $('qstring/'+f).value = obj.error;
1455- }
1456- });
1457- }
1458- if (obj.frm) {
1459- for (var i in obj.frm) {
1460- var temp_domain = [];
1461- var operator = 'None';
1462-
1463- row_id = serializeJSON(i);
1464- id = row_id.split('/')[1];
1465- id = parseInt(id, 10);
1466-
1467- var fid = 'filter_fields/' + id;
1468- var eid = 'expr/' + id;
1469- var select_andor = 'select_andor/' + id;
1470- var type = obj.frm[i].type;
1471- if($(select_andor)){
1472- if ($(select_andor).value == 'AND') {
1473- var operator = '&';
1474- }
1475- else {
1476- var operator = '|';
1477- }
1478- }
1479- if (operator != 'None') {
1480- temp_domain.push(operator);
1481- }
1482-
1483- var first_text = obj.frm[i].rec;
1484- var expression = $(eid).value;
1485- var right_text = obj.frm[i].rec_val;
1486- if (expression=='ilike'||expression=='not ilike'){
1487- if (type=='integer'||type=='float'||type=='date'||type=='datetime'||type=='boolean'){
1488- if (expression == 'ilike')
1489- expression = '=';
1490- else {
1491- expression = '!=';
1492- }
1493- }
1494- }
1495- if ((expression == '<' || expression == '>') && (type!='integer'||type!='float'||type!='date'||type!='datetime'||type!='boolean')){
1496- expression = '=';
1497- }
1498- if (expression == 'in' || expression == 'not in'){
1499- right_text = right_text.split(',');
1500- }
1501-
1502- temp_domain.push(first_text);
1503- temp_domain.push(expression);
1504- temp_domain.push(right_text);
1505-
1506- custom_domain.push(temp_domain);
1507- }
1508- }
1509- custom_domain = serializeJSON(custom_domain);
1510- all_domains = serializeJSON(all_domains);
1511-
1512- final_search_domain(custom_domain, all_domains, group_by_ctx);
1513- });
1514- }
1515- else {
1516- custom_domain = openobject.dom.get('_terp_filter_domain').value || []
1517- all_domains = serializeJSON(all_domains);
1518- final_search_domain(custom_domain, all_domains, group_by_ctx);
1519- }
1520-}
1521-
1522-var final_search_domain = function(custom_domain, all_domain, group_by_ctx) {
1523- var req = openobject.http.postJSON('/search/eval_domain_filter', {source: '_terp_list',
1524- model: $('_terp_model').value,
1525- custom_domain: custom_domain,
1526- all_domains: all_domains,
1527- group_by_ctx: group_by_ctx});
1528-
1529- req.addCallback(function(obj){
1530- if (obj.flag) {
1531- var params = {'domain': obj.sf_dom,
1532- 'model': openobject.dom.get('_terp_model').value,
1533- 'flag': obj.flag};
1534- if(group_by_ctx!='')
1535- params['group_by'] = group_by_ctx
1536- openobject.tools.openWindow(openobject.http.getURL('/search/save_filter', params), {width: 400, height: 250});
1537- }
1538- if (obj.action) { // For manage Filter
1539- action = serializeJSON(obj.action);
1540- window.location.href = openobject.http.getURL('/search/manage_filter', {action: action});
1541- }
1542- if (obj.domain) { // For direct search
1543- var in_req = eval_domain_context_request({source: '_terp_list', domain: obj.domain, context: obj.context});
1544-
1545- in_req.addCallback(function(in_obj){
1546- openobject.dom.get('_terp_search_domain').value = in_obj.domain;
1547- openobject.dom.get('_terp_search_data').value = obj.search_data;
1548- openobject.dom.get('_terp_context').value = in_obj.context;
1549- openobject.dom.get('_terp_filter_domain').value = obj.filter_domain;
1550- if (getElement('_terp_list') != null){
1551- new ListView('_terp_list').reload()
1552- }
1553- });
1554- }
1555- });
1556-}
1557-
1558-var expand_group_option = function(id, event) {
1559- if(getElement(id).style.display == '') {
1560- getElement(id).style.display = 'none'
1561- event.target.className = 'group-expand';
1562- }
1563- else {
1564- getElement(id).style.display = '';
1565- event.target.className = 'group-collapse';
1566- }
1567-}
1568-
1569-MochiKit.DOM.addLoadEvent(function(evt){
1570-
1571- onKey_Event(evt);
1572- search_filter();
1573+ forEach(active_editors, function(e) {
1574+ MochiKit.Signal.connect(e, 'onkeydown', self, onKeyDown_search);
1575+ });
1576+}
1577+
1578+function onKeyDown_search(evt) {
1579+ if (evt.key().string == "KEY_ENTER") {
1580+ search_filter();
1581+ }
1582+}
1583+
1584+function search_filter(src, id) {
1585+ all_domains = {};
1586+ check_domain = 'None';
1587+ domains = {};
1588+ search_context = {};
1589+ var group_by_ctx = [];
1590+
1591+ domain = 'None';
1592+ if (src) {
1593+ src.checked = !src.checked;
1594+ id.className = src.checked ? 'active_filter' : 'inactive_filter';
1595+ }
1596+ var filter_table = $('filter_table');
1597+ datas = $$('[name]', 'search_filter_data');
1598+
1599+ forEach(datas, function(d) {
1600+ if (d.type != 'checkbox' && d.name && d.value && d.name.indexOf('_terp_') == -1 && d.name != 'filter_list') {
1601+ value = d.value;
1602+ if (getNodeAttribute(d, 'kind') == 'selection') {
1603+ value = parseInt(d.value);
1604+ if (getNodeAttribute(d, 'search_context')) {
1605+ search_context['context'] = getNodeAttribute(d, 'search_context');
1606+ search_context['value'] = value;
1607+ }
1608+ }
1609+ domains[d.name] = value;
1610+ }
1611+ });
1612+
1613+ domains = serializeJSON(domains);
1614+ all_domains['domains'] = domains;
1615+ all_domains['search_context'] = search_context;
1616+ selected_boxes = getElementsByTagAndClassName('input', 'grid-domain-selector');
1617+
1618+ all_boxes = [];
1619+
1620+ forEach(selected_boxes, function(box) {
1621+ if (box.id && box.checked && box.value != '[]') {
1622+ all_boxes = all_boxes.concat(box.value);
1623+ }
1624+ if (box.id && box.checked && getNodeAttribute(box, 'group_by_ctx').length > 0) {
1625+ group = getNodeAttribute(box, 'group_by_ctx');
1626+ group_by_ctx = group_by_ctx.concat(group);
1627+ }
1628+ });
1629+
1630+ openobject.dom.get('_terp_group_by_ctx').value = group_by_ctx;
1631+
1632+ checked_button = all_boxes.toString();
1633+
1634+ if (checked_button.length > 0) {
1635+ check_domain = checked_button.replace(/(]\,\[)/g, ', ');
1636+ }
1637+ else {
1638+ check_domain = 'None';
1639+ }
1640+
1641+ all_domains['check_domain'] = check_domain;
1642+
1643+ var selection_domain = $('filter_list').value;
1644+
1645+ if (selection_domain) {
1646+ all_domains['selection_domain'] = selection_domain;
1647+ }
1648+
1649+ if (openobject.dom.get('_terp_filter_domain').value != '[]') {
1650+
1651+ var params = {};
1652+ var record = {};
1653+
1654+ filter_table.style.display = '';
1655+
1656+ children = MochiKit.DOM.getElementsByTagAndClassName('tr', 'filter_row_class', filter_table);
1657+ forEach(children, function(ch) {
1658+
1659+ var ids = ch['id']; // row id...
1660+ var id = ids.split('/')[1];
1661+ var qid = 'qstring/' + id;
1662+ var fid = 'filter_fields/' + id;
1663+ if ($(qid) && $(qid).value) {
1664+ var rec = {};
1665+ rec[$(fid).value] = $(qid).value;
1666+ params['_terp_model'] = openobject.dom.get('_terp_model').value;
1667+ }
1668+ if (rec) {
1669+ record[ids] = rec;
1670+ }
1671+ });
1672+
1673+ record = serializeJSON(record);
1674+ params['record'] = record;
1675+
1676+ var search_req = openobject.http.postJSON('/search/get', params);
1677+
1678+ var custom_domain = [];
1679+ search_req.addCallback(function(obj) {
1680+ if (obj.error) {
1681+ forEach(children, function(child) {
1682+ var cids = child['id'];
1683+ var id = cids.split('/')[1];
1684+ var fid = 'filter_fields/' + id;
1685+ if ($(fid).value == obj.error_field) {
1686+ f = fid.split('/')[1];
1687+ $('qstring/' + f).style.background = '#FF6666';
1688+ $('qstring/' + f).value = obj.error;
1689+ }
1690+ });
1691+ }
1692+ if (obj.frm) {
1693+ for (var i in obj.frm) {
1694+ var temp_domain = [];
1695+ var operator = 'None';
1696+
1697+ row_id = serializeJSON(i);
1698+ id = row_id.split('/')[1];
1699+ id = parseInt(id, 10);
1700+
1701+ var eid = 'expr/' + id;
1702+ var select_andor = 'select_andor/' + id;
1703+ var type = obj.frm[i].type;
1704+ if ($(select_andor)) {
1705+ if ($(select_andor).value == 'AND') {
1706+ operator = '&';
1707+ } else {
1708+ operator = '|';
1709+ }
1710+ }
1711+ if (operator != 'None') {
1712+ temp_domain.push(operator);
1713+ }
1714+
1715+ var first_text = obj.frm[i].rec;
1716+ var expression = $(eid).value;
1717+ var right_text = obj.frm[i].rec_val;
1718+ if (expression == 'ilike' || expression == 'not ilike') {
1719+ if (type == 'integer' || type == 'float' || type == 'date' || type == 'datetime' || type == 'boolean') {
1720+ if (expression == 'ilike') {
1721+ expression = '=';
1722+ } else {
1723+ expression = '!=';
1724+ }
1725+ }
1726+ }
1727+ if ((expression == '<' || expression == '>') && (type != 'integer' || type != 'float' || type != 'date' || type != 'datetime' || type != 'boolean')) {
1728+ expression = '=';
1729+ }
1730+ if (expression == 'in' || expression == 'not in') {
1731+ right_text = right_text.split(',');
1732+ }
1733+
1734+ temp_domain.push(first_text);
1735+ temp_domain.push(expression);
1736+ temp_domain.push(right_text);
1737+
1738+ custom_domain.push(temp_domain);
1739+ }
1740+ }
1741+ custom_domain = serializeJSON(custom_domain);
1742+ all_domains = serializeJSON(all_domains);
1743+
1744+ final_search_domain(custom_domain, all_domains, group_by_ctx);
1745+ });
1746+ } else {
1747+ custom_domain = openobject.dom.get('_terp_filter_domain').value || [];
1748+ all_domains = serializeJSON(all_domains);
1749+ final_search_domain(custom_domain, all_domains, group_by_ctx);
1750+ }
1751+}
1752+
1753+function final_search_domain(custom_domain, all_domain, group_by_ctx) {
1754+ var req = openobject.http.postJSON('/search/eval_domain_filter', {
1755+ source: '_terp_list',
1756+ model: $('_terp_model').value,
1757+ custom_domain: custom_domain,
1758+ all_domains: all_domains,
1759+ group_by_ctx: group_by_ctx
1760+ });
1761+
1762+ req.addCallback(function(obj) {
1763+ if (obj.flag) {
1764+ var params = {'domain': obj.sf_dom,
1765+ 'model': openobject.dom.get('_terp_model').value,
1766+ 'flag': obj.flag};
1767+ if (group_by_ctx != '') {
1768+ params['group_by'] = group_by_ctx;
1769+ }
1770+ openobject.tools.openWindow(openobject.http.getURL('/search/save_filter', params), {
1771+ width: 400,
1772+ height: 250
1773+ });
1774+ }
1775+ if (obj.action) { // For manage Filter
1776+ action = serializeJSON(obj.action);
1777+ window.location.href = openobject.http.getURL('/search/manage_filter', {action: action});
1778+ }
1779+ if (obj.domain) { // For direct search
1780+ var in_req = eval_domain_context_request({
1781+ source: '_terp_list',
1782+ domain: obj.domain,
1783+ context: obj.context
1784+ });
1785+
1786+ in_req.addCallback(function(in_obj) {
1787+ openobject.dom.get('_terp_search_domain').value = in_obj.domain;
1788+ openobject.dom.get('_terp_search_data').value = obj.search_data;
1789+ openobject.dom.get('_terp_context').value = in_obj.context;
1790+ openobject.dom.get('_terp_filter_domain').value = obj.filter_domain;
1791+ if (getElement('_terp_list') != null) {
1792+ new ListView('_terp_list').reload()
1793+ }
1794+ });
1795+ }
1796+ });
1797+}
1798+
1799+/**
1800+ * @event groupby-toggle triggered when changing the display state of the groupby options
1801+ * @target #search_filter_data the element holding the filter rows
1802+ * @argument 'the action performed ("expand" or "collapse")
1803+ */
1804+function expand_group_option(id, event) {
1805+ var groupbyElement = getElement(id);
1806+ var action;
1807+ if (groupbyElement.style.display == '') {
1808+ groupbyElement.style.display = 'none';
1809+ event.target.className = 'group-expand';
1810+ action = 'collapse';
1811+ } else {
1812+ groupbyElement.style.display = '';
1813+ event.target.className = 'group-collapse';
1814+ action = 'expand';
1815+ }
1816+ MochiKit.Signal.signal(
1817+ $('search_filter_data'),
1818+ 'groupby-toggle',
1819+ action);
1820+}
1821+
1822+MochiKit.DOM.addLoadEvent(function(evt) {
1823+ onKey_Event(evt);
1824+ search_filter();
1825 });
1826
1827=== modified file 'addons/openerp/static/javascript/treegrid.js'
1828--- addons/openerp/static/javascript/treegrid.js 2010-04-06 09:51:49 +0000
1829+++ addons/openerp/static/javascript/treegrid.js 2010-04-06 12:34:17 +0000
1830@@ -31,22 +31,34 @@
1831 var KEY_ARROW_UP = 38;
1832 var KEY_ARROW_DOWN = 40;
1833
1834-var TreeGrid = function(elem, options){
1835+/**
1836+ * @event treegrid-render triggered on treegrid rendering
1837+ * @target document
1838+ * @argument 'the treegrid instance being rendered'
1839+ *
1840+ * @event treenode-expand triggered when a sub-node is expanded
1841+ * @target document
1842+ * @argument 'the treenode being expanded'
1843+ *
1844+ * @event treenode-collapse triggered when a sub-node is collaped
1845+ * @target document
1846+ * @argument 'the treenode being collapsed'
1847+ */
1848+var TreeGrid = function(elem, options) {
1849 this.__init__(elem, options);
1850 };
1851
1852 TreeGrid.prototype = {
1853
1854 __init__ : function(elem, options) {
1855-
1856 this.id = openobject.dom.get(elem).id;
1857
1858 this.options = MochiKit.Base.update({
1859 'showheaders': true,
1860 'expandall' : false,
1861- 'onselect' : function(){},
1862- 'onbuttonclick' : function(){},
1863- 'onheaderclick' : function(){},
1864+ 'onselect' : function() {},
1865+ 'onbuttonclick' : function() {},
1866+ 'onheaderclick' : function() {},
1867 'linktarget': null
1868 }, options || {});
1869
1870@@ -63,39 +75,45 @@
1871 // references to ajax url and params
1872 this.ajax_url = null;
1873 this.ajax_params = {};
1874+
1875+ // receive some events from the treenodes and redispatch to the document
1876+ MochiKit.Signal.connect(this, 'onNodeExpand', function (tree, node) {
1877+ MochiKit.Signal.signal(window.document, 'treenode-expand', node);
1878+ });
1879+ MochiKit.Signal.connect(this, 'onNodeCollapse', function (tree, node) {
1880+ MochiKit.Signal.signal(window.document, 'treenode-collapse', node);
1881+ });
1882 },
1883
1884 setHeaders : function(headers/*, params */) {
1885-
1886 this.headers = headers;
1887
1888- if (typeof(headers) == 'string'){
1889+ if (typeof(headers) == 'string') {
1890
1891- var self = this;
1892- var req = openobject.http.postJSON(headers, arguments[1]);
1893-
1894- self._ajax_counter += 1;
1895-
1896- req.addCallback(function(obj){
1897- self.headers = obj.headers;
1898- });
1899-
1900- req.addBoth(function(){
1901- self._ajax_counter -= 1;
1902- });
1903+ var self = this;
1904+ var req = openobject.http.postJSON(headers, arguments[1]);
1905+
1906+ self._ajax_counter += 1;
1907+
1908+ req.addCallback(function(obj) {
1909+ self.headers = obj.headers;
1910+ });
1911+
1912+ req.addBoth(function() {
1913+ self._ajax_counter -= 1;
1914+ });
1915
1916 }
1917 },
1918
1919 setRecords : function(records/*, params */) {
1920-
1921 if (!this.headers) {
1922 return;
1923 }
1924
1925 this.records = records;
1926
1927- if (typeof(records) == 'string'){
1928+ if (typeof(records) == 'string') {
1929
1930 this.ajax_url = records;
1931 this.ajax_params = arguments[1] || {};
1932@@ -108,12 +126,12 @@
1933
1934 self._ajax_counter += 1;
1935
1936- req.addCallback(function(obj){
1937+ req.addCallback(function(obj) {
1938 self.records = obj.records;
1939 MochiKit.Signal.signal(self, 'onDataLoad', self, null);
1940 });
1941
1942- req.addBoth(function(obj){
1943+ req.addBoth(function() {
1944 self._ajax_counter -= 1;
1945 });
1946
1947@@ -121,8 +139,7 @@
1948
1949 },
1950
1951- render : function(){
1952-
1953+ render : function() {
1954 // wait till ajax calls finish
1955 if (this._ajax_counter > 0) {
1956 return MochiKit.Async.callLater(0.01, MochiKit.Base.bind(this.render, this));
1957@@ -141,6 +158,7 @@
1958 if (openobject.dom.get(this.id) != this.table) {
1959 MochiKit.DOM.swapDOM(this.id, this.table);
1960 }
1961+ MochiKit.Signal.signal(window.document, 'treegrid-render', this);
1962 },
1963
1964 reload : function() {
1965@@ -153,11 +171,10 @@
1966 return new TreeNode(this, record);
1967 },
1968
1969- _makeHeader : function(){
1970-
1971+ _makeHeader : function() {
1972 var tr = MochiKit.DOM.TR({'class':'header'});
1973
1974- for(var i in this.headers){
1975+ for (var i in this.headers) {
1976
1977 var header = this.headers[i];
1978 var th = MochiKit.DOM.TH(null, header.string);
1979@@ -167,9 +184,9 @@
1980 MochiKit.DOM.setNodeAttribute(th, 'width', header.width);
1981 MochiKit.DOM.setNodeAttribute(th, 'align', header.align);
1982
1983- if (this.options.onheaderclick){
1984- th.onclick = MochiKit.Base.bind(MochiKit.Base.partial(this._onHeaderClick, header), this);
1985- th.style.cursor = 'pointer';
1986+ if (this.options.onheaderclick) {
1987+ th.onclick = MochiKit.Base.bind(MochiKit.Base.partial(this._onHeaderClick, header), this);
1988+ th.style.cursor = 'pointer';
1989 }
1990
1991 header.tree = this;
1992@@ -191,7 +208,6 @@
1993 },
1994
1995 copy: function(elem, options, ids) {
1996-
1997 var tree = new TreeGrid(elem, options);
1998 MochiKit.Base.update(tree.options, this.options);
1999
2000@@ -247,7 +263,7 @@
2001 __delete__ : function() {
2002
2003
2004- while(this.childNodes.length > 0) {
2005+ while (this.childNodes.length > 0) {
2006 this.childNodes[0].__delete__();
2007 }
2008
2009@@ -258,14 +274,14 @@
2010 var pn = this.parentNode;
2011 var idx = MochiKit.Base.findIdentical(pn.childNodes, this);
2012
2013- pn.childNodes.splice(idx,1);
2014+ pn.childNodes.splice(idx, 1);
2015
2016 if (pn.firsChild == this) {
2017 pn.firstChild = pn.childNodes[0] || null;
2018 }
2019
2020 if (pn.lastChild == this) {
2021- pn.lastChild = pn.childNodes[pn.childNodes.length-1] || null;
2022+ pn.lastChild = pn.childNodes[pn.childNodes.length - 1] || null;
2023 }
2024
2025 if (this.previousSibling) {
2026@@ -276,7 +292,7 @@
2027 this.nextSibling.previousSibling = this.previousSibling;
2028 }
2029
2030- this.tree.selection.splice(MochiKit.Base.findIdentical(this.tree.selection, this),1);
2031+ this.tree.selection.splice(MochiKit.Base.findIdentical(this.tree.selection, this), 1);
2032 this.tree.selection_last = this.selection_last == this ? null : this.selection_last;
2033
2034 var table = this.tree.table;
2035@@ -295,7 +311,7 @@
2036 }
2037 },
2038
2039- __repr__ : function(){
2040+ __repr__ : function() {
2041 return '<TreeNode ' + this.name + '>';
2042 },
2043
2044@@ -307,7 +323,7 @@
2045 var indent = this.getPath().length - 1;
2046
2047 var len = this.tree.headers.length;
2048- for (var i=0; i<len; ++i) {
2049+ for (var i = 0; i < len; ++i) {
2050 var header = this.tree.headers[i];
2051
2052 var key = header.name;
2053@@ -345,9 +361,9 @@
2054 MochiKit.Signal.connect(value, 'onclick', function (e) {
2055 MochiKit.Signal.signal(e.src().tree, "onaction", e.src());
2056 var frame = jQuery('#appFrame');
2057- if(frame.contentWindow) {
2058+ if (frame.contentWindow) {
2059 frame.contentWindow.location.replace(record.action);
2060- } else if(frame.contentDocument) {
2061+ } else if (frame.contentDocument) {
2062 frame.contentDocument.location.replace(record.action);
2063 } else {
2064 // just in case there's still a browser needing DOM0 frames
2065@@ -416,34 +432,34 @@
2066
2067 MochiKit.Base.update(this.record, record || {});
2068
2069- var record = this.record;
2070+ var current_record = this.record;
2071
2072- for (var i in this.tree.headers){
2073+ for (var i in this.tree.headers) {
2074
2075 var header = this.tree.headers[i];
2076
2077 var key = header.name;
2078- var value = record.items[key];
2079+ var value = current_record.items[key];
2080
2081 var td = this.element.cells[i];
2082
2083 if (i == 0) { // first column
2084
2085- if (record.icon && this.element_i) {
2086- this.element_i.src = record.icon;
2087+ if (current_record.icon && this.element_i) {
2088+ this.element_i.src = current_record.icon;
2089 }
2090
2091 this.element_a.innerHTML = MochiKit.DOM.escapeHTML(value);
2092
2093- if (record.action) {
2094- MochiKit.DOM.setNodeAttribute(this.element_a, 'href', openobject.http.getURL(record.action));
2095- }
2096-
2097- if (record.target) {
2098- MochiKit.DOM.setNodeAttribute(this.element_a, 'target', openobject.http.getURL(record.target));
2099- }
2100-
2101- if(record.required) {
2102+ if (current_record.action) {
2103+ MochiKit.DOM.setNodeAttribute(this.element_a, 'href', openobject.http.getURL(current_record.action));
2104+ }
2105+
2106+ if (current_record.target) {
2107+ MochiKit.DOM.setNodeAttribute(this.element_a, 'target', openobject.http.getURL(current_record.target));
2108+ }
2109+
2110+ if (current_record.required) {
2111 MochiKit.DOM.setNodeAttribute(this.element_a, 'class', 'requiredfield');
2112 }
2113
2114@@ -455,7 +471,7 @@
2115 case 'email':
2116 var link = openobject.dom.select('a', td)[0];
2117 MochiKit.DOM.setNodeAttribute(link, 'href', value);
2118- MochiKit.DOM.setNodeAttribute(link, 'target', record.target || '_blank');
2119+ MochiKit.DOM.setNodeAttribute(link, 'target', current_record.target || '_blank');
2120
2121 link.innerHTML = MochiKit.DOM.escapeHTML(value);
2122 break;
2123@@ -482,7 +498,7 @@
2124 case KEY_ARROW_LEFT:
2125 if (this.expanded) {
2126 this.collapse();
2127- } else if (this.parentNode.element){
2128+ } else if (this.parentNode.element) {
2129 this.parentNode.onSelect(evt);
2130 }
2131 return evt.stop();
2132@@ -496,7 +512,7 @@
2133 return evt.stop();
2134
2135 case KEY_ARROW_UP:
2136- visible_nodes = MochiKit.Base.filter(function(node){
2137+ visible_nodes = MochiKit.Base.filter(function(node) {
2138 return node.element && "none" != node.element.style.display;
2139 }, this.tree.rootNode.getAllChildren());
2140
2141@@ -509,11 +525,11 @@
2142 return evt.stop();
2143
2144 case KEY_ARROW_DOWN:
2145- visible_nodes = MochiKit.Base.filter(function(node){
2146+ visible_nodes = MochiKit.Base.filter(function(node) {
2147 return node.element && "none" != node.element.style.display;
2148 }, this.tree.rootNode.getAllChildren());
2149
2150- visible_nodes = visible_nodes.slice(MochiKit.Base.findIdentical(visible_nodes, this)+1);
2151+ visible_nodes = visible_nodes.slice(MochiKit.Base.findIdentical(visible_nodes, this) + 1);
2152
2153 if (visible_nodes.length > 0) {
2154 visible_nodes[0].onSelect(evt);
2155@@ -535,12 +551,11 @@
2156
2157 var trg = evt ? evt.target() : this.element;
2158
2159- if (MochiKit.Base.findValue(['collapse', 'expand', 'loading'], trg.className) > -1){
2160+ if (MochiKit.Base.findValue(['collapse', 'expand', 'loading'], trg.className) > -1) {
2161 return;
2162 }
2163
2164 var tree = this.tree;
2165- var src = this.element;
2166
2167 var ctr = evt ? evt.modifier().ctrl : null;
2168 var sft = evt ? evt.modifier().shift : null;
2169@@ -549,12 +564,12 @@
2170 this.element_a.focus();
2171 }
2172
2173- forEach(tree.selection, function(node){
2174+ forEach(tree.selection, function(node) {
2175 MochiKit.DOM.removeElementClass(node.element, "selected");
2176 });
2177
2178 if (ctr) {
2179- if (MochiKit.Base.findIdentical(tree.selection, this) == -1){
2180+ if (MochiKit.Base.findIdentical(tree.selection, this) == -1) {
2181 tree.selection.push(this);
2182 } else {
2183 tree.selection.splice(MochiKit.Base.findIdentical(tree.selection, this), 1);
2184@@ -562,7 +577,7 @@
2185 } else if (sft) {
2186
2187 var nodes = tree.rootNode.getAllChildren();
2188- nodes = MochiKit.Base.filter(function(node){
2189+ nodes = MochiKit.Base.filter(function(node) {
2190 return node.element.style.display != 'none';
2191 }, nodes);
2192
2193@@ -572,17 +587,17 @@
2194 var begin = MochiKit.Base.findIdentical(nodes, this);
2195 var end = MochiKit.Base.findIdentical(nodes, last);
2196
2197- tree.selection = begin > end ? nodes.slice(end, begin+1) : nodes.slice(begin, end+1);
2198+ tree.selection = begin > end ? nodes.slice(end, begin + 1) : nodes.slice(begin, end + 1);
2199
2200 } else {
2201 tree.selection = [this];
2202 }
2203
2204- if (!sft){
2205- tree.selection_last = tree.selection[tree.selection.length-1];
2206+ if (!sft) {
2207+ tree.selection_last = tree.selection[tree.selection.length - 1];
2208 }
2209
2210- forEach(tree.selection, function(node){
2211+ forEach(tree.selection, function(node) {
2212 MochiKit.DOM.addElementClass(node.element, "selected");
2213 });
2214
2215@@ -604,7 +619,7 @@
2216
2217 var result = [];
2218
2219- forEach(this.childNodes, function(n){
2220+ forEach(this.childNodes, function(n) {
2221 result = result.concat(n);
2222 result = result.concat(n.getAllChildren());
2223 });
2224@@ -629,21 +644,23 @@
2225 },
2226
2227 _loadChildNodes : function(/* optional */expandall) {
2228-
2229- if (this._ajax_counter > 0)
2230- return;
2231+ if (this._ajax_counter > 0) {
2232+ return;
2233+ }
2234
2235 var self = this;
2236
2237 function _makeChildNodes(records) {
2238
2239- MochiKit.Iter.forEach(records, function(record){
2240+ MochiKit.Iter.forEach(records, function(record) {
2241 self.appendChild(self.tree.createNode(record));
2242 });
2243
2244- if (!expandall) { return; }
2245+ if (!expandall) {
2246+ return;
2247+ }
2248
2249- forEach(self.childNodes, function(child){
2250+ forEach(self.childNodes, function(child) {
2251 child.expand(expandall);
2252 });
2253 }
2254@@ -665,13 +682,13 @@
2255
2256 this.setState('loading');
2257
2258- req.addCallback(function(obj){
2259+ req.addCallback(function(obj) {
2260 _makeChildNodes(obj.records);
2261 MochiKit.Signal.signal(self.tree, 'onDataLoad', self.tree, self);
2262 MochiKit.Signal.signal(self.tree, 'onNodeExpand', self.tree, self);
2263 });
2264
2265- req.addBoth(function(obj){
2266+ req.addBoth(function(obj) {
2267 self.tree._ajax_counter -= 1;
2268 self.setState('collapse');
2269 });
2270@@ -733,7 +750,8 @@
2271 return;
2272 }
2273
2274- var span = this.element.getElementsByTagName('span'); span = span[span.length-1];
2275+ var span = this.element.getElementsByTagName('span');
2276+ span = span[span.length - 1];
2277 MochiKit.DOM.setNodeAttribute(span, 'class', state);
2278 },
2279
2280
2281=== modified file 'openobject/static/javascript/openobject/openobject.base.js'
2282--- openobject/static/javascript/openobject/openobject.base.js 2010-04-06 09:51:49 +0000
2283+++ openobject/static/javascript/openobject/openobject.base.js 2010-04-06 12:34:17 +0000
2284@@ -31,67 +31,66 @@
2285 throw "MochiKit is required.";
2286 }
2287
2288+var openobject;
2289 if (typeof(openobject) == "undefined") {
2290- window.openobject = openobject = {};
2291+ openobject = {};
2292+ window.openobject = openobject;
2293 }
2294
2295 openobject.base = {
2296-
2297 filter: function(items, callback, instance) {
2298 if (instance) {
2299 callback = MochiKit.Base.bind(callback, instance);
2300 }
2301 return MochiKit.Base.filter(callback, items);
2302 },
2303-
2304+
2305 map: function(items, callback, instance) {
2306 if (instance) {
2307 callback = MochiKit.Base.bind(callback, instance);
2308 }
2309 return MochiKit.Base.map(callback, items);
2310 },
2311-
2312+
2313 each: function(items, callback, instance) {
2314 return MochiKit.Iter.forEach(items, callback, instance);
2315 },
2316-
2317+
2318 find: function(items, value, start, end) {
2319 return MochiKit.Base.findIdentical(items, value, start, end);
2320 }
2321-
2322-}
2323+};
2324
2325 // browser information
2326 openobject.browser = {
2327-
2328 // Internet Explorer
2329 isIE: /msie/.test(navigator.userAgent.toLowerCase()),
2330-
2331+
2332 // Internet Explorer 6
2333 isIE6: /msie 6/.test(navigator.userAgent.toLowerCase()),
2334-
2335+
2336 // Internet Explorer 7
2337 isIE7: /msie 7/.test(navigator.userAgent.toLowerCase()),
2338-
2339+
2340 // Gecko(Mozilla) derived
2341 isGecko: /gecko\//.test(navigator.userAgent.toLowerCase()),
2342-
2343+
2344 isGecko18: /rv:1.9.*gecko\//.test(navigator.userAgent.toLowerCase()),
2345-
2346+
2347 isGecko19: /rv:1.9.*gecko\//.test(navigator.userAgent.toLowerCase()),
2348-
2349+
2350 // Apple WebKit derived
2351 isWebKit: /webkit/.test(navigator.userAgent.toLowerCase()),
2352
2353 // Opera
2354 isOpera: /opera/.test(navigator.userAgent.toLowerCase())
2355-}
2356-
2357-window.browser = openobject.browser
2358-
2359-// hack to prevent cross-domain secutiry errors, if window is opened
2360+};
2361+
2362+window.browser = openobject.browser;
2363+
2364+// hack to prevent cross-domain security errors, if window is opened
2365 // from different domain.
2366-MochiKit.DOM.addLoadEvent(function(evt){
2367+MochiKit.DOM.addLoadEvent(function() {
2368 try {
2369 window.opener.document.domain;
2370 } catch (e) {
2371@@ -99,6 +98,89 @@
2372 }
2373 });
2374
2375-
2376-// vim: ts=4 sts=4 sw=4 si et
2377-
2378+var MENU_WIDTH = 250;
2379+/**
2380+ * Tries to fit the size of the #appFrame frame to better fit its current
2381+ * content.extend
2382+ * Has to be called from the document outside of the frame itself.
2383+ *
2384+ * Probably won't get it exactly right, you might want to call it
2385+ * several times
2386+ */
2387+function adjustAppFrame() {
2388+ var frameHeight = jQuery("#appFrame").contents().find("body").height();
2389+ var frameWidth = jQuery("#appFrame").contents().width();
2390+
2391+ jQuery("#menubar").width(MENU_WIDTH);
2392+ jQuery("#appFrame").height(Math.max(0, frameHeight));
2393+
2394+ var menuWidth = jQuery("#menubar").height();
2395+ var windowWidth = jQuery(window).width();
2396+ var totalWidth = jQuery("#menubar").width() + frameWidth;
2397+ var rw = windowWidth - jQuery("#menubar").width();
2398+
2399+ var newWidth = totalWidth > windowWidth ? frameWidth : rw - 16;
2400+
2401+ jQuery("#appFrame").width(Math.max(0, newWidth));
2402+ jQuery("table#contents").height(Math.max(frameHeight, menuWidth));
2403+}
2404+function adjust(count) {
2405+ if (!count) {
2406+ count = 0;
2407+ }
2408+ if (count < 3) {
2409+ try {
2410+ adjustAppFrame();
2411+ } catch (e) {
2412+ // don't do anything when adjustment blows up.
2413+ }
2414+ setTimeout(adjust, 10, count + 1);
2415+ }
2416+}
2417+if (window !== window.parent) {
2418+ MochiKit.DOM.addLoadEvent(function () {
2419+ // Gecko blows up if we try to directly call window.parent.adjust()
2420+ // and cross-frame events don't seem to work either
2421+ // so use intermediate function.
2422+ var do_adjust = function () {
2423+ window.parent.adjust();
2424+ };
2425+ setTimeout(do_adjust, 10);
2426+ // bind on all modifying events of notebooks
2427+ forEach($$('.notebook'), function (notebook_element) {
2428+ forEach(['remove', 'show', 'hide', 'activate', 'click'], function (event) {
2429+ MochiKit.Signal.connect(notebook_element.notebook,
2430+ event, do_adjust);
2431+ });
2432+ });
2433+ // bind to resize event of text area
2434+ forEach($$('.resizable-textarea'), function (textarea_element) {
2435+ MochiKit.Signal.connect(textarea_element.textarea, 'onresize', do_adjust);
2436+ });
2437+ // bind to alterations of the list views
2438+ forEach($$('.gridview'), function (listview_element) {
2439+ var name = listview_element.getAttribute('id');
2440+ MochiKit.Signal.connect(ListView(name), 'onreload', do_adjust);
2441+ });
2442+ // bind to addition and removal of filter rows in search widget
2443+ var filter_table = $('filter_table');
2444+ if (filter_table) {
2445+ MochiKit.Signal.connect(filter_table, 'onaddfilter',
2446+ do_adjust);
2447+ MochiKit.Signal.connect(filter_table, 'onremovefilter',
2448+ do_adjust);
2449+ }
2450+ // bind to change of the groupby display state in search widget
2451+ var search_filter = $('search_filter_data');
2452+ if(search_filter) {
2453+ MochiKit.Signal.connect(search_filter, 'groupby-toggle',
2454+ do_adjust);
2455+ }
2456+ // bind to changes to treegrids and treenodes
2457+ MochiKit.Signal.connect(window.document, 'treegrid-render', do_adjust);
2458+ MochiKit.Signal.connect(window.document, 'treenode-expand', do_adjust);
2459+ MochiKit.Signal.connect(window.document, 'treenode-collapse', do_adjust);
2460+ // bind to "onchange" attributes on view/form fields, maybe
2461+ MochiKit.Signal.connect(window.document, 'onfieldchange', do_adjust);
2462+ });
2463+}

Subscribers

People subscribed via source and target branches