[MERGE] from trunk

bzr revid: chm@openerp.com-20130726141841-a30nn35b63p2l3uh
This commit is contained in:
Christophe Matthieu 2013-07-26 16:18:41 +02:00
commit 25f117a056
357 changed files with 1019 additions and 752 deletions

View File

@ -1,21 +1,15 @@
.*.swp
.bzrignore
.idea
.project
.pydevproject
.ropeproject
.settings
.DS_Store
openerp/addons/*
openerp/filestore*
.Python
*.pyc
*.pyo
bin/*
.*
*.egg-info
*.orig
*.vim
build/
include/
lib/
share/
doc/_build/*
win32/*.bat
win32/meta.py
RE:^bin/
RE:^dist/
RE:^include/
RE:^share/
RE:^man/
RE:^lib/
RE:^addons/\w+/doc/_build/
RE:^.*?/node_modules

20
addons/web/Gruntfile.js Normal file
View File

@ -0,0 +1,20 @@
module.exports = function(grunt) {
grunt.initConfig({
jshint: {
src: ['static/src/**/*.js', 'static/test/**/*.js'],
options: {
sub: true, //[] instead of .
evil: true, //eval
laxbreak: true, //unsafe line breaks
},
}
});
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.registerTask('test', ['jshint']);
grunt.registerTask('default', ['jshint']);
};

View File

@ -88,9 +88,6 @@ def rjsmin(script):
db_list = http.db_list
def db_monodb_redirect():
return http.db_redirect(not config['list_db'])
db_monodb = http.db_monodb
def redirect_with_hash(url, code=303):
@ -296,13 +293,13 @@ def manifest_glob(extension, addons=None, db=None, include_remotes=False):
r.append((path, fs2web(path[len(addons_path):])))
return r
def manifest_list(extension, mods=None, db=None):
def manifest_list(extension, mods=None, db=None, debug=False):
""" list ressources to load specifying either:
mods: a comma separated string listing modules
db: a database name (return all installed modules in that database)
"""
files = manifest_glob(extension, addons=mods, db=db, include_remotes=True)
if not request.debug:
if not debug:
path = '/web/webclient/' + extension
if mods is not None:
path += '?' + urllib.urlencode({'mods': mods})
@ -535,13 +532,24 @@ html_template = """<!DOCTYPE html>
class Home(http.Controller):
@http.route('/', type='http', auth="none")
def index(self, s_action=None, db=None, **kw):
db, redir = db_monodb_redirect()
if redir:
return redirect_with_hash(redir)
def index(self, s_action=None, db=None, debug=False, **kw):
debug = debug != False
if db is not None:
lst = http.db_list(True)
if db in lst and db != request.session.db:
request.session.logout()
request.session.db = db
js = "\n ".join('<script type="text/javascript" src="%s"></script>' % i for i in manifest_list('js', db=db))
css = "\n ".join('<link rel="stylesheet" href="%s">' % i for i in manifest_list('css', db=db))
if db != request.session.db:
query = dict(urlparse.parse_qsl(request.httprequest.query_string, keep_blank_values=True))
query.update({'db': request.session.db})
redirect = request.httprequest.path + '?' + urllib.urlencode(query)
return redirect_with_hash(redirect)
db = request.session.db
js = "\n ".join('<script type="text/javascript" src="%s"></script>' % i for i in manifest_list('js', db=db, debug=debug))
css = "\n ".join('<link rel="stylesheet" href="%s">' % i for i in manifest_list('css', db=db, debug=debug))
r = html_template % {
'js': js,
@ -549,7 +557,7 @@ class Home(http.Controller):
'modules': simplejson.dumps(module_boot(db=db)),
'init': 'var wc = new s.web.WebClient();wc.appendTo($(document.body));'
}
return r
return request.make_response(r, {'Cache-Control': 'no-cache', 'Content-Type': 'text/html; charset=utf-8'})
@http.route('/login', type='http', auth="user")
def login(self, db, login, key):
@ -778,7 +786,7 @@ class Database(http.Controller):
return request.make_response(db_dump,
[('Content-Type', 'application/octet-stream; charset=binary'),
('Content-Disposition', content_disposition(filename))],
{'fileToken': int(token)}
{'fileToken': token}
)
except Exception, e:
return simplejson.dumps([[],[{'error': openerp.tools.ustr(e), 'title': _('Backup Database')}]])
@ -819,7 +827,7 @@ class Session(http.Controller):
@http.route('/web/session/get_session_info', type='json', auth="none")
def get_session_info(self):
request.uid = request.session.uid
request.db = request.session.db
request.disable_db = False
return self.session_info()
@http.route('/web/session/authenticate', type='json', auth="none")
@ -1273,7 +1281,7 @@ class Binary(http.Controller):
return request.make_response(filecontent,
headers=[('Content-Type', 'application/octet-stream'),
('Content-Disposition', content_disposition(filename))],
cookies={'fileToken': int(token)})
cookies={'fileToken': token})
@http.route('/web/binary/upload', type='http', auth="user")
def upload(self, callback, ufile):
@ -1399,7 +1407,10 @@ class Export(http.Controller):
:returns: for each export format, a pair of identifier and printable name
:rtype: [(str, str)]
"""
return ["CSV", "Excel"]
return [
{'tag': 'csv', 'label': 'CSV'},
{'tag': 'xls', 'label': 'Excel', 'error': None if xlwt else "XLWT required"},
]
def fields_get(self, model):
Model = request.session.model(model)
@ -1572,10 +1583,9 @@ class ExportFormat(object):
headers=[('Content-Disposition',
content_disposition(self.filename(model))),
('Content-Type', self.content_type)],
cookies={'fileToken': int(token)})
cookies={'fileToken': token})
class CSVExport(ExportFormat, http.Controller):
fmt = {'tag': 'csv', 'label': 'CSV'}
@http.route('/web/export/csv', type='http', auth="user")
def index(self, data, token):
@ -1613,11 +1623,6 @@ class CSVExport(ExportFormat, http.Controller):
return data
class ExcelExport(ExportFormat, http.Controller):
fmt = {
'tag': 'xls',
'label': 'Excel',
'error': None if xlwt else "XLWT required"
}
@http.route('/web/export/xls', type='http', auth="user")
def index(self, data, token):
@ -1719,6 +1724,6 @@ class Reports(http.Controller):
('Content-Disposition', content_disposition(file_name)),
('Content-Type', report_mimetype),
('Content-Length', len(report))],
cookies={'fileToken': int(token)})
cookies={'fileToken': token})
# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -85,10 +85,6 @@ class WebRequest(object):
:class:`~collections.Mapping` of context values for the current request
.. attribute:: debug
``bool``, indicates whether the debug mode is active on the client
.. attribute:: db
``str``, the name of the database linked to the current request. Can be ``None``
@ -105,20 +101,17 @@ class WebRequest(object):
self.httpsession = httprequest.session
self.session = httprequest.session
self.session_id = httprequest.session.sid
self.db = None
self.disable_db = False
self.uid = None
self.func = None
self.auth_method = None
self._cr_cm = None
self._cr = None
self.func_request_type = None
self.debug = self.httprequest.args.get('debug', False) is not False
with set_request(self):
self.db = self.session.db or db_monodb()
# set db/uid trackers - they're cleaned up at the WSGI
# dispatching phase in openerp.service.wsgi_server.application
if self.db:
threading.current_thread().dbname = self.session.db
threading.current_thread().dbname = self.db
if self.session.uid:
threading.current_thread().uid = self.session.uid
self.context = self.session.context
@ -132,17 +125,16 @@ class WebRequest(object):
self.session.logout()
raise SessionExpiredException("Session expired for request %s" % self.httprequest)
if self.auth_method == "none":
self.db = None
self.disable_db = True
self.uid = None
elif self.auth_method == "admin":
self.db = self.session.db or db_monodb()
self.disable_db = False
if not self.db:
raise SessionExpiredException("No valid database for request %s" % self.httprequest)
self.uid = openerp.SUPERUSER_ID
else: # auth
self.db = self.session.db
self.disable_db = False
self.uid = self.session.uid
@property
def registry(self):
"""
@ -151,6 +143,14 @@ class WebRequest(object):
"""
return openerp.modules.registry.RegistryManager.get(self.db) if self.db else None
@property
def db(self):
"""
The registry to the database linked to this request. Can be ``None`` if the current request uses the
``none'' authentication.
"""
return self.session.db if not self.disable_db else None
@property
def cr(self):
"""
@ -184,7 +184,7 @@ class WebRequest(object):
return self.func(*args, **kwargs)
finally:
# just to be sure no one tries to re-use the request
self.db = None
self.disable_db = True
self.uid = None
def route(route, type="http", auth="user"):
@ -304,8 +304,6 @@ class JsonRequest(WebRequest):
error = None
try:
#if _logger.isEnabledFor(logging.DEBUG):
# _logger.debug("--> %s.%s\n%s", func.im_class.__name__, func.__name__, pprint.pformat(self.jsonrequest))
response['id'] = self.jsonrequest.get('id')
response["result"] = self._call_function(**self.params)
except AuthenticationError, e:
@ -327,9 +325,6 @@ class JsonRequest(WebRequest):
if error:
response["error"] = error
if _logger.isEnabledFor(logging.DEBUG):
_logger.debug("<--\n%s", pprint.pformat(response))
if self.jsonp:
# If we use jsonp, that's mean we are called from another host
# Some browser (IE and Safari) do no allow third party cookies
@ -394,7 +389,7 @@ class HttpRequest(WebRequest):
def __init__(self, *args):
super(HttpRequest, self).__init__(*args)
params = dict(self.httprequest.args)
ex = set(["session_id", "debug"])
ex = set(["session_id"])
for k in params.keys():
if k in ex:
del params[k]
@ -409,7 +404,6 @@ class HttpRequest(WebRequest):
akw[key] = value
else:
akw[key] = type(value)
#_logger.debug("%s --> %s.%s %r", self.httprequest.func, func.im_class.__name__, func.__name__, akw)
try:
r = self._call_function(**self.params)
except werkzeug.exceptions.HTTPException, e:
@ -426,10 +420,6 @@ class HttpRequest(WebRequest):
else:
if not r:
r = werkzeug.wrappers.Response(status=204) # no content
if isinstance(r, (werkzeug.wrappers.BaseResponse, werkzeug.exceptions.HTTPException)):
_logger.debug('<-- %s', r)
else:
_logger.debug("<-- size: %s", len(r))
return r
def make_response(self, data, headers=None, cookies=None):
@ -597,12 +587,7 @@ class OpenERPSession(werkzeug.contrib.sessions.Session):
self.modified = False
super(OpenERPSession, self).__init__(*args, **kwargs)
self.inited = True
self.setdefault("db", None)
self.setdefault("uid", None)
self.setdefault("login", None)
self.setdefault("password", None)
self.setdefault("context", {'tz': "UTC", "uid": None})
self.setdefault("jsonp_requests", {})
self._default_values()
self.modified = False
def __getattr__(self, attr):
@ -631,8 +616,8 @@ class OpenERPSession(werkzeug.contrib.sessions.Session):
self.uid = uid
self.login = login
self.password = password
request.db = db
request.uid = uid
request.disable_db = False
if uid: self.get_context()
return uid
@ -650,6 +635,15 @@ class OpenERPSession(werkzeug.contrib.sessions.Session):
def logout(self):
for k in self.keys():
del self[k]
self._default_values()
def _default_values(self):
self.setdefault("db", None)
self.setdefault("uid", None)
self.setdefault("login", None)
self.setdefault("password", None)
self.setdefault("context", {'tz': "UTC", "uid": None})
self.setdefault("jsonp_requests", {})
def get_context(self):
"""
@ -896,6 +890,8 @@ class Root(object):
else:
httprequest.session = self.session_store.get(sid)
self._find_db(httprequest)
if not "lang" in httprequest.session.context:
lang = httprequest.accept_languages.best or "en_US"
lang = babel.core.LOCALE_ALIASES.get(lang, lang).replace('-', '_')
@ -932,6 +928,12 @@ class Root(object):
except werkzeug.exceptions.HTTPException, e:
return e(environ, start_response)
def _find_db(self, httprequest):
db = db_monodb(httprequest)
if db != httprequest.session.db:
httprequest.session.logout()
httprequest.session.db = db
def _build_request(self, httprequest):
if httprequest.args.get('jsonp'):
return JsonRequest(httprequest)
@ -1046,43 +1048,16 @@ class Root(object):
root = None
def db_list(force=False):
proxy = request.session.proxy("db")
dbs = proxy.list(force)
h = request.httprequest.environ['HTTP_HOST'].split(':')[0]
def db_list(force=False, httprequest=None):
httprequest = httprequest or request.httprequest
dbs = openerp.netsvc.dispatch_rpc("db", "list", [force])
h = httprequest.environ['HTTP_HOST'].split(':')[0]
d = h.split('.')[0]
r = openerp.tools.config['dbfilter'].replace('%h', h).replace('%d', d)
dbs = [i for i in dbs if re.match(r, i)]
return dbs
def db_redirect(match_first_only_if_unique):
db = None
redirect = None
# 1 try the db in the url
db_url = request.httprequest.args.get('db')
if db_url:
return (db_url, None)
dbs = db_list(True)
# 2 use the database from the cookie if it's listable and still listed
cookie_db = request.httprequest.cookies.get('last_used_database')
if cookie_db in dbs:
db = cookie_db
# 3 use the first db if user can list databases
if dbs and not db and (not match_first_only_if_unique or len(dbs) == 1):
db = dbs[0]
# redirect to the chosen db if multiple are available
if db and len(dbs) > 1:
query = dict(urlparse.parse_qsl(request.httprequest.query_string, keep_blank_values=True))
query.update({'db': db})
redirect = request.httprequest.path + '?' + urllib.urlencode(query)
return (db, redirect)
def db_monodb():
def db_monodb(httprequest=None):
"""
Magic function to find the current database.
@ -1091,10 +1066,27 @@ def db_monodb():
* Magic
* More magic
Return ``None`` if the magic is not magic enough.
Returns ``None`` if the magic is not magic enough.
"""
return db_redirect(True)[0]
httprequest = httprequest or request.httprequest
db = None
redirect = None
dbs = db_list(True, httprequest)
# 1 try the db already in the session
db_session = httprequest.session.db
if db_session in dbs:
return db_session
# 2 if there is only one db in the db filters, take it
if len(dbs) == 1:
return dbs[0]
# 3 if there are multiple dbs, take the first one only if we can list them
if len(dbs) > 1 and config['list_db']:
return dbs[0]
return None
class CommonController(Controller):

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:03+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:39+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:03+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:39+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:03+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
"X-Poedit-Language: Czech\n"

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
"Language: es\n"

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:03+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:39+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:40+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web
@ -1440,7 +1440,7 @@ msgstr "Wijzig standaard"
#: code:addons/web/static/src/xml/base.xml:189
#, python-format
msgid "Original database name:"
msgstr "Originele database naam:"
msgstr "Naam originele database:"
#. module: web
#. openerp-web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -15,7 +15,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web
@ -378,7 +378,7 @@ msgstr "'%s' não é uma data correta"
#: code:addons/web/static/src/js/view_list.js:432
#, python-format
msgid "Group"
msgstr "Agrupar"
msgstr "Grupo"
#. module: web
#. openerp-web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:03+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:39+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:04+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:41+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web

6
addons/web/package.json Normal file
View File

@ -0,0 +1,6 @@
{
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-jshint": "~0.6.0"
}
}

View File

@ -438,7 +438,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({
self.$el.html(QWeb.render("DatabaseManager", { widget : self }));
$('.oe_user_menu_placeholder').append(QWeb.render("DatabaseManager.user_menu",{ widget : self }));
$('.oe_secondary_menus_container').append(QWeb.render("DatabaseManager.menu",{ widget : self }));
$('ul.oe_secondary_submenu > li:first').addClass('oe_active')
$('ul.oe_secondary_submenu > li:first').addClass('oe_active');
$('ul.oe_secondary_submenu > li').bind('click', function (event) {
var menuitem = $(this);
menuitem.addClass('oe_active').siblings().removeClass('oe_active');
@ -705,20 +705,9 @@ instance.web.Login = instance.web.Widget.extend({
}
return d;
},
remember_last_used_database: function(db) {
// This cookie will be used server side in order to avoid db reloading on first visit
var ttl = 24 * 60 * 60 * 365;
document.cookie = [
'last_used_database=' + db,
'path=/',
'max-age=' + ttl,
'expires=' + new Date(new Date().getTime() + ttl * 1000).toGMTString()
].join(';');
},
database_selected: function(db) {
var params = $.deparam.querystring();
params.db = db;
this.remember_last_used_database(db);
this.$('.oe_login_dbpane').empty().text(_t('Loading...'));
this.$('[name=login], [name=password]').prop('readonly', true);
instance.web.redirect('/?' + $.param(params));
@ -769,7 +758,6 @@ instance.web.Login = instance.web.Widget.extend({
self.hide_error();
self.$(".oe_login_pane").fadeOut("slow");
return this.session.session_authenticate(db, login, password).then(function() {
self.remember_last_used_database(db);
if (self.has_local_storage && self.remember_credentials) {
localStorage.setItem(db + '|last_login', login);
if (self.session.debug) {
@ -804,10 +792,17 @@ instance.web.redirect = function(url, wait) {
instance.client.crashmanager.active = false;
}
var wait_server = function() {
instance.session.rpc("/web/webclient/version_info", {}).done(function() {
var load = function() {
var old = "" + window.location;
if (old === url) {
window.location.reload();
} else {
window.location = url;
}).fail(function() {
}
};
var wait_server = function() {
instance.session.rpc("/web/webclient/version_info", {}).done(load).fail(function() {
setTimeout(wait_server, 250);
});
};
@ -815,7 +810,7 @@ instance.web.redirect = function(url, wait) {
if (wait) {
setTimeout(wait_server, 1000);
} else {
window.location = url;
load();
}
};
@ -830,7 +825,6 @@ instance.web.Reload = function(parent, action) {
var l = window.location;
var sobj = $.deparam(l.search.substr(1));
sobj.ts = new Date().getTime();
if (params.url_search) {
sobj = _.extend(sobj, params.url_search);
}
@ -875,7 +869,7 @@ instance.web.ChangePassword = instance.web.Widget.extend({
$button.appendTo(this.getParent().$buttons);
$button.eq(2).click(function(){
self.getParent().close();
})
});
$button.eq(0).click(function(){
self.rpc("/web/session/change_password",{
'fields': $("form[name=change_password_form]").serializeArray()
@ -887,7 +881,7 @@ instance.web.ChangePassword = instance.web.Widget.extend({
instance.webclient.on_logout();
}
});
})
});
},
display_error: function (error) {
return instance.web.dialog($('<div>'), {
@ -898,7 +892,7 @@ instance.web.ChangePassword = instance.web.Widget.extend({
]
}).html(error.error);
},
})
});
instance.web.client_actions.add("change_password", "instance.web.ChangePassword");
instance.web.Menu = instance.web.Widget.extend({
@ -1114,7 +1108,7 @@ instance.web.Menu = instance.web.Widget.extend({
add_menu_ids(menu);
});
}
};
}
add_menu_ids(menu);
self.do_load_needaction(menu_ids).then(function () {
self.trigger("need_action_reloaded");

View File

@ -73,7 +73,7 @@ openerp.web.corelib = function(instance) {
*/
(function() {
var initializing = false,
fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
fnTest = /xyz/.test(function(){xyz();}) ? /\b_super\b/ : /.*/;
// The web Class implementation (does nothing)
instance.web.Class = function(){};
@ -96,7 +96,7 @@ openerp.web.corelib = function(instance) {
initializing = false;
// Copy the properties over onto the new prototype
for (var name in prop) {
_.each(prop, function(val, name) {
// Check if we're overwriting an existing function
prototype[name] = typeof prop[name] == "function" &&
fnTest.test(prop[name]) ?
@ -117,13 +117,12 @@ openerp.web.corelib = function(instance) {
};
})(name, prop[name]) :
prop[name];
}
});
// The dummy class constructor
function Class() {
if(this.constructor !== instance.web.Class){
throw new Error("You can only instanciate objects with the 'new' operator");
return null;
}
// All construction is actually done in the init method
if (!initializing && this.init) {
@ -133,7 +132,7 @@ openerp.web.corelib = function(instance) {
return this;
}
Class.include = function (properties) {
for (var name in properties) {
_.each(properties, function(val, name) {
if (typeof properties[name] !== 'function'
|| !fnTest.test(properties[name])) {
prototype[name] = properties[name];
@ -146,7 +145,7 @@ openerp.web.corelib = function(instance) {
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
}
};
})(name, properties[name], prototype[name]);
} else if (typeof _super[name] === 'function') {
prototype[name] = (function (name, fn) {
@ -156,10 +155,10 @@ openerp.web.corelib = function(instance) {
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
}
};
})(name, properties[name]);
}
}
});
};
// Populate our constructed prototype object
@ -297,7 +296,7 @@ var Events = instance.web.Class.extend({
var ev;
events = events.split(/\s+/);
var calls = this._callbacks || (this._callbacks = {});
while (ev = events.shift()) {
while ((ev = events.shift())) {
var list = calls[ev] || (calls[ev] = {});
var tail = list.tail || (list.tail = list.next = {});
tail.callback = callback;
@ -311,9 +310,9 @@ var Events = instance.web.Class.extend({
var ev, calls, node;
if (!events) {
delete this._callbacks;
} else if (calls = this._callbacks) {
} else if ((calls = this._callbacks)) {
events = events.split(/\s+/);
while (ev = events.shift()) {
while ((ev = events.shift())) {
node = calls[ev];
delete calls[ev];
if (!callback || !node)
@ -347,7 +346,7 @@ var Events = instance.web.Class.extend({
all = calls['all'];
(events = events.split(/\s+/)).push(null);
// Save references to the current heads & tails.
while (event = events.shift()) {
while ((event = events.shift())) {
if (all)
events.push({
next : all.next,
@ -362,7 +361,7 @@ var Events = instance.web.Class.extend({
});
}
rest = Array.prototype.slice.call(arguments, 1);
while (node = events.pop()) {
while ((node = events.pop())) {
tail = node.tail;
args = node.event ? [ node.event ].concat(rest) : rest;
while ((node = node.next) !== tail) {
@ -504,7 +503,7 @@ instance.web.Controller = instance.web.Class.extend(instance.web.PropertiesMixin
return function () {
var fn = (typeof method === 'string') ? self[method] : method;
return fn.apply(self, arguments);
}
};
},
/**
* Informs the action manager to do an action. This supposes that
@ -692,11 +691,6 @@ instance.web.Widget = instance.web.Controller.extend({
insertion(target);
return this.start();
},
/**
* This is the method to implement to render the Widget.
*/
renderElement: function() {
},
/**
* Method called after rendering. Mostly used to bind actions, perform asynchronous
* calls, etc...
@ -889,7 +883,7 @@ instance.web.Registry = instance.web.Class.extend({
contains: function (key) {
if (key === undefined) { return false; }
if (key in this.map) {
return true
return true;
}
if (this.parent) {
return this.parent.contains(key);
@ -966,7 +960,7 @@ instance.web.JsonRPC = instance.web.Class.extend(instance.web.PropertiesMixin, {
init: function() {
instance.web.PropertiesMixin.init.call(this);
this.server = null;
this.debug = ($.deparam($.param.querystring()).debug != undefined);
this.debug = ($.deparam($.param.querystring()).debug !== undefined);
this.override_session = false;
this.session_id = undefined;
},
@ -1154,6 +1148,6 @@ instance.web.py_eval = function(expr, context) {
return py.eval(expr, _.extend({}, context || {}, {"true": true, "false": false, "null": null}));
};
}
};
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:

View File

@ -88,7 +88,7 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess
this.session_id = this.get_cookie('session_id');
}
return def.then(function() {
return self.rpc("/web/session/get_session_info", {})
return self.rpc("/web/session/get_session_info", {});
}).then(function(result) {
// If immediately follows a login (triggered by trying to restore
// an invalid session or no session at all), refresh session data
@ -250,7 +250,7 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess
continue;
instance[mod] = {};
// init module mod
if(instance._openerp[mod] != undefined) {
if(instance._openerp[mod] !== undefined) {
instance._openerp[mod](instance,instance[mod]);
this.module_loaded[mod] = true;
}
@ -343,7 +343,7 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess
$input = $('<input type="hidden" name="' + key + '">')
.appendTo($form_data);
}
$input.val(value)
$input.val(value);
});
$form
@ -404,7 +404,7 @@ instance.web.Bus = instance.web.Class.extend(instance.web.EventDispatcherMixin,
});
});
}
})
});
instance.web.bus = new instance.web.Bus();
/** OpenERP Translations */
@ -466,12 +466,12 @@ $.fn.getAttributes = function() {
var o = {};
if (this.length) {
for (var attr, i = 0, attrs = this[0].attributes, l = attrs.length; i < l; i++) {
attr = attrs.item(i)
attr = attrs.item(i);
o[attr.nodeName] = attr.nodeValue;
}
}
return o;
}
};
$.fn.openerpClass = function(additionalClass) {
// This plugin should be applied on top level elements
additionalClass = additionalClass || '';
@ -557,7 +557,7 @@ instance.web._t = new instance.web.TranslationDataBase().build_translation_funct
* @returns {Object} lazy translation object
*/
instance.web._lt = function (s) {
return {toString: function () { return instance.web._t(s); }}
return {toString: function () { return instance.web._t(s); }};
};
instance.web.qweb = new QWeb2.Engine();
instance.web.qweb.debug = instance.session.debug;
@ -585,7 +585,7 @@ instance.web.qweb.preprocess_node = function() {
case Node.ELEMENT_NODE:
// Element
var attr, attrs = ['label', 'title', 'alt', 'placeholder'];
while (attr = attrs.pop()) {
while ((attr = attrs.pop())) {
if (this.attributes[attr]) {
this.attributes[attr] = instance.web._t(this.attributes[attr]);
}
@ -692,13 +692,13 @@ instance.web.blockUI = function() {
instance.web.Throbber.throbbers.push(throbber);
throbber.appendTo($(".oe_blockui_spin_container"));
return tmp;
}
};
instance.web.unblockUI = function() {
_.each(instance.web.Throbber.throbbers, function(el) {
el.destroy();
});
return $.unblockUI.apply($, arguments);
}
};
/**
* Registry for all the client actions key: tag value: widget

View File

@ -100,7 +100,7 @@ instance.web.Query = instance.web.Class.extend({
* @returns {jQuery.Deferred<Number>}
*/
count: function () {
if (this._count != undefined) { return $.when(this._count); }
if (this._count !== undefined) { return $.when(this._count); }
return this._model.call(
'search_count', [this._filter], {
context: this._model.context(this._context)});
@ -494,7 +494,7 @@ instance.web.DataSet = instance.web.Class.extend(instance.web.PropertiesMixin,
return this._model.call('create', [data], {
context: this.get_context()
}).done(function () {
self.trigger('dataset_changed', data, options)
self.trigger('dataset_changed', data, options);
});
},
/**
@ -514,7 +514,7 @@ instance.web.DataSet = instance.web.Class.extend(instance.web.PropertiesMixin,
return this._model.call('write', [[id], data], {
context: this.get_context(options.context)
}).done(function () {
self.trigger('dataset_changed', id, data, options)
self.trigger('dataset_changed', id, data, options);
});
},
/**
@ -527,7 +527,7 @@ instance.web.DataSet = instance.web.Class.extend(instance.web.PropertiesMixin,
return this._model.call('unlink', [ids], {
context: this.get_context()
}).done(function () {
self.trigger('dataset_changed', ids)
self.trigger('dataset_changed', ids);
});
},
/**
@ -747,7 +747,7 @@ instance.web.DataSetSearch = instance.web.DataSet.extend({
});
},
size: function () {
if (this._length != null) {
if (this._length !== null) {
return this._length;
}
return this._super();
@ -810,7 +810,7 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({
var self = this;
_.each(ids, function(id) {
if (! _.detect(self.to_create, function(x) { return x.id === id; })) {
self.to_delete.push({id: id})
self.to_delete.push({id: id});
}
});
this.to_create = _.reject(this.to_create, function(x) { return _.include(ids, x.id);});
@ -838,7 +838,7 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({
_.each(fields, function(x) {if (cached.values[x] === undefined)
cached.values[x] = created.defaults[x] || false;});
} else {
if (!cached || !_.all(fields, function(x) {return cached.values[x] !== undefined}))
if (!cached || !_.all(fields, function(x) {return cached.values[x] !== undefined;}))
to_get.push(id);
}
});

View File

@ -71,7 +71,7 @@ instance.web.DataExport = instance.web.Dialog.extend({
opt.replaceChild(
document.createTextNode(
_.str.sprintf("%s — %s", format.label, format.error)),
opt.childNodes[0])
opt.childNodes[0]);
}
$fmts.append(opt);
});
@ -93,7 +93,7 @@ instance.web.DataExport = instance.web.Dialog.extend({
self.$el.find('#fields_list option').remove();
var export_id = self.$el.find('#saved_export_list option:selected').val();
if (export_id) {
self.rpc('/web/export/namelist', {'model': self.dataset.model, export_id: parseInt(export_id)}).done(self.do_load_export_field);
self.rpc('/web/export/namelist', {'model': self.dataset.model, export_id: parseInt(export_id, 10)}).done(self.do_load_export_field);
}
});
self.$el.find('#delete_export_list').click(function() {
@ -215,7 +215,7 @@ instance.web.DataExport = instance.web.Dialog.extend({
self.$el.find("tr[id='treerow-" + record.id + "']").click(function(e) {
if (e.shiftKey) {
var frst_click, scnd_click = '';
if (self.row_index == 0) {
if (self.row_index === 0) {
self.row_index = this.rowIndex;
frst_click = self.$el.find("tr[id^='treerow-']")[self.row_index-1];
$(frst_click).addClass("ui-selected");
@ -378,21 +378,28 @@ instance.web.DataExport = instance.web.Dialog.extend({
exported_fields.unshift({name: 'id', label: 'External ID'});
var export_format = this.$el.find("#export_format").val();
var ids_to_export = this.$('#export_selection_only').prop('checked')
? this.getParent().get_selected_ids()
: this.dataset.ids;
instance.web.blockUI();
this.session.get_file({
url: '/web/export/' + export_format,
data: {data: JSON.stringify({
model: this.dataset.model,
fields: exported_fields,
ids: ids_to_export,
domain: this.dataset.domain,
import_compat: !!this.$el.find("#import_compat").val(),
})},
complete: instance.web.unblockUI,
this.getParent().get_active_domain().then(function (domain) {
if (domain === undefined) {
var ids_to_export = self.getParent().get_selected_ids();
var domain = self.dataset.domain;
}
else {
var ids_to_export = false;
var domain = domain;
}
instance.web.blockUI();
self.session.get_file({
url: '/web/export/' + export_format,
data: {data: JSON.stringify({
model: self.dataset.model,
fields: exported_fields,
ids: ids_to_export,
domain: domain,
import_compat: !!self.$el.find("#import_compat").val(),
})},
complete: instance.web.unblockUI,
});
});
},
close: function() {

View File

@ -141,6 +141,7 @@ instance.web.format_value = function (value, descriptor, value_if_empty) {
return '';
}
console.warn('Field', descriptor, 'had an empty string as value, treating as false...');
return value_if_empty === undefined ? '' : value_if_empty;
case false:
case Infinity:
case -Infinity:
@ -199,7 +200,7 @@ instance.web.format_value = function (value, descriptor, value_if_empty) {
case 'selection': case 'statusbar':
// Each choice is [value, label]
if(_.isArray(value)) {
value = value[0]
value = value[0];
}
var result = _(descriptor.selection).detect(function (choice) {
return choice[0] === value;
@ -219,9 +220,9 @@ instance.web.parse_value = function (value, descriptor, value_if_empty) {
case "":
return value_if_empty === undefined ? false : value_if_empty;
}
var tmp;
switch (descriptor.widget || descriptor.type || (descriptor.field && descriptor.field.type)) {
case 'integer':
var tmp;
do {
tmp = value;
value = value.replace(instance.web._t.database.parameters.thousands_sep, "");
@ -231,7 +232,7 @@ instance.web.parse_value = function (value, descriptor, value_if_empty) {
throw new Error(_.str.sprintf(_t("'%s' is not a correct integer"), value));
return tmp;
case 'float':
var tmp = Number(value);
tmp = Number(value);
if (!isNaN(tmp))
return tmp;
@ -314,4 +315,34 @@ instance.web.auto_date_to_str = function(value, type) {
}
};
/**
* performs a half up rounding with arbitrary precision, correcting for float loss of precision
* See the corresponding float_round() in server/tools/float_utils.py for more info
* @param {Number} the value to be rounded
* @param {Number} a non zero precision parameter. eg: 0.01 rounds to two digits.
*/
instance.web.round_precision = function(value, precision){
if(!value){
return 0;
}else if(!precision){
throw new Error('round_precision(...): Cannot round value: '+value+' with a precision of zero (or undefined)');
}
var normalized_value = value / precision;
var epsilon_magnitude = Math.log(Math.abs(normalized_value))/Math.log(2);
var epsilon = Math.pow(2, epsilon_magnitude - 53);
normalized_value += normalized_value >= 0 ? epsilon : -epsilon;
var rounded_value = Math.round(normalized_value);
return rounded_value * precision;
};
/**
* performs a half up rounding with a fixed amount of decimals, correcting for float loss of precision
* See the corresponding float_round() in server/tools/float_utils.py for more info
* @param {Number} the value to be rounded
* @param {Number} the number of decimals. eg: round_decimals(3.141592,2) -> 3.14
*/
instance.web.round_decimals = function(value, decimals){
return instance.web.round_precision(value, Math.pow(10,-decimals));
};
};

View File

@ -97,7 +97,7 @@ openerp.web.pyeval = function (instance) {
divmod(n, 365, function (_n1, n) {
n1 = _n1;
n0 = n;
})
});
});
});
});
@ -139,7 +139,7 @@ openerp.web.pyeval = function (instance) {
if (microsecond < 0 || microsecond > 999999) {
divmod(microsecond, 1000000, function (carry, ms) {
microsecond = ms;
second += carry
second += carry;
});
}
if (second < 0 || second > 59) {
@ -152,13 +152,13 @@ openerp.web.pyeval = function (instance) {
divmod(minute, 60, function (carry, m) {
minute = m;
hour += carry;
})
});
}
if (hour < 0 || hour > 23) {
divmod(hour, 24, function (carry, h) {
hour = h;
day += carry;
})
});
}
// That was easy. Now it gets muddy: the proper range for day
// can't be determined without knowing the correct month and year,
@ -170,7 +170,7 @@ openerp.web.pyeval = function (instance) {
divmod(month-1, 12, function (carry, m) {
month = m + 1;
year += carry;
})
});
}
// Now only day can be out of bounds (year may also be out of bounds
// for a datetime object, but we don't care about that here).
@ -247,7 +247,7 @@ openerp.web.pyeval = function (instance) {
});
divmod(seconds, 24*3600, function (days, seconds) {
d += days;
s += seconds
s += seconds;
});
// seconds isn't referenced again before redefinition
@ -358,7 +358,7 @@ openerp.web.pyeval = function (instance) {
return py.float.fromJSON(
this.days * 86400
+ this.seconds
+ this.microseconds / 1000000)
+ this.microseconds / 1000000);
},
__nonzero__: function () {
return (!!this.days || !!this.seconds || !!this.microseconds)
@ -466,7 +466,7 @@ openerp.web.pyeval = function (instance) {
return py.float.fromJSON(ymd2ord(this.year, this.month, this.day));
},
fromJSON: function (year, month, day) {
return py.PY_call(datetime.date, [year, month, day])
return py.PY_call(datetime.date, [year, month, day]);
}
});
/**
@ -505,7 +505,7 @@ openerp.web.pyeval = function (instance) {
var args = _.map(('year month day hour minute second microsecond '
+ 'years months weeks days hours minutes secondes microseconds '
+ 'weekday leakdays yearday nlyearday').split(' '), function (arg) {
return [arg, null]
return [arg, null];
});
args.unshift('*');
var relativedelta = py.type('relativedelta', null, {
@ -795,13 +795,20 @@ openerp.web.pyeval = function (instance) {
//noinspection FallthroughInSwitchStatementJS
switch(type) {
case 'context': object = [object];
case 'contexts': return eval_contexts((options.no_user_context ? [] : [instance.session.user_context]).concat(object), context);
case 'domain': object = [object];
case 'domains': return eval_domains(object, context);
case 'groupbys': return eval_groupbys(object, context);
case 'context':
case 'contexts':
if (type === 'context')
object = [object];
return eval_contexts((options.no_user_context ? [] : [instance.session.user_context]).concat(object), context);
case 'domain':
case 'domains':
if (type === 'domain')
object = [object];
return eval_domains(object, context);
case 'groupbys':
return eval_groupbys(object, context);
}
throw new Error("Unknow evaluation type " + type)
throw new Error("Unknow evaluation type " + type);
};
var eval_arg = function (arg) {
@ -856,5 +863,5 @@ openerp.web.pyeval = function (instance) {
}});
}
}, 0); });
}
};
};

View File

@ -65,7 +65,7 @@ my.SearchQuery = B.Collection.extend({
}, this);
},
add: function (values, options) {
options || (options = {});
options = options || {};
if (!(values instanceof Array)) {
values = [values];
}
@ -85,7 +85,7 @@ my.SearchQuery = B.Collection.extend({
return this;
},
toggle: function (value, options) {
options || (options = {});
options = options || {};
var facet = this.detect(function (facet) {
return facet.get('category') === value.category
@ -148,7 +148,7 @@ my.InputView = instance.web.Widget.extend({
range.setStart(root, 0);
}
if (range.endContainer === this.el && range.endOffset === 1) {
range.setEnd(root, root.length)
range.setEnd(root, root.length);
}
assert(range.startContainer === root,
"selection should be in the input view");
@ -157,7 +157,7 @@ my.InputView = instance.web.Widget.extend({
return {
start: range.startOffset,
end: range.endOffset
}
};
},
onKeydown: function (e) {
this.el.normalize();
@ -401,7 +401,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
});
$.when(load_view).then(function (r) {
return self.search_view_loaded(r)
return self.search_view_loaded(r);
}).fail(function () {
self.ready.reject.apply(null, arguments);
});
@ -950,7 +950,7 @@ instance.web.search.Input = instance.web.search.Widget.extend( /** @lends instan
* @returns {jQuery.Deferred<null|Array>}
*/
complete: function (value) {
return $.when(null)
return $.when(null);
},
/**
* Returns a Facet instance for the provided defaults if they apply to
@ -1073,7 +1073,7 @@ instance.web.search.FilterGroup = instance.web.search.Input.extend(/** @lends in
icon: this.icon,
values: values,
field: this
}
};
},
make_value: function (filter) {
return {
@ -1107,7 +1107,7 @@ instance.web.search.FilterGroup = instance.web.search.Input.extend(/** @lends in
if (!contexts.length) { return; }
if (contexts.length === 1) { return contexts[0]; }
return _.extend(new instance.web.CompoundContext, {
return _.extend(new instance.web.CompoundContext(), {
__contexts: contexts
});
},
@ -1176,7 +1176,7 @@ instance.web.search.FilterGroup = instance.web.search.Input.extend(/** @lends in
label: _.str.sprintf(self.completion_label.toString(),
_.escape(facet_value.label)),
facet: self.make_facet([facet_value])
}
};
}));
}
});
@ -1198,7 +1198,7 @@ instance.web.search.GroupbyGroup = instance.web.search.FilterGroup.extend({
get_context: this.proxy('get_context'),
get_domain: this.proxy('get_domain'),
get_groupby: this.proxy('get_groupby')
}
};
}
},
match_facet: function (facet) {
@ -1276,7 +1276,7 @@ instance.web.search.Field = instance.web.search.Input.extend( /** @lends instanc
if (contexts.length === 1) { return contexts[0]; }
return _.extend(new instance.web.CompoundContext, {
return _.extend(new instance.web.CompoundContext(), {
__contexts: contexts
});
},
@ -1321,7 +1321,7 @@ instance.web.search.Field = instance.web.search.Input.extend( /** @lends instanc
domains.unshift(['|']);
}
return _.extend(new instance.web.CompoundDomain, {
return _.extend(new instance.web.CompoundDomain(), {
__domains: domains
});
}
@ -1564,7 +1564,7 @@ instance.web.search.ManyToOneField = instance.web.search.CharField.extend({
return this.model.call('name_get', [value]).then(function (names) {
if (_(names).isEmpty()) { return null; }
return facet_from(self, names[0]);
})
});
},
value_from: function (facetValue) {
return facetValue.get('label');
@ -1919,7 +1919,7 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
},
changed: function() {
var nval = this.$(".searchview_extended_prop_field").val();
if(this.attrs.selected == null || nval != this.attrs.selected.name) {
if(this.attrs.selected === null || this.attrs.selected === undefined || nval != this.attrs.selected.name) {
this.select_field(_.detect(this.fields, function(x) {return x.name == nval;}));
}
},
@ -1941,13 +1941,13 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
*/
select_field: function(field) {
var self = this;
if(this.attrs.selected != null) {
if(this.attrs.selected !== null && this.attrs.selected !== undefined) {
this.value.destroy();
this.value = null;
this.$('.searchview_extended_prop_op').html('');
}
this.attrs.selected = field;
if(field == null) {
if(field === null || field === undefined) {
return;
}
@ -1967,7 +1967,7 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
},
get_proposition: function() {
if ( this.attrs.selected == null)
if (this.attrs.selected === null || this.attrs.selected === undefined)
return null;
var field = this.attrs.selected;
var op_select = this.$('.searchview_extended_prop_op')[0];
@ -2097,7 +2097,7 @@ instance.web.search.ExtendedSearchProposition.Integer = instance.web.search.Exte
get_value: function() {
try {
var val =this.$el.val();
return instance.web.parse_value(val == "" ? 0 : val, {'widget': 'integer'});
return instance.web.parse_value(val === "" ? 0 : val, {'widget': 'integer'});
} catch (e) {
return "";
}
@ -2124,7 +2124,7 @@ instance.web.search.ExtendedSearchProposition.Float = instance.web.search.Extend
get_value: function() {
try {
var val =this.$el.val();
return instance.web.parse_value(val == "" ? 0.0 : val, {'widget': 'float'});
return instance.web.parse_value(val === "" ? 0.0 : val, {'widget': 'float'});
} catch (e) {
return "";
}

View File

@ -73,6 +73,6 @@ openerp.test_support = {
return;
}
fn(e.data.name);
})
});
}
};

View File

@ -176,9 +176,9 @@ openerp.testing = {};
});
QUnit.module(testing.current_module + '.' + name, {_oe: options});
body(testing.case);
body(testing['case']);
};
testing.case = function (name, options, callback) {
testing['case'] = function (name, options, callback) {
if (_.isFunction(options)) {
callback = options;
options = {};
@ -359,7 +359,7 @@ openerp.testing = {};
return $.Deferred(function (d) {
$.when(result).then(function () {
d.resolve.apply(d, arguments)
d.resolve.apply(d, arguments);
}, function () {
d.reject.apply(d, arguments);
});

View File

@ -346,7 +346,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
self.on_form_changed();
self.rendering_engine.init_fields();
self.is_initialized.resolve();
self.do_update_pager(record.id == null);
self.do_update_pager(record.id === null || record.id === undefined);
if (self.sidebar) {
self.sidebar.do_attachement_update(self.dataset, self.datarecord.id);
}
@ -437,7 +437,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
var method = call[1];
if (!_.str.trim(call[2])) {
return {method: method, args: []}
return {method: method, args: []};
}
var argument_replacement = {
@ -465,7 +465,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
// form field
if (self.fields[field]) {
var value_ = self.fields[field].get_value();
return value_ == null ? false : value_;
return value_ === null || value_ === undefined ? false : value_;
}
// parent field
var splitted = field.split('.');
@ -475,7 +475,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
}
var p_val = parent_fields[_.str.trim(splitted[1])];
if (p_val !== undefined) {
return p_val == null ? false : p_val;
return p_val === null || p_val === undefined ? false : p_val;
}
}
// string literal
@ -621,7 +621,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
}
return $.when();
});
};
}
return iterate();
});
},
@ -778,7 +778,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
} else {
$.async_when().done(function () {
def.reject();
})
});
}
});
return def.promise();
@ -943,11 +943,11 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
reload: function() {
var self = this;
return this.reload_mutex.exec(function() {
if (self.dataset.index == null) {
if (self.dataset.index === null || self.dataset.index === undefined) {
self.trigger("previous_view");
return $.Deferred().reject().promise();
}
if (self.dataset.index == null || self.dataset.index < 0) {
if (self.dataset.index < 0) {
return $.when(self.on_button_new());
} else {
var fields = _.keys(self.fields_view.fields);
@ -1028,7 +1028,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
return field.get_displayed();
}
return value;
}
};
var fields = _.chain(this.fields)
.map(function (field) {
var value = field.get_value();
@ -1049,7 +1049,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
string: field.string,
value: value,
displayed: display(field, value),
}
};
})
.compact()
.sortBy(function (field) { return field.string; })
@ -1063,7 +1063,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
string: field.string,
value: value,
displayed: display(field, value),
}
};
})
.value();
@ -1429,7 +1429,7 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt
row_cols = cols;
} else if (tagName==='group') {
// When <group> <group/><group/> </group>, we need a spacing between the two groups
$td.addClass('oe_group_right')
$td.addClass('oe_group_right');
}
row_cols -= colspan;
@ -1714,7 +1714,7 @@ instance.web.form.compute_domain = function(expr, fields) {
};
instance.web.form.is_bin_size = function(v) {
return /^\d+(\.\d*)? \w+$/.test(v);
return (/^\d+(\.\d*)? \w+$/).test(v);
};
/**
@ -1852,7 +1852,8 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi
return QWeb.render(template, {
debug: instance.session.debug,
widget: widget
})},
});
},
gravity: $.fn.tipsy.autoBounds(50, 'nw'),
html: true,
opacity: 0.85,
@ -2073,7 +2074,7 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w
* @param node
*/
init: function(field_manager, node) {
var self = this
var self = this;
this._super(field_manager, node);
this.name = this.node.attrs.name;
this.field = this.field_manager.get_field_desc(this.name);
@ -2642,7 +2643,7 @@ instance.web.form.FieldText = instance.web.form.AbstractField.extend(instance.we
if (! this.get("effective_readonly")) {
var show_value = instance.web.format_value(this.get('value'), this, '');
if (show_value === '') {
this.$textarea.css('height', parseInt(this.default_height)+"px");
this.$textarea.css('height', parseInt(this.default_height, 10)+"px");
}
this.$textarea.val(show_value);
if (! this.auto_sized) {
@ -2937,7 +2938,7 @@ instance.web.form.FieldRadio = instance.web.form.AbstractField.extend(instance.w
set_value: function (value_) {
if (value_) {
if (this.field.type == "selection") {
value_ = _.find(this.field.selection, function (sel) { return sel[0] == value_});
value_ = _.find(this.field.selection, function (sel) { return sel[0] == value_;});
}
else if (!this.selection.length) {
this.selection = [value_];
@ -2954,7 +2955,7 @@ instance.web.form.FieldRadio = instance.web.form.AbstractField.extend(instance.w
this.$el.toggleClass("oe_readonly", this.get('effective_readonly'));
this.$("input:checked").prop("checked", false);
if (this.get_value()) {
this.$("input").filter(function () {return this.value == self.get_value()}).prop("checked", true);
this.$("input").filter(function () {return this.value == self.get_value();}).prop("checked", true);
this.$(".oe_radio_readonly").text(this.get('value') ? this.get('value')[1] : "");
}
}
@ -3090,7 +3091,7 @@ instance.web.form.CompletionFieldMixin = {
self.field.relation,
{
title: (view === 'search' ? _t("Search: ") : _t("Create: ")) + this.string,
initial_ids: ids ? _.map(ids, function(x) {return x[0]}) : undefined,
initial_ids: ids ? _.map(ids, function(x) {return x[0];}) : undefined,
initial_view: view,
disable_multiple_selection: true
},
@ -3265,7 +3266,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
this.$input.keydown(input_changed);
this.$input.change(input_changed);
this.$drop_down.click(function() {
self.$input.focus();
self.$input.focus();
if (self.$input.autocomplete("widget").is(":visible")) {
self.$input.autocomplete("close");
} else {
@ -3455,7 +3456,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
var self = this;
if (value_ instanceof Array) {
this.display_value = {};
this.display_value_backup = {}
this.display_value_backup = {};
if (! this.options.always_reload) {
this.display_value["" + value_[0]] = value_[1];
}
@ -3720,7 +3721,7 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
});
controller.on('pager_action_executed',self,self.save_any_view);
} else if (view_type == "graph") {
self.reload_current_view()
self.reload_current_view();
}
def.resolve();
});
@ -3740,7 +3741,7 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
},
reload_current_view: function() {
var self = this;
return self.is_loaded = self.is_loaded.then(function() {
self.is_loaded = self.is_loaded.then(function() {
var active_view = self.viewmanager.active_view;
var view = self.viewmanager.views[active_view].controller;
if(active_view === "list") {
@ -3758,13 +3759,15 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
return view.do_search(self.build_domain(), self.dataset.get_context(), []);
}
}, undefined);
return self.is_loaded;
},
set_value: function(value_) {
value_ = value_ || [];
var self = this;
this.dataset.reset_ids([]);
var ids;
if(value_.length >= 1 && value_[0] instanceof Array) {
var ids = [];
ids = [];
_.each(value_, function(command) {
var obj = {values: command[2]};
switch (command[0]) {
@ -3795,7 +3798,7 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
this._super(ids);
this.dataset.set_ids(ids);
} else if (value_.length >= 1 && typeof(value_[0]) === "object") {
var ids = [];
ids = [];
this.dataset.delete_all = true;
_.each(value_, function(command) {
var obj = {values: command};
@ -3850,7 +3853,7 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
this.viewmanager.views[this.viewmanager.active_view].controller) {
var view = this.viewmanager.views[this.viewmanager.active_view].controller;
if (this.viewmanager.active_view === "form") {
if (!view.is_initialized.state() === 'resolved') {
if (view.is_initialized.state() !== 'resolved') {
return $.when(false);
}
return $.when(view.save());
@ -3870,7 +3873,6 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
.invoke('is_valid')
.all(_.identity)
.value();
break;
case 'list':
return view.is_valid();
}
@ -3962,7 +3964,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({
var form = editor.form;
// If no edition is pending, the listview can not be invalid (?)
if (!editor.record) {
return true
return true;
}
// If the form has not been modified, the view can only be valid
// NB: is_dirty will also be set on defaults/onchanges/whatever?
@ -4167,7 +4169,7 @@ instance.web.form.One2ManyList = instance.web.ListView.List.extend({
if ($padding.length) {
$padding.before($newrow);
} else {
this.$current.append($newrow)
this.$current.append($newrow);
}
}
});
@ -4256,7 +4258,7 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
},
core: {
onSetInputData: function(e, data) {
if (data == '') {
if (data === '') {
this._plugins.autocomplete._suggestions = null;
}
this.input().val(data);
@ -4578,8 +4580,9 @@ instance.web.form.FieldMany2ManyKanban = instance.web.form.AbstractField.extend(
if (type !== "form")
return;
var self = this;
var pop;
if (this.dataset.index === null) {
var pop = new instance.web.form.SelectCreatePopup(this);
pop = new instance.web.form.SelectCreatePopup(this);
pop.select_element(
this.field.relation,
{
@ -4599,7 +4602,7 @@ instance.web.form.FieldMany2ManyKanban = instance.web.form.AbstractField.extend(
});
} else {
var id = self.dataset.ids[self.dataset.index];
var pop = new instance.web.form.FormOpenPopup(this);
pop = new instance.web.form.FormOpenPopup(this);
pop.show_element(self.field.relation, id, self.build_context(), {
title: _t("Open: ") + self.string,
write_function: function(id, data, options) {
@ -4935,7 +4938,7 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
self.select_elements(self.selected_ids);
self.destroy();
});
var $cbutton = self.$buttonpane.find(".oe_selectcreatepopup-search-create");
$cbutton = self.$buttonpane.find(".oe_selectcreatepopup-search-create");
$cbutton.click(function() {
self.new_object();
});
@ -5020,8 +5023,8 @@ instance.web.form.FieldReference = instance.web.form.AbstractField.extend(instan
this.selection.on("change:value", this, this.on_selection_changed);
this.selection.appendTo(this.$(".oe_form_view_reference_selection"));
this.selection
.on('focused', null, function () {self.trigger('focused')})
.on('blurred', null, function () {self.trigger('blurred')});
.on('focused', null, function () {self.trigger('focused');})
.on('blurred', null, function () {self.trigger('blurred');});
this.m2o = new instance.web.form.FieldMany2One(fm, { attrs: {
name: 'm2o',
@ -5030,8 +5033,8 @@ instance.web.form.FieldReference = instance.web.form.AbstractField.extend(instan
this.m2o.on("change:value", this, this.data_changed);
this.m2o.appendTo(this.$(".oe_form_view_reference_m2o"));
this.m2o
.on('focused', null, function () {self.trigger('focused')})
.on('blurred', null, function () {self.trigger('blurred')});
.on('focused', null, function () {self.trigger('focused');})
.on('blurred', null, function () {self.trigger('blurred');});
},
on_selection_changed: function() {
if (this.reference_ready) {
@ -5190,18 +5193,18 @@ instance.web.form.FieldBinaryFile = instance.web.form.FieldBinary.extend({
}
},
render_value: function() {
var show_value;
if (!this.get("effective_readonly")) {
var show_value;
if (this.node.attrs.filename) {
show_value = this.view.datarecord[this.node.attrs.filename] || '';
} else {
show_value = (this.get('value') != null && this.get('value') !== false) ? this.get('value') : '';
show_value = (this.get('value') !== null && this.get('value') !== undefined && this.get('value') !== false) ? this.get('value') : '';
}
this.$el.find('input').eq(0).val(show_value);
} else {
this.$el.find('a').toggle(!!this.get('value'));
if (this.get('value')) {
var show_value = _t("Download")
show_value = _t("Download");
if (this.view)
show_value += " " + (this.view.datarecord[this.node.attrs.filename] || '');
this.$el.find('a').text(show_value);
@ -5420,7 +5423,7 @@ instance.web.form.FieldMany2ManyBinaryMultiFiles = instance.web.form.AbstractFie
values.push(result.id);
this.set({'value': values});
}
this.render_value()
this.render_value();
},
on_file_delete: function (event) {
event.stopPropagation();
@ -5474,7 +5477,7 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
var self = this;
var content = QWeb.render("FieldStatus.content", {
'widget': self,
'value_folded': _.find(self.selection.folded, function(i){return i[0] === self.get('value')})
'value_folded': _.find(self.selection.folded, function(i){return i[0] === self.get('value');})
});
self.$el.html(content);
},
@ -5506,7 +5509,7 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
return new instance.web.DataSetSearch(self, self.field.relation, self.build_context(), self.get("evaluated_selection_domain"))
.read_slice(fields.fold ? ['fold'] : ['id'], {}).then(function (records) {
var ids = _.map(records, function (val) {return val.id});
var ids = _.map(records, function (val) {return val.id;});
return self.dataset.name_get(ids).then(function (records_name) {
_.each(records, function (record) {
var name = _.find(records_name, function (val) {return val[0] == record.id;})[1];
@ -5516,7 +5519,7 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
selection_unfolded.push([record.id, name]);
}
});
})
});
});
});
} else {
@ -5548,16 +5551,17 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
return new instance.web.Model(self.field.relation).call("fields_get", [["fold"]]).then(function(fields) {
self.distant_fields = fields;
return fields;
})
});
},
on_click_stage: function (ev) {
var self = this;
var $li = $(ev.currentTarget);
var val;
if (this.field.type == "many2one") {
var val = parseInt($li.data("id"));
val = parseInt($li.data("id"), 10);
}
else {
var val = $li.data("id");
val = $li.data("id");
}
if (val != self.get('value')) {
this.view.recursive_save().done(function() {

View File

@ -132,8 +132,8 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
this.groups = groups;
$(this.groups).bind({
'selected': function (e, ids, records) {
self.do_select(ids, records);
'selected': function (e, ids, records, deselected) {
self.do_select(ids, records, deselected);
},
'deleted': function (e, ids) {
self.do_delete(ids);
@ -171,11 +171,13 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
current_date: new Date().toString('yyyy-MM-dd')
// TODO: time, datetime, relativedelta
});
var i;
var pair;
var expression;
if (this.fonts) {
for(var i=0, len=this.fonts.length; i<len; ++i) {
var pair = this.fonts[i],
font = pair[0],
for(i=0, len=this.fonts.length; i<len; ++i) {
pair = this.fonts[i];
var font = pair[0];
expression = pair[1];
if (py.evaluate(expression, context).toJSON()) {
switch(font) {
@ -194,10 +196,10 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
}
if (!this.colors) { return style; }
for(var i=0, len=this.colors.length; i<len; ++i) {
var pair = this.colors[i],
color = pair[0],
expression = pair[1];
for(i=0, len=this.colors.length; i<len; ++i) {
pair = this.colors[i];
var color = pair[0];
expression = pair[1];
if (py.evaluate(expression, context).toJSON()) {
return style += 'color: ' + color + ';';
}
@ -361,7 +363,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
sort_by_column: function (e) {
e.stopPropagation();
var $column = $(e.currentTarget);
var col_name = $column.data('id')
var col_name = $column.data('id');
var field = this.fields_view.fields[col_name];
// test if the field is a function field with store=false, since it's impossible
// for the server to sort those fields we desactivate the feature
@ -394,7 +396,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
var total = dataset.size();
var limit = this.limit() || total;
if (total == 0)
if (total === 0)
this.$pager.hide();
else
this.$pager.css("display", "");
@ -454,7 +456,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
* @param {String} [view="page"] the view type to switch to
*/
select_record:function (index, view) {
view = view || index == null ? 'form' : 'form';
view = view || index === null || index === undefined ? 'form' : 'form';
this.dataset.index = index;
_.delay(_.bind(function () {
this.do_switch_view(view);
@ -503,7 +505,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
var reloaded = $.Deferred();
this.$el.find('.oe_list_content').append(
this.groups.render(function () {
if (self.dataset.index == null && self.records.length ||
if ((self.dataset.index === null || self.dataset.index === undefined) && self.records.length ||
self.dataset.index >= self.records.length) {
self.dataset.index = 0;
}
@ -603,7 +605,12 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
* @param {Array} ids selected record ids
* @param {Array} records selected record values
*/
do_select: function (ids, records) {
do_select: function (ids, records, deselected) {
// uncheck header hook if at least one row has been deselected
if (deselected) {
this.$('.oe_list_record_selector').prop('checked', false);
}
if (!ids.length) {
this.dataset.index = 0;
if (this.sidebar) {
@ -790,6 +797,26 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
var ids = this.groups.get_selection().ids;
return ids;
},
/**
* Calculate the active domain of the list view. This should be done only
* if the header checkbox has been checked.
*/
get_active_domain: function () {
if (this.$('.oe_list_record_selector').prop('checked')) {
var search_view = this.getParent().searchview;
var search_data = search_view.build_search_data();
return instance.web.pyeval.eval_domains_and_contexts({
domains: search_data.domains,
contexts: search_data.contexts,
group_by_seq: search_data.groupbys || []
}).then(function (results) {
return results.domain;
});
}
else {
return $.Deferred().resolve();
}
},
/**
* Adds padding columns at the start or end of all table rows (including
* field names row)
@ -951,8 +978,9 @@ instance.web.ListView.List = instance.web.Class.extend( /** @lends instance.web.
.delegate('th.oe_list_record_selector', 'click', function (e) {
e.stopPropagation();
var selection = self.get_selection();
var checked = $(e.currentTarget).find('input').prop('checked');
$(self).trigger(
'selected', [selection.ids, selection.records]);
'selected', [selection.ids, selection.records, ! checked]);
})
.delegate('td.oe_list_record_delete button', 'click', function (e) {
e.stopPropagation();
@ -1398,10 +1426,10 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we
bind_child_events: function (child) {
var $this = $(this),
self = this;
$(child).bind('selected', function (e) {
$(child).bind('selected', function (e, _0, _1, deselected) {
// can have selections spanning multiple links
var selection = self.get_selection();
$this.trigger(e, [selection.ids, selection.records]);
$this.trigger(e, [selection.ids, selection.records, deselected]);
}).bind(this.passthrough_events, function (e) {
// additional positional parameters are provided to trigger as an
// Array, following the event type or event object, but are
@ -1428,7 +1456,7 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we
d = new $.Deferred(),
page = this.datagroup.openable ? this.page : view.page;
var fields = _.pluck(_.select(this.columns, function(x) {return x.tag == "field"}), 'name');
var fields = _.pluck(_.select(this.columns, function(x) {return x.tag == "field";}), 'name');
var options = { offset: page * limit, limit: limit, context: {bin_size: true} };
//TODO xmo: investigate why we need to put the setTimeout
$.async_when().done(function() {
@ -1517,20 +1545,21 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we
// if drag to 1st row (to = 0), start sequencing from 0
// (exclusive lower bound)
seq = to ? list.records.at(to - 1).get(seqname) : 0;
while (++seq, record = list.records.at(index++)) {
var fct = function (dataset, id, seq) {
$.async_when().done(function () {
var attrs = {};
attrs[seqname] = seq;
dataset.write(id, attrs);
});
};
while (++seq, (record = list.records.at(index++))) {
// write are independent from one another, so we can just
// launch them all at the same time and we don't really
// give a fig about when they're done
// FIXME: breaks on o2ms (e.g. Accounting > Financial
// Accounting > Taxes > Taxes, child tax accounts)
// when synchronous (without setTimeout)
(function (dataset, id, seq) {
$.async_when().done(function () {
var attrs = {};
attrs[seqname] = seq;
dataset.write(id, attrs);
});
}(dataset, record.get('id'), seq));
fct(dataset, record.get('id'), seq);
record.set(seqname, seq);
}
}
@ -1543,7 +1572,7 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we
this.datagroup.list(
_(this.view.visible_columns).chain()
.filter(function (column) { return column.tag === 'field' })
.filter(function (column) { return column.tag === 'field';})
.pluck('name').value(),
function (groups) {
$el[0].appendChild(
@ -1588,7 +1617,7 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we
return {
count: this.datagroup.length,
values: this.datagroup.aggregates
}
};
}
return _(this.children).chain()
.map(function (child) {
@ -1825,7 +1854,7 @@ var Collection = instance.web.Class.extend(/** @lends Collection# */{
var instance_ = (records[i] instanceof Record) ? records[i] : new Record(records[i]);
instance_.bind(null, this._onRecordEvent);
this._byId[instance_.get('id')] = instance_;
if (options.at == undefined) {
if (options.at === undefined || options.at === null) {
this.records.push(instance_);
if (!options.silent) {
this.trigger('add', this, instance_, this.records.length-1);
@ -1867,7 +1896,8 @@ var Collection = instance.web.Class.extend(/** @lends Collection# */{
if (!_(this._proxies).isEmpty()) {
var record = null;
_(this._proxies).detect(function (proxy) {
return record = proxy.get(id);
record = proxy.get(id);
return record;
});
return record;
}
@ -1881,10 +1911,11 @@ var Collection = instance.web.Class.extend(/** @lends Collection# */{
* @returns {Collection}
*/
proxy: function (section) {
return this._proxies[section] = new Collection(null, {
this._proxies[section] = new Collection(null, {
parent: this,
key: section
}).bind(null, this._onRecordEvent);
return this._proxies[section];
},
/**
* @param {Array} [records]
@ -1954,7 +1985,7 @@ var Collection = instance.web.Class.extend(/** @lends Collection# */{
var record;
for(var section in this._proxies) {
if (!this._proxies.hasOwnProperty(section)) {
continue
continue;
}
if ((record = this._proxies[section].find(callback))) {
return record;
@ -2071,7 +2102,7 @@ instance.web.list.columns.for_ = function (id, field, node) {
tag + '.'+ description.type,
tag
]);
return new Type(id, node.tag, description)
return new Type(id, node.tag, description);
};
instance.web.list.Column = instance.web.Class.extend({
@ -2234,7 +2265,7 @@ instance.web.list.Char = instance.web.list.Column.extend({
_format: function (row_data, options) {
var value = row_data[this.id].value;
if (value && this.password === 'True') {
return value.replace(/[\s\S]/g, _.escape(this.replacement))
return value.replace(/[\s\S]/g, _.escape(this.replacement));
}
return this._super(row_data, options);
}

View File

@ -202,7 +202,7 @@ openerp.web.list_editable = function (instance) {
make_empty_record: function (id) {
var attrs = {id: id};
_(this.columns).chain()
.filter(function (x) { return x.tag === 'field'})
.filter(function (x) { return x.tag === 'field';})
.pluck('name')
.each(function (field) { attrs[field] = false; });
return new instance.web.list.Record(attrs);
@ -260,7 +260,7 @@ openerp.web.list_editable = function (instance) {
get_cells_for: function ($row) {
var cells = {};
$row.children('td').each(function (index, el) {
cells[el.getAttribute('data-field')] = el
cells[el.getAttribute('data-field')] = el;
});
return cells;
},
@ -346,7 +346,7 @@ openerp.web.list_editable = function (instance) {
var record = self.records.get(attrs.id);
if (!record) {
// Record removed by third party during edition
return
return;
}
return self.reload_record(record);
}
@ -515,10 +515,6 @@ openerp.web.list_editable = function (instance) {
};
} else if (document.body.createTextRange) {
throw new Error("Implement text range handling for MSIE");
var sel = document.body.createTextRange();
if (sel.parentElement() === el) {
}
}
// Element without selection ranges (select, div/@contenteditable)
return null;
@ -695,9 +691,9 @@ openerp.web.list_editable = function (instance) {
var arch = edition_view.arch;
if (!(arch && arch.children instanceof Array)) {
throw new Error("Editor delegate's #edition_view must have a" +
" non-empty arch")
" non-empty arch");
}
if (!(arch.tag === "form")) {
if (arch.tag !== "form") {
throw new Error("Editor delegate's #edition_view must have a" +
" 'form' root node");
}

View File

@ -49,7 +49,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
if (last) {
last.hide();
}
var item = _.extend({
item = _.extend({
show: function(index) {
this.widget.$el.show();
},
@ -423,7 +423,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
if (!(ClientWidget.prototype instanceof instance.web.Widget)) {
var next;
if (next = ClientWidget(this, action)) {
if ((next = ClientWidget(this, action))) {
return this.do_action(next, options);
}
return $.when();
@ -459,7 +459,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
action_id: action.id,
context: action.context || {}
}).done(function (action) {
self.do_action(action, options)
self.do_action(action, options);
});
},
ir_actions_report_xml: function(action, options) {
@ -478,8 +478,8 @@ instance.web.ActionManager = instance.web.Widget.extend({
var params = {
action: JSON.stringify(action),
token: new Date().getTime()
}
var url = self.session.url('/web/report', params)
};
var url = self.session.url('/web/report', params);
instance.web.unblockUI();
$('<a href="'+url+'" target="_blank"></a>')[0].click();
return;
@ -502,7 +502,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
c.rpc_error.apply(c, arguments);
d.reject();
}
})
});
});
});
},
@ -677,7 +677,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
this.$el.find('.oe_view_title_text:first').text(title);
},
add_breadcrumb: function(options) {
var options = options || {};
options = options || {};
var self = this;
var views = [this.active_view || this.views_src[0].view_type];
this.on('switch_mode', self, function(mode) {
@ -958,7 +958,6 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({
view_type : 'list',
view_mode : 'list'
});
break;
case 'edit':
this.do_edit_resource($option.data('model'), $option.data('id'), { name : $option.text() });
break;
@ -1000,7 +999,7 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({
evt.currentTarget.selectedIndex = 0;
},
do_edit_resource: function(model, id, action) {
var action = _.extend({
action = _.extend({
res_model : model,
res_id : id,
type : 'ir.actions.act_window',
@ -1038,7 +1037,7 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({
},
get_action_manager: function() {
var cur = this;
while (cur = cur.getParent()) {
while ((cur = cur.getParent())) {
if (cur instanceof instance.web.ActionManager) {
return cur;
}
@ -1122,7 +1121,7 @@ instance.web.Sidebar = instance.web.Widget.extend({
self.$("[title]").tipsy({
'html': true,
'delayIn': 500,
})
});
},
/**
* For each item added to the section:
@ -1166,7 +1165,7 @@ instance.web.Sidebar = instance.web.Widget.extend({
label: items[i]['name'],
action: items[i],
classname: 'oe_sidebar_' + type
}
};
}
self.add_items(type=='print' ? 'print' : 'other', items);
}
@ -1176,32 +1175,40 @@ instance.web.Sidebar = instance.web.Widget.extend({
var self = this;
self.getParent().sidebar_eval_context().done(function (sidebar_eval_context) {
var ids = self.getParent().get_selected_ids();
if (ids.length == 0) {
var domain = self.getParent().get_active_domain();
if (ids.length === 0) {
instance.web.dialog($("<div />").text(_t("You must choose at least one record.")), { title: _t("Warning"), modal: true });
return false;
}
var active_ids_context = {
active_id: ids[0],
active_ids: ids,
active_model: self.getParent().dataset.model
};
var c = instance.web.pyeval.eval('context',
active_model: self.getParent().dataset.model,
};
$.when(domain).done(function (domain) {
if (domain !== undefined) {
active_ids_context.active_domain = domain;
}
var c = instance.web.pyeval.eval('context',
new instance.web.CompoundContext(
sidebar_eval_context, active_ids_context));
self.rpc("/web/action/load", {
action_id: item.action.id,
context: c
}).done(function(result) {
result.context = new instance.web.CompoundContext(
result.context || {}, active_ids_context)
.set_eval_context(c);
result.flags = result.flags || {};
result.flags.new_window = true;
self.do_action(result, {
on_close: function() {
// reload view
self.getParent().reload();
},
self.rpc("/web/action/load", {
action_id: item.action.id,
context: c
}).done(function(result) {
result.context = new instance.web.CompoundContext(
result.context || {}, active_ids_context)
.set_eval_context(c);
result.flags = result.flags || {};
result.flags.new_window = true;
self.do_action(result, {
on_close: function() {
// reload view
self.getParent().reload();
},
});
});
});
});
@ -1426,7 +1433,7 @@ instance.web.View = instance.web.Widget.extend({
if (self.is_active()) {
fn.apply(self, arguments);
}
}
};
},
do_push_state: function(state) {
if (this.getParent() && this.getParent().do_push_state) {
@ -1537,9 +1544,10 @@ instance.web.xml_to_json = function(node, strip_whitespace) {
children: _.compact(_.map(node.childNodes, function(node) {
return instance.web.xml_to_json(node, strip_whitespace);
})),
}
};
}
}
};
instance.web.json_node_to_xml = function(node, human_readable, indent) {
// For debugging purpose, this function will convert a json node back to xml
indent = indent || 0;

View File

@ -459,7 +459,7 @@
<tr>
<td class="oe_leftbar" valign="top">
<t t-set="debug" t-value="__debug__ ? '&amp;debug' : ''"/>
<a class="oe_logo" t-attf-href="/?ts=#{Date.now()}#{debug}">
<a class="oe_logo" t-attf-href="/?#{debug}">
<span class="oe_logo_edit">Edit Company data</span>
<img t-att-src='widget.session.url("/web/binary/company_logo")'/>
</a>
@ -1744,9 +1744,6 @@
<label for="export_format">Export Formats</label>
<select id="export_format" name="export_format"></select>
<label for="export_selection_only">Only export selection:</label>
<input type="checkbox" id="export_selection_only"/>
</td>
</tr>

View File

@ -7,7 +7,7 @@ openerp.testing.section('Widget.proxy', {
this.executed = true;
}
});
var w = new W;
var w = new W();
var fn = w.proxy('exec');
fn();
ok(w.executed, 'should execute the named method in the right context');
@ -18,7 +18,7 @@ openerp.testing.section('Widget.proxy', {
this.executed = arg;
}
});
var w = new W;
var w = new W();
var fn = w.proxy('exec');
fn(42);
ok(w.executed, "should execute the named method in the right context");
@ -32,7 +32,7 @@ openerp.testing.section('Widget.proxy', {
this.executed = 1;
}
});
var w = new W;
var w = new W();
var fn = w.proxy('exec');
W.include({
exec: function () { this.executed = 2; }
@ -43,14 +43,14 @@ openerp.testing.section('Widget.proxy', {
});
test('(Function)', function (instance) {
var w = new (instance.web.Widget.extend({ }));
var w = new (instance.web.Widget.extend({ }))();
var fn = w.proxy(function () { this.executed = true; });
fn();
ok(w.executed, "should set the function's context (like Function#bind)");
});
test('(Function)(*args)', function (instance) {
var w = new (instance.web.Widget.extend({ }));
var w = new (instance.web.Widget.extend({ }))();
var fn = w.proxy(function (arg) { this.executed = arg; });
fn(42);
@ -79,7 +79,7 @@ openerp.testing.section('Widget.renderElement', {
}
}, function (test) {
test('no template, default', function (instance) {
var w = new (instance.web.Widget.extend({ }));
var w = new (instance.web.Widget.extend({ }))();
var $original = w.$el;
ok($original, "should initially have a root element");
@ -96,7 +96,7 @@ openerp.testing.section('Widget.renderElement', {
test('no template, custom tag', function (instance) {
var w = new (instance.web.Widget.extend({
tagName: 'ul'
}));
}))();
w.renderElement();
equal(w.el.nodeName, 'UL', "should have generated the custom element tag");
@ -104,7 +104,7 @@ openerp.testing.section('Widget.renderElement', {
test('no template, @id', function (instance) {
var w = new (instance.web.Widget.extend({
id: 'foo'
}));
}))();
w.renderElement();
equal(w.el.attributes.length, 1, "should have one attribute");
@ -114,7 +114,7 @@ openerp.testing.section('Widget.renderElement', {
test('no template, @className', function (instance) {
var w = new (instance.web.Widget.extend({
className: 'oe_some_class'
}));
}))();
w.renderElement();
equal(w.el.className, 'oe_some_class', "should have the right property");
@ -129,7 +129,7 @@ openerp.testing.section('Widget.renderElement', {
'clark': 'gable',
'spoiler': 'snape kills dumbledore'
}
}));
}))();
w.renderElement();
equal(w.el.attributes.length, 5, "should have all the specified attributes");
@ -150,7 +150,7 @@ openerp.testing.section('Widget.renderElement', {
test('template', function (instance) {
var w = new (instance.web.Widget.extend({
template: 'test.widget.template'
}));
}))();
w.renderElement();
equal(w.el.nodeName, 'OL');
@ -160,7 +160,7 @@ openerp.testing.section('Widget.renderElement', {
test('repeated', { asserts: 4 }, function (instance, $fix) {
var w = new (instance.web.Widget.extend({
template: 'test.widget.template-value'
}));
}))();
w.value = 42;
return w.appendTo($fix)
.done(function () {
@ -194,7 +194,7 @@ openerp.testing.section('Widget.$', {
test('basic-alias', function (instance) {
var w = new (instance.web.Widget.extend({
template: 'test.widget.template'
}));
}))();
w.renderElement();
ok(w.$('li:eq(3)').is(w.$el.find('li:eq(3)')),
@ -226,13 +226,13 @@ openerp.testing.section('Widget.events', {
events: {
'click': function () {
a[0] = true;
strictEqual(this, w, "should trigger events in widget")
strictEqual(this, w, "should trigger events in widget");
},
'click li.class-3': 'class3',
'change input': function () { a[2] = true; }
},
class3: function () { a[1] = true; }
}));
}))();
w.renderElement();
w.$el.click();
@ -248,9 +248,9 @@ openerp.testing.section('Widget.events', {
var w = new (instance.web.Widget.extend({
template: 'test.widget.template',
events: { 'click li': function () { clicked = true; } }
}));
}))();
w.renderElement();
w.$el.on('click', 'li', function () { newclicked = true });
w.$el.on('click', 'li', function () { newclicked = true; });
w.$('li').click();
ok(clicked, "should trigger bound events");

View File

@ -0,0 +1,76 @@
openerp.testing.section('data.model.group_by', {
rpc: 'mock',
dependencies: ['web.data'],
}, function (test) {
var group_result = [{
bar: 3, bar_count: 5, __context: {}, __domain: [['bar', '=', 3]],
}, {
bar: 5, bar_count: 3, __context: {}, __domain: [['bar', '=', 5]],
}, {
bar: 8, bar_count: 0, __context: {}, __domain: [['bar', '=', 8]],
}];
test('basic', {asserts: 7}, function (instance, $fix, mock) {
var m = new instance.web.Model('foo');
mock('foo:read_group', function (args, kwargs) {
deepEqual(kwargs.fields, ['bar'],
"should read grouping field");
deepEqual(kwargs.groupby, ['bar'],
"should have single grouping field");
return group_result;
});
mock('/web/dataset/search_read', function (args) {
deepEqual(args.params.domain, [['bar', '=', 3]],
"should have domain matching that of group_by result");
return {records: [
{bar: 3, id: 1},
{bar: 3, id: 2},
{bar: 3, id: 4},
{bar: 3, id: 8},
{bar: 3, id: 16}
], length: 5};
});
return m.query().group_by('bar')
.then(function (groups) {
ok(groups, "should have data");
equal(groups.length, 3, "should have three results");
var first = groups[0];
ok(first.attributes.has_children, "should have children");
return first.query().all();
}).done(function (first) {
equal(first.length, 5, "should have 5 records");
});
});
test('noleaf', {asserts: 5}, function (instance, $fix, mock) {
var m = new instance.web.Model('foo', {group_by_no_leaf: true});
mock('foo:read_group', function (args, kwargs) {
deepEqual(kwargs.fields, ['bar'],
"should read grouping field");
deepEqual(kwargs.groupby, ['bar'],
"should have single grouping field");
return group_result;
});
return m.query().group_by('bar')
.then(function (groups) {
ok(groups, "should have data");
equal(groups.length, 3, "should have three results");
ok(!groups[0].attributes.has_children,
"should not have children because no_leaf");
});
});
test('nogroup', {rpc: false}, function (instance, $f, mock) {
var m = new instance.web.Model('foo');
strictEqual(m.query().group_by(), null, "should not group");
});
test('empty.noleaf', {asserts: 1}, function (instance, $f, mock) {
var m = new instance.web.Model('foo', {group_by_no_leaf: true});
mock('foo:read_group', function (args, kwargs) {
return [{__context: [], __domain: []}];
});
return m.query().group_by().done(function (groups) {
strictEqual(groups.length, 1,
"should generate a single fake-ish group");
});
});
});

View File

@ -9,9 +9,9 @@ openerp.testing.section('eval.types', {
return function (expr, func, message) {
// evaluate expr between two calls to new Date(), and check that
// the result is between the transformed dates
var d0 = new Date;
var d0 = new Date();
var result = py.eval(expr, context);
var d1 = new Date;
var d1 = new Date();
ok(func(d0) <= result && result <= func(d1), message);
};
};
@ -118,7 +118,7 @@ openerp.testing.section('eval.types', {
// Issue #11576
eq('td(999999999, 86399, 999999) - td(999999999, 86399, 999998)', 'td(0, 0, 1)');
eq('td(999999999, 1, 1) - td(999999999, 1, 0)',
'td(0, 0, 1)')
'td(0, 0, 1)');
});
test('timedelta.test_basic_attributes', function (instance) {
var ctx = instance.web.pyeval.context();
@ -264,7 +264,7 @@ openerp.testing.section('eval.types', {
py.eval("(datetime.date(2012, 2, 15) + relativedelta(days=-1)).strftime('%Y-%m-%d 23:59:59')",
instance.web.pyeval.context()),
"2012-02-14 23:59:59");
})
});
});
openerp.testing.section('eval.edc', {
dependencies: ['web.data'],

View File

@ -126,8 +126,8 @@ openerp.testing.section('web-formats', {
var str = "134,112.1234";
var val = instance.web.parse_value(str, {type:"float"});
equal(val, 134112.1234);
var str = "-134,112.1234";
var val = instance.web.parse_value(str, {type:"float"});
str = "-134,112.1234";
val = instance.web.parse_value(str, {type:"float"});
equal(val, -134112.1234);
_.extend(instance.web._t.database.parameters, {
decimal_point: ',',

View File

@ -49,7 +49,7 @@ openerp.testing.section('editor', {
readonly: field.readonly
})
}
}
};
});
return {
arch: {
@ -108,7 +108,7 @@ openerp.testing.section('editor', {
.done(function (record) {
ok(!e.is_editing(), "should have stopped editing");
equal(record.id, 42, "should have newly created id");
})
});
});
test('toggle-edition-cancel', { asserts: 2 }, function (instance, $fix) {
var e = new instance.web.list.Editor({
@ -131,7 +131,7 @@ openerp.testing.section('editor', {
.done(function (record) {
ok(!e.is_editing(), "should have stopped editing");
ok(!record.id, "should have no id");
})
});
});
test('toggle-save-required', {
asserts: 2,

View File

@ -7,7 +7,7 @@ openerp.testing.section('list.events', {
}
function Cls() {}
Cls.prototype = o;
return new Cls;
return new Cls();
};
test('Simple event triggering', function (instance) {
var e = create(instance.web.list.Events), passed = false;
@ -23,9 +23,9 @@ openerp.testing.section('list.events', {
});
test('Propagate trigger params', function (instance) {
var e = create(instance.web.list.Events), p = false;
e.bind(null, function (_, param) { p = param });
e.bind(null, function (_, param) { p = param; });
e.trigger('foo', true);
strictEqual(p, true)
strictEqual(p, true);
});
test('Bind multiple callbacks', function (instance) {
var e = create(instance.web.list.Events), count;
@ -53,7 +53,7 @@ openerp.testing.section('list.events', {
method: function () { this.trigger('e'); }
});
cls.include(instance.web.list.Events);
var i = new cls, triggered = false;
var i = new cls(), triggered = false;
i.bind('e', function () { triggered = true; });
i.method();
@ -97,7 +97,7 @@ openerp.testing.section('list.records', {
test('Change all the things', function (instance) {
var r = new instance.web.list.Record(), changed = false, field;
r.bind('change', function () { changed = true; });
r.bind(null, function (e) { field = field || e.split(':')[1]});
r.bind(null, function (e) { field = field || e.split(':')[1]; });
r.set('foo', 1);
strictEqual(r.get('foo'), 1);
ok(changed);

View File

@ -122,6 +122,6 @@ openerp.testing.section('misordered resolution managemeng', {
ok(!fail2);
done.resolve();
}, 400);
return $.when(d1, d2, done)
return $.when(d1, d2, done);
});
});

View File

@ -2,7 +2,7 @@ openerp.testing.section('search.query', {
dependencies: ['web.search']
}, function (test) {
test('Adding a facet to the query creates a facet and a value', function (instance) {
var query = new instance.web.search.SearchQuery;
var query = new instance.web.search.SearchQuery();
var field = {};
query.add({
category: 'Foo',
@ -16,7 +16,7 @@ openerp.testing.section('search.query', {
deepEqual(facet.get('values'), [{label: 'Value', value: 3}]);
});
test('Adding two facets', function (instance) {
var query = new instance.web.search.SearchQuery;
var query = new instance.web.search.SearchQuery();
query.add([
{ category: 'Foo', field: {}, values: [{label: 'Value', value: 3}] },
{ category: 'Bar', field: {}, values: [{label: 'Value 2', value: 4}] }
@ -27,7 +27,7 @@ openerp.testing.section('search.query', {
equal(query.at(1).values.length, 1);
});
test('If a facet already exists, add values to it', function (instance) {
var query = new instance.web.search.SearchQuery;
var query = new instance.web.search.SearchQuery();
var field = {};
query.add({category: 'A', field: field, values: [{label: 'V1', value: 0}]});
query.add({category: 'A', field: field, values: [{label: 'V2', value: 1}]});
@ -40,18 +40,18 @@ openerp.testing.section('search.query', {
]);
});
test('Facet being implicitly changed should trigger change, not add', function (instance) {
var query = new instance.web.search.SearchQuery;
var query = new instance.web.search.SearchQuery();
var field = {}, added = false, changed = false;
query.add({category: 'A', field: field, values: [{label: 'V1', value: 0}]});
query.on('add', function () { added = true; })
.on('change', function () { changed = true });
.on('change', function () { changed = true; });
query.add({category: 'A', field: field, values: [{label: 'V2', value: 1}]});
ok(!added, "query.add adding values to a facet should not trigger an add");
ok(changed, "query.add adding values to a facet should not trigger a change");
});
test('Toggling a facet, value which does not exist should add it', function (instance) {
var query = new instance.web.search.SearchQuery;
var query = new instance.web.search.SearchQuery();
var field = {};
query.toggle({category: 'A', field: field, values: [{label: 'V1', value: 0}]});
@ -63,7 +63,7 @@ openerp.testing.section('search.query', {
});
test('Toggling a facet which exists with a value which does not should add the value to the facet', function (instance) {
var field = {};
var query = new instance.web.search.SearchQuery;
var query = new instance.web.search.SearchQuery();
query.add({category: 'A', field: field, values: [{label: 'V1', value: 0}]});
query.toggle({category: 'A', field: field, values: [{label: 'V2', value: 1}]});
@ -77,7 +77,7 @@ openerp.testing.section('search.query', {
});
test('Toggling a facet which exists with a value which does as well should remove the value from the facet', function (instance) {
var field = {};
var query = new instance.web.search.SearchQuery;
var query = new instance.web.search.SearchQuery();
query.add({category: 'A', field: field, values: [{label: 'V1', value: 0}]});
query.add({category: 'A', field: field, values: [{label: 'V2', value: 1}]});
@ -92,7 +92,7 @@ openerp.testing.section('search.query', {
});
test('Toggling off the last value of a facet should remove the facet', function (instance) {
var field = {};
var query = new instance.web.search.SearchQuery;
var query = new instance.web.search.SearchQuery();
query.add({category: 'A', field: field, values: [{label: 'V1', value: 0}]});
query.toggle({category: 'A', field: field, values: [{label: 'V1', value: 0}]});
@ -101,7 +101,7 @@ openerp.testing.section('search.query', {
});
test('Intermediate emptiness should not remove the facet', function (instance) {
var field = {};
var query = new instance.web.search.SearchQuery;
var query = new instance.web.search.SearchQuery();
query.add({category: 'A', field: field, values: [{label: 'V1', value: 0}]});
query.toggle({category: 'A', field: field, values: [
@ -118,7 +118,7 @@ openerp.testing.section('search.query', {
});
test('Reseting with multiple facets should still work to load defaults', function (instance) {
var query = new instance.web.search.SearchQuery;
var query = new instance.web.search.SearchQuery();
var field = {};
query.reset([
{category: 'A', field: field, values: [{label: 'V1', value: 0}]},
@ -129,7 +129,7 @@ openerp.testing.section('search.query', {
deepEqual(query.at(0).get('values'), [
{label: 'V1', value: 0},
{label: 'V2', value: 1}
])
]);
});
});
@ -346,7 +346,7 @@ openerp.testing.section('search.defaults', {
{attrs: {name: 'dummy', string: 'Dummy'}},
{relation: 'dummy.model.name'},
view);
mock('dummy.model.name:name_get', function () { return [] });
mock('dummy.model.name:name_get', function () { return []; });
return f.facet_for_defaults({dummy: id})
.done(function (facet) {
ok(!facet, "an invalid m2o default should yield a non-facet");
@ -358,9 +358,9 @@ openerp.testing.section('search.defaults', {
{attrs: {name: 'dummy', string: 'Dummy'}},
{relation: 'dummy.model.name'},
view);
raises(function () { f.facet_for_defaults({dummy: [6, 7]}) },
raises(function () { f.facet_for_defaults({dummy: [6, 7]}); },
"should not accept multiple default values");
})
});
});
openerp.testing.section('search.completions', {
dependencies: ['web.search'],
@ -614,6 +614,59 @@ openerp.testing.section('search.completions', {
{relation: 'dummy.model'}, view);
return f.complete("bob");
});
test('Integer: invalid', {asserts: 1}, function (instance) {
var view = {inputs: []};
var f = new instance.web.search.IntegerField(
{attrs: {string: "Dummy"}}, {}, view);
return f.complete("qux")
.done(function (completions) {
ok(!completions, "non-number => no completion");
});
});
test('Integer: non-zero', {asserts: 5}, function (instance) {
var view = {inputs: []};
var f = new instance.web.search.IntegerField(
{attrs: {string: "Dummy"}}, {}, view);
return f.complete("-2")
.done(function (completions) {
equal(completions.length, 1, "number fields provide 1 completion only");
var facet = new instance.web.search.Facet(completions[0].facet);
equal(facet.get('category'), f.attrs.string);
equal(facet.get('field'), f);
var value = facet.values.at(0);
equal(value.get('label'), "-2");
equal(value.get('value'), -2);
});
});
test('Integer: zero', {asserts: 3}, function (instance) {
var view = {inputs: []};
var f = new instance.web.search.IntegerField(
{attrs: {string: "Dummy"}}, {}, view);
return f.complete("0")
.done(function (completions) {
equal(completions.length, 1, "number fields provide 1 completion only");
var facet = new instance.web.search.Facet(completions[0].facet);
var value = facet.values.at(0);
equal(value.get('label'), "0");
equal(value.get('value'), 0);
});
});
test('Float: non-zero', {asserts: 5}, function (instance) {
var view = {inputs: []};
var f = new instance.web.search.FloatField(
{attrs: {string: "Dummy"}}, {}, view);
return f.complete("42.37")
.done(function (completions) {
equal(completions.length, 1, "float fields provide 1 completion only");
var facet = new instance.web.search.Facet(completions[0].facet);
equal(facet.get('category'), f.attrs.string);
equal(facet.get('field'), f);
var value = facet.values.at(0);
equal(value.get('label'), "42.37");
equal(value.get('value'), 42.37);
});
});
});
openerp.testing.section('search.serialization', {
dependencies: ['web.search'],
@ -651,7 +704,7 @@ openerp.testing.section('search.serialization', {
ok(!got_groupby, "no facet, should not have fetched groupby");
ok(_(gs).isEmpty(), "groupby list should be empty");
})
});
});
test('London, calling', {asserts: 8}, function (instance, $fix) {
var got_domain = false, got_context = false, got_groupby = false;
@ -686,7 +739,7 @@ openerp.testing.section('search.serialization', {
ok(got_groupby, "should have fetched groupby");
ok(_(gs).isEmpty(), "groupby list should be empty");
})
});
});
test('Generate domains', {asserts: 1}, function (instance, $fix) {
var view = makeSearchView(instance, {
@ -1065,7 +1118,7 @@ openerp.testing.section('search.groupby', {
'<filter string="Baz" context="{\'group_by\': \'baz\'}"/>',
'</search>'
].join(''),
}
};
});
}
}, function (instance, $fix) {
@ -1076,7 +1129,7 @@ openerp.testing.section('search.groupby', {
equal(view.inputs.length, 7,
'should have 7 inputs total');
var group = _.find(view.inputs, function (f) {
return f instanceof instance.web.search.GroupbyGroup
return f instanceof instance.web.search.GroupbyGroup;
});
ok(group, "should have a GroupbyGroup input");
strictEqual(group.getParent(), view,
@ -1095,7 +1148,7 @@ openerp.testing.section('search.groupby', {
deepEqual(results.groupbys, [
"{'group_by': 'foo'}",
"{'group_by': 'baz'}"
], "should have sequence of contexts")
], "should have sequence of contexts");
});
});
test('unified multiple groupby groups', {
@ -1114,7 +1167,7 @@ openerp.testing.section('search.groupby', {
'<filter string="Baz" context="{\'group_by\': \'baz\'}"/>',
'</search>'
].join(''),
}
};
});
}
}, function (instance, $fix) {
@ -1125,7 +1178,7 @@ openerp.testing.section('search.groupby', {
equal(view.inputs.length, 9, "should have 9 inputs total");
var groups = _.filter(view.inputs, function (f) {
return f instanceof instance.web.search.GroupbyGroup
return f instanceof instance.web.search.GroupbyGroup;
});
equal(groups.length, 3, "should have 3 GroupbyGroups");
@ -1169,7 +1222,7 @@ openerp.testing.section('search.filters.saved', {
"displayed label should be the name of the filter");
equal(values.at(0).get('value'), null,
"should have no value set");
})
});
});
test('removal', {asserts: 1}, function (instance, $fix, mock) {
var view = makeSearchView(instance);
@ -1361,7 +1414,7 @@ openerp.testing.section('search.invisible', {
}, ['<search>',
'<field name="field0"/>',
'<field name="field1" modifiers="{&quot;invisible&quot;: true}"/>',
'</search>'].join());
'</search>'].join(''));
return view.appendTo($fix)
.then(function () {
var done = $.Deferred();
@ -1380,7 +1433,7 @@ openerp.testing.section('search.invisible', {
'<search>',
'<filter string="filter 0"/>',
'<filter string="filter 1" modifiers="{&quot;invisible&quot;: true}"/>',
'</search>'].join());
'</search>'].join(''));
return view.appendTo($fix)
.then(function () {
var $fs = $fix.find('.oe_searchview_filters ul');
@ -1400,6 +1453,26 @@ openerp.testing.section('search.invisible', {
return done;
});
});
test('invisible-previous-sibling', {asserts: 3}, function (instance, $fix, mock) {
var view = makeView(instance, mock, {}, [
'<search>',
'<filter string="filter 0" context="{&quot;test&quot;: 0}"/>',
'<filter string="filter 1" modifiers="{&quot;invisible&quot;: true}" context="{&quot;test&quot;: 1}"/>',
'<filter string="filter 2" modifiers="{&quot;invisible&quot;: true}" context="{&quot;test&quot;: 2}"/>',
'<filter string="filter 3" context="{&quot;test&quot;: 3}"/>',
'</search>'].join(''));
return view.appendTo($fix)
.done(function () {
// Select filter 3
$fix.find('.oe_searchview_filters ul li:contains("filter 3")').click();
equal(view.query.length, 1, "should have selected a filter");
var facet = view.query.at(0);
strictEqual(facet.values.at(0).get('label'), "filter 3",
"should have correctly labelled the facet");
deepEqual(view.build_search_data().contexts, [{test: 3}],
"should have built correct context");
});
});
// Invisible filter groups should not appear in the drawer
// Group invisibility should be inherited by children
test('group-invisibility', {asserts: 6}, function (instance, $fix, mock) {

View File

@ -21,7 +21,7 @@ openerp.testing.section('testing.stack', function (test) {
return s.execute(function () {
return $.when(42);
}).then(function (val) {
strictEqual(val, 42, "should return the handler value")
strictEqual(val, 42, "should return the handler value");
});
});
test('direct, deferred, failure', {asserts: 1}, function () {

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web_calendar

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web_calendar

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web_calendar

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web_calendar

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web_calendar

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
"X-Poedit-Language: Czech\n"

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web_calendar

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web_calendar

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web_calendar

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web_calendar

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web_calendar

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web_calendar

View File

@ -15,7 +15,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
"Language: es\n"

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web_calendar

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web_calendar

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-07-06 06:05+0000\n"
"X-Launchpad-Export-Date: 2013-07-17 06:42+0000\n"
"X-Generator: Launchpad (build 16696)\n"
#. module: web_calendar

Some files were not shown because too many files have changed in this diff Show More