summaryrefslogtreecommitdiff
path: root/addons/web
diff options
context:
space:
mode:
authorVidhin Mehta (OpenERP) <vme@tinyerp.com>2014-05-05 10:02:33 +0530
committerVidhin Mehta (OpenERP) <vme@tinyerp.com>2014-05-05 10:02:33 +0530
commite41508cb8d7fd2a2c06e3fab9ce1503e8efa30fa (patch)
tree8e0fbb849cebc9b3ac0f87355a5248f51826a491 /addons/web
parent4312b921f3db41529cbd4f501a6b5dcba2bebd08 (diff)
parent8fbebfd752fa8933584711522675d354b3217839 (diff)
[MERGE]Trunk.
bzr revid: vme@tinyerp.com-20140505043233-2t2e2vb1yv86hyxp
Diffstat (limited to 'addons/web')
-rw-r--r--addons/web/__openerp__.py74
-rw-r--r--addons/web/controllers/__init__.py1
-rw-r--r--addons/web/controllers/main.py301
-rw-r--r--addons/web/controllers/testing.py159
-rw-r--r--addons/web/i18n/ar.po2
-rw-r--r--addons/web/i18n/bg.po2
-rw-r--r--addons/web/i18n/bn.po2
-rw-r--r--addons/web/i18n/bs.po2
-rw-r--r--addons/web/i18n/ca.po2
-rw-r--r--addons/web/i18n/cs.po2
-rw-r--r--addons/web/i18n/da.po2
-rw-r--r--addons/web/i18n/de.po2
-rw-r--r--addons/web/i18n/en_AU.po2
-rw-r--r--addons/web/i18n/en_GB.po2
-rw-r--r--addons/web/i18n/es.po2
-rw-r--r--addons/web/i18n/es_CL.po2
-rw-r--r--addons/web/i18n/es_CR.po2
-rw-r--r--addons/web/i18n/es_DO.po2
-rw-r--r--addons/web/i18n/es_EC.po2
-rw-r--r--addons/web/i18n/es_MX.po2
-rw-r--r--addons/web/i18n/es_PE.po2
-rw-r--r--addons/web/i18n/et.po2
-rw-r--r--addons/web/i18n/eu.po2
-rw-r--r--addons/web/i18n/fa.po2
-rw-r--r--addons/web/i18n/fi.po2
-rw-r--r--addons/web/i18n/fr.po2
-rw-r--r--addons/web/i18n/fr_CA.po2
-rw-r--r--addons/web/i18n/gl.po2
-rw-r--r--addons/web/i18n/gu.po2
-rw-r--r--addons/web/i18n/he.po2
-rw-r--r--addons/web/i18n/hi.po2
-rw-r--r--addons/web/i18n/hr.po2
-rw-r--r--addons/web/i18n/hu.po2
-rw-r--r--addons/web/i18n/id.po2
-rw-r--r--addons/web/i18n/it.po2
-rw-r--r--addons/web/i18n/ja.po2
-rw-r--r--addons/web/i18n/ka.po2
-rw-r--r--addons/web/i18n/ko.po2
-rw-r--r--addons/web/i18n/lo.po2
-rw-r--r--addons/web/i18n/lt.po2
-rw-r--r--addons/web/i18n/lv.po2
-rw-r--r--addons/web/i18n/mk.po2
-rw-r--r--addons/web/i18n/mn.po2
-rw-r--r--addons/web/i18n/nb.po2
-rw-r--r--addons/web/i18n/nl.po2
-rw-r--r--addons/web/i18n/nl_BE.po2
-rw-r--r--addons/web/i18n/pl.po2
-rw-r--r--addons/web/i18n/pt.po2
-rw-r--r--addons/web/i18n/pt_BR.po2
-rw-r--r--addons/web/i18n/ro.po2
-rw-r--r--addons/web/i18n/ru.po2
-rw-r--r--addons/web/i18n/sk.po2
-rw-r--r--addons/web/i18n/sl.po2
-rw-r--r--addons/web/i18n/sq.po2
-rw-r--r--addons/web/i18n/sr@latin.po2
-rw-r--r--addons/web/i18n/sv.po2
-rw-r--r--addons/web/i18n/th.po2
-rw-r--r--addons/web/i18n/tr.po2
-rw-r--r--addons/web/i18n/uk.po2
-rw-r--r--addons/web/i18n/vi.po2
-rw-r--r--addons/web/i18n/zh_CN.po2
-rw-r--r--addons/web/i18n/zh_TW.po2
-rw-r--r--addons/web/static/lib/fontawesome/css/font-awesome.css15
-rw-r--r--addons/web/static/src/css/base.css84
-rw-r--r--addons/web/static/src/css/base.sass90
-rw-r--r--addons/web/static/src/js/chrome.js2
-rw-r--r--addons/web/static/src/js/core.js29
-rw-r--r--addons/web/static/src/js/data_export.js2
-rw-r--r--addons/web/static/src/js/search.js32
-rw-r--r--addons/web/static/src/js/testing.js23
-rw-r--r--addons/web/static/src/js/view_form.js11
-rw-r--r--addons/web/static/src/xml/base.xml21
-rw-r--r--addons/web/static/test/list-editable.js4
-rw-r--r--addons/web/tests/__init__.py1
-rw-r--r--addons/web/tests/qunitsuite/README.rst116
-rw-r--r--addons/web/tests/qunitsuite/__init__.py0
-rw-r--r--addons/web/tests/qunitsuite/grunt/bootstrap.js95
-rw-r--r--addons/web/tests/qunitsuite/grunt/license22
-rw-r--r--addons/web/tests/qunitsuite/grunt/phantomjs.json1
-rw-r--r--addons/web/tests/qunitsuite/grunt/qunit-phantomjs-bridge.js88
-rw-r--r--addons/web/tests/qunitsuite/suite.py136
-rw-r--r--addons/web/tests/test_js.py26
-rw-r--r--addons/web/tests/test_menu.py4
-rw-r--r--addons/web/tests/test_ui.py16
-rw-r--r--addons/web/tests/test_ui_hello.js5
-rw-r--r--addons/web/tests/test_ui_load.js4
-rw-r--r--addons/web/views/webclient_templates.xml156
87 files changed, 484 insertions, 1150 deletions
diff --git a/addons/web/__openerp__.py b/addons/web/__openerp__.py
index 5941a6aa5b0..a4000856afe 100644
--- a/addons/web/__openerp__.py
+++ b/addons/web/__openerp__.py
@@ -14,81 +14,7 @@ This module provides the core of the OpenERP Web Client.
'data': [
'views/webclient_templates.xml',
],
- 'js': [
- "static/lib/es5-shim/es5-shim.min.js",
- "static/lib/datejs/globalization/en-US.js",
- "static/lib/datejs/core.js",
- "static/lib/datejs/parser.js",
- "static/lib/datejs/sugarpak.js",
- "static/lib/datejs/extras.js",
- "static/lib/jquery/jquery.js",
- "static/lib/jquery.form/jquery.form.js",
- "static/lib/jquery.validate/jquery.validate.js",
- "static/lib/jquery.ba-bbq/jquery.ba-bbq.js",
- "static/lib/spinjs/spin.js",
- "static/lib/jquery.autosize/jquery.autosize.js",
- "static/lib/jquery.blockUI/jquery.blockUI.js",
- "static/lib/jquery.hotkeys/jquery.hotkeys.js",
- "static/lib/jquery.placeholder/jquery.placeholder.js",
- "static/lib/jquery.ui/js/jquery-ui-1.9.1.custom.js",
- "static/lib/jquery.ui.timepicker/js/jquery-ui-timepicker-addon.js",
- "static/lib/jquery.ui.notify/js/jquery.notify.js",
- "static/lib/jquery.deferred-queue/jquery.deferred-queue.js",
- "static/lib/jquery.scrollTo/jquery.scrollTo-min.js",
- "static/lib/jquery.textext/jquery.textext.js",
- "static/lib/jquery.timeago/jquery.timeago.js",
- "static/lib/bootstrap/js/bootstrap.js",
- "static/lib/qweb/qweb2.js",
- "static/lib/underscore/underscore.js",
- "static/lib/underscore.string/lib/underscore.string.js",
- "static/lib/backbone/backbone.js",
- "static/lib/cleditor/jquery.cleditor.js",
- "static/lib/py.js/lib/py.js",
- "static/lib/select2/select2.js",
- "static/src/js/openerpframework.js",
- "static/src/js/boot.js",
- "static/src/js/testing.js",
- "static/src/js/pyeval.js",
- "static/src/js/core.js",
- "static/src/js/formats.js",
- "static/src/js/chrome.js",
- "static/src/js/views.js",
- "static/src/js/data.js",
- "static/src/js/data_export.js",
- "static/src/js/search.js",
- "static/src/js/view_list.js",
- "static/src/js/view_form.js",
- "static/src/js/view_list_editable.js",
- "static/src/js/view_tree.js",
- ],
- 'css' : [
- "static/lib/jquery.ui.bootstrap/css/custom-theme/jquery-ui-1.9.0.custom.css",
- "static/lib/jquery.ui.timepicker/css/jquery-ui-timepicker-addon.css",
- "static/lib/jquery.ui.notify/css/ui.notify.css",
- "static/lib/jquery.textext/jquery.textext.css",
- "static/lib/fontawesome/css/font-awesome.css",
- "static/lib/bootstrap/css/bootstrap.css",
- "static/lib/select2/select2.css",
- "static/src/css/base.css",
- "static/src/css/data_export.css",
- "static/lib/cleditor/jquery.cleditor.css",
- ],
'qweb' : [
"static/src/xml/*.xml",
],
- 'test': [
- "static/test/testing.js",
- "static/test/framework.js",
- "static/test/registry.js",
- "static/test/form.js",
- "static/test/data.js",
- "static/test/list-utils.js",
- "static/test/formats.js",
- "static/test/rpc-misordered.js",
- "static/test/evals.js",
- "static/test/search.js",
- "static/test/list.js",
- "static/test/list-editable.js",
- "static/test/mutex.js"
- ],
}
diff --git a/addons/web/controllers/__init__.py b/addons/web/controllers/__init__.py
index 74c27518ece..12a7e529b67 100644
--- a/addons/web/controllers/__init__.py
+++ b/addons/web/controllers/__init__.py
@@ -1,2 +1 @@
from . import main
-from . import testing
diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py
index f2101b27fd3..6dcc069fcc2 100644
--- a/addons/web/controllers/main.py
+++ b/addons/web/controllers/main.py
@@ -31,6 +31,7 @@ except ImportError:
import openerp
import openerp.modules.registry
+from openerp.addons.base.ir.ir_qweb import AssetsBundle, QWebTemplateNotFound
from openerp.tools.translate import _
from openerp import http
@@ -52,50 +53,6 @@ env.filters["json"] = simplejson.dumps
# OpenERP Web helpers
#----------------------------------------------------------
-def rjsmin(script):
- """ Minify js with a clever regex.
- Taken from http://opensource.perlig.de/rjsmin
- Apache License, Version 2.0 """
- def subber(match):
- """ Substitution callback """
- groups = match.groups()
- return (
- groups[0] or
- groups[1] or
- groups[2] or
- groups[3] or
- (groups[4] and '\n') or
- (groups[5] and ' ') or
- (groups[6] and ' ') or
- (groups[7] and ' ') or
- ''
- )
-
- result = re.sub(
- r'([^\047"/\000-\040]+)|((?:(?:\047[^\047\\\r\n]*(?:\\(?:[^\r\n]|\r?'
- r'\n|\r)[^\047\\\r\n]*)*\047)|(?:"[^"\\\r\n]*(?:\\(?:[^\r\n]|\r?\n|'
- r'\r)[^"\\\r\n]*)*"))[^\047"/\000-\040]*)|(?:(?<=[(,=:\[!&|?{};\r\n]'
- r')(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/'
- r'))*((?:/(?![\r\n/*])[^/\\\[\r\n]*(?:(?:\\[^\r\n]|(?:\[[^\\\]\r\n]*'
- r'(?:\\[^\r\n][^\\\]\r\n]*)*\]))[^/\\\[\r\n]*)*/)[^\047"/\000-\040]*'
- r'))|(?:(?<=[\000-#%-,./:-@\[-^`{-~-]return)(?:[\000-\011\013\014\01'
- r'6-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*((?:/(?![\r\n/*])[^/'
- r'\\\[\r\n]*(?:(?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]'
- r'*)*\]))[^/\\\[\r\n]*)*/)[^\047"/\000-\040]*))|(?<=[^\000-!#%&(*,./'
- r':-@\[\\^`{|~])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/'
- r'*][^*]*\*+)*/))*(?:((?:(?://[^\r\n]*)?[\r\n]))(?:[\000-\011\013\01'
- r'4\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+(?=[^\000-\040"#'
- r'%-\047)*,./:-@\\-^`|-~])|(?<=[^\000-#%-,./:-@\[-^`{-~-])((?:[\000-'
- r'\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=[^'
- r'\000-#%-,./:-@\[-^`{-~-])|(?<=\+)((?:[\000-\011\013\014\016-\040]|'
- r'(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=\+)|(?<=-)((?:[\000-\011\0'
- r'13\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=-)|(?:[\0'
- r'00-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))+|(?:'
- r'(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*'
- r']*\*+(?:[^/*][^*]*\*+)*/))*)+', subber, '\n%s\n' % script
- ).strip()
- return result
-
db_list = http.db_list
db_monodb = http.db_monodb
@@ -309,45 +266,6 @@ def concat_xml(file_list):
root.append(child)
return ElementTree.tostring(root, 'utf-8'), checksum.hexdigest()
-def concat_files(file_list, reader=None, intersperse=""):
- """ Concatenates contents of all provided files
-
- :param list(str) file_list: list of files to check
- :param function reader: reading procedure for each file
- :param str intersperse: string to intersperse between file contents
- :returns: (concatenation_result, checksum)
- :rtype: (str, str)
- """
- checksum = hashlib.new('sha1')
- if not file_list:
- return '', checksum.hexdigest()
-
- if reader is None:
- def reader(f):
- import codecs
- with codecs.open(f, 'rb', "utf-8-sig") as fp:
- return fp.read().encode("utf-8")
-
- files_content = []
- for fname in file_list:
- contents = reader(fname)
- checksum.update(contents)
- files_content.append(contents)
-
- files_concat = intersperse.join(files_content)
- return files_concat, checksum.hexdigest()
-
-concat_js_cache = {}
-
-def concat_js(file_list):
- content, checksum = concat_files(file_list, intersperse=';')
- if checksum in concat_js_cache:
- content = concat_js_cache[checksum]
- else:
- content = rjsmin(content)
- concat_js_cache[checksum] = content
- return content, checksum
-
def fs2web(path):
"""convert FS path into web path"""
return '/'.join(path.split(os.path.sep))
@@ -371,30 +289,17 @@ def manifest_glob(extension, addons=None, db=None, include_remotes=False):
r.append((None, pattern))
else:
for path in glob.glob(os.path.normpath(os.path.join(addons_path, addon, pattern))):
- # Hack for IE, who limit 288Ko, 4095 rules, 31 sheets
- # http://support.microsoft.com/kb/262161/en
- if pattern == "static/lib/bootstrap/css/bootstrap.css":
- if include_remotes:
- r.insert(0, (None, fs2web(path[len(addons_path):])))
- else:
- r.append((path, fs2web(path[len(addons_path):])))
+ r.append((path, fs2web(path[len(addons_path):])))
return r
-def manifest_list(extension, mods=None, db=None, debug=False):
+def manifest_list(extension, mods=None, db=None, debug=None):
""" list ressources to load specifying either:
mods: a comma separated string listing modules
db: a database name (return all installed modules in that database)
"""
+ if debug is not None:
+ _logger.warning("openerp.addons.web.main.manifest_list(): debug parameter is deprecated")
files = manifest_glob(extension, addons=mods, db=db, include_remotes=True)
- if not debug:
- path = '/web/webclient/' + extension
- if mods is not None:
- path += '?' + werkzeug.url_encode({'mods': mods})
- elif db:
- path += '?' + werkzeug.url_encode({'db': db})
-
- remotes = [wp for fp, wp in files if fp is None]
- return [path] + remotes
return [wp for _fp, wp in files]
def get_last_modified(files):
@@ -411,7 +316,7 @@ def get_last_modified(files):
for f in files)
return datetime.datetime(1970, 1, 1)
-def make_conditional(response, last_modified=None, etag=None):
+def make_conditional(response, last_modified=None, etag=None, max_age=0):
""" Makes the provided response conditional based upon the request,
and mandates revalidation from clients
@@ -426,7 +331,7 @@ def make_conditional(response, last_modified=None, etag=None):
:rtype: werkzeug.wrappers.Response
"""
response.cache_control.must_revalidate = True
- response.cache_control.max_age = 0
+ response.cache_control.max_age = max_age
if last_modified:
response.last_modified = last_modified
if etag:
@@ -603,6 +508,7 @@ html_template = """<!DOCTYPE html>
<title>OpenERP</title>
<link rel="shortcut icon" href="/web/static/src/img/favicon.ico" type="image/x-icon"/>
<link rel="stylesheet" href="/web/static/src/css/full.css" />
+
%(css)s
%(js)s
<script type="text/javascript">
@@ -621,26 +527,16 @@ html_template = """<!DOCTYPE html>
</html>
"""
-def render_bootstrap_template(template, values=None, debug=False, db=None, **kw):
- if not db:
- db = request.db
- if request.debug:
- debug = True
+def render_bootstrap_template(template, values=None, **kw):
if values is None:
- values = {}
- values['debug'] = debug
- values['current_db'] = db
+ values = dict()
try:
values['databases'] = http.db_list()
except openerp.exceptions.AccessDenied:
values['databases'] = None
- for res in ['js', 'css']:
- if res not in values:
- values[res] = manifest_list(res, db=db, debug=debug)
-
if 'modules' not in values:
- values['modules'] = module_boot(db=db)
+ values['modules'] = module_boot()
values['modules'] = simplejson.dumps(values['modules'])
return request.render(template, values, **kw)
@@ -682,9 +578,11 @@ class Home(http.Controller):
redirect = '/web?' + request.httprequest.query_string
values['redirect'] = redirect
if request.httprequest.method == 'POST':
+ old_uid = request.uid
uid = request.session.authenticate(request.session.db, request.params['login'], request.params['password'])
if uid is not False:
return http.redirect_with_hash(redirect)
+ request.uid = old_uid
values['error'] = "Wrong login/password"
return render_bootstrap_template('web.login', values)
@@ -692,83 +590,47 @@ class Home(http.Controller):
def login(self, db, login, key, redirect="/web", **kw):
return login_and_redirect(db, login, key, redirect_url=redirect)
-class WebClient(http.Controller):
-
- @http.route('/web/webclient/csslist', type='json', auth="none")
- def csslist(self, mods=None):
- return manifest_list('css', mods=mods)
-
- @http.route('/web/webclient/jslist', type='json', auth="none")
- def jslist(self, mods=None):
- return manifest_list('js', mods=mods)
-
- @http.route('/web/webclient/qweblist', type='json', auth="none")
- def qweblist(self, mods=None):
- return manifest_list('qweb', mods=mods)
-
- @http.route('/web/webclient/css', type='http', auth="none")
- def css(self, mods=None, db=None):
- files = list(manifest_glob('css', addons=mods, db=db))
- last_modified = get_last_modified(f[0] for f in files)
- if request.httprequest.if_modified_since and request.httprequest.if_modified_since >= last_modified:
- return werkzeug.wrappers.Response(status=304)
-
- file_map = dict(files)
-
- rx_import = re.compile(r"""@import\s+('|")(?!'|"|/|https?://)""", re.U)
- rx_url = re.compile(r"""url\s*\(\s*('|"|)(?!'|"|/|https?://|data:)""", re.U)
-
- def reader(f):
- """read the a css file and absolutify all relative uris"""
- with open(f, 'rb') as fp:
- data = fp.read().decode('utf-8')
-
- path = file_map[f]
- web_dir = os.path.dirname(path)
-
- data = re.sub(
- rx_import,
- r"""@import \1%s/""" % (web_dir,),
- data,
- )
-
- data = re.sub(
- rx_url,
- r"url(\1%s/" % (web_dir,),
- data,
- )
- return data.encode('utf-8')
+ @http.route('/web/js/<xmlid>', type='http', auth="public")
+ def js_bundle(self, xmlid, **kw):
+ # manifest backward compatible mode, to be removed
+ values = {'manifest_list': manifest_list}
+ try:
+ assets_html = request.render(xmlid, lazy=False, qcontext=values)
+ except QWebTemplateNotFound:
+ return request.not_found()
+ bundle = AssetsBundle(xmlid, assets_html, debug=request.debug)
- content, checksum = concat_files((f[0] for f in files), reader)
+ response = request.make_response(
+ bundle.js(), [('Content-Type', 'application/javascript')])
- # move up all @import and @charset rules to the top
- matches = []
- def push(matchobj):
- matches.append(matchobj.group(0))
- return ''
+ # TODO: check that we don't do weird lazy overriding of __call__ which break body-removal
+ return make_conditional(
+ response, bundle.last_modified, bundle.checksum, max_age=60*60*24)
- content = re.sub(re.compile("(@charset.+;$)", re.M), push, content)
- content = re.sub(re.compile("(@import.+;$)", re.M), push, content)
+ @http.route('/web/css/<xmlid>', type='http', auth='public')
+ def css_bundle(self, xmlid, **kw):
+ values = {'manifest_list': manifest_list} # manifest backward compatible mode, to be removed
+ try:
+ assets_html = request.render(xmlid, lazy=False, qcontext=values)
+ except QWebTemplateNotFound:
+ return request.not_found()
+ bundle = AssetsBundle(xmlid, assets_html, debug=request.debug)
- matches.append(content)
- content = '\n'.join(matches)
+ response = request.make_response(
+ bundle.css(), [('Content-Type', 'text/css')])
return make_conditional(
- request.make_response(content, [('Content-Type', 'text/css')]),
- last_modified, checksum)
+ response, bundle.last_modified, bundle.checksum, max_age=60*60*24)
- @http.route('/web/webclient/js', type='http', auth="none")
- def js(self, mods=None, db=None):
- files = [f[0] for f in manifest_glob('js', addons=mods, db=db)]
- last_modified = get_last_modified(files)
- if request.httprequest.if_modified_since and request.httprequest.if_modified_since >= last_modified:
- return werkzeug.wrappers.Response(status=304)
+class WebClient(http.Controller):
- content, checksum = concat_js(files)
+ @http.route('/web/webclient/csslist', type='json', auth="none")
+ def csslist(self, mods=None):
+ return manifest_list('css', mods=mods)
- return make_conditional(
- request.make_response(content, [('Content-Type', 'application/javascript')]),
- last_modified, checksum)
+ @http.route('/web/webclient/jslist', type='json', auth="none")
+ def jslist(self, mods=None):
+ return manifest_list('js', mods=mods)
@http.route('/web/webclient/qweb', type='http', auth="none")
def qweb(self, mods=None, db=None):
@@ -843,6 +705,10 @@ class WebClient(http.Controller):
def version_info(self):
return openerp.service.common.exp_version()
+ @http.route('/web/tests', type='http', auth="none")
+ def index(self, mod=None, **kwargs):
+ return request.render('web.qunit_suite')
+
class Proxy(http.Controller):
@http.route('/web/proxy/load', type='json', auth="none")
@@ -879,8 +745,64 @@ class Database(http.Controller):
def manager(self, **kw):
# TODO: migrate the webclient's database manager to server side views
request.session.logout()
- js = "\n ".join('<script type="text/javascript" src="%s"></script>' % i for i in manifest_list('js', debug=request.debug))
- css = "\n ".join('<link rel="stylesheet" href="%s">' % i for i in manifest_list('css', debug=request.debug))
+ css = """
+ <link href="/web/static/lib/fontawesome/css/font-awesome.css" rel="stylesheet"/>
+ <link href="/web/static/lib/cleditor/jquery.cleditor.css" rel="stylesheet"/>
+ <link href="/web/static/lib/jquery.textext/jquery.textext.css" rel="stylesheet"/>
+ <link href="/web/static/lib/select2/select2.css" rel="stylesheet"/>
+ <link href="/web/static/lib/jquery.ui.bootstrap/css/custom-theme/jquery-ui-1.9.0.custom.css" rel="stylesheet"/>
+ <link href="/web/static/lib/jquery.ui.timepicker/css/jquery-ui-timepicker-addon.css" rel="stylesheet"/>
+ <link href="/web/static/lib/jquery.ui.notify/css/ui.notify.css" rel="stylesheet"/>
+ <link href="/web/static/lib/bootstrap/css/bootstrap.css" rel="stylesheet"/>
+ <link href="/web/static/src/css/base.css" rel="stylesheet"/>
+ <link href="/web/static/src/css/data_export.css" rel="stylesheet"/>
+ <link href="/base/static/src/css/modules.css" rel="stylesheet"/>"""
+ js = """
+ <script src="/web/static/lib/es5-shim/es5-shim.min.js" type="text/javascript"></script>
+ <script src="/web/static/lib/underscore/underscore.js" type="text/javascript"></script>
+ <script src="/web/static/lib/underscore.string/lib/underscore.string.js" type="text/javascript"></script>
+ <script src="/web/static/lib/datejs/globalization/en-US.js" type="text/javascript"></script>
+ <script src="/web/static/lib/spinjs/spin.js" type="text/javascript"></script>
+ <script src="/web/static/lib/jquery/jquery.js" type="text/javascript"></script>
+ <script src="/web/static/lib/jquery.blockUI/jquery.blockUI.js" type="text/javascript"></script>
+ <script src="/web/static/lib/jquery.hotkeys/jquery.hotkeys.js" type="text/javascript"></script>
+ <script src="/web/static/lib/jquery.placeholder/jquery.placeholder.js" type="text/javascript"></script>
+ <script src="/web/static/lib/jquery.timeago/jquery.timeago.js" type="text/javascript"></script>
+ <script src="/web/static/lib/jquery.form/jquery.form.js" type="text/javascript"></script>
+ <script src="/web/static/lib/jquery.ba-bbq/jquery.ba-bbq.js" type="text/javascript"></script>
+ <script src="/web/static/lib/datejs/core.js" type="text/javascript"></script>
+ <script src="/web/static/lib/datejs/parser.js" type="text/javascript"></script>
+ <script src="/web/static/lib/datejs/sugarpak.js" type="text/javascript"></script>
+ <script src="/web/static/lib/datejs/extras.js" type="text/javascript"></script>
+ <script src="/web/static/lib/jquery.validate/jquery.validate.js" type="text/javascript"></script>
+ <script src="/web/static/lib/jquery.autosize/jquery.autosize.js" type="text/javascript"></script>
+ <script src="/web/static/lib/jquery.scrollTo/jquery.scrollTo-min.js" type="text/javascript"></script>
+ <script src="/web/static/lib/cleditor/jquery.cleditor.js" type="text/javascript"></script>
+ <script src="/web/static/lib/jquery.textext/jquery.textext.js" type="text/javascript"></script>
+ <script src="/web/static/lib/select2/select2.js" type="text/javascript"></script>
+ <script src="/web/static/lib/jquery.ui/js/jquery-ui-1.9.1.custom.js" type="text/javascript"></script>
+ <script src="/web/static/lib/jquery.ui.timepicker/js/jquery-ui-timepicker-addon.js" type="text/javascript"></script>
+ <script src="/web/static/lib/jquery.ui.notify/js/jquery.notify.js" type="text/javascript"></script>
+ <script src="/web/static/lib/bootstrap/js/bootstrap.js" type="text/javascript"></script>
+ <script src="/web/static/lib/backbone/backbone.js" type="text/javascript"></script>
+ <script src="/web/static/lib/qweb/qweb2.js" type="text/javascript"></script>
+ <script src="/web/static/src/js/openerpframework.js" type="text/javascript"></script>
+ <script src="/web/static/lib/py.js/lib/py.js" type="text/javascript"></script>
+ <script src="/web/static/src/js/boot.js" type="text/javascript"></script>
+ <script src="/web/static/src/js/testing.js" type="text/javascript"></script>
+ <script src="/web/static/src/js/pyeval.js" type="text/javascript"></script>
+ <script src="/web/static/src/js/core.js" type="text/javascript"></script>
+ <script src="/web/static/src/js/formats.js" type="text/javascript"></script>
+ <script src="/web/static/src/js/chrome.js" type="text/javascript"></script>
+ <script src="/web/static/src/js/views.js" type="text/javascript"></script>
+ <script src="/web/static/src/js/data.js" type="text/javascript"></script>
+ <script src="/web/static/src/js/data_export.js" type="text/javascript"></script>
+ <script src="/web/static/src/js/search.js" type="text/javascript"></script>
+ <script src="/web/static/src/js/view_list.js" type="text/javascript"></script>
+ <script src="/web/static/src/js/view_form.js" type="text/javascript"></script>
+ <script src="/web/static/src/js/view_list_editable.js" type="text/javascript"></script>
+ <script src="/web/static/src/js/view_tree.js" type="text/javascript"></script>
+ <script src="/base/static/src/js/apps.js" type="text/javascript"></script>"""
r = html_template % {
'js': js,
@@ -1088,16 +1010,7 @@ class Menu(http.Controller):
"""
s = request.session
Menus = s.model('ir.ui.menu')
- # If a menu action is defined use its domain to get the root menu items
- user_menu_id = s.model('res.users').read([s.uid], ['menu_id'],
- request.context)[0]['menu_id']
-
menu_domain = [('parent_id', '=', False)]
- if user_menu_id:
- domain_string = s.model('ir.actions.act_window').read(
- [user_menu_id[0]], ['domain'],request.context)[0]['domain']
- if domain_string:
- menu_domain = ast.literal_eval(domain_string)
return Menus.search(menu_domain, 0, False, False, request.context)
diff --git a/addons/web/controllers/testing.py b/addons/web/controllers/testing.py
deleted file mode 100644
index a51b619d49f..00000000000
--- a/addons/web/controllers/testing.py
+++ /dev/null
@@ -1,159 +0,0 @@
-# coding=utf-8
-# -*- encoding: utf-8 -*-
-
-import glob
-import itertools
-import json
-import operator
-import os
-
-from mako.template import Template
-from openerp.modules import module
-from openerp import http
-from openerp.http import request
-
-from .main import module_topological_sort
-
-NOMODULE_TEMPLATE = Template(u"""<!DOCTYPE html>
-<html>
- <head>
- <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
- <meta http-equiv="content-type" content="text/html; charset=utf-8" />
- <title>OpenERP Testing</title>
- </head>
- <body>
- <form action="/web/tests" method="GET">
- <button name="mod" value="*">Run all tests</button>
- <ul>
- % for name, module in modules:
- <li>${name} <button name="mod" value="${module}">
- Run Tests</button></li>
- % endfor
- </ul>
- </form>
- </body>
-</html>
-""", default_filters=['h'])
-NOTFOUND = Template(u"""
-<p>Unable to find the module [${module}], please check that the module
- name is correct and the module is on OpenERP's path.</p>
-<a href="/web/tests">&lt;&lt; Back to tests</a>
-""", default_filters=['h'])
-TESTING = Template(u"""<!DOCTYPE html>
-<html style="height: 100%">
-<%def name="to_path(module, p)">/${module}/${p}</%def>
-<head>
- <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
- <meta http-equiv="content-type" content="text/html; charset=utf-8" />
- <title>OpenERP Web Tests</title>
- <link rel="shortcut icon" href="/web/static/src/img/favicon.ico" type="image/x-icon"/>
-
- <link rel="stylesheet" href="/web/static/lib/qunit/qunit.css">
- <script src="/web/static/lib/qunit/qunit.js"></script>
-
- <script type="text/javascript">
- // List of modules, each module is preceded by its dependencies
- var oe_all_dependencies = ${dependencies | n};
- QUnit.config.testTimeout = 5 * 60 * 1000;
- </script>
-</head>
-<body id="oe" class="openerp">
- <div id="qunit"></div>
- <div id="qunit-fixture"></div>
-</body>
-<!-- TODO xmo please use the regular template even for testing -->
-% for module, jss, tests, templates in files:
- % for js in jss:
- % if not js.endswith('/apps.js'):
- <script src="${to_path(module, js)}"></script>
- % endif
- % endfor
- % if tests or templates:
- <script>
- openerp.testing.current_module = "${module}";
- % for template in templates:
- openerp.testing.add_template("${to_path(module, template)}");
- % endfor
- </script>
- % endif
- % if tests:
- % for test in tests:
- <script type="text/javascript" src="${to_path(module, test)}"></script>
- % endfor
- % endif
-% endfor
-</html>
-""", default_filters=['h'])
-
-class TestRunnerController(http.Controller):
-
- @http.route('/web/tests', type='http', auth="none")
- def index(self, mod=None, **kwargs):
- ms = module.get_modules()
- manifests = dict(
- (name, desc)
- for name, desc in zip(ms, map(self.load_manifest, ms))
- if desc # remove not-actually-openerp-modules
- )
-
- if not mod:
- return NOMODULE_TEMPLATE.render(modules=(
- (manifest['name'], name)
- for name, manifest in manifests.iteritems()
- if any(testfile.endswith('.js')
- for testfile in manifest['test'])
- ))
- sorted_mods = module_topological_sort(dict(
- (name, manifest.get('depends', []))
- for name, manifest in manifests.iteritems()
- ))
- # to_load and to_test should be zippable lists of the same length.
- # A falsy value in to_test indicate nothing to test at that index (just
- # load the corresponding part of to_load)
- to_test = sorted_mods
- if mod != '*':
- if mod not in manifests:
- return request.not_found(NOTFOUND.render(module=mod))
- idx = sorted_mods.index(mod)
- to_test = [None] * len(sorted_mods)
- to_test[idx] = mod
-
- tests_candicates = [
- filter(lambda path: path.endswith('.js'),
- manifests[mod]['test'] if mod else [])
- for mod in to_test]
- # remove trailing test-less modules
- tests = reversed(list(
- itertools.dropwhile(
- operator.not_,
- reversed(tests_candicates))))
-
- files = [
- (mod, manifests[mod]['js'], tests, manifests[mod]['qweb'])
- for mod, tests in itertools.izip(sorted_mods, tests)
- ]
-
- return TESTING.render(files=files, dependencies=json.dumps(
- [name for name in sorted_mods
- if module.get_module_resource(name, 'static')
- if manifests[name]['js']]))
-
- def load_manifest(self, name):
- manifest = module.load_information_from_description_file(name)
- if manifest:
- path = module.get_module_path(name)
- manifest['js'] = list(
- self.expand_patterns(path, manifest.get('js', [])))
- manifest['test'] = list(
- self.expand_patterns(path, manifest.get('test', [])))
- manifest['qweb'] = list(
- self.expand_patterns(path, manifest.get('qweb', [])))
- return manifest
-
- def expand_patterns(self, root, patterns):
- for pattern in patterns:
- normalized_pattern = os.path.normpath(os.path.join(root, pattern))
- for path in glob.glob(normalized_pattern):
- # replace OS path separators (from join & normpath) by URI ones
- yield path[len(root):].replace(os.path.sep, '/')
-
diff --git a/addons/web/i18n/ar.po b/addons/web/i18n/ar.po
index 4b2083866bc..5500e9103f1 100644
--- a/addons/web/i18n/ar.po
+++ b/addons/web/i18n/ar.po
@@ -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: 2014-04-18 06:38+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/bg.po b/addons/web/i18n/bg.po
index 4877f186483..8cfebbfe61f 100644
--- a/addons/web/i18n/bg.po
+++ b/addons/web/i18n/bg.po
@@ -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: 2014-04-18 06:38+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/bn.po b/addons/web/i18n/bn.po
index a2e1317df9f..b2aa1b04340 100644
--- a/addons/web/i18n/bn.po
+++ b/addons/web/i18n/bn.po
@@ -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: 2014-04-18 06:38+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/bs.po b/addons/web/i18n/bs.po
index 3cfb2e85bdf..b35ac75513d 100644
--- a/addons/web/i18n/bs.po
+++ b/addons/web/i18n/bs.po
@@ -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: 2014-04-18 06:38+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/ca.po b/addons/web/i18n/ca.po
index 0e1fe377fa3..5a772e2ca2f 100644
--- a/addons/web/i18n/ca.po
+++ b/addons/web/i18n/ca.po
@@ -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: 2014-04-18 06:38+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/cs.po b/addons/web/i18n/cs.po
index 4dac86f7964..acd387fa39a 100644
--- a/addons/web/i18n/cs.po
+++ b/addons/web/i18n/cs.po
@@ -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: 2014-04-18 06:38+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
"X-Poedit-Language: Czech\n"
diff --git a/addons/web/i18n/da.po b/addons/web/i18n/da.po
index 758400611c0..8bf7a9f5086 100644
--- a/addons/web/i18n/da.po
+++ b/addons/web/i18n/da.po
@@ -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: 2014-04-18 06:38+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/de.po b/addons/web/i18n/de.po
index b3aa01c56fd..cb5f6fa9e6e 100644
--- a/addons/web/i18n/de.po
+++ b/addons/web/i18n/de.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/en_AU.po b/addons/web/i18n/en_AU.po
index 01509d52bbf..f92d5c282b3 100644
--- a/addons/web/i18n/en_AU.po
+++ b/addons/web/i18n/en_AU.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/en_GB.po b/addons/web/i18n/en_GB.po
index bd0a20a5f7a..88f6a33907f 100644
--- a/addons/web/i18n/en_GB.po
+++ b/addons/web/i18n/en_GB.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/es.po b/addons/web/i18n/es.po
index 2b9303e87a4..52e1f5dbadf 100644
--- a/addons/web/i18n/es.po
+++ b/addons/web/i18n/es.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/es_CL.po b/addons/web/i18n/es_CL.po
index bc342c8bcd0..d54195b2ffe 100644
--- a/addons/web/i18n/es_CL.po
+++ b/addons/web/i18n/es_CL.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/es_CR.po b/addons/web/i18n/es_CR.po
index 0ef3e7a0975..862531a7b68 100644
--- a/addons/web/i18n/es_CR.po
+++ b/addons/web/i18n/es_CR.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
"Language: es\n"
diff --git a/addons/web/i18n/es_DO.po b/addons/web/i18n/es_DO.po
index 86d6f43f20d..96e28c1ae9d 100644
--- a/addons/web/i18n/es_DO.po
+++ b/addons/web/i18n/es_DO.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/es_EC.po b/addons/web/i18n/es_EC.po
index c4fa890182f..e634ab5c076 100644
--- a/addons/web/i18n/es_EC.po
+++ b/addons/web/i18n/es_EC.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:54+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/es_MX.po b/addons/web/i18n/es_MX.po
index 84298e0bce1..ec8bf391953 100644
--- a/addons/web/i18n/es_MX.po
+++ b/addons/web/i18n/es_MX.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:54+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/es_PE.po b/addons/web/i18n/es_PE.po
index 3ec2d60e5bb..71d37a83395 100644
--- a/addons/web/i18n/es_PE.po
+++ b/addons/web/i18n/es_PE.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:54+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/et.po b/addons/web/i18n/et.po
index b55354266a8..6efd5e392d3 100644
--- a/addons/web/i18n/et.po
+++ b/addons/web/i18n/et.po
@@ -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: 2014-04-18 06:38+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/eu.po b/addons/web/i18n/eu.po
index 4e059ff6b09..b29f74e3b76 100644
--- a/addons/web/i18n/eu.po
+++ b/addons/web/i18n/eu.po
@@ -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: 2014-04-18 06:38+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/fa.po b/addons/web/i18n/fa.po
index 309ac285423..c190534f18c 100644
--- a/addons/web/i18n/fa.po
+++ b/addons/web/i18n/fa.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/fi.po b/addons/web/i18n/fi.po
index 821429ebae1..827eb9edac0 100644
--- a/addons/web/i18n/fi.po
+++ b/addons/web/i18n/fi.po
@@ -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: 2014-04-18 06:38+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/fr.po b/addons/web/i18n/fr.po
index d4efe82bbcf..5cc8a8785a1 100644
--- a/addons/web/i18n/fr.po
+++ b/addons/web/i18n/fr.po
@@ -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: 2014-04-18 06:38+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/fr_CA.po b/addons/web/i18n/fr_CA.po
index 840dfb3b07e..5860eea177e 100644
--- a/addons/web/i18n/fr_CA.po
+++ b/addons/web/i18n/fr_CA.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/gl.po b/addons/web/i18n/gl.po
index 07f34b44994..108125b647c 100644
--- a/addons/web/i18n/gl.po
+++ b/addons/web/i18n/gl.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/gu.po b/addons/web/i18n/gu.po
index dbcbf6bab93..5e064c2f121 100644
--- a/addons/web/i18n/gu.po
+++ b/addons/web/i18n/gu.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/he.po b/addons/web/i18n/he.po
index b9f64d0585c..6982efa679a 100644
--- a/addons/web/i18n/he.po
+++ b/addons/web/i18n/he.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/hi.po b/addons/web/i18n/hi.po
index 0db5502ce67..b8d43b0547c 100644
--- a/addons/web/i18n/hi.po
+++ b/addons/web/i18n/hi.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/hr.po b/addons/web/i18n/hr.po
index 375bd8d6a12..d47cefc95d3 100644
--- a/addons/web/i18n/hr.po
+++ b/addons/web/i18n/hr.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/hu.po b/addons/web/i18n/hu.po
index e710ce1d9d9..f1a92ab0186 100644
--- a/addons/web/i18n/hu.po
+++ b/addons/web/i18n/hu.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/id.po b/addons/web/i18n/id.po
index 86a783057cf..ecc7f580c42 100644
--- a/addons/web/i18n/id.po
+++ b/addons/web/i18n/id.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/it.po b/addons/web/i18n/it.po
index 124054cea6b..e37592a6b89 100644
--- a/addons/web/i18n/it.po
+++ b/addons/web/i18n/it.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/ja.po b/addons/web/i18n/ja.po
index 7c80f9b942a..81fa526f501 100644
--- a/addons/web/i18n/ja.po
+++ b/addons/web/i18n/ja.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/ka.po b/addons/web/i18n/ka.po
index b13eefea7f6..bbfbdad689e 100644
--- a/addons/web/i18n/ka.po
+++ b/addons/web/i18n/ka.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/ko.po b/addons/web/i18n/ko.po
index 7788c990963..c2445599c55 100644
--- a/addons/web/i18n/ko.po
+++ b/addons/web/i18n/ko.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/lo.po b/addons/web/i18n/lo.po
index 4559a6b28d5..8f4bf33bcd1 100644
--- a/addons/web/i18n/lo.po
+++ b/addons/web/i18n/lo.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/lt.po b/addons/web/i18n/lt.po
index afbd9a9e1d6..384a22b5d7a 100644
--- a/addons/web/i18n/lt.po
+++ b/addons/web/i18n/lt.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/lv.po b/addons/web/i18n/lv.po
index e32d8f57708..a1358f54205 100644
--- a/addons/web/i18n/lv.po
+++ b/addons/web/i18n/lv.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/mk.po b/addons/web/i18n/mk.po
index 1faa1f5a07c..70d9144d92f 100644
--- a/addons/web/i18n/mk.po
+++ b/addons/web/i18n/mk.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/mn.po b/addons/web/i18n/mn.po
index f9853570da9..09694dae1c4 100644
--- a/addons/web/i18n/mn.po
+++ b/addons/web/i18n/mn.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/nb.po b/addons/web/i18n/nb.po
index 9a2545585b2..7ff320014f4 100644
--- a/addons/web/i18n/nb.po
+++ b/addons/web/i18n/nb.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/nl.po b/addons/web/i18n/nl.po
index c55799ac9cb..3f1e2d7c5ac 100644
--- a/addons/web/i18n/nl.po
+++ b/addons/web/i18n/nl.po
@@ -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: 2014-04-18 06:38+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/nl_BE.po b/addons/web/i18n/nl_BE.po
index dc52a1a7d67..f6dc9d6f34f 100644
--- a/addons/web/i18n/nl_BE.po
+++ b/addons/web/i18n/nl_BE.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/pl.po b/addons/web/i18n/pl.po
index 8ee646f2dc7..df2dd4def17 100644
--- a/addons/web/i18n/pl.po
+++ b/addons/web/i18n/pl.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/pt.po b/addons/web/i18n/pt.po
index 6d781d7454e..a1716f3b7b0 100644
--- a/addons/web/i18n/pt.po
+++ b/addons/web/i18n/pt.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/pt_BR.po b/addons/web/i18n/pt_BR.po
index 1e0d6547806..c9e6cfab751 100644
--- a/addons/web/i18n/pt_BR.po
+++ b/addons/web/i18n/pt_BR.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/ro.po b/addons/web/i18n/ro.po
index 9b5aa45f1ca..2285aa1ec28 100644
--- a/addons/web/i18n/ro.po
+++ b/addons/web/i18n/ro.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/ru.po b/addons/web/i18n/ru.po
index 7b6ad85b2d3..7ab615d6312 100644
--- a/addons/web/i18n/ru.po
+++ b/addons/web/i18n/ru.po
@@ -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: 2014-04-18 06:39+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/sk.po b/addons/web/i18n/sk.po
index e191a83103e..e1ad376ba14 100644
--- a/addons/web/i18n/sk.po
+++ b/addons/web/i18n/sk.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/sl.po b/addons/web/i18n/sl.po
index e0d7ae00ef5..6c7dc176481 100644
--- a/addons/web/i18n/sl.po
+++ b/addons/web/i18n/sl.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/sq.po b/addons/web/i18n/sq.po
index 3309d32e981..1e338e967a5 100644
--- a/addons/web/i18n/sq.po
+++ b/addons/web/i18n/sq.po
@@ -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: 2014-04-18 06:38+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/sr@latin.po b/addons/web/i18n/sr@latin.po
index 733c2defc8f..88d941461c7 100644
--- a/addons/web/i18n/sr@latin.po
+++ b/addons/web/i18n/sr@latin.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:54+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/sv.po b/addons/web/i18n/sv.po
index 561fb58b765..9847bdf1ffe 100644
--- a/addons/web/i18n/sv.po
+++ b/addons/web/i18n/sv.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/th.po b/addons/web/i18n/th.po
index 9ea50242c2b..d61e828b1a7 100644
--- a/addons/web/i18n/th.po
+++ b/addons/web/i18n/th.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/tr.po b/addons/web/i18n/tr.po
index dff19630d9e..4decaa7f356 100644
--- a/addons/web/i18n/tr.po
+++ b/addons/web/i18n/tr.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/uk.po b/addons/web/i18n/uk.po
index 547d9eb3b72..92826b245bc 100644
--- a/addons/web/i18n/uk.po
+++ b/addons/web/i18n/uk.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/vi.po b/addons/web/i18n/vi.po
index a6fadf0ae53..6eef5cbad3c 100644
--- a/addons/web/i18n/vi.po
+++ b/addons/web/i18n/vi.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/zh_CN.po b/addons/web/i18n/zh_CN.po
index 2f6ded3b9b0..9bfc9ed283a 100644
--- a/addons/web/i18n/zh_CN.po
+++ b/addons/web/i18n/zh_CN.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:54+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/i18n/zh_TW.po b/addons/web/i18n/zh_TW.po
index 06ab836e14f..80de08053cb 100644
--- a/addons/web/i18n/zh_TW.po
+++ b/addons/web/i18n/zh_TW.po
@@ -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: 2014-04-18 06:40+0000\n"
+"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n"
"X-Generator: Launchpad (build 16985)\n"
#. module: web
diff --git a/addons/web/static/lib/fontawesome/css/font-awesome.css b/addons/web/static/lib/fontawesome/css/font-awesome.css
index 7fa0e6f467b..35da66e7484 100644
--- a/addons/web/static/lib/fontawesome/css/font-awesome.css
+++ b/addons/web/static/lib/fontawesome/css/font-awesome.css
@@ -207,6 +207,9 @@
.fa-star:before {
content: "\f005";
}
+. fa-tasks:before {
+ content: "\f0ae";
+}
.fa-star-o:before {
content: "\f006";
}
@@ -237,6 +240,12 @@
.fa-search-minus:before {
content: "\f010";
}
+.fa-adn:before {
+ content: "\f170";
+}
+. fa-times:before {
+ content: "\f00d";
+}
.fa-power-off:before {
content: "\f011";
}
@@ -308,6 +317,9 @@
.fa-qrcode:before {
content: "\f029";
}
+.fa-calendar:before {
+ content: "\f073";
+}
.fa-barcode:before {
content: "\f02a";
}
@@ -759,6 +771,9 @@
.fa-pinterest:before {
content: "\f0d2";
}
+.fa-pencil-square-o:before {
+ content: "\f044";
+}
.fa-pinterest-square:before {
content: "\f0d3";
}
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css
index 916e4ffe9ba..8534927def1 100644
--- a/addons/web/static/src/css/base.css
+++ b/addons/web/static/src/css/base.css
@@ -1,4 +1,4 @@
-@charset "utf-8";
+@charset "UTF-8";
@font-face {
font-family: "mnmliconsRegular";
src: url("/web/static/src/font/mnmliconsv21-webfont.eot") format("eot");
@@ -79,7 +79,7 @@
vertical-align: top;
}
.openerp .oe_title {
- width: 50%;
+ width: 38%;
float: left;
}
.openerp .oe_title:after {
@@ -314,56 +314,58 @@
.openerp .oe_form_dirty button.oe_highlight_on_dirty:hover {
background: #ed6f6a;
}
-.openerp .oe_button_box {
- width: 400px;
- text-align: left;
-}
-.openerp .oe_button_box .oe_stat_button:hover {
- background: #7c7bad;
- color: white;
-}
-.openerp .oe_button_box .oe_stat_button:hover .fa {
- color: white;
-}
-.openerp .oe_button_box .oe_stat_button {
+.openerp .oe_stat_button {
font-weight: normal;
- display: inline-table;
- width: 33% !important;
- height: 42px;
+ width: 132px !important;
+ height: 40px;
+ color: #666666;
margin: 0px -1px -1px 0px;
padding: 0;
- color: #666666;
border: 1px solid #dddddd;
border-radius: 0;
box-shadow: none;
background: white;
}
-.openerp .oe_button_box .oe_stat_button > div {
+.openerp .oe_stat_button > div {
display: table-cell;
vertical-align: middle;
text-align: left;
padding: 0;
line-height: 120%;
}
-.openerp .oe_button_box .oe_stat_button .stat_button_icon {
+.openerp .oe_stat_button .stat_button_icon {
color: #7c7bad;
font-size: 24px;
padding: 0px 3px;
width: 37px;
text-align: center;
}
-.openerp .oe_button_box .oe_stat_button .oe_form_field_percent_pie {
+.openerp .oe_stat_button .oe_form_field_percent_pie {
width: 42px;
}
-.openerp .oe_button_box .oe_stat_button .oe_form_field_bar_chart {
+.openerp .oe_stat_button .oe_form_field_bar_chart {
width: 42px;
}
-.openerp .oe_button_box .oe_stat_button svg {
+.openerp .oe_stat_button svg {
width: 38px;
height: 38px;
display: inline;
vertical-align: middle;
}
+.openerp .oe_stat_button:hover {
+ background: #7c7bad;
+ color: white;
+}
+.openerp .oe_stat_button:hover .fa {
+ color: white;
+}
+.openerp .oe_button_box {
+ width: 400px;
+ text-align: right;
+}
+.openerp .oe_button_box .oe_stat_button {
+ display: inline-table;
+}
.openerp .oe_avatar > img {
max-height: 90px;
max-width: 90px;
@@ -720,7 +722,7 @@
border-bottom-left-radius: 8px;
}
.openerp .oe_notification {
- z-index: 1050;
+ z-index: 1500;
}
.openerp .oe_webclient_timezone_notification a {
color: white;
@@ -2742,13 +2744,15 @@
padding: 3px 6px;
white-space: pre-line;
}
-.openerp .oe_list_content > tbody > tr > td > button.btn_img, .openerp .oe_list_content > tbody > tr > th > button.btn_img {
+.openerp .oe_list_content > tbody > tr > td > button, .openerp .oe_list_content > tbody > tr > th > button {
border: none;
background: transparent;
padding: 0;
- -moz-box-shadow: none;
- -webkit-box-shadow: none;
- box-shadow: none;
+}
+.openerp .oe_list_content > tbody > tr > td > button.btn_txt, .openerp .oe_list_content > tbody > tr > th > button.btn_txt {
+ border: 1px solid rgba(0, 0, 0, 0.4);
+ background: #e3e3e3;
+ padding: 3px 12px;
}
.openerp .oe_list_content > tbody > tr > td.oe_list_checkbox:first-child, .openerp .oe_list_content > tbody > tr th.oe_list_checkbox:first-child {
width: 17px;
@@ -3293,11 +3297,6 @@ body.oe_single_form .oe_single_form_container {
overflow: hidden !important;
}
}
-.ui-icon {
- width: 18px;
- height: 18px;
-}
-
.tooltip {
padding: 0;
margin: 0;
@@ -3307,8 +3306,6 @@ body.oe_single_form .oe_single_form_container {
background: white;
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
background-color: transparent;
- /*We need a greater z-index in order for tooltip to go over bootstrap modal z-index*/
- z-index: 1500;
}
.tooltip .tooltip-inner {
text-align: left !important;
@@ -3345,6 +3342,12 @@ body.oe_single_form .oe_single_form_container {
.tooltip .tooltip-inner .oe_tooltip_message {
max-width: 310px;
}
+
+.ui-icon {
+ width: 18px;
+ height: 18px;
+}
+
.modal .modal-header button.close {
border: none;
background: none;
@@ -3355,12 +3358,17 @@ body.oe_single_form .oe_single_form_container {
.modal .modal-footer {
text-align: left;
}
-.modal .oe_act_window.modal-body{
+.modal .oe_button {
+ margin: 0 4px 0 0;
+}
+.modal .oe_act_window.modal-body {
padding: 0;
}
-.modal .oe_button{
- margin: 0 4px 0 0;
+
+.ui-datepicker {
+ z-index: 1500 !important;
}
+
input[type="radio"], input[type="checkbox"] {
margin-right: 4px;
margin-left: 4px;
diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass
index d83b09bc897..f1a92f44288 100644
--- a/addons/web/static/src/css/base.sass
+++ b/addons/web/static/src/css/base.sass
@@ -190,7 +190,7 @@ $sheet-padding: 16px
td
vertical-align: top
.oe_title
- width: 50%
+ width: 38%
float: left
.oe_title:after
content: "."
@@ -330,47 +330,48 @@ $sheet-padding: 16px
@include box-shadow(none)
&:hover
background: #ED6F6A
+ .oe_stat_button
+ font-weight: normal
+ width: 132px !important
+ height: 40px
+ color: #666
+ margin: 0px -1px -1px 0px
+ padding: 0
+ border: 1px solid #dddddd
+ border-radius: 0
+ box-shadow: none
+ background: white
+ > div
+ display: table-cell
+ vertical-align: middle
+ text-align: left
+ padding: 0
+ line-height: 120%
+ .stat_button_icon
+ color: #7C7BAD
+ font-size: 24px
+ padding: 0px 3px
+ width: 37px
+ text-align: center
+ .oe_form_field_percent_pie
+ width: 42px
+ .oe_form_field_bar_chart
+ width: 42px
+ svg
+ width: 38px
+ height: 38px
+ display: inline
+ vertical-align: middle
+ .oe_stat_button:hover
+ background: #7c7bad
+ color: white
+ .fa
+ color: white
.oe_button_box
width: 400px
- text-align: left
- .oe_stat_button:hover
- background: #7c7bad
- color: white
- .fa
- color: white
+ text-align: right
.oe_stat_button
- font-weight: normal
display: inline-table
- width: 33% !important
- height: 42px
- margin: 0px -1px -1px 0px
- padding: 0
- color: #666
- border: 1px solid #dddddd
- border-radius: 0
- box-shadow: none
- background: white
- > div
- display: table-cell
- vertical-align: middle
- text-align: left
- padding: 0
- line-height: 120%
- .stat_button_icon
- color: #7C7BAD
- font-size: 24px
- padding: 0px 3px
- width: 37px
- text-align: center
- .oe_form_field_percent_pie
- width: 42px
- .oe_form_field_bar_chart
- width: 42px
- svg
- width: 38px
- height: 38px
- display: inline
- vertical-align: middle
.oe_avatar
> img
max-height: 90px
@@ -639,7 +640,8 @@ $sheet-padding: 16px
// }}}
// Notifications {{{
.oe_notification
- z-index: 1050
+ z-index: 1500
+
.oe_webclient_timezone_notification
a
color: white
@@ -2220,11 +2222,14 @@ $sheet-padding: 16px
padding: 3px 6px
white-space: pre-line
> td, > th
- > button.btn_img
+ > button
border: none
background: transparent
padding: 0
- @include box-shadow(none)
+ > button.btn_txt
+ border: 1px solid rgba(0,0,0,0.4)
+ background: #e3e3e3
+ padding: 3px 12px
> td.oe_list_checkbox:first-child, th.oe_list_checkbox:first-child
width: 17px
&:after
@@ -2736,6 +2741,9 @@ body.oe_single_form
.oe_act_window.modal-body
padding: 0
+.ui-datepicker
+ z-index: 1500 !important
+
input[type="radio"], input[type="checkbox"]
margin-right: 4px
margin-left: 4px
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js
index e1b654aa3f7..0aa46ebb104 100644
--- a/addons/web/static/src/js/chrome.js
+++ b/addons/web/static/src/js/chrome.js
@@ -1460,7 +1460,7 @@ instance.web.embed = function (origin, dbname, login, key, action, options) {
$('head').append($('<link>', {
'rel': 'stylesheet',
'type': 'text/css',
- 'href': origin +'/web/webclient/css'
+ 'href': origin +'/web/css/web.assets_webclient'
}));
var currentScript = document.currentScript;
if (!currentScript) {
diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js
index a4bcd1922de..c64da7e5810 100644
--- a/addons/web/static/src/js/core.js
+++ b/addons/web/static/src/js/core.js
@@ -232,7 +232,7 @@ instance.web.Session.include( /** @lends instance.web.Session# */{
var self = this;
return this.session_reload().then(function(result) {
var modules = instance._modules.join(',');
- var deferred = self.rpc('/web/webclient/qweblist', {mods: modules}).then(self.load_qweb.bind(self));
+ var deferred = self.load_qweb(modules);
if(self.session_is_valid()) {
return deferred.then(function() { return self.load_modules(); });
}
@@ -318,7 +318,7 @@ instance.web.Session.include( /** @lends instance.web.Session# */{
loaded = $.when(
loaded,
self.rpc('/web/webclient/csslist', {mods: to_load}).done(self.load_css.bind(self)),
- self.rpc('/web/webclient/qweblist', {mods: to_load}).then(self.load_qweb.bind(self)),
+ self.load_qweb(to_load),
self.rpc('/web/webclient/jslist', {mods: to_load}).done(function(files) {
file_list = file_list.concat(files);
})
@@ -375,14 +375,12 @@ instance.web.Session.include( /** @lends instance.web.Session# */{
}
return d;
},
- load_qweb: function(files) {
+ load_qweb: function(mods) {
var self = this;
- _.each(files, function(file) {
- self.qweb_mutex.exec(function() {
- return self.rpc('/web/proxy/load', {path: file}).then(function(xml) {
- if (!xml) { return; }
- instance.web.qweb.add_template(_.str.trim(xml));
- });
+ self.qweb_mutex.exec(function() {
+ return self.rpc('/web/proxy/load', {path: '/web/webclient/qweb?mods=' + mods}).then(function(xml) {
+ if (!xml) { return; }
+ instance.web.qweb.add_template(_.str.trim(xml));
});
});
return self.qweb_mutex.def;
@@ -460,14 +458,11 @@ instance.web.Session.include( /** @lends instance.web.Session# */{
.appendTo(document.body)
.load(function () {
try {
- if (options.error) {
- if (!this.contentDocument.body.childNodes[1]) {
- options.error(this.contentDocument.body.childNodes);
- }
- else {
- options.error(JSON.parse(this.contentDocument.body.childNodes[1].textContent));
- }
- }
+ if (options.error) {
+ var body = this.contentDocument.body;
+ var node = body.childNodes[1] || body.childNodes[0];
+ options.error(JSON.parse(node.textContent));
+ }
} finally {
complete();
}
diff --git a/addons/web/static/src/js/data_export.js b/addons/web/static/src/js/data_export.js
index 2de933f45e8..2f7ff81d089 100644
--- a/addons/web/static/src/js/data_export.js
+++ b/addons/web/static/src/js/data_export.js
@@ -32,7 +32,7 @@ instance.web.DataExport = instance.web.Dialog.extend({
var self = this;
var options = {
buttons: [
- {text: _t("Close"), click: function () { self.close(); }},
+ {text: _t("Close"), click: function () { self.$el.parents('.modal').modal('hide'); }},
{text: _t("Export To File"), click: function () { self.on_click_export_data(); }}
],
close: function () { self.close();}
diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js
index 04bb1a61d99..832faa4ca62 100644
--- a/addons/web/static/src/js/search.js
+++ b/addons/web/static/src/js/search.js
@@ -29,8 +29,8 @@ my.Facet = B.Model.extend({
B.Model.prototype.initialize.apply(this, arguments);
this.values = new my.FacetValues(values || []);
- this.values.on('add remove change reset', function () {
- this.trigger('change', this);
+ this.values.on('add remove change reset', function (_, options) {
+ this.trigger('change', this, options);
}, this);
},
get: function (key) {
@@ -399,7 +399,8 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
this.setup_global_completion();
this.query = new my.SearchQuery()
.on('add change reset remove', this.proxy('do_search'))
- .on('add change reset remove', this.proxy('renderFacets'));
+ .on('change', this.proxy('renderChangedFacets'))
+ .on('add reset remove', this.proxy('renderFacets'));
if (this.options.hidden) {
this.$el.hide();
@@ -578,14 +579,20 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
.trigger('blur');
},
/**
- *
- * @param {openerp.web.search.SearchQuery | openerp.web.search.Facet} _1
- * @param {openerp.web.search.Facet} [_2]
+ * Call the renderFacets method with the correct arguments.
+ * This is due to the fact that change events are called with two arguments
+ * (model, options) while add, reset and remove events are called with
+ * (collection, model, options) as arguments
+ */
+ renderChangedFacets: function (model, options) {
+ this.renderFacets(undefined, model, options);
+ },
+ /**
+ * @param {openerp.web.search.SearchQuery | undefined} Undefined if event is change
+ * @param {openerp.web.search.Facet}
* @param {Object} [options]
*/
- renderFacets: function (_1, _2, options) {
- // _1: model if event=change, otherwise collection
- // _2: undefined if event=change, otherwise model
+ renderFacets: function (collection, model, options) {
var self = this;
var started = [];
var $e = this.$('div.oe_searchview_facets');
@@ -610,6 +617,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
});
$.when.apply(null, started).then(function () {
+ if (options && options.focus_input === false) return;
var input_to_focus;
// options.at: facet inserted at given index, focus next input
// otherwise just focus last input
@@ -618,7 +626,6 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
} else {
input_to_focus = self.input_subviews[(options.at + 1) * 2];
}
-
input_to_focus.$el.focus();
});
},
@@ -1602,8 +1609,11 @@ instance.web.search.ManyToOneField = instance.web.search.CharField.extend({
return facetValue.get('label');
},
make_domain: function (name, operator, facetValue) {
- if (operator === this.default_operator) {
+ switch(operator){
+ case this.default_operator:
return [[name, '=', facetValue.get('value')]];
+ case 'child_of':
+ return [[name, 'child_of', facetValue.get('value')]];
}
return this._super(name, operator, facetValue);
},
diff --git a/addons/web/static/src/js/testing.js b/addons/web/static/src/js/testing.js
index 1f1c718ad5f..5e9483addc1 100644
--- a/addons/web/static/src/js/testing.js
+++ b/addons/web/static/src/js/testing.js
@@ -48,15 +48,6 @@ openerp.testing = {};
testing.dependencies = window['oe_all_dependencies'] || [];
testing.current_module = null;
- testing.templates = { };
- testing.add_template = function (name) {
- var xhr = QWeb2.Engine.prototype.get_xhr();
- xhr.open('GET', name, false);
- xhr.send(null);
- (testing.templates[testing.current_module] =
- testing.templates[testing.current_module] || [])
- .push(xhr.responseXML);
- };
/**
* Function which does not do anything
*/
@@ -206,7 +197,7 @@ openerp.testing = {};
teardown: testing.noop
});
- QUnit.module(testing.current_module + '.' + name, {_oe: options});
+ QUnit.module(name, {_oe: options});
body(testing['case']);
};
testing['case'] = function (name, options, callback) {
@@ -244,18 +235,6 @@ openerp.testing = {};
expect(opts.asserts);
}
- if (opts.templates) {
- for(var i=0; i<module_deps.length; ++i) {
- var dep = module_deps[i];
- var templates = testing.templates[dep];
- if (_.isEmpty(templates)) { continue; }
-
- for (var j=0; j < templates.length; ++j) {
- instance.web.qweb.add_template(templates[j]);
- }
- }
- }
-
var $fixture = $('#qunit-fixture');
var mock, async = false;
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index 247fd2d2a1a..2c68a23dbf9 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -1940,7 +1940,7 @@ instance.web.form.WidgetButton = instance.web.form.FormWidget.extend({
init: function(field_manager, node) {
node.attrs.type = node.attrs['data-button-type'];
this.is_stat_button = /\boe_stat_button\b/.test(node.attrs['class']);
- this.icon = node.attrs.icon && "<span class=\"fa " + node.attrs.icon + " fa-fw\"></span>";
+ this.icon_class = node.attrs.icon && "stat_button_icon fa " + node.attrs.icon + " fa-fw";
this._super(field_manager, node);
this.force_disabled = false;
this.string = (this.node.attrs.string || '').replace(/_/g, '');
@@ -3356,13 +3356,16 @@ instance.web.form.CompletionFieldMixin = {
instance.web.form.M2ODialog = instance.web.Dialog.extend({
template: "M2ODialog",
init: function(parent) {
+ this.name = parent.string;
this._super(parent, {
- title: _.str.sprintf(_t("Add %s"), parent.string),
+ title: _.str.sprintf(_t("Create a %s"), parent.string),
size: 'medium',
});
},
start: function() {
var self = this;
+ var text = _.str.sprintf(_t("You are creating a new %s, are you sure it does not exist yet?"), self.name);
+ this.$("p").text( text );
this.$buttons.html(QWeb.render("M2ODialog.buttons"));
this.$("input").val(this.getParent().last_query);
this.$buttons.find(".oe_form_m2o_qc_button").click(function(){
@@ -3486,7 +3489,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
self.display_value_backup = {};
self.render_value();
self.focus();
- self.view.do_onchange(self);
+ self.trigger('changed_value');
});
});
});
@@ -3621,6 +3624,8 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
minLength: 0,
delay: 250
});
+ // set position for list of suggestions box
+ this.$input.autocomplete( "option", "position", { my : "left top", at: "left bottom" } );
this.$input.autocomplete("widget").openerpClass();
// used to correct a bug when selecting an element by pushing 'enter' in an editable list
this.$input.keyup(function(e) {
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 24c5ba625b0..18a55656df2 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -40,7 +40,7 @@
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 class="modal-title"><t t-raw="title"/></h3>
</div>
- <div class="modal-body">
+ <div class="modal-body" style="overflow-y: auto;">
</div>
</div>
</div>
@@ -800,12 +800,11 @@
</t>
<button t-name="ListView.row.text_button" type="button"
t-att-title="widget.string" t-att-disabled="disabled || undefined"
- t-att-class="disabled ? 'oe_list_button_disabled btn' : 'btn'">
- <t t-esc="widget.string"/>
-</button>
+ t-att-class="disabled ? 'oe_list_button_disabled btn_txt oe_link' : 'btn_txt oe_link'"
+ ><t t-esc="widget.string"/></button>
<button t-name="ListView.row.button" type="button"
t-att-title="widget.string" t-att-disabled="disabled || undefined"
- t-att-class="disabled ? 'oe_list_button_disabled btn_img' : 'btn_img'"
+ t-att-class="disabled ? 'oe_list_button_disabled' : ''"
><img t-attf-src="#{prefix}/web/static/src/img/icons/#{widget.icon}.png"
t-att-alt="widget.string"/></button>
<t t-extend="ListView.row">
@@ -1409,7 +1408,7 @@
t-att-autofocus="widget.node.attrs.autofocus"
t-att-accesskey="widget.node.attrs.accesskey">
<img t-if="!widget.is_stat_button and widget.node.attrs.icon " t-att-src="_s + widget.node.attrs.icon" width="16" height="16"/>
- <div t-if="widget.is_stat_button and widget.icon" class="stat_button_icon"><t t-raw="widget.icon"/></div>
+ <div t-if="widget.is_stat_button and widget.icon_class" t-att-class="widget.icon_class"></div>
<span t-if="widget.string and !widget.is_stat_button"><t t-esc="widget.string"/></span>
<div t-if="widget.string and widget.is_stat_button"><t t-esc="widget.string"/></div>
</button>
@@ -1948,13 +1947,14 @@
</t>
<t t-name="M2ODialog">
<div>
+ <p class="oe_grey"/>
Name: <input class="oe_form_m2o_input_name" type="text"/>
</div>
</t>
<t t-name="M2ODialog.buttons">
- <button class="oe_form_m2o_qc_button oe_button oe_highlight">Quick Add</button>
- <button class="oe_form_m2o_sc_button oe_button">Add All Info...</button>
- <button class="oe_form_m2o_cancel_button oe_button">Cancel</button>
+ <button class="oe_form_m2o_qc_button oe_button oe_highlight">Create</button>
+ <button class="oe_form_m2o_sc_button oe_button">Create and edit</button> or
+ <button class="oe_form_m2o_cancel_button oe_button oe_link"><span>Cancel</span></button>
</t>
<t t-name="FieldMonetary" t-extend="FieldChar">
<t t-jquery="t:first" t-operation="before">
@@ -1985,6 +1985,5 @@
<a href="javascript:void(0)"><t t-esc="text"/></a>
</t>
<t t-name="StatInfo">
- <strong><t t-esc="value"/></strong>
- <t t-esc="text"/></t>
+ <strong><t t-esc="value"/></strong><br/><t t-esc="text"/></t>
</templates>
diff --git a/addons/web/static/test/list-editable.js b/addons/web/static/test/list-editable.js
index e73249549b8..ef2d608bc5d 100644
--- a/addons/web/static/test/list-editable.js
+++ b/addons/web/static/test/list-editable.js
@@ -361,8 +361,8 @@ openerp.testing.section('list.edition.onwrite', {
strictEqual(
$fix.find('tbody tr:eq(1)').css('color'), 'rgb(255, 0, 0)',
'shoud have color applied');
- strictEqual(
- $fix.find('tbody tr:eq(2)').css('color'), 'rgb(0, 0, 0)',
+ notStrictEqual(
+ $fix.find('tbody tr:eq(2)').css('color'), 'rgb(255, 0, 0)',
'should have default color applied');
});
});
diff --git a/addons/web/tests/__init__.py b/addons/web/tests/__init__.py
index 8c20aed1ce5..beb9e90eb76 100644
--- a/addons/web/tests/__init__.py
+++ b/addons/web/tests/__init__.py
@@ -2,4 +2,3 @@
import test_js
import test_menu
import test_serving_base
-import test_ui
diff --git a/addons/web/tests/qunitsuite/README.rst b/addons/web/tests/qunitsuite/README.rst
deleted file mode 100644
index f1cfb96a508..00000000000
--- a/addons/web/tests/qunitsuite/README.rst
+++ /dev/null
@@ -1,116 +0,0 @@
-QUnitSuite is a ``unittest.TestSuite`` able to run QUnit_ test suites
-within the normal unittest process, through PhantomJS_.
-
-QUnitSuite is built upon `Ben Alman`_'s work of for the interfacing
-between PhantomJS_ and the host/reporting code: the shims and the
-PhantomJS_ configuration files are those of grunt_'s ``qunit`` task.
-
-Why
----
-
-You're a Python shop or developer, you have tools and tests built
-around unittest (or compatible with unittests) and your testing
-pipeline is predicated upon that, you're doing web development of some
-sort these days (as so many are) and you'd like to do some testing of
-your web stuff.
-
-But you don't really want to redo your whole testing stack just for
-that.
-
-QUnitSuite simply grafts QUnit_-based tests, run in PhantomJS_, in
-your existing ``unittest``-based architecture.
-
-What
-----
-
-QUnitSuite currently provides a single object as part of its API:
-``qunitsuite.QUnitSuite(testfile[, timeout])``.
-
-This produces a ``unittest.TestSuite`` suitable for all the usual
-stuff (running it, and giving it to an other test suite which will run
-it, that is).
-
-``testfile`` is the HTML file bootstrapping your qunit tests, as would
-usually be accessed via a browser. It can be either a local
-(``file:``) url, or an HTTP one. As long as a regular browser can open
-and execute it, PhantomJS_ will manage.
-
-``timeout`` is a check passed to the PhantomJS_ runner: if the runner
-produces no information for longer than ``timeout`` milliseconds, the
-run will be cancelled and a test error will be generated. This
-situation usually means either your ``testfile`` is not a qunit test
-file, qunit is not running or qunit's runner was stopped (for an async
-test) and never restarted.
-
-The default value is very conservative, most tests should run
-correctly with lower timeouts (especially if all tests are
-synchronous).
-
-How
----
-
-``unittest``'s autodiscovery protocol does not directly work with test
-suites (it looks for test cases). If you want autodiscovery to work
-correctly, you will have to use the ``load_tests`` protocol::
-
- # in a testing module
- def load_tests(loader, tests, pattern):
- tests.addTest(QUnitSuite(qunit_test_path.html))
- return tests
-
-outside of that specific case, you can use a ``QUnitSuite`` as a
-standard ``TestSuite`` instance, running it, adding it to an other
-suite or passing it to a ``TestRunner``
-
-Complaints and Grievances
--------------------------
-
-Speed
-~~~~~
-
-Starting up a phantomjs instance and running a suite turns out to have
-a rather high overhead, on the order of a second on this machine
-(2.4GHz, 8GB RAM and an SSD).
-
-As each ``QUnitSuite`` currently creates its own phantomjs instance,
-it's probably a good idea to create bigger suites (put many modules &
-tests in the same QUnit html file, which doesn't preclude splitting
-them across multiple js files).
-
-Hacks
-~~~~~
-
-QUnitSuite contains a pretty big hack which may or may not cause
-problem depending on your exact setup: in case of case failure or
-error, ``unittest.TestResult`` formats the error traceback provided
-alongside the test object. This goes through Python's
-traceback-formatting code and there are no hooks there.
-
-One could expect to use a custom ``TestResult``, but for test suites
-the ``TestResult`` instance must be provided by the caller, so there
-is no direct hook onto it.
-
-This leaves three options:
-
-* Create a custom ``TestResult`` class and require that it be the one
- provided to the test suite. This requires altered work flows,
- customization of the test runner and (as far as I know) isn't
- available through Python 2.7's autodiscovery. It's the cleanest
- option but completely fails on practicality.
-
-* Create a custom ``TestResult`` which directly alters the original
- result's ``errors`` and ``failures`` attributes as they're part of
- the testrunner API. This would work but may put custom results in a
- strange state and break e.g. unittest2's ``@failfast``.
-
-* Lastly, monkeypatch the undocumented and implementation detail
- ``_exc_info_to_string`` on the provided ``result``. This is the
- route taken, at least for now.
-
-.. _QUnit: http://qunitjs.com/
-
-.. _PhantomJS: http://phantomjs.org/
-
-.. _Ben Alman: http://benalman.com/
-
-.. _grunt: http://gruntjs.com/
diff --git a/addons/web/tests/qunitsuite/__init__.py b/addons/web/tests/qunitsuite/__init__.py
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/addons/web/tests/qunitsuite/__init__.py
+++ /dev/null
diff --git a/addons/web/tests/qunitsuite/grunt/bootstrap.js b/addons/web/tests/qunitsuite/grunt/bootstrap.js
deleted file mode 100644
index 3d5e38912ca..00000000000
--- a/addons/web/tests/qunitsuite/grunt/bootstrap.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * grunt
- * http://gruntjs.com/
- *
- * Copyright (c) 2012 "Cowboy" Ben Alman
- * Licensed under the MIT license.
- * http://benalman.com/about/license/
- */
-
-/*global phantom:true*/
-
-'use strict';
-
-var fs = require('fs');
-
-// The page .html file to load.
-var url = phantom.args[0];
-// Extra, optionally overridable stuff.
-var options = JSON.parse(phantom.args[1] || {});
-
-// Default options.
-if (!options.timeout) { options.timeout = 5000; }
-
-// Keep track of the last time a client message was sent.
-var last = new Date();
-
-// Messages are sent to the parent by appending them to the tempfile.
-var sendMessage = function(arg) {
- var args = Array.isArray(arg) ? arg : [].slice.call(arguments);
- last = new Date();
- console.log(JSON.stringify(args));
-};
-
-// This allows grunt to abort if the PhantomJS version isn't adequate.
-sendMessage('private', 'version', phantom.version);
-
-// Abort if the page doesn't send any messages for a while.
-setInterval(function() {
- if (new Date() - last > options.timeout) {
- sendMessage('fail.timeout');
- phantom.exit();
- }
-}, 100);
-
-// Create a new page.
-var page = require('webpage').create();
-
-// The client page must send its messages via alert(jsonstring).
-page.onAlert = function(args) {
- sendMessage(JSON.parse(args));
-};
-
-// Keep track if the client-side helper script already has been injected.
-var injected;
-page.onUrlChanged = function(newUrl) {
- injected = false;
- sendMessage('onUrlChanged', newUrl);
-};
-
-// Relay console logging messages.
-page.onConsoleMessage = function(message) {
- sendMessage('console', message);
-};
-
-// For debugging.
-page.onResourceRequested = function(request) {
- sendMessage('onResourceRequested', request.url);
-};
-
-page.onResourceReceived = function(request) {
- if (request.stage === 'end') {
- sendMessage('onResourceReceived', request.url);
- }
-};
-
-// Run when the page has finished loading.
-page.onLoadFinished = function(status) {
- // The window has loaded.
- sendMessage('onLoadFinished', status);
- if (status === 'success') {
- if (options.inject && !injected) {
- // Inject client-side helper script, but only if it has not yet been
- // injected.
- sendMessage('inject', options.inject);
- page.injectJs(options.inject);
- }
- } else {
- // File loading failure.
- sendMessage('fail.load', url);
- phantom.exit();
- }
-};
-
-// Actually load url.
-page.open(url);
diff --git a/addons/web/tests/qunitsuite/grunt/license b/addons/web/tests/qunitsuite/grunt/license
deleted file mode 100644
index 90c336c39d3..00000000000
--- a/addons/web/tests/qunitsuite/grunt/license
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2012 "Cowboy" Ben Alman
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
diff --git a/addons/web/tests/qunitsuite/grunt/phantomjs.json b/addons/web/tests/qunitsuite/grunt/phantomjs.json
deleted file mode 100644
index 9e26dfeeb6e..00000000000
--- a/addons/web/tests/qunitsuite/grunt/phantomjs.json
+++ /dev/null
@@ -1 +0,0 @@
-{} \ No newline at end of file
diff --git a/addons/web/tests/qunitsuite/grunt/qunit-phantomjs-bridge.js b/addons/web/tests/qunitsuite/grunt/qunit-phantomjs-bridge.js
deleted file mode 100644
index 032fe8a3aa0..00000000000
--- a/addons/web/tests/qunitsuite/grunt/qunit-phantomjs-bridge.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * grunt
- * http://gruntjs.com/
- *
- * Copyright (c) 2012 "Cowboy" Ben Alman
- * Licensed under the MIT license.
- * http://benalman.com/about/license/
- */
-
-/*global QUnit:true, alert:true*/
-
-'use strict';
-
-// Don't re-order tests.
-QUnit.config.reorder = false;
-// Run tests serially, not in parallel.
-QUnit.config.autorun = false;
-
-// Send messages to the parent PhantomJS process via alert! Good times!!
-function sendMessage() {
- var args = [].slice.call(arguments);
- alert(JSON.stringify(args));
-}
-
-// These methods connect QUnit to PhantomJS.
-QUnit.log(function(obj) {
- // What is this I don’t even
- if (obj.message === '[object Object], undefined:undefined') { return; }
- // Parse some stuff before sending it.
- var actual = QUnit.jsDump.parse(obj.actual);
- var expected = QUnit.jsDump.parse(obj.expected);
- // Send it.
- sendMessage('qunit.log', obj.result, actual, expected, obj.message, obj.source);
-});
-
-QUnit.testStart(function(obj) {
- sendMessage('qunit.testStart', obj.name);
-});
-
-QUnit.testDone(function(obj) {
- sendMessage('qunit.testDone', obj.name, obj.failed, obj.passed, obj.total);
-});
-
-QUnit.moduleStart(function(obj) {
- sendMessage('qunit.moduleStart', obj.name);
-});
-
-QUnit.moduleDone(function(obj) {
- sendMessage('qunit.moduleDone', obj.name, obj.failed, obj.passed, obj.total);
-});
-
-QUnit.begin(function() {
- sendMessage('qunit.begin');
-});
-
-QUnit.done(function(obj) {
- sendMessage('qunit.done', obj.failed, obj.passed, obj.total, obj.runtime);
-});
-
-// PhantomJS (up to and including 1.7) uses a version of webkit so old
-// it does not have Function.prototype.bind:
-// http://code.google.com/p/phantomjs/issues/detail?id=522
-
-// Use moz polyfill:
-// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind#Compatibility
-if (!Function.prototype.bind) {
- Function.prototype.bind = function (oThis) {
- if (typeof this !== "function") {
- // closest thing possible to the ECMAScript 5 internal IsCallable function
- throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
- }
-
- var aArgs = Array.prototype.slice.call(arguments, 1),
- fToBind = this,
- fNOP = function () {},
- fBound = function () {
- return fToBind.apply(this instanceof fNOP && oThis
- ? this
- : oThis,
- aArgs.concat(Array.prototype.slice.call(arguments)));
- };
-
- fNOP.prototype = this.prototype;
- fBound.prototype = new fNOP();
-
- return fBound;
- };
-}
diff --git a/addons/web/tests/qunitsuite/suite.py b/addons/web/tests/qunitsuite/suite.py
deleted file mode 100644
index 54d2e18e36e..00000000000
--- a/addons/web/tests/qunitsuite/suite.py
+++ /dev/null
@@ -1,136 +0,0 @@
-import json
-import subprocess
-import unittest
-import os
-import time
-
-ROOT = os.path.join(os.path.dirname(__file__), 'grunt')
-
-__all__ = ['QUnitSuite']
-
-def _exc_info_to_string(err, test):
- return err
-
-class QUnitTest(unittest.TestCase):
- def __init__(self, module, name):
- self.module = module
- self.name = name
- self.failed = False
- def shortDescription(self):
- return None
- def __repr__(self):
- return '<QUnitTest %s:%s>' % (self.module, self.name)
- def __str__(self):
- return '%s: %s' % (self.module, self.name)
-
-class QUnitSuite(unittest.TestSuite):
- def __init__(self, qunitfile, timeout=5000):
- super(QUnitSuite, self).__init__()
- self.testfile = qunitfile
- self.timeout = timeout
- self._module = None
- self._test = None
-
- def run(self, result):
- try:
- subprocess.call(['phantomjs', '-v'],
- stdout=open(os.devnull, 'w'),
- stderr=subprocess.STDOUT)
- except OSError:
- test = QUnitTest('phantomjs', 'javascript tests')
- result.startTest(test)
- result.startTest(test)
- result.addSkip(test , "phantomjs command not found")
- result.stopTest(test)
- return
-
- result._exc_info_to_string = _exc_info_to_string
- try:
- self._run(result)
- finally:
- del result._exc_info_to_string
-
- def _run(self, result):
- phantom = subprocess.Popen([
- 'phantomjs',
- '--config=%s' % os.path.join(ROOT, 'phantomjs.json'),
- os.path.join(ROOT, 'bootstrap.js'), self.testfile,
- json.dumps({
- 'timeout': self.timeout,
- 'inject': os.path.join(ROOT, 'qunit-phantomjs-bridge.js')
- })
- ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-
- try:
- while True:
- line = phantom.stdout.readline()
- if line:
- if self.process(line, result):
- break
- else:
- time.sleep(0.1)
- finally:
- # If the phantomjs process hasn't quit, kill it
- if phantom.poll() is None:
- phantom.terminate()
-
- def process(self, line, result):
- try:
- args = json.loads(line)
- except ValueError: # phantomjs stderr
- if 'CoreText' not in line:
- print line
- return False
- event_name = args[0]
-
- if event_name == 'qunit.done':
- return True
- elif event_name == 'fail.load':
- self.add_error(result, "PhantomJS unable to load %s" % args[1])
- return True
- elif event_name == 'fail.timeout':
- self.add_error(result, "PhantomJS timed out, possibly due to a"
- " missing QUnit start() call")
- return True
-
- elif event_name == 'qunit.moduleStart':
- self._module = args[1].encode('utf-8') if args[1] else ''
- elif event_name == 'qunit.moduleStop':
- self._test = None
- self._module = None
- elif event_name == 'qunit.testStart':
- self._test = QUnitTest(self._module, args[1].encode('utf-8'))
- result.startTest(self._test)
- elif event_name == 'qunit.testDone':
- if not self._test.failed:
- result.addSuccess(self._test)
- result.stopTest(self._test)
- self._test = None
- elif event_name == 'qunit.log':
- if args[1]:
- return False
-
- self._test.failed = True
- result.addFailure(
- self._test, self.failure_to_str(*args[2:]))
- elif event_name == 'console':
- print args[1]
-
- return False
-
- def add_error(self, result, s):
- test = QUnitTest('phantomjs', 'startup')
- result.startTest(test)
- result.addError(test, s)
- result.stopTest(test)
-
- def failure_to_str(self, actual, expected, message, source):
- if message or actual == expected:
- formatted = str(message or '')
- else:
- formatted = "%s != %s" % (actual, expected)
-
- if source:
- formatted += '\n\n' + source
-
- return formatted
diff --git a/addons/web/tests/test_js.py b/addons/web/tests/test_js.py
index 0bab1de96a5..496d7e283bc 100644
--- a/addons/web/tests/test_js.py
+++ b/addons/web/tests/test_js.py
@@ -1,24 +1,6 @@
-import urllib
-import urlparse
-from openerp import sql_db, tools
-from qunitsuite.suite import QUnitSuite
+import openerp
-class WebSuite(QUnitSuite):
- def __init__(self, module):
- url = urlparse.urlunsplit([
- 'http',
- 'localhost:{port}'.format(port=tools.config['xmlrpc_port']),
- '/web/tests',
- urllib.urlencode({
- 'mod': module,
- 'source': tools.config['db_name'],
- 'supadmin': tools.config['admin_passwd'],
- 'password': 'admin',
- }),
- ''
- ])
- super(WebSuite, self).__init__(url, 50000)
+class WebSuite(openerp.tests.HttpCase):
+ def test_01_js(self):
+ self.phantom_js('/web/tests?mod=web',"","", login='admin')
-def load_tests(loader, standard_tests, _):
- standard_tests.addTest(WebSuite('web'))
- return standard_tests
diff --git a/addons/web/tests/test_menu.py b/addons/web/tests/test_menu.py
index fb9337a589b..0978a7093ad 100644
--- a/addons/web/tests/test_menu.py
+++ b/addons/web/tests/test_menu.py
@@ -28,9 +28,7 @@ class LoadTest(common.MockRequestCase):
self.MockMenus = model('ir.ui.menu')
# Mock the absence of custom menu
- model('res.users').read.return_value = [{
- 'menu_id': False
- }]
+ model('res.users').read.return_value = []
def tearDown(self):
del self.MockMenus
diff --git a/addons/web/tests/test_ui.py b/addons/web/tests/test_ui.py
deleted file mode 100644
index 4bbc4a3954c..00000000000
--- a/addons/web/tests/test_ui.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# -*- coding: utf-8 -*-
-import os
-
-import openerp.tests
-
-class TestUi(openerp.tests.HttpCase):
- def test_01_jsfile_ui_hello(self):
- self.phantom_jsfile(os.path.join(os.path.dirname(__file__), 'test_ui_hello.js'))
- def test_02_jsfile_ui_load(self):
- self.phantom_jsfile(os.path.join(os.path.dirname(__file__), 'test_ui_load.js'))
- def test_03_js_public(self):
- self.phantom_js('/',"console.log('ok')","console")
- def test_04_js_admin(self):
- self.phantom_js('/',"console.log('ok')","openerp.client.action_manager.inner_widget.views.form", login='admin')
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/web/tests/test_ui_hello.js b/addons/web/tests/test_ui_hello.js
deleted file mode 100644
index 6a453e947aa..00000000000
--- a/addons/web/tests/test_ui_hello.js
+++ /dev/null
@@ -1,5 +0,0 @@
-console.log("hello from test_phantom_hello.js");
-console.log("ok");
-// For a failure use:
-//console.log("error");
-phantom.exit();
diff --git a/addons/web/tests/test_ui_load.js b/addons/web/tests/test_ui_load.js
deleted file mode 100644
index 9d76250d239..00000000000
--- a/addons/web/tests/test_ui_load.js
+++ /dev/null
@@ -1,4 +0,0 @@
-// Load helper
-phantom.injectJs(phantom.args[0]);
-pt = new PhantomTest();
-pt.run("/", "console.log('ok')", "console");
diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml
index 46bae5f83ca..2c3a16ac13f 100644
--- a/addons/web/views/webclient_templates.xml
+++ b/addons/web/views/webclient_templates.xml
@@ -3,6 +3,101 @@
-->
<openerp>
<data>
+ <template id="web.assets_common">
+ <script type="text/javascript" src="/web/static/lib/es5-shim/es5-shim.min.js"></script>
+ <script type="text/javascript" src="/web/static/lib/underscore/underscore.js"></script>
+ <script type="text/javascript" src="/web/static/lib/underscore.string/lib/underscore.string.js"></script>
+ <script type="text/javascript" src="/web/static/lib/datejs/globalization/en-US.js"></script>
+ <script type="text/javascript" src="/web/static/lib/spinjs/spin.js"></script>
+
+ <!-- jQuery stuff -->
+ <script type="text/javascript" src="/web/static/lib/jquery/jquery.js"></script>
+ <script type="text/javascript" src="/web/static/lib/jquery.blockUI/jquery.blockUI.js"></script>
+ <script type="text/javascript" src="/web/static/lib/jquery.hotkeys/jquery.hotkeys.js"></script>
+ <script type="text/javascript" src="/web/static/lib/jquery.placeholder/jquery.placeholder.js"></script>
+ <script type="text/javascript" src="/web/static/lib/jquery.timeago/jquery.timeago.js"></script>
+ <script type="text/javascript" src="/web/static/lib/jquery.form/jquery.form.js"></script>
+
+ <script type="text/javascript" src="/web/static/lib/jquery.ba-bbq/jquery.ba-bbq.js"></script>
+
+ <link rel="stylesheet" href="/web/static/lib/fontawesome/css/font-awesome.css"/>
+ </template>
+
+ <template id="web.assets_backend">
+ <t t-call="web.assets_common"/>
+ <!-- Datejs -->
+ <script type="text/javascript" src="/web/static/lib/datejs/core.js"></script>
+ <script type="text/javascript" src="/web/static/lib/datejs/parser.js"></script>
+ <script type="text/javascript" src="/web/static/lib/datejs/sugarpak.js"></script>
+ <script type="text/javascript" src="/web/static/lib/datejs/extras.js"></script>
+
+ <!-- jQuery addons -->
+ <script type="text/javascript" src="/web/static/lib/jquery.validate/jquery.validate.js"></script>
+ <script type="text/javascript" src="/web/static/lib/jquery.autosize/jquery.autosize.js"></script>
+ <script type="text/javascript" src="/web/static/lib/jquery.scrollTo/jquery.scrollTo-min.js"></script>
+
+ <link rel="stylesheet" href="/web/static/lib/cleditor/jquery.cleditor.css"/>
+ <script type="text/javascript" src="/web/static/lib/cleditor/jquery.cleditor.js"></script>
+
+ <link rel="stylesheet" href="/web/static/lib/jquery.textext/jquery.textext.css"/>
+ <script type="text/javascript" src="/web/static/lib/jquery.textext/jquery.textext.js"></script>
+
+ <link rel="stylesheet" href="/web/static/lib/select2/select2.css"/>
+ <script type="text/javascript" src="/web/static/lib/select2/select2.js"></script>
+
+
+ <!-- jQuery ui -->
+ <link rel="stylesheet" href="/web/static/lib/jquery.ui.bootstrap/css/custom-theme/jquery-ui-1.9.0.custom.css"/>
+ <script type="text/javascript" src="/web/static/lib/jquery.ui/js/jquery-ui-1.9.1.custom.js"></script>
+
+ <link rel="stylesheet" href="/web/static/lib/jquery.ui.timepicker/css/jquery-ui-timepicker-addon.css"/>
+ <script type="text/javascript" src="/web/static/lib/jquery.ui.timepicker/js/jquery-ui-timepicker-addon.js"></script>
+
+ <link rel="stylesheet" href="/web/static/lib/jquery.ui.notify/css/ui.notify.css"/>
+ <script type="text/javascript" src="/web/static/lib/jquery.ui.notify/js/jquery.notify.js"></script>
+
+ <!-- Bootstrap must be loaded after jquery.ui until jquery.ui is removed -->
+ <link rel="stylesheet" href="/web/static/lib/bootstrap/css/bootstrap.css"/>
+ <script type="text/javascript" src="/web/static/lib/bootstrap/js/bootstrap.js"></script>
+
+ <!-- Backbone -->
+ <script type="text/javascript" src="/web/static/lib/backbone/backbone.js"></script>
+
+ <!-- Internals -->
+ <link rel="stylesheet" href="/web/static/src/css/base.css"/>
+ <link rel="stylesheet" href="/web/static/src/css/data_export.css"/>
+ <link rel="stylesheet" href="/base/static/src/css/modules.css"/>
+
+ <script type="text/javascript" src="/web/static/lib/qweb/qweb2.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/openerpframework.js"></script>
+ <script type="text/javascript" src="/web/static/lib/py.js/lib/py.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/boot.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/testing.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/pyeval.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/core.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/formats.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/chrome.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/views.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/data.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/data_export.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/search.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/view_list.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/view_form.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/view_list_editable.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/view_tree.js"></script>
+ <script type="text/javascript" src="/base/static/src/js/apps.js"></script>
+
+ </template>
+
+ <template id="web.assets_webclient_manifest">
+ <!-- This bundle can be used for module manifest asset declaration backward compatibility -->
+ <t t-foreach="manifest_list('css')" t-as="css_file">
+ <link rel="stylesheet" t-att-href="css_file"/>
+ </t>
+ <t t-foreach="manifest_list('js')" t-as="js_file">
+ <script type="text/javascript" t-att-src="js_file"></script>
+ </t>
+ </template>
<template id="web.layout" name="Web layout">&lt;!DOCTYPE html&gt;
<html style="height: 100%">
@@ -23,12 +118,7 @@
<template id="web.webclient_bootstrap" name="Webclient Bootstrap">
<t t-call="web.layout">
<t t-set="head">
- <t t-foreach="css" t-as="css_file">
- <link rel="stylesheet" t-att-href="css_file"/>
- </t>
- <t t-foreach="js" t-as="js_file">
- <script type="text/javascript" t-att-src="js_file"></script>
- </t>
+ <t t-call-assets="web.assets_backend"/>
<script type="text/javascript">
$(function() {
var s = new openerp.init(<t t-raw="modules"/>);
@@ -78,10 +168,10 @@
</script>
<div class="form-group field-db" t-if="databases and len(databases) &gt; 1">
<label for="db" class="control-label">Database</label>
- <select name="db" id="db" class="form-control" required="required" t-att-autofocus="'autofocus' if current_db not in databases else None" onchange="dbchanged(this.value)">
+ <select name="db" id="db" class="form-control" required="required" t-att-autofocus="'autofocus' if request.db not in databases else None" onchange="dbchanged(this.value)">
<option></option>
<t t-foreach="databases" t-as="db">
- <option t-att-selected="'selected' if db == current_db else None">
+ <option t-att-selected="'selected' if db == request.db else None">
<t t-esc="db"/>
</option>
</t>
@@ -121,5 +211,55 @@
</t>
</template>
+ <template id="web.qunit_suite">
+ &lt;!DOCTYPE html&gt;
+ <html style="height: 100%">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+ <title>OpenERP Web Tests</title>
+
+ <link rel="shortcut icon" href="/web/static/src/img/favicon.ico" type="image/x-icon"/>
+ <link rel="stylesheet" href="/web/static/lib/qunit/qunit.css"/>
+ <script src="/web/static/lib/qunit/qunit.js"></script>
+
+ <t t-call="web.assets_backend"/>
+
+ <script type="text/javascript" id="qunit_config">
+ QUnit.config.testTimeout = 5 * 60 * 1000;
+ QUnit.moduleDone(function(result) {
+ console.log(result.name + " (" + result.passed + "/" + result.total + " passed tests)");
+ });
+ QUnit.done(function(result) {
+ if (result.failed === 0) {
+ console.log('ok');
+ }
+ });
+ openerp.web.qweb.add_template("/web/webclient/qweb");
+ </script>
+
+ <script type="text/javascript" src="/web/static/test/testing.js"></script>
+ <script type="text/javascript" src="/web/static/test/framework.js"></script>
+ <script type="text/javascript" src="/web/static/test/registry.js"></script>
+ <script type="text/javascript" src="/web/static/test/form.js"></script>
+ <script type="text/javascript" src="/web/static/test/data.js"></script>
+ <script type="text/javascript" src="/web/static/test/list-utils.js"></script>
+ <script type="text/javascript" src="/web/static/test/formats.js"></script>
+ <script type="text/javascript" src="/web/static/test/rpc-misordered.js"></script>
+ <script type="text/javascript" src="/web/static/test/evals.js"></script>
+ <script type="text/javascript" src="/web/static/test/search.js"></script>
+ <script type="text/javascript" src="/web/static/test/list.js"></script>
+ <script type="text/javascript" src="/web/static/test/list-editable.js"></script>
+ <script type="text/javascript" src="/web/static/test/mutex.js"></script>
+ </head>
+
+ <body id="oe" class="openerp">
+ <div id="qunit"></div>
+ <div id="qunit-fixture"></div>
+ </body>
+ </html>
+
+ </template>
+
</data>
</openerp>