diff --git a/addons/web/__openerp__.py b/addons/web/__openerp__.py index 2855441bf6b..a4000856afe 100644 --- a/addons/web/__openerp__.py +++ b/addons/web/__openerp__.py @@ -14,83 +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.tipsy/jquery.tipsy.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.tipsy/tipsy.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 a6b5fa63918..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 = """ OpenERP + %(css)s %(js)s ' % i for i in manifest_list('js', debug=request.debug)) - css = "\n ".join('' % i for i in manifest_list('css', debug=request.debug)) + css = """ + + + + + + + + + + + """ + js = """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + """ 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) @@ -1225,7 +1138,7 @@ class DataSet(http.Controller): records = getattr(request.session.model(model), method)(*args, **kwargs) for record in records: record['display_name'] = \ - names.get(record['id']) or "%s#%d" % (model, (record['id'])) + names.get(record['id']) or "{0}#{1}".format(model, (record['id'])) return records if method.startswith('_'): 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""" - - - - - OpenERP Testing - - -
- - -
- - -""", default_filters=['h']) -NOTFOUND = Template(u""" -

Unable to find the module [${module}], please check that the module - name is correct and the module is on OpenERP's path.

-<< Back to tests -""", default_filters=['h']) -TESTING = Template(u""" - -<%def name="to_path(module, p)">/${module}/${p} - - - - OpenERP Web Tests - - - - - - - - -
-
- - -% for module, jss, tests, templates in files: - % for js in jss: - % if not js.endswith('/apps.js'): - - % endif - % endfor - % if tests or templates: - - % endif - % if tests: - % for test in tests: - - % endfor - % endif -% endfor - -""", 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 d847ecb2e1b..5500e9103f1 100644 --- a/addons/web/i18n/ar.po +++ b/addons/web/i18n/ar.po @@ -14,8 +14,8 @@ 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-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/bg.po b/addons/web/i18n/bg.po index 3200798afca..8cfebbfe61f 100644 --- a/addons/web/i18n/bg.po +++ b/addons/web/i18n/bg.po @@ -14,8 +14,8 @@ 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-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/bn.po b/addons/web/i18n/bn.po index 5ad67dbc189..b2aa1b04340 100644 --- a/addons/web/i18n/bn.po +++ b/addons/web/i18n/bn.po @@ -14,8 +14,8 @@ 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-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/bs.po b/addons/web/i18n/bs.po index d3ad8c5fcaa..b35ac75513d 100644 --- a/addons/web/i18n/bs.po +++ b/addons/web/i18n/bs.po @@ -14,8 +14,8 @@ 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-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/ca.po b/addons/web/i18n/ca.po index a9a6f60fa22..5a772e2ca2f 100644 --- a/addons/web/i18n/ca.po +++ b/addons/web/i18n/ca.po @@ -14,8 +14,8 @@ 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-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/cs.po b/addons/web/i18n/cs.po index d572f8ce11f..acd387fa39a 100644 --- a/addons/web/i18n/cs.po +++ b/addons/web/i18n/cs.po @@ -14,8 +14,8 @@ 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-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" "X-Poedit-Language: Czech\n" #. module: web diff --git a/addons/web/i18n/da.po b/addons/web/i18n/da.po index 571dedcc5c4..8bf7a9f5086 100644 --- a/addons/web/i18n/da.po +++ b/addons/web/i18n/da.po @@ -14,8 +14,8 @@ 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-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/de.po b/addons/web/i18n/de.po index a22df51ce71..cb5f6fa9e6e 100644 --- a/addons/web/i18n/de.po +++ b/addons/web/i18n/de.po @@ -14,8 +14,8 @@ 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-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/en_AU.po b/addons/web/i18n/en_AU.po index a1cdf449f9b..f92d5c282b3 100644 --- a/addons/web/i18n/en_AU.po +++ b/addons/web/i18n/en_AU.po @@ -14,8 +14,8 @@ 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-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/en_GB.po b/addons/web/i18n/en_GB.po index 586c44543c3..88f6a33907f 100644 --- a/addons/web/i18n/en_GB.po +++ b/addons/web/i18n/en_GB.po @@ -14,8 +14,8 @@ 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-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/es.po b/addons/web/i18n/es.po index 2911e97a98b..52e1f5dbadf 100644 --- a/addons/web/i18n/es.po +++ b/addons/web/i18n/es.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/es_CL.po b/addons/web/i18n/es_CL.po index 8786cde4424..d54195b2ffe 100644 --- a/addons/web/i18n/es_CL.po +++ b/addons/web/i18n/es_CL.po @@ -14,8 +14,8 @@ 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-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/es_CR.po b/addons/web/i18n/es_CR.po index 5aec19d8207..862531a7b68 100644 --- a/addons/web/i18n/es_CR.po +++ b/addons/web/i18n/es_CR.po @@ -14,8 +14,8 @@ 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-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" "Language: es\n" #. module: web diff --git a/addons/web/i18n/es_DO.po b/addons/web/i18n/es_DO.po index 23b88465fdd..96e28c1ae9d 100644 --- a/addons/web/i18n/es_DO.po +++ b/addons/web/i18n/es_DO.po @@ -14,8 +14,8 @@ 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-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/es_EC.po b/addons/web/i18n/es_EC.po index 8fc6129e4ec..e634ab5c076 100644 --- a/addons/web/i18n/es_EC.po +++ b/addons/web/i18n/es_EC.po @@ -14,8 +14,8 @@ 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-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:54+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/es_MX.po b/addons/web/i18n/es_MX.po index a635938be37..ec8bf391953 100644 --- a/addons/web/i18n/es_MX.po +++ b/addons/web/i18n/es_MX.po @@ -14,8 +14,8 @@ 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-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:54+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/es_PE.po b/addons/web/i18n/es_PE.po index c79aedb7c54..71d37a83395 100644 --- a/addons/web/i18n/es_PE.po +++ b/addons/web/i18n/es_PE.po @@ -14,8 +14,8 @@ 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-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:54+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/et.po b/addons/web/i18n/et.po index 31124e42155..6efd5e392d3 100644 --- a/addons/web/i18n/et.po +++ b/addons/web/i18n/et.po @@ -14,8 +14,8 @@ 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-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/eu.po b/addons/web/i18n/eu.po index 3dbe990e9d4..b29f74e3b76 100644 --- a/addons/web/i18n/eu.po +++ b/addons/web/i18n/eu.po @@ -14,8 +14,8 @@ 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-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/fa.po b/addons/web/i18n/fa.po index 73189acbf3b..c190534f18c 100644 --- a/addons/web/i18n/fa.po +++ b/addons/web/i18n/fa.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/fi.po b/addons/web/i18n/fi.po index 7964566fd42..827eb9edac0 100644 --- a/addons/web/i18n/fi.po +++ b/addons/web/i18n/fi.po @@ -14,8 +14,8 @@ 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-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/fr.po b/addons/web/i18n/fr.po index 3b8bb419f5b..5cc8a8785a1 100644 --- a/addons/web/i18n/fr.po +++ b/addons/web/i18n/fr.po @@ -14,8 +14,8 @@ 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-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/fr_CA.po b/addons/web/i18n/fr_CA.po index f7bee061dd0..5860eea177e 100644 --- a/addons/web/i18n/fr_CA.po +++ b/addons/web/i18n/fr_CA.po @@ -14,8 +14,8 @@ 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-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/gl.po b/addons/web/i18n/gl.po index 31e924db129..108125b647c 100644 --- a/addons/web/i18n/gl.po +++ b/addons/web/i18n/gl.po @@ -14,8 +14,8 @@ 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-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/gu.po b/addons/web/i18n/gu.po index 0a0e108f59e..5e064c2f121 100644 --- a/addons/web/i18n/gu.po +++ b/addons/web/i18n/gu.po @@ -14,8 +14,8 @@ 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-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/he.po b/addons/web/i18n/he.po index c2ca619ac10..6982efa679a 100644 --- a/addons/web/i18n/he.po +++ b/addons/web/i18n/he.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/hi.po b/addons/web/i18n/hi.po index fb858fb82f0..b8d43b0547c 100644 --- a/addons/web/i18n/hi.po +++ b/addons/web/i18n/hi.po @@ -14,8 +14,8 @@ 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-10 05:56+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/hr.po b/addons/web/i18n/hr.po index 2bff56b362b..d47cefc95d3 100644 --- a/addons/web/i18n/hr.po +++ b/addons/web/i18n/hr.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/hu.po b/addons/web/i18n/hu.po index 1074f41727a..f1a92ab0186 100644 --- a/addons/web/i18n/hu.po +++ b/addons/web/i18n/hu.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/id.po b/addons/web/i18n/id.po index 483ca79f8ab..ecc7f580c42 100644 --- a/addons/web/i18n/id.po +++ b/addons/web/i18n/id.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/it.po b/addons/web/i18n/it.po index 5d5e7e064b5..e37592a6b89 100644 --- a/addons/web/i18n/it.po +++ b/addons/web/i18n/it.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/ja.po b/addons/web/i18n/ja.po index d46eee695ea..81fa526f501 100644 --- a/addons/web/i18n/ja.po +++ b/addons/web/i18n/ja.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/ka.po b/addons/web/i18n/ka.po index 89d3011b25d..bbfbdad689e 100644 --- a/addons/web/i18n/ka.po +++ b/addons/web/i18n/ka.po @@ -14,8 +14,8 @@ 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-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/ko.po b/addons/web/i18n/ko.po index ce4c2b6b019..c2445599c55 100644 --- a/addons/web/i18n/ko.po +++ b/addons/web/i18n/ko.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/lo.po b/addons/web/i18n/lo.po index bb484d07f1d..8f4bf33bcd1 100644 --- a/addons/web/i18n/lo.po +++ b/addons/web/i18n/lo.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/lt.po b/addons/web/i18n/lt.po index 25efa7b8f5c..384a22b5d7a 100644 --- a/addons/web/i18n/lt.po +++ b/addons/web/i18n/lt.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/lv.po b/addons/web/i18n/lv.po index 9f685f70d31..a1358f54205 100644 --- a/addons/web/i18n/lv.po +++ b/addons/web/i18n/lv.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/mk.po b/addons/web/i18n/mk.po index 79a9cecaf20..70d9144d92f 100644 --- a/addons/web/i18n/mk.po +++ b/addons/web/i18n/mk.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/mn.po b/addons/web/i18n/mn.po index d47989ab748..09694dae1c4 100644 --- a/addons/web/i18n/mn.po +++ b/addons/web/i18n/mn.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/nb.po b/addons/web/i18n/nb.po index 5db5fdb8333..7ff320014f4 100644 --- a/addons/web/i18n/nb.po +++ b/addons/web/i18n/nb.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/nl.po b/addons/web/i18n/nl.po index ee2fcb2d04c..3f1e2d7c5ac 100644 --- a/addons/web/i18n/nl.po +++ b/addons/web/i18n/nl.po @@ -14,8 +14,8 @@ 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-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/nl_BE.po b/addons/web/i18n/nl_BE.po index b04d024e96e..f6dc9d6f34f 100644 --- a/addons/web/i18n/nl_BE.po +++ b/addons/web/i18n/nl_BE.po @@ -14,8 +14,8 @@ 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-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/pl.po b/addons/web/i18n/pl.po index 98b94458f0a..df2dd4def17 100644 --- a/addons/web/i18n/pl.po +++ b/addons/web/i18n/pl.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/pt.po b/addons/web/i18n/pt.po index 22abc7689fb..a1716f3b7b0 100644 --- a/addons/web/i18n/pt.po +++ b/addons/web/i18n/pt.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/pt_BR.po b/addons/web/i18n/pt_BR.po index 1417acfdf5b..c9e6cfab751 100644 --- a/addons/web/i18n/pt_BR.po +++ b/addons/web/i18n/pt_BR.po @@ -15,8 +15,8 @@ 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-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/ro.po b/addons/web/i18n/ro.po index cea4b12cd8a..2285aa1ec28 100644 --- a/addons/web/i18n/ro.po +++ b/addons/web/i18n/ro.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/ru.po b/addons/web/i18n/ru.po index e6ccd923125..7ab615d6312 100644 --- a/addons/web/i18n/ru.po +++ b/addons/web/i18n/ru.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/sk.po b/addons/web/i18n/sk.po index d191a3f7470..e1ad376ba14 100644 --- a/addons/web/i18n/sk.po +++ b/addons/web/i18n/sk.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/sl.po b/addons/web/i18n/sl.po index cc7c4633a12..6c7dc176481 100644 --- a/addons/web/i18n/sl.po +++ b/addons/web/i18n/sl.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/sq.po b/addons/web/i18n/sq.po index dd2ce5edd1b..1e338e967a5 100644 --- a/addons/web/i18n/sq.po +++ b/addons/web/i18n/sq.po @@ -14,8 +14,8 @@ 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-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:52+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/sr@latin.po b/addons/web/i18n/sr@latin.po index a0178bd5140..88d941461c7 100644 --- a/addons/web/i18n/sr@latin.po +++ b/addons/web/i18n/sr@latin.po @@ -14,8 +14,8 @@ 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-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:54+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/sv.po b/addons/web/i18n/sv.po index c785e60777e..9847bdf1ffe 100644 --- a/addons/web/i18n/sv.po +++ b/addons/web/i18n/sv.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/th.po b/addons/web/i18n/th.po index 5cff3bb8f8d..d61e828b1a7 100644 --- a/addons/web/i18n/th.po +++ b/addons/web/i18n/th.po @@ -14,8 +14,8 @@ 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-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/tr.po b/addons/web/i18n/tr.po index 8a65bd712d4..4decaa7f356 100644 --- a/addons/web/i18n/tr.po +++ b/addons/web/i18n/tr.po @@ -14,8 +14,8 @@ 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-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/uk.po b/addons/web/i18n/uk.po index 31d499f1180..92826b245bc 100644 --- a/addons/web/i18n/uk.po +++ b/addons/web/i18n/uk.po @@ -14,8 +14,8 @@ 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-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/vi.po b/addons/web/i18n/vi.po index 9c6de31b9bc..6eef5cbad3c 100644 --- a/addons/web/i18n/vi.po +++ b/addons/web/i18n/vi.po @@ -14,8 +14,8 @@ 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-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/zh_CN.po b/addons/web/i18n/zh_CN.po index ceaf734876d..9bfc9ed283a 100644 --- a/addons/web/i18n/zh_CN.po +++ b/addons/web/i18n/zh_CN.po @@ -14,8 +14,8 @@ 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-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:54+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/zh_TW.po b/addons/web/i18n/zh_TW.po index a3d58934af4..80de08053cb 100644 --- a/addons/web/i18n/zh_TW.po +++ b/addons/web/i18n/zh_TW.po @@ -14,8 +14,8 @@ 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-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-04-26 06:53+0000\n" +"X-Generator: Launchpad (build 16985)\n" #. module: web #. openerp-web diff --git a/addons/web/static/lib/jquery.tipsy/jquery.tipsy.js b/addons/web/static/lib/jquery.tipsy/jquery.tipsy.js deleted file mode 100644 index e978042f21b..00000000000 --- a/addons/web/static/lib/jquery.tipsy/jquery.tipsy.js +++ /dev/null @@ -1,250 +0,0 @@ -// tipsy, facebook style tooltips for jquery -// version 1.0.0a -// (c) 2008-2010 jason frame [jason@onehackoranother.com] -// released under the MIT license - -(function($) { - - function maybeCall(thing, ctx) { - return (typeof thing == 'function') ? (thing.call(ctx)) : thing; - }; - - function Tipsy(element, options) { - this.$element = $(element); - this.options = options; - this.enabled = true; - this.fixTitle(); - }; - - Tipsy.prototype = { - show: function() { - $.fn.tipsy.clear(); - if (!this.$element.parent().length) { - return; - } - var title = this.getTitle(); - if (title && this.enabled) { - var $tip = this.tip(); - - $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title); - $tip[0].className = 'tipsy '; // reset classname in case of dynamic gravity - $tip.openerpClass('oe_tooltip'); - $tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).prependTo(document.body); - - var pos = $.extend({}, this.$element.offset(), { - width: this.$element[0].offsetWidth, - height: this.$element[0].offsetHeight - }); - - var actualWidth = $tip[0].offsetWidth, - actualHeight = $tip[0].offsetHeight, - gravity = maybeCall(this.options.gravity, this.$element[0]); - - var tp; - switch (gravity.charAt(0)) { - case 'n': - tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}; - break; - case 's': - tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}; - break; - case 'e': - tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset}; - break; - case 'w': - tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset}; - break; - } - - if (gravity.length == 2) { - if (gravity.charAt(1) == 'w') { - tp.left = pos.left + pos.width / 2 - 15; - } else { - tp.left = pos.left + pos.width / 2 - actualWidth + 15; - } - } - - $tip.css(tp).addClass('tipsy-' + gravity); - $tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0); - if (this.options.className) { - $tip.addClass(maybeCall(this.options.className, this.$element[0])); - } - - if (this.options.fade) { - $tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity}); - } else { - $tip.css({visibility: 'visible', opacity: this.options.opacity}); - } - } - }, - - hide: function() { - if (this.options.fade) { - this.tip().stop().fadeOut(function() { $(this).remove(); }); - } else { - this.tip().remove(); - } - }, - - fixTitle: function() { - var $e = this.$element; - if ($e.attr('title') || typeof($e.attr('original-title')) != 'string') { - $e.attr('original-title', $e.attr('title') || '').removeAttr('title'); - } - }, - - getTitle: function() { - var title, $e = this.$element, o = this.options; - this.fixTitle(); - var title, o = this.options; - if (typeof o.title == 'string') { - title = $e.attr(o.title == 'title' ? 'original-title' : o.title); - } else if (typeof o.title == 'function') { - title = o.title.call($e[0]); - } - title = ('' + title).replace(/(^\s*|\s*$)/, ""); - return title || o.fallback; - }, - - tip: function() { - if (!this.$tip) { - this.$tip = $('
').html('
'); - } - return this.$tip; - }, - - validate: function() { - if (!this.$element[0].parentNode) { - this.hide(); - this.$element = null; - this.options = null; - } - }, - - enable: function() { this.enabled = true; }, - disable: function() { this.enabled = false; }, - toggleEnabled: function() { this.enabled = !this.enabled; } - }; - - $.fn.tipsy = function(options) { - - if (options === true) { - return this.data('tipsy'); - } else if (typeof options == 'string') { - var tipsy = this.data('tipsy'); - if (tipsy) tipsy[options](); - return this; - } - - options = $.extend({}, $.fn.tipsy.defaults, options); - - function get(ele) { - var tipsy = $.data(ele, 'tipsy'); - if (!tipsy) { - tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options)); - $.data(ele, 'tipsy', tipsy); - } - return tipsy; - } - - function enter() { - var tipsy = get(this); - tipsy.hoverState = 'in'; - if (options.delayIn == 0) { - tipsy.show(); - } else { - tipsy.fixTitle(); - setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn); - } - }; - - function leave() { - var tipsy = get(this); - tipsy.hoverState = 'out'; - if (options.delayOut == 0) { - tipsy.hide(); - } else { - setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut); - } - }; - - if (!options.live) this.each(function() { get(this); }); - - if (options.trigger != 'manual') { - var binder = options.live ? 'live' : 'bind', - eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus', - eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur'; - this[binder](eventIn, enter)[binder](eventOut, leave); - } - - return this; - - }; - - $.fn.tipsy.clear = function() { - $('div.tipsy').stop().remove(); - } - - $.fn.tipsy.defaults = { - className: null, - delayIn: 0, - delayOut: 0, - fade: false, - fallback: '', - gravity: 'n', - html: false, - live: false, - offset: 0, - opacity: 0.8, - title: 'title', - trigger: 'hover' - }; - - // Overwrite this method to provide options on a per-element basis. - // For example, you could store the gravity in a 'tipsy-gravity' attribute: - // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' }); - // (remember - do not modify 'options' in place!) - $.fn.tipsy.elementOptions = function(ele, options) { - return $.metadata ? $.extend({}, options, $(ele).metadata()) : options; - }; - - $.fn.tipsy.autoNS = function() { - return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n'; - }; - - $.fn.tipsy.autoWE = function() { - return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w'; - }; - - /** - * yields a closure of the supplied parameters, producing a function that takes - * no arguments and is suitable for use as an autogravity function like so: - * - * @param margin (int) - distance from the viewable region edge that an - * element should be before setting its tooltip's gravity to be away - * from that edge. - * @param prefer (string, e.g. 'n', 'sw', 'w') - the direction to prefer - * if there are no viewable region edges effecting the tooltip's - * gravity. It will try to vary from this minimally, for example, - * if 'sw' is preferred and an element is near the right viewable - * region edge, but not the top edge, it will set the gravity for - * that element's tooltip to be 'se', preserving the southern - * component. - */ - $.fn.tipsy.autoBounds = function(margin, prefer) { - return function() { - var dir = {ns: prefer[0], ew: (prefer.length > 1 ? prefer[1] : false)}, - boundTop = $(document).scrollTop() + margin, - boundLeft = $(document).scrollLeft() + margin, - $this = $(this); - - if ($this.offset().top < boundTop) dir.ns = 'n'; - if ($this.offset().left < boundLeft) dir.ew = 'w'; - if ($(window).width() + $(document).scrollLeft() - $this.offset().left < margin) dir.ew = 'e'; - if ($(window).height() + $(document).scrollTop() - $this.offset().top < margin) dir.ns = 's'; - - return dir.ns + (dir.ew ? dir.ew : ''); - } - }; - -})(jQuery); diff --git a/addons/web/static/lib/jquery.tipsy/tipsy.css b/addons/web/static/lib/jquery.tipsy/tipsy.css deleted file mode 100644 index 59d0fb97b9e..00000000000 --- a/addons/web/static/lib/jquery.tipsy/tipsy.css +++ /dev/null @@ -1,25 +0,0 @@ -.tipsy { font-size: 90%; position: absolute; padding: 5px; z-index: 100000; overflow: hidden;} - .tipsy-inner { background-color: #000; color: #FFF; max-width: 500px; padding: 5px 8px 4px 8px; } - - /* Rounded corners */ - .tipsy-inner { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; } - - /* Uncomment for shadow */ - .tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; } - - .tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; } - - /* Rules to colour arrows */ - .tipsy-arrow-n { border-bottom-color: #000; } - .tipsy-arrow-s { border-top-color: #000; } - .tipsy-arrow-e { border-left-color: #000; } - .tipsy-arrow-w { border-right-color: #000; } - - .tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; } - .tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} - .tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} - .tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } - .tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } - .tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } - .tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; } - .tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; } diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index b0bfcda8b38..8534927def1 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -506,40 +506,6 @@ font-style: italic; text-decoration: none; } -.openerp.oe_tooltip { - font-size: 12px; -} -.openerp.oe_tooltip .oe_tooltip_string { - color: #ffdd55; - font-weight: bold; - font-size: 13px; -} -.openerp.oe_tooltip .oe_tooltip_help { - white-space: pre-wrap; -} -.openerp.oe_tooltip .oe_tooltip_technical { - padding: 0 0 4px 0; - margin: 5px 0 0 15px; -} -.openerp.oe_tooltip .oe_tooltip_technical li { - list-style: circle; -} -.openerp.oe_tooltip .oe_tooltip_technical_title { - font-weight: bold; -} -.openerp.oe_tooltip .oe_tooltip_close { - margin: -5px 0 0 2px; - cursor: default; - float: right; - color: white; -} -.openerp.oe_tooltip .oe_tooltip_close:hover { - color: #999999; - cursor: pointer; -} -.openerp.oe_tooltip .oe_tooltip_message { - max-width: 310px; -} .openerp .oe_notebook { margin: 8px 0; padding: 0 16px; @@ -756,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; @@ -1926,7 +1892,7 @@ .openerp .oe_form > :not(.oe_form_nosheet) header { padding-left: 2px; } -.openerp .oe_form > :not(.oe_form_nosheet) header ul { +.openerp .oe_form > :not(.oe_form_nosheet) header ul:not(.oe_tooltip_technical):not(.oe_dropdown_menu) { display: inline-block; float: right; } @@ -2778,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; @@ -3329,6 +3297,52 @@ body.oe_single_form .oe_single_form_container { overflow: hidden !important; } } +.tooltip { + padding: 0; + margin: 0; + font-family: "Lucida Grande", Helvetica, Verdana, Arial, sans-serif; + color: #4c4c4c; + font-size: 12px; + background: white; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5); + background-color: transparent; +} +.tooltip .tooltip-inner { + text-align: left !important; + max-width: 350px; +} +.tooltip .tooltip-inner .oe_tooltip_string { + color: #ffdd55; + font-weight: bold; + font-size: 13px; +} +.tooltip .tooltip-inner .oe_tooltip_help { + white-space: pre-wrap; +} +.tooltip .tooltip-inner .oe_tooltip_technical { + padding: 0 0 4px 0; + margin: 5px 0 0 15px; +} +.tooltip .tooltip-inner .oe_tooltip_technical li { + list-style: circle; +} +.tooltip .tooltip-inner .oe_tooltip_technical_title { + font-weight: bold; +} +.tooltip .tooltip-inner .oe_tooltip_close { + margin: -5px 0 0 2px; + cursor: default; + float: right; + color: white; +} +.tooltip .tooltip-inner .oe_tooltip_close:hover { + color: #999999; + cursor: pointer; +} +.tooltip .tooltip-inner .oe_tooltip_message { + max-width: 310px; +} + .ui-icon { width: 18px; height: 18px; @@ -3351,6 +3365,10 @@ body.oe_single_form .oe_single_form_container { 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/css/base.sass b/addons/web/static/src/css/base.sass index 7b863cb1527..f1a92f44288 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -473,33 +473,6 @@ $sheet-padding: 16px text-decoration: none margin-bottom: 1px // }}} - // Tooltips {{{ - &.oe_tooltip - font-size: 12px - .oe_tooltip_string - color: #FD5 - font-weight: bold - font-size: 13px - .oe_tooltip_help - white-space: pre-wrap - .oe_tooltip_technical - padding: 0 0 4px 0 - margin: 5px 0 0 15px - li - list-style: circle - .oe_tooltip_technical_title - font-weight: bold - .oe_tooltip_close - margin: -5px 0 0 2px - cursor: default - float: right - color: white - &:hover - color: #999 - cursor: pointer - .oe_tooltip_message - max-width: 310px - // }}} // Notebook {{{ .oe_notebook margin: 8px 0 @@ -667,7 +640,8 @@ $sheet-padding: 16px // }}} // Notifications {{{ .oe_notification - z-index: 1050 + z-index: 1500 + .oe_webclient_timezone_notification a color: white @@ -1578,7 +1552,7 @@ $sheet-padding: 16px // FormView.header {{{ .oe_form > :not(.oe_form_nosheet) header padding-left: 2px - ul + ul:not(.oe_tooltip_technical):not(.oe_dropdown_menu) display: inline-block float: right .oe_button @@ -2248,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 @@ -2704,6 +2681,44 @@ body.oe_single_form overflow: hidden !important // }}} +// End of customize + +// Customize bootstrap3 for tooltip +.tooltip + padding: 0 + margin: 0 + font-family: "Lucida Grande", Helvetica, Verdana, Arial, sans-serif + color: #4c4c4c + font-size: 12px + background: white + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5) + background-color: transparent + .tooltip-inner + text-align: left !important + max-width: 350px + .oe_tooltip_string + color: #FD5 + font-weight: bold + font-size: 13px + .oe_tooltip_help + white-space: pre-wrap + .oe_tooltip_technical + padding: 0 0 4px 0 + margin: 5px 0 0 15px + li + list-style: circle + .oe_tooltip_technical_title + font-weight: bold + .oe_tooltip_close + margin: -5px 0 0 2px + cursor: default + float: right + color: white + &:hover + color: #999 + cursor: pointer + .oe_tooltip_message + max-width: 310px // Hack for ui icon {{{ .ui-icon @@ -2726,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 fca55957fd7..4f12a915a7c 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -1078,8 +1078,8 @@ instance.web.Client = instance.web.Widget.extend({ }, bind_events: function() { var self = this; - this.$el.on('mouseenter', '.oe_systray > div:not([data-tipsy=true])', function() { - $(this).attr('data-tipsy', 'true').tipsy().trigger('mouseenter'); + this.$el.on('mouseenter', '.oe_systray > div:not([data-toggle=tooltip])', function() { + $(this).attr('data-toggle', 'tooltip').tooltip().trigger('mouseenter'); }); this.$el.on('click', '.oe_dropdown_toggle', function(ev) { ev.preventDefault(); @@ -1103,7 +1103,7 @@ instance.web.Client = instance.web.Widget.extend({ }, 0); }); instance.web.bus.on('click', this, function(ev) { - $.fn.tipsy.clear(); + $.fn.tooltip('destroy'); if (!$(ev.target).is('input[type=file]')) { self.$el.find('.oe_dropdown_menu.oe_opened, .oe_dropdown_toggle.oe_opened').removeClass('oe_opened'); } @@ -1457,7 +1457,7 @@ instance.web.embed = function (origin, dbname, login, key, action, options) { $('head').append($('', { '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 90c84ba9cda..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(); } @@ -788,6 +783,22 @@ instance.web.unblockUI = function() { return $.unblockUI.apply($, arguments); }; + +/* Bootstrap defaults overwrite */ +$.fn.tooltip.Constructor.DEFAULTS.placement = 'auto top'; +$.fn.tooltip.Constructor.DEFAULTS.html = true; +$.fn.tooltip.Constructor.DEFAULTS.container = 'body'; +//overwrite bootstrap tooltip method to fix bug when using placement +//auto and the parent element does not exist anymore resulting in +//an error. This should be remove once bootstrap fix the bug +var bootstrap_show_function = $.fn.tooltip.Constructor.prototype.show; +$.fn.tooltip.Constructor.prototype.show = function (e) { + if (this.$element.parent().length === 0){ + return; + } + return bootstrap_show_function.call(this, e); +}; + /** * Registry for all the client actions key: tag value: widget */ 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 0){ + container = $(trigger).parents('.oe_view_manager_view_form'); + } + else { + if (window.$('.modal.in').length>0){ + container = window.$('.modal.in:last()'); + } + } options = _.extend({ - delayIn: 500, - delayOut: 0, - fade: true, + delay: { show: 500, hide: 0 }, + trigger: 'hover', + container: container, title: function() { var template = widget.template + '.tooltip'; if (!QWeb.has_template(template)) { @@ -1880,12 +1898,12 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi widget: widget }); }, - gravity: $.fn.tipsy.autoBounds(50, 'nw'), - html: true, - opacity: 0.85, - trigger: 'hover' }, options || {}); - $(trigger).tipsy(options); + //only show tooltip if we are in debug or if we have a help to show, otherwise it will display + //as empty + if (instance.session.debug || widget.node.attrs.help || (widget.field && widget.field.help)){ + $(trigger).tooltip(options); + } }, /** * Builds a new context usable for operations related to fields by merging @@ -2122,8 +2140,8 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w this.$el.find('.oe_field_translate').click(this.on_translate); } this.$label = this.view ? this.view.$el.find('label[for=' + this.id_for_label + ']') : $(); + this.do_attach_tooltip(this, this.$label[0] || this.$el); if (instance.session.debug) { - this.do_attach_tooltip(this, this.$label[0] || this.$el); this.$label.off('dblclick').on('dblclick', function() { console.log("Field '%s' of type '%s' in View: %o", self.name, (self.node.attrs.widget || self.field.type), self.view); window.w = self; @@ -3338,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(){ @@ -3468,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'); }); }); }); @@ -3603,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/js/views.js b/addons/web/static/src/js/views.js index dc9f706d40e..b9015f6b311 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -581,7 +581,7 @@ instance.web.ViewManager = instance.web.Widget.extend({ var self = this; this.$el.find('.oe_view_manager_switch a').click(function() { self.switch_mode($(this).data('view-type')); - }).tipsy(); + }).tooltip(); var views_ids = {}; _.each(this.views_src, function(view) { self.views[view.view_type] = $.extend({}, view, { @@ -1157,10 +1157,8 @@ instance.web.Sidebar = instance.web.Widget.extend({ this.$('.oe_form_dropdown_section').each(function() { $(this).toggle(!!$(this).find('li').length); }); - - self.$("[title]").tipsy({ - 'html': true, - 'delayIn': 500, + self.$("[title]").tooltip({ + delay: { show: 500, hide: 0} }); }, /** diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 7b502bc4e8a..18a55656df2 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -40,7 +40,7 @@ - @@ -800,12 +800,11 @@ + t-att-class="disabled ? 'oe_list_button_disabled btn_txt oe_link' : 'btn_txt oe_link'" + > @@ -943,7 +942,6 @@ @@ -1005,7 +1003,7 @@
  • Selection: -
      +
      • [] - @@ -1949,13 +1947,14 @@
        +

        Name:

        - - - + + or + 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 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 '' % (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/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 @@ --> + + + + +