[MERGE] xmo great-addons-cleanup-of-2011-xmo

Fixed loading of addons, including basic loading of CSS files whern loading addons
Also fixed content type of AjaxIM poll method.

bzr revid: al@openerp.com-20110414135837-ov0y0olvol4omxzh
This commit is contained in:
Antony Lesuisse 2011-04-14 15:58:37 +02:00
commit a0d4acefb1
17 changed files with 219 additions and 209 deletions

View File

@ -58,13 +58,17 @@ class Xml2Json:
class Session(openerpweb.Controller): class Session(openerpweb.Controller):
_cp_path = "/base/session" _cp_path = "/base/session"
def manifest_glob(self, modlist, key): def manifest_glob(self, addons, key):
files = [] files = []
for i in modlist: for addon in addons:
globlist = openerpweb.addons_manifest.get(i, {}).get(key, []) globlist = openerpweb.addons_manifest.get(addon, {}).get(key, [])
for j in globlist:
for k in glob.glob(os.path.join(openerpweb.path_addons, i, j)): files.extend([
files.append(k[len(openerpweb.path_addons):]) resource_path[len(openerpweb.path_addons):]
for pattern in globlist
for resource_path in glob.glob(os.path.join(
openerpweb.path_addons, addon, pattern))
])
return files return files
def concat_files(self, file_list): def concat_files(self, file_list):
@ -96,14 +100,16 @@ class Session(openerpweb.Controller):
@openerpweb.jsonrequest @openerpweb.jsonrequest
def modules(self, req): def modules(self, req):
return {"modules": ["base", "base_hello", "base_calendar", "base_gantt"]} return {"modules": [name
for name, manifest in openerpweb.addons_manifest.iteritems()
if manifest.get('active', True)]}
@openerpweb.jsonrequest @openerpweb.jsonrequest
def csslist(self, req, mods='base,base_hello'): def csslist(self, req, mods='base'):
return {'files': self.manifest_glob(mods.split(','), 'css')} return {'files': self.manifest_glob(mods.split(','), 'css')}
@openerpweb.jsonrequest @openerpweb.jsonrequest
def jslist(self, req, mods='base,base_hello'): def jslist(self, req, mods='base'):
return {'files': self.manifest_glob(mods.split(','), 'js')} return {'files': self.manifest_glob(mods.split(','), 'js')}
def css(self, req, mods='base,base_hello'): def css(self, req, mods='base,base_hello'):

View File

@ -24,32 +24,10 @@
<script type="text/javascript" src="/base/static/src/js/search.js"></script> <script type="text/javascript" src="/base/static/src/js/search.js"></script>
<script type="text/javascript" src="/base/static/src/js/views.js"></script> <script type="text/javascript" src="/base/static/src/js/views.js"></script>
<script type="text/javascript" src="/base_diagram/static/src/js/diagram.js"></script>
<script type="text/javascript" src="/base_diagram/static/lib/js/raphael-min.js"></script>
<script type="text/javascript" src="/base_diagram/static/lib/js/dracula_graffle.js"></script>
<script type="text/javascript" src="/base_diagram/static/lib/js/dracula_graph.js"></script>
<script type="text/javascript" src="/base_gantt/static/lib/dhtmlxGantt/codebase/dhtmlxcommon.js"></script>
<script type="text/javascript" src="/base_gantt/static/lib/dhtmlxGantt/codebase/dhtmlxgantt.js"></script>
<script type="text/javascript" src="/base_gantt/static/src/gantt.js"></script>
<script type="text/javascript" src="/base_calendar/static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.js"></script>
<script type="text/javascript" src="/base_calendar/static/src/js/calendar.js"></script>
<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery.jsonp-1.1.0.js"></script>
<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery.jstore-all-min.js"></script>
<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery.md5.js"></script>
<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/im.js"></script>
<link rel="stylesheet" type="text/css" media="screen" href="/base/static/lib/jquery.ui/css/smoothness/jquery-ui-1.8.9.custom.css" /> <link rel="stylesheet" type="text/css" media="screen" href="/base/static/lib/jquery.ui/css/smoothness/jquery-ui-1.8.9.custom.css" />
<link rel="stylesheet" type="text/css" media="screen" href="/base/static/lib/jquery.ui.notify/css/ui.notify.css" /> <link rel="stylesheet" type="text/css" media="screen" href="/base/static/lib/jquery.ui.notify/css/ui.notify.css" />
<link rel="stylesheet" type="text/css" href="/base/static/lib/jquery.superfish/css/superfish.css" media="screen"> <link rel="stylesheet" type="text/css" href="/base/static/lib/jquery.superfish/css/superfish.css" media="screen">
<link rel="stylesheet" type="text/css" media="screen" href="/base_gantt/static/lib/dhtmlxGantt/codebase/dhtmlxgantt.css" />
<link rel="stylesheet" type="text/css" media="screen" href="/base_calendar/static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.css">
<link rel="stylesheet" href="/base/static/src/css/base.css" type="text/css"/> <link rel="stylesheet" href="/base/static/src/css/base.css" type="text/css"/>
<script type="text/javascript"> <script type="text/javascript">
@ -58,18 +36,6 @@
oe.base.webclient("oe"); oe.base.webclient("oe");
}); });
</script> </script>
<script>
var AjaxIM, AjaxIMLoadedFunction;
$(function() {
AjaxIM.init({
pollServer: '/web_chat/pollserver',
theme: '/web_chat/static/lib/AjaxIM/themes/default',
flashStorage: '/web_chat/static/lib/AjaxIM/js/jStore.Flash.html'
});
AjaxIM.client.login();
});
</script>
</head> </head>
<body id="oe" class="openerp"> <body id="oe" class="openerp">
</body> </body>

View File

@ -126,9 +126,6 @@ openerp.base = function(instance) {
openerp.base.search(instance); openerp.base.search(instance);
openerp.base.list(instance); openerp.base.list(instance);
openerp.base.form(instance); openerp.base.form(instance);
openerp.base.calendar(instance);
openerp.base.gantt(instance);
openerp.base.diagram(instance);
}; };
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax: // vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:

View File

@ -450,10 +450,21 @@ openerp.base.Session = openerp.base.BasicController.extend( /** @lends openerp.b
var self = this; var self = this;
this.rpc('/base/session/modules', {}, function(result) { this.rpc('/base/session/modules', {}, function(result) {
self.module_list = result['modules']; self.module_list = result['modules'];
self.rpc('/base/session/jslist', {"mods": self.module_list.join(',')}, self.debug ? self.do_load_modules_debug : self.do_load_modules_prod); var modules = self.module_list.join(',');
self.rpc('/base/session/csslist', {mods: modules}, self.do_load_css);
self.rpc('/base/session/jslist', {"mods": modules}, self.debug ? self.do_load_modules_debug : self.do_load_modules_prod);
openerp._modules_loaded = true; openerp._modules_loaded = true;
}); });
}, },
do_load_css: function (result) {
_.each(result.files, function (file) {
$('head').append($('<link>', {
'href': file,
'rel': 'stylesheet',
'type': 'text/css'
}));
});
},
do_load_modules_debug: function(result) { do_load_modules_debug: function(result) {
$LAB.setOptions({AlwaysPreserveOrder: true}) $LAB.setOptions({AlwaysPreserveOrder: true})
.script(result.files) .script(result.files)
@ -466,16 +477,15 @@ openerp.base.Session = openerp.base.BasicController.extend( /** @lends openerp.b
// use $.getScript(your_3rd_party-script.js); ? i want to keep lineno ! // use $.getScript(your_3rd_party-script.js); ? i want to keep lineno !
}, },
on_modules_loaded: function() { on_modules_loaded: function() {
var self = this; for(var j=0; j<this.module_list.length; j++) {
for(var j=0; j<self.module_list.length; j++) { var mod = this.module_list[j];
var mod = self.module_list[j]; if(this.module_loaded[mod])
if(self.module_loaded[mod])
continue; continue;
openerp[mod] = {}; openerp[mod] = {};
// init module mod // init module mod
if(openerp._openerp[mod] != undefined) { if(openerp._openerp[mod] != undefined) {
openerp._openerp[mod](openerp); openerp._openerp[mod](openerp);
self.module_loaded[mod] = true; this.module_loaded[mod] = true;
} }
} }
} }
@ -491,7 +501,7 @@ openerp.base.Controller = openerp.base.BasicController.extend( /** @lends opener
controller_manifest: { controller_manifest: {
register: null, register: null,
template: "", template: "",
element_post_prefix: false, element_post_prefix: false
}, },
/** /**
* Controller registry, * Controller registry,
@ -702,7 +712,7 @@ openerp.base.CrashManager = openerp.base.Controller.extend({
openerp.base.Loading = openerp.base.Controller.extend({ openerp.base.Loading = openerp.base.Controller.extend({
controller_manifest: { controller_manifest: {
register: ["Loading"], register: ["Loading"]
}, },
init: function(session, element_id) { init: function(session, element_id) {
this._super(session, element_id); this._super(session, element_id);

View File

@ -231,10 +231,6 @@
<button type="button" name="delete"></button> <button type="button" name="delete"></button>
</td> </td>
</tr> </tr>
<t t-name="DiagramView">
<h2 class="oe_view_title"><t t-esc="fields_view.arch.attrs.string"/></h2>
<div id="dia-canvas" style="overflow: auto;"></div>
</t>
<t t-name="FormView"> <t t-name="FormView">
<h2 class="oe_view_title"><t t-esc="view.fields_view.arch.attrs.string"/></h2> <h2 class="oe_view_title"><t t-esc="view.fields_view.arch.attrs.string"/></h2>
<div class="oe_form_header" t-att-id="view.element_id + '_header'"> <div class="oe_form_header" t-att-id="view.element_id + '_header'">
@ -574,48 +570,4 @@
</p> </p>
</div> </div>
</t> </t>
<t t-name="CalendarView">
<h3 class="title"><t t-esc="view.fields_view.arch.attrs.string"/></h3>
<table class="calendar-view" width="100%" height="100%" cellspacing="0" cellpadding="0">
<tr>
<td>
<div style="height: 1000px;width: 100%;">
<div id="calendar-sidebar">
</div>
</div>
</td>
<td style="width:85%;" align="left">
<div id="openerp_scheduler" class="dhx_cal_container" style="height: 1000px;width: 100%;">
<div class="dhx_cal_navline">
<div class="dhx_cal_prev_button"></div>
<div class="dhx_cal_next_button"></div>
<div class="dhx_cal_today_button"></div>
<div class="dhx_cal_date"></div>
<div class="dhx_minical_icon" id="dhx_minical_icon"></div>
<div class="dhx_cal_tab" name="day_tab" style="right:204px;"></div>
<div class="dhx_cal_tab" name="week_tab" style="right:140px;"></div>
<div class="dhx_cal_tab" name="month_tab" style="right:76px;"></div>
</div>
<div class="dhx_cal_header">
</div>
<div class="dhx_cal_data">
</div>
</div>
</td>
</tr>
</table>
</t>
<t t-name="GanttView">
<h3 class="title"><t t-esc="view.fields_view.arch.attrs.string"/></h3>
<table class="gantt-view" width="100%" height="100%" cellspacing="0" cellpadding="0">
<tr>
<td style="width:85%">
<div style="width:100%;height:300px;position:relative" id="GanttDiv"></div>
</td>
<td valign = "top">
<div id="gantt-sidebar"></div>
</td>
</tr>
</table>
</t>
</templates> </templates>

View File

@ -1,57 +1,11 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{ {
"name" : "Basic Calendar Functionality", "name": "Base calendar",
"version" : "1.0", "version": "2.0",
"depends" : ["base"], "depends": ['base'],
'description': """ "js": [
This is a full-featured calendar system. 'static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.js',
======================================== 'static/src/js/calendar.js'
It supports:
- Calendar of events
- Alerts (create requests)
- Recurring events
- Invitations to people""",
"author" : "OpenERP SA",
'category': 'Tools',
'website': 'http://www.openerp.com',
"init_xml" : [
'base_calendar_data.xml'
], ],
"demo_xml" : [], "css": ['static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.css'],
"update_xml" : [ 'active': True
'security/calendar_security.xml',
'security/ir.model.access.csv',
'wizard/calendar_event_edit_all_view.xml',
'wizard/base_calendar_invite_attendee_view.xml',
'wizard/base_calendar_set_exrule_view.xml',
'base_calendar_view.xml'
],
"test" : ['test/base_calendar_test.yml'],
"installable" : True,
"active" : False,
"certificate" : "00694071962960352821",
'images': ['images/base_calendar1.jpeg','images/base_calendar2.jpeg','images/base_calendar3.jpeg','images/base_calendar4.jpeg',],
} }
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -2,10 +2,10 @@
* OpenERP base_calendar * OpenERP base_calendar
*---------------------------------------------------------*/ *---------------------------------------------------------*/
openerp.base.calendar = function(openerp) { openerp.base_calendar = function(openerp) {
QWeb.add_template('/base_calendar/static/src/xml/base_calendar.xml');
openerp.base.views.add('calendar', 'openerp.base.CalendarView'); openerp.base.views.add('calendar', 'openerp.base_calendar.CalendarView');
openerp.base.CalendarView = openerp.base.Controller.extend({ openerp.base_calendar.CalendarView = openerp.base.Controller.extend({
// Dhtmlx scheduler ? // Dhtmlx scheduler ?
init: function(view_manager, session, element_id, dataset, view_id){ init: function(view_manager, session, element_id, dataset, view_id){
this._super(session, element_id); this._super(session, element_id);
@ -201,7 +201,7 @@ openerp.base.CalendarView = openerp.base.Controller.extend({
do_hide: function () { do_hide: function () {
this.$element.hide(); this.$element.hide();
}, }
}); });
//openerp.base.Action = openerp.base.Action.extend({ //openerp.base.Action = openerp.base.Action.extend({

View File

@ -0,0 +1,33 @@
<template>
<t t-name="CalendarView">
<h3 class="title"><t t-esc="view.fields_view.arch.attrs.string"/></h3>
<table class="calendar-view" width="100%" height="100%" cellspacing="0" cellpadding="0">
<tr>
<td>
<div style="height: 1000px;width: 100%;">
<div id="calendar-sidebar">
</div>
</div>
</td>
<td style="width:85%;" align="left">
<div id="openerp_scheduler" class="dhx_cal_container" style="height: 1000px;width: 100%;">
<div class="dhx_cal_navline">
<div class="dhx_cal_prev_button"/>
<div class="dhx_cal_next_button"/>
<div class="dhx_cal_today_button"/>
<div class="dhx_cal_date"/>
<div class="dhx_minical_icon" id="dhx_minical_icon"/>
<div class="dhx_cal_tab" name="day_tab" style="right:204px;"/>
<div class="dhx_cal_tab" name="week_tab" style="right:140px;"/>
<div class="dhx_cal_tab" name="month_tab" style="right:76px;"/>
</div>
<div class="dhx_cal_header">
</div>
<div class="dhx_cal_data">
</div>
</div>
</td>
</tr>
</table>
</t>
</template>

View File

@ -2,5 +2,5 @@
"name" : "OpenERP Web base Diagram", "name" : "OpenERP Web base Diagram",
"version" : "2.0", "version" : "2.0",
"depends" : [], "depends" : [],
'active': True, 'active': False,
} }

View File

@ -1,7 +1,12 @@
{ {
"name": "Base Gantt", "name": "Base Gantt",
"version": "2.0", "version": "2.0",
"depends": [], "depends": ['base'],
"js": ["static/*/js/*.js"], "js": [
"css": [], 'static/lib/dhtmlxGantt/codebase/dhtmlxcommon.js',
'static/lib/dhtmlxGantt/codebase/dhtmlxgantt.js',
'static/src/js/gantt.js'
],
"css": ['static/lib/dhtmlxGantt/codebase/dhtmlxgantt.css'],
'active': True
} }

View File

@ -2,9 +2,10 @@
* OpenERP base_gantt * OpenERP base_gantt
*---------------------------------------------------------*/ *---------------------------------------------------------*/
openerp.base.gantt = function (openerp) { openerp.base_gantt = function (openerp) {
openerp.base.views.add('gantt', 'openerp.base.GanttView'); QWeb.add_template('/base_gantt/static/src/xml/base_gantt.xml');
openerp.base.GanttView = openerp.base.Controller.extend({ openerp.base.views.add('gantt', 'openerp.base_gantt.GanttView');
openerp.base_gantt.GanttView = openerp.base.Controller.extend({
init: function(view_manager, session, element_id, dataset, view_id) { init: function(view_manager, session, element_id, dataset, view_id) {
this._super(session, element_id); this._super(session, element_id);
@ -216,7 +217,7 @@ openerp.base.GanttView = openerp.base.Controller.extend({
}, },
function(result) { function(result) {
}) })
}, }
}); });

View File

@ -0,0 +1,15 @@
<template>
<t t-name="GanttView">
<h3 class="title"><t t-esc="view.fields_view.arch.attrs.string"/></h3>
<table class="gantt-view" width="100%" height="100%" cellspacing="0" cellpadding="0">
<tr>
<td style="width:85%">
<div style="width:100%;height:300px;position:relative" id="GanttDiv"/>
</td>
<td valign = "top">
<div id="gantt-sidebar"/>
</td>
</tr>
</table>
</t>
</template>

View File

@ -1,8 +1,14 @@
{ {
"name": "Web Chat", "name": "Web Chat",
"version": "2.0", "version": "2.0",
"depends": [], "depends": ['base'],
"js": [], "js": [
'static/lib/AjaxIM/js/jquery.jsonp-1.1.0.js',
'static/lib/AjaxIM/js/jquery.jstore-all-min.js',
'static/lib/AjaxIM/js/jquery.md5.js',
'static/lib/AjaxIM/js/im.js',
'static/src/js/web_chat.js'
],
"css": [], "css": [],
'active': True, 'active': False,
} }

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sys, time import sys, time
import cherrypy
import simplejson import simplejson
import random import random
@ -102,11 +103,6 @@ class PollServer(openerpweb.Controller):
@openerpweb.httprequest @openerpweb.httprequest
def poll(self, req, **kw): def poll(self, req, **kw):
mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
# Method: Long Poll
""" """
--> GET http://im.ajaxim.com/poll?callback=jsonp1302138663582&_1302138663582= --> GET http://im.ajaxim.com/poll?callback=jsonp1302138663582&_1302138663582=
<-- 200 OK <-- 200 OK
@ -129,9 +125,15 @@ class PollServer(openerpweb.Controller):
echo '<script type="text/javascript">parent.AjaxIM.incoming('. json_encode($this->_pollParseMessages($messages)) . ');</script>' echo '<script type="text/javascript">parent.AjaxIM.incoming('. json_encode($this->_pollParseMessages($messages)) . ');</script>'
""" """
mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
# Method: Long Poll
msg = '[]' msg = '[]'
cherrypy.response.headers['content-type'] = 'application/javascript';
for i in range(5): for i in range(5):
received_msg = mq.read('Guest1', i) received_msg = mq.read('Guest1', i)
if received_msg: if received_msg:
@ -145,12 +147,6 @@ class PollServer(openerpweb.Controller):
@openerpweb.httprequest @openerpweb.httprequest
def send(self, req, **kw): def send(self, req, **kw):
to = kw.get('to')
message = kw.get('message')
mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
""" """
--> GET http://im.ajaxim.com/send?callback=jsonp1302139980022&to=Guest130205108745.47&message=test&_1302139980022= --> GET http://im.ajaxim.com/send?callback=jsonp1302139980022&to=Guest130205108745.47&message=test&_1302139980022=
callback: jsonp1302139980022 callback: jsonp1302139980022
@ -168,6 +164,12 @@ class PollServer(openerpweb.Controller):
""" """
to = kw.get('to')
message = kw.get('message')
mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
if not req.applicationsession['current_user']: if not req.applicationsession['current_user']:
return dict(r='error', e='no session found') return dict(r='error', e='no session found')
@ -182,8 +184,6 @@ class PollServer(openerpweb.Controller):
@openerpweb.httprequest @openerpweb.httprequest
def status(self, req, **kw): def status(self, req, **kw):
mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
""" """
--> GET status call --> GET status call
const Offline = 0; const Offline = 0;
@ -198,6 +198,8 @@ class PollServer(openerpweb.Controller):
return array('r' => 'error', 'e' => 'no session found'); return array('r' => 'error', 'e' => 'no session found');
return array('r' => 'error', 'e' => 'status error'); return array('r' => 'error', 'e' => 'status error');
""" """
mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
print "======== chat status ========",kw print "======== chat status ========",kw
# mq.write() # mq.write()
return {"action": ""} return {"action": ""}

View File

@ -0,0 +1,10 @@
openerp.web_chat = function (openerp) {
openerp.web_chat = {};
openerp.web_chat.im = new AjaxIM({
storageMethod: 'local',
pollServer: '/web_chat/pollserver',
theme: '/web_chat/static/lib/AjaxIM/themes/default',
flashStorage: '/web_chat/static/lib/AjaxIM/js/jStore.Flash.html'
});
openerp.web_chat.im.login();
};

View File

@ -1,24 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery-1.3.2.js"></script>
<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery.jsonp-1.1.0.js"></script>
<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery.jstore-all-min.js"></script>
<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery.md5.js"></script>
<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/im.js"></script>
</head>
<body>
<script>
var AjaxIM, AjaxIMLoadedFunction;
$(function() {
AjaxIM.init({
pollServer: '/web_chat/pollserver',
theme: '/web_chat/static/lib/AjaxIM/themes/default',
flashStorage: '/web_chat/static/lib/AjaxIM/js/jStore.Flash.html'
});
AjaxIM.client.login();
});
</script>
</body>
</html>

View File

@ -1,6 +1,10 @@
Developing OpenERP Web Addons Developing OpenERP Web Addons
============================= =============================
An OpenERP Web addon is simply a Python package with an openerp
descriptor (a ``__openerp__.py`` file) which follows a few structural
and namespacing rules.
Structure Structure
--------- ---------
@ -50,6 +54,79 @@ Structure
``test/`` ``test/``
The directories in which all tests for the addon are located. The directories in which all tests for the addon are located.
Some of these are guidelines (and not enforced by code), but it's
suggested that these be followed. Code which does not fit into these
categories can go wherever deemed suitable.
Namespacing
-----------
Python
++++++
Because addons are also Python packages, they're inherently namespaced
and nothing special needs to be done on that front.
JavaScript
++++++++++
The JavaScript side of an addon has to live in the namespace
``openerp.$addon_name``. For instance, everything created by the addon
``base`` lives in ``openerp.base``.
The root namespace of the addon is a function which takes a single
parameter ``openerp``, which is an OpenERP client instance. Objects
(as well as functions, registry instances, etc...) should be added on
the correct namespace on that object.
The root function will be called by the OpenERP Web client when
initializing the addon.
.. code-block:: javascript
// root namespace of the openerp.example addon
/** @namespace */
openerp.example = function (openerp) {
// basic initialization code (e.g. templates loading)
openerp.example.SomeClass = Class.extend(
/** @lends openerp.example.SomeClass# */{
/**
* Description for SomeClass's constructor here
*
* @constructs
*/
init: function () {
// SomeClass initialization code
}
// rest of SomeClass
});
// access an object in an other addon namespace to replace it
openerp.base.SearchView = openerp.base.SearchView.extend({
init: function () {
this._super.apply(this, arguments);
console.log('Search view initialized');
}
});
}
Utility behaviors
-----------------
JavaScript
++++++++++
* All javascript objects inheriting from
:js:class:`openerp.base.BasicConroller` will have all methods
starting with ``on_`` or ``do_`` bound to their ``this``. This means
they don't have to be manually bound (via ``_.bind`` or ``$.proxy``)
in order to be useable as bound event handlers (event handlers
keeping their object as ``this`` rather than taking whatever
``this`` object they were called with).
Beware that this is only valid for methods starting with ``do_`` and
``on_``, any other method will have to be bound manually.
.. _addons-testing: .. _addons-testing:
Testing Testing