From 80657b1c29ec9dea947426fccc1ffc7b20a6d97a Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Mon, 24 Oct 2011 11:07:27 +0200 Subject: [PATCH 01/59] [IMP] support for jsonp bzr revid: chs@openerp.com-20111024090727-f8w5wv08ugxnrpt8 --- addons/web/__openerp__.py | 1 + addons/web/common/http.py | 137 ++++++++++++++++++++++++++----- addons/web/common/session.py | 4 +- addons/web/static/src/js/core.js | 29 +++---- 4 files changed, 132 insertions(+), 39 deletions(-) diff --git a/addons/web/__openerp__.py b/addons/web/__openerp__.py index 0afd43190d6..1cff3c7956b 100644 --- a/addons/web/__openerp__.py +++ b/addons/web/__openerp__.py @@ -28,6 +28,7 @@ "static/lib/underscore/underscore.string.js", "static/lib/labjs/LAB.src.js", "static/lib/py.parse/lib/py.js", + "static/src/js/jq_ajax.js", "static/src/js/boot.js", "static/src/js/core.js", "static/src/js/dates.js", diff --git a/addons/web/common/http.py b/addons/web/common/http.py index e23a0431a7c..ed7a5344192 100644 --- a/addons/web/common/http.py +++ b/addons/web/common/http.py @@ -85,13 +85,23 @@ class WebRequest(object): self.httpresponse = None self.httpsession = request.session self.config = config + self.session = None + + def init_session(self, session_id): + if self.session: + assert self.session.id == session_id + return + + self.session_id = session_id or uuid.uuid4().hex + self.session = self.httpsession.setdefault(self.session_id, session.OpenERPSession(self.session_id)) + self.session.config = self.config def init(self, params): self.params = dict(params) + # OpenERP session setup - self.session_id = self.params.pop("session_id", None) or uuid.uuid4().hex - self.session = self.httpsession.setdefault(self.session_id, session.OpenERPSession()) - self.session.config = self.config + session_id = self.params.pop("session_id", None) + self.init_session(session_id) self.context = self.params.pop('context', None) self.debug = self.params.pop('debug', False) != False @@ -129,25 +139,88 @@ class JsonRequest(WebRequest): """ - def dispatch(self, controller, method, requestf=None, request=None): - """ Calls the method asked for by the JSON-RPC2 request + + def _init_jsonrpc2(self): + assert self.jsonrequest.get('jsonrpc') == '2.0' + self.init(self.jsonrequest.get("params", {})) + response = {"jsonrpc": "2.0" } + return response + + def _init_jsonp(self): + self.init(self.jsonrequest) + return {} + + + def dispatch(self, controller, method): + """ Calls the method asked for by the JSON-RPC2 or JSONP request :param controller: the instance of the controller which received the request :param method: the method which received the request - :param requestf: a file-like object containing an encoded JSON-RPC2 request - :param request: a JSON-RPC2 request - :returns: an utf8 encoded JSON-RPC2 reply + :returns: an utf8 encoded JSON-RPC2 or JSONP reply """ - response = {"jsonrpc": "2.0" } + + requestf = self.httprequest.stream + direct_json_request = None + jsonp_callback = None + if requestf: + direct_json_request = requestf.read() + + if not direct_json_request: + params = self.httprequest.args + direct_json_request = params.get('r') + jsonp_callback = params.get('callback') + + if direct_json_request: + try: + self.jsonrequest = simplejson.loads(direct_json_request, object_hook=nonliterals.non_literal_decoder) + except Exception, e: + _logger.error(e) + return werkzeug.exceptions.BadRequest(e) + else: + # no direct json request, try to get it from jsonp POST request + params = self.httprequest.args + rid = params.get('rid') + session_id = params.get('sid') + if session_id: + self.init_session(session_id) + stored_request = self.session.jsonp_requests.get(rid, {}) + else: + stored_request = {} + + jsonp_callback = stored_request.get('jsonp') + self.jsonrequest = stored_request.get('params', {}) + + + if self.jsonrequest.get('jsonrpc') == '2.0': + response = self._init_jsonrpc2() + + def build_response(response): + content = simplejson.dumps(response, cls=nonliterals.NonLiteralEncoder) + return werkzeug.wrappers.Response( + content, headers=[('Content-Type', 'application/json'), + ('Content-Length', len(content))]) + + + elif jsonp_callback: + + response = self._init_jsonp() + + def build_response(response): + content = "%s(%s);" % (\ + jsonp_callback, + simplejson.dumps(response, cls=nonliterals.NonLiteralEncoder), + ) + + return werkzeug.wrappers.Response( + content, headers=[('Content-Type', 'application/javascript'), + ('Content-Length', len(content))]) + + else: + return werkzeug.exceptions.BadRequest() + error = None try: - # Read POST content or POST Form Data named "request" - if requestf: - self.jsonrequest = simplejson.load(requestf, object_hook=nonliterals.non_literal_decoder) - else: - self.jsonrequest = simplejson.loads(request, object_hook=nonliterals.non_literal_decoder) - self.init(self.jsonrequest.get("params", {})) if _logger.isEnabledFor(logging.DEBUG): _logger.debug("--> %s.%s\n%s", controller.__class__.__name__, method.__name__, pprint.pformat(self.jsonrequest)) response['id'] = self.jsonrequest.get('id') @@ -188,10 +261,8 @@ class JsonRequest(WebRequest): if _logger.isEnabledFor(logging.DEBUG): _logger.debug("<--\n%s", pprint.pformat(response)) - content = simplejson.dumps(response, cls=nonliterals.NonLiteralEncoder) - return werkzeug.wrappers.Response( - content, headers=[('Content-Type', 'application/json'), - ('Content-Length', len(content))]) + + return build_response(response) def jsonrequest(f): """ Decorator marking the decorated method as being a handler for a @@ -205,8 +276,7 @@ def jsonrequest(f): """ @functools.wraps(f) def json_handler(controller, request, config): - return JsonRequest(request, config).dispatch( - controller, f, requestf=request.stream) + return JsonRequest(request, config).dispatch(controller, f) json_handler.exposed = True return json_handler @@ -300,7 +370,8 @@ def session_context(request, storage_path, session_cookie='sessionid'): # either by login process or by HTTP requests without an OpenERP # session id, and are generally noise for key, value in request.session.items(): - if isinstance(value, session.OpenERPSession) and not value._uid: + if isinstance(value, session.OpenERPSession) and not value._uid and not value.jsonp_requests: + _logger.info('remove session %s: %r', key, value.jsonp_requests) del request.session[key] # FIXME: remove this when non-literals disappear @@ -344,6 +415,28 @@ class ControllerType(type): class Controller(object): __metaclass__ = ControllerType + +class JSONP(Controller): + _cp_path = '/web/jsonp' + + @httprequest + def post(self, req, request_id, params, callback): + params = simplejson.loads(params, object_hook=nonliterals.non_literal_decoder) + params.update( + session_id=req.session.id, + ) + params['session_id'] = req.session.id + req.session.jsonp_requests[request_id] = { + 'jsonp': callback, + 'params': params, + 'id': request_id, + } + + headers=[('Content-Type', 'text/plain; charset=utf-8')] + response = werkzeug.wrappers.Response(request_id, headers=headers) + return response + + class Root(object): """Root WSGI application for the OpenERP Web Client. diff --git a/addons/web/common/session.py b/addons/web/common/session.py index e8027db8ea4..06f46faa9d0 100644 --- a/addons/web/common/session.py +++ b/addons/web/common/session.py @@ -28,7 +28,8 @@ class OpenERPSession(object): Used to store references to non-literal domains which need to be round-tripped to the client browser. """ - def __init__(self): + def __init__(self, sid): + self.id = sid self.config = None self._db = False self._uid = False @@ -37,6 +38,7 @@ class OpenERPSession(object): self.context = {} self.contexts_store = {} self.domains_store = {} + self.jsonp_requests = {} # FIXME use a LRU def __getstate__(self): state = dict(self.__dict__) diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 4ed33341ea6..1b6a6302f72 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -346,12 +346,12 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web * @param {String} [server] JSON-RPC endpoint hostname * @param {String} [port] JSON-RPC endpoint port */ - init: function(server, port) { + init: function(server) { this._super(); - this.server = (server == undefined) ? location.hostname : server; - this.port = (port == undefined) ? location.port : port; - this.rpc_mode = (server == location.hostname) ? "ajax" : "jsonp"; - this.debug = (window.location.search.indexOf('?debug') !== -1); + var hostname = _('%s//%s').sprintf(location.protocol, location.host); + this.server = (server == undefined) ? hostname : server; + this.rpc_mode = (this.server == hostname) ? "oe-json" : "oe-jsonp"; + this.debug = ($.deparam($.param.querystring()).debug != undefined); this.session_id = false; this.uid = false; this.user_context= {}; @@ -390,13 +390,9 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web // Call using the rpc_mode var deferred = $.Deferred(); - this.rpc_ajax(url, { - jsonrpc: "2.0", - method: "call", - params: params, - id: _.uniqueId('browser-client-') - }).then(function () {deferred.resolve.apply(deferred, arguments);}, - function(error) {deferred.reject(error, $.Event());}); + this.rpc_ajax(url, params) + .then(function () {deferred.resolve.apply(deferred, arguments);}, + function(error) {deferred.reject(error, $.Event());}); return deferred.fail(function() { deferred.fail(function(error, event) { if (!event.isDefaultPrevented()) { @@ -422,10 +418,11 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web var ajax = _.extend({ type: "POST", url: url, - dataType: 'json', + dataType: this.rpc_mode, contentType: 'application/json', - data: JSON.stringify(payload), - processData: false + data: payload, + processData: false, + openerp: _.extend({}, this), // need a plainObject }, url); var deferred = $.Deferred(); $.ajax(ajax).done(function(response, textStatus, jqXHR) { @@ -440,7 +437,7 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web } self.uid = false; self.on_session_invalid(function() { - self.rpc(url, payload.params, + self.rpc(url, payload, function() { deferred.resolve.apply(deferred, arguments); }, From 66a99fd118a5309f801d48c2cbc75ac08cc76805 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 25 Oct 2011 11:50:16 +0200 Subject: [PATCH 02/59] [FIX] web: add missing file bzr revid: chs@openerp.com-20111025095016-4ebswa44be2h4cmd --- addons/web/static/src/js/jq_ajax.js | 192 ++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 addons/web/static/src/js/jq_ajax.js diff --git a/addons/web/static/src/js/jq_ajax.js b/addons/web/static/src/js/jq_ajax.js new file mode 100644 index 00000000000..cf90016ba4c --- /dev/null +++ b/addons/web/static/src/js/jq_ajax.js @@ -0,0 +1,192 @@ + + $.ajaxSetup({ + converters: { + "json oe-jsonp": true, + "json oe-json": true, + } + }); + + + // common preconditions checks + $.ajaxPrefilter("oe-json oe-jsonp", function(options, originalOptions, jqXHR) { + console.log('use', options.dataType); + if (!$.isPlainObject(options.openerp)) { + console.error(options.openerp); + $.error('"openerp" option is required.'); + } + + if (_(options.openerp.server).endsWith('/')) { + options.openerp.server = options.openerp.server.substr(0, options.openerp.server.length-1); + } + + if (!$.isPlainObject(options.data)) { + $.error('data must not be serialized'); + } + options.processData = false; + }); + + + + $.ajaxPrefilter("oe-json", function(options, originalOptions, jqXHR) { + options.data = JSON.stringify({ + jsonrpc: '2.0', + method: 'call', + params: options.data, + id: _.uniqueId('browser-client-') + }); + + return 'json'; + }); + + + $.ajaxPrefilter("oe-jsonp", function(options, originalOptions, jqXHR) { + + var data = null; + if (options.data) { + data = $.param({r:JSON.stringify(options.data)}); + } + + + var max_url_length = options.max_url_length || 1000, + absolute_url, full_url; + + var r_has_protocol = /^https?:\/\//, + r_absolute_internal = /^\/[^\/]/; // starts with / (but not //) + + + if (r_has_protocol.test(options.url)) { + if (!_(options.url).startsWith(options.openerp.server + '/')) { + $.error('can only contact openerp.server'); + } + absolute_url = options.url; + } else if (r_absolute_internal.test(options.url)) { + absolute_url = options.openerp.server + options.url; + } else { // relative url + var parts = document.location.pathname.split('/'); + parts.pop(); + parts.push(options.url); + absolute_url = options.openerp.server + parts.join('/'); + } + + + /// now, made the same url changes that jQuery will do... + var rquery = /\?/, + rts = /([?&])_=[^&]*/; + + full_url = absolute_url; + if (data) { + full_url += (rquery.test(full_url) ? "&" : "?") + data; + } + + // Add anti-cache in url if needed + if (!options.cache) { + var ts = $.now(), + // try replacing _= if it is there + ret = full_url.replace(rts, "$1_=" + ts); + + // if nothing was replaced, add timestamp to the end + full_url = ret + ((ret === full_url) ? (rquery.test(full_url) ? "&" : "?") + "_=" + ts : ""); + } + + console.log('absolute_url', absolute_url); + console.log('full_url', full_url); + + options.url = absolute_url; + + if (full_url.length < max_url_length) { + options.type = "GET"; + options.data = data; + return "jsonp"; // classic jsonp query... + } + }); + + + $.ajaxTransport("oe-jsonp", function(options, originalOptions, jqXHR) { + + console.log('real oe-jsonp', options); + var $iframe = null; + var $form = $('
') + .attr('method', 'POST') + .attr('enctype', "multipart/form-data") + .attr('action', options.openerp.server + "/web/jsonp/post") + .hide() + .appendTo($('body')) + ; + + console.log($form); + + function cleanUp() { + if ($iframe) { + $iframe.unbind("load").attr("src", "javascript:false;").remove(); + } + $form.remove(); + } + + return { + + send: function(headers, completeCallback) { + + var ifid = _.uniqueId('oe_jsonp_iframe_'); + var request_id = _.uniqueId('browser-client-'); + var oe_callback = _.uniqueId('oe_callback_'); + + window[oe_callback] = function(result) { + completeCallback(200, 'success', {json: result}); + }; + + + $iframe = $(_("").sprintf(ifid, ifid)); + + + // the first bind is fired up when the iframe is added to the DOM + $iframe.bind('load', function() { + //console.log('bind1', this); + // the second bind is fired up when the result of the form submission is received + $iframe.unbind('load').bind('load', function() { + //console.log('bind2', this); + + // we cannot access the content of remote iframe. + // but we don't care, we try to get the result in any cases + + $.ajax({ + type: "GET", + url: options.url, + dataType: 'jsonp', + jsonp: false, // do not append callback=? argument on query string + jsonpCallback: oe_callback, + data: { + sid: options.openerp.session_id, + rid: request_id, + }, + }).always(function() { + cleanUp(); + }); + + }); + + + // now that the iframe can receive data, we fill and submit the form + var params = JSON.stringify(options.data); + + $form + .append($('').attr('value', options.openerp.session_id)) + .append($('').attr('value', request_id)) + .append($('').attr('value', params)) + .append($('').attr('value', oe_callback)) + .submit() + ; + + }); + + $form.attr('target', ifid) // set the iframe as target of the form + .after($iframe); // append the iframe to the DOM (will trigger the first load) + + }, + abort: function() { + cleanUp(); + }, + }; + + }); + + From 1b7125432843d0db93628b04e56065e77d7d14ee Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 26 Oct 2011 15:27:14 +0200 Subject: [PATCH 03/59] [FIX] jsonp: force crossdomain request bzr revid: chs@openerp.com-20111026132714-6uko5u7f35y2yaj4 --- addons/web/static/src/js/jq_ajax.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/web/static/src/js/jq_ajax.js b/addons/web/static/src/js/jq_ajax.js index cf90016ba4c..8d347c398d7 100644 --- a/addons/web/static/src/js/jq_ajax.js +++ b/addons/web/static/src/js/jq_ajax.js @@ -41,6 +41,8 @@ $.ajaxPrefilter("oe-jsonp", function(options, originalOptions, jqXHR) { + options.crossDomain = true; + var data = null; if (options.data) { data = $.param({r:JSON.stringify(options.data)}); From 10bbbad52f76a7fc40eaf6de94bf9b3d14f8ff02 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 9 Nov 2011 09:14:59 +0100 Subject: [PATCH 04/59] [FIX] base.xml: use full absolute url for all images bzr revid: chs@openerp.com-20111109081459-b031iutztocpxo9w --- addons/web/static/src/xml/base.xml | 72 +++++++++++++++--------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 1fc98ba34ee..01da70335b6 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -264,7 +264,7 @@
- +
@@ -304,7 +304,7 @@ @@ -813,7 +813,7 @@ @@ -826,12 +826,12 @@ t-attf-class="field_#{widget.type}" t-attf-style="width: #{widget.field.translate ? '99' : '100'}%" > - +
-
- + Full featured
@@ -313,7 +313,7 @@
- + Open Source
@@ -322,7 +322,7 @@
- + User Friendly
@@ -350,13 +350,13 @@
  • - +
  • - +
  • - +
@@ -694,7 +694,7 @@ @@ -779,7 +779,7 @@ t-attf-class="field_#{widget.type}" t-attf-style="width: #{widget.field.translate ? '99' : '100'}%" /> - +
- @@ -938,14 +938,14 @@
@@ -973,7 +973,7 @@ @@ -982,13 +982,13 @@ @@ -996,7 +996,7 @@ - + Uploading ... @@ -1007,7 +1007,7 @@ @@ -1057,7 +1057,7 @@ t-att-title="attrs.help" t-att-class="classes.join(' ')" t-att-autofocus="attrs.default_focus === '1' ? 'autofocus' : undefined"> - +
@@ -1204,7 +1204,7 @@ - +

@@ -1292,7 +1292,7 @@

+ t-att-src='widget.session.server + "/web/static/src/img/collapse.gif"' width="16" height="16" border="0"/> @@ -1305,22 +1305,22 @@
+ id="side-add" t-att-src='widget.session.server + "/web/static/src/img/icons/gtk-add.png"' style="cursor: pointer;"/> - + + id="side-edit" t-att-src='widget.session.server + "/web/static/src/img/icons/gtk-edit.png"' style="cursor: pointer;"/> + id="side-up" t-att-src='widget.session.server + "/web/static/src/img/icons/gtk-go-up.png"' style="cursor: pointer;"/> + id="side-down" t-att-src='widget.session.server + "/web/static/src/img/icons/gtk-go-down.png"' style="cursor: pointer;"/>
@@ -1402,7 +1402,7 @@ - + @@ -1518,7 +1518,7 @@ - + From bccc64ac7c2a6671a15f74d13465c27b8f13e9d8 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 9 Nov 2011 09:16:26 +0100 Subject: [PATCH 05/59] [FIX] use absolute url when getting css/js/qweb files + use a static proxy for getting qweb files bzr revid: chs@openerp.com-20111109081626-l868h7w8glinbxdl --- addons/web/common/http.py | 14 +++++++++ addons/web/static/src/js/core.js | 49 ++++++++++++++++++++++++++--- addons/web/static/src/js/jq_ajax.js | 21 +++---------- 3 files changed, 63 insertions(+), 21 deletions(-) diff --git a/addons/web/common/http.py b/addons/web/common/http.py index ed7a5344192..ab3c3c4129b 100644 --- a/addons/web/common/http.py +++ b/addons/web/common/http.py @@ -9,6 +9,7 @@ import logging import urllib import os import pprint +import re import sys import traceback import uuid @@ -436,6 +437,19 @@ class JSONP(Controller): response = werkzeug.wrappers.Response(request_id, headers=headers) return response + @jsonrequest + def static_proxy(self, req, path): + #req.config.socket_port + + + #if not re.match('^/[^/]+/static/.*', path): + # return werkzeug.exceptions.BadRequest() + + env = req.httprequest.environ + port = env['SERVER_PORT'] + + o = urllib.urlopen('http://127.0.0.1:%s%s' % (port, path)) + return o.read() class Root(object): """Root WSGI application for the OpenERP Web Client. diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 951e6e2b01f..fac18f18734 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -349,7 +349,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. init: function(server) { this._super(); var hostname = _('%s//%s').sprintf(location.protocol, location.host); - this.server = (server == undefined) ? hostname : server; + this.server = _.rtrim((server == undefined) ? hostname : server, '/'); this.rpc_mode = (this.server == hostname) ? "oe-json" : "oe-jsonp"; this.debug = ($.deparam($.param.querystring()).debug != undefined); this.session_id = false; @@ -370,6 +370,29 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. start: function() { this.session_restore(); }, + + get_absolute_url: function(path) { + var r_has_protocol = /^https?:\/\//, + r_absolute_internal = /^\/[^\/]/; // starts with / (but not //) + + + if (r_has_protocol.test(path)) { + if (!_(path).startsWith(this.server + '/')) { + $.error('can only contact openerp.server'); + } + absolute_url = path; + } else if (r_absolute_internal.test(path)) { + absolute_url = this.server + path; + } else { // relative url + // XXX is it correct to mix document.location and this.server ?? + var parts = document.location.pathname.split('/'); + parts.pop(); + parts.push(path); + absolute_url = this.server + parts.join('/'); + } + return absolute_url + }, + /** * Executes an RPC call, registering the provided callbacks. * @@ -574,11 +597,11 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. self.user_context.lang.replace("_", "-") + ".js" ]; + self.rpc('/web/webclient/qweblist', {"mods": modules}, self.do_load_qweb); self.rpc('/web/webclient/csslist', {"mods": modules}, self.do_load_css); self.rpc('/web/webclient/jslist', {"mods": modules}, function(files) { self.do_load_js(file_list.concat(files)); }); - self.rpc('/web/webclient/qweblist', {"mods": modules}, self.do_load_qweb); openerp._modules_loaded = true; }); }); @@ -587,7 +610,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. var self = this; _.each(files, function (file) { $('head').append($('', { - 'href': file, + 'href': self.get_absolute_url(file), 'rel': 'stylesheet', 'type': 'text/css' })); @@ -599,7 +622,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. var file = files.shift(); var tag = document.createElement('script'); tag.type = 'text/javascript'; - tag.src = file; + tag.src = self.get_absolute_url(file); tag.onload = tag.onreadystatechange = function() { if ( (tag.readyState && tag.readyState != "loaded" && tag.readyState != "complete") || tag.onload_done ) return; @@ -615,7 +638,23 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. do_load_qweb: function(files) { var self = this; _.each(files, function(file) { - openerp.web.qweb.add_template(file); + self.rpc({ + //url: self.get_absolute_url(file), + url: '/web/jsonp/static_proxy', + async: false, + //dataType: 'text', + + }, + { + path: file, + }, + function(xml) { + //function(result) { + // console.log('do_load_qweb', result); + // var xml = result.result; + //}).then(function(xml) { + openerp.web.qweb.add_template(_(xml).trim()); + }); }); }, on_modules_loaded: function() { diff --git a/addons/web/static/src/js/jq_ajax.js b/addons/web/static/src/js/jq_ajax.js index 8d347c398d7..19c3bb31295 100644 --- a/addons/web/static/src/js/jq_ajax.js +++ b/addons/web/static/src/js/jq_ajax.js @@ -9,16 +9,11 @@ // common preconditions checks $.ajaxPrefilter("oe-json oe-jsonp", function(options, originalOptions, jqXHR) { - console.log('use', options.dataType); if (!$.isPlainObject(options.openerp)) { console.error(options.openerp); $.error('"openerp" option is required.'); } - if (_(options.openerp.server).endsWith('/')) { - options.openerp.server = options.openerp.server.substr(0, options.openerp.server.length-1); - } - if (!$.isPlainObject(options.data)) { $.error('data must not be serialized'); } @@ -49,9 +44,10 @@ } + var max_url_length = options.max_url_length || 1000, absolute_url, full_url; - + /* var r_has_protocol = /^https?:\/\//, r_absolute_internal = /^\/[^\/]/; // starts with / (but not //) @@ -69,7 +65,9 @@ parts.push(options.url); absolute_url = options.openerp.server + parts.join('/'); } - + // */ + + var absolute_url = options.openerp.get_absolute_url(options.url); /// now, made the same url changes that jQuery will do... var rquery = /\?/, @@ -89,9 +87,6 @@ // if nothing was replaced, add timestamp to the end full_url = ret + ((ret === full_url) ? (rquery.test(full_url) ? "&" : "?") + "_=" + ts : ""); } - - console.log('absolute_url', absolute_url); - console.log('full_url', full_url); options.url = absolute_url; @@ -105,7 +100,6 @@ $.ajaxTransport("oe-jsonp", function(options, originalOptions, jqXHR) { - console.log('real oe-jsonp', options); var $iframe = null; var $form = $('
') .attr('method', 'POST') @@ -115,8 +109,6 @@ .appendTo($('body')) ; - console.log($form); - function cleanUp() { if ($iframe) { $iframe.unbind("load").attr("src", "javascript:false;").remove(); @@ -142,11 +134,8 @@ // the first bind is fired up when the iframe is added to the DOM $iframe.bind('load', function() { - //console.log('bind1', this); // the second bind is fired up when the result of the form submission is received $iframe.unbind('load').bind('load', function() { - //console.log('bind2', this); - // we cannot access the content of remote iframe. // but we don't care, we try to get the result in any cases From fafa6b2d910735bd7d193a2471ec4797552456c2 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 15 Nov 2011 17:10:16 +0100 Subject: [PATCH 06/59] [FIX] jq_ajax: addapt code to new version of underscore.string [IMP] jq_ajax: only show transport iframe in debug mode bzr revid: chs@openerp.com-20111115161016-q1p2ne4zp1geui92 --- addons/web/static/src/js/jq_ajax.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/js/jq_ajax.js b/addons/web/static/src/js/jq_ajax.js index 19c3bb31295..611ab1e1e22 100644 --- a/addons/web/static/src/js/jq_ajax.js +++ b/addons/web/static/src/js/jq_ajax.js @@ -129,7 +129,8 @@ }; - $iframe = $(_("").sprintf(ifid, ifid)); + var display = options.openerp.debug ? 'block' : 'none'; + $iframe = $(_.str.sprintf("", ifid, ifid, display)); // the first bind is fired up when the iframe is added to the DOM From bc9149f5b682e3969e913cf437d8719d01dff6e1 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 15 Nov 2011 17:12:51 +0100 Subject: [PATCH 07/59] [FIX] lock accesses to session file bzr revid: chs@openerp.com-20111115161251-wntoqdx42jbh7k0e --- addons/web/common/http.py | 65 +++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/addons/web/common/http.py b/addons/web/common/http.py index ab3c3c4129b..e5af2621c89 100644 --- a/addons/web/common/http.py +++ b/addons/web/common/http.py @@ -9,8 +9,9 @@ import logging import urllib import os import pprint -import re +#import re import sys +import threading import traceback import uuid import xmlrpclib @@ -176,7 +177,7 @@ class JsonRequest(WebRequest): try: self.jsonrequest = simplejson.loads(direct_json_request, object_hook=nonliterals.non_literal_decoder) except Exception, e: - _logger.error(e) + _logger.exception(e) return werkzeug.exceptions.BadRequest(e) else: # no direct json request, try to get it from jsonp POST request @@ -352,17 +353,19 @@ STORES = {} @contextlib.contextmanager def session_context(request, storage_path, session_cookie='sessionid'): - session_store = STORES.get(storage_path) + session_store, session_lock = STORES.get(storage_path, (None, None)) if not session_store: session_store = werkzeug.contrib.sessions.FilesystemSessionStore( storage_path) - STORES[storage_path] = session_store + session_lock = threading.Lock() + STORES[storage_path] = session_store, session_lock sid = request.cookies.get(session_cookie) - if sid: - request.session = session_store.get(sid) - else: - request.session = session_store.new() + with session_lock: + if sid: + request.session = session_store.get(sid) + else: + request.session = session_store.new() try: yield request.session @@ -375,29 +378,31 @@ def session_context(request, storage_path, session_cookie='sessionid'): _logger.info('remove session %s: %r', key, value.jsonp_requests) del request.session[key] - # FIXME: remove this when non-literals disappear - if sid: - # Re-load sessions from storage and merge non-literal - # contexts and domains (they're indexed by hash of the - # content so conflicts should auto-resolve), otherwise if - # two requests alter those concurrently the last to finish - # will overwrite the previous one, leading to loss of data - # (a non-literal is lost even though it was sent to the - # client and client errors) - # - # note that domains_store and contexts_store are append-only (we - # only ever add items to them), so we can just update one with the - # other to get the right result, if we want to merge the - # ``context`` dict we'll need something smarter - in_store = session_store.get(sid) - for k, v in request.session.iteritems(): - stored = in_store.get(k) - if stored and isinstance(v, session.OpenERPSession)\ - and v != stored: - v.contexts_store.update(stored.contexts_store) - v.domains_store.update(stored.domains_store) + with session_lock: + # FIXME: remove this when non-literals disappear + if sid: + # Re-load sessions from storage and merge non-literal + # contexts and domains (they're indexed by hash of the + # content so conflicts should auto-resolve), otherwise if + # two requests alter those concurrently the last to finish + # will overwrite the previous one, leading to loss of data + # (a non-literal is lost even though it was sent to the + # client and client errors) + # + # note that domains_store and contexts_store are append-only (we + # only ever add items to them), so we can just update one with the + # other to get the right result, if we want to merge the + # ``context`` dict we'll need something smarter + in_store = session_store.get(sid) + for k, v in request.session.iteritems(): + stored = in_store.get(k) + if stored and isinstance(v, session.OpenERPSession)\ + and v != stored: + v.contexts_store.update(stored.contexts_store) + v.domains_store.update(stored.domains_store) + v.jsonp_requests.update(stored.jsonp_requests) - session_store.save(request.session) + session_store.save(request.session) #---------------------------------------------------------- # OpenERP Web Module/Controller Loading and URL Routing From 7e9d606238ed1fa00d2bf8b852987889566c49e0 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 15 Nov 2011 18:04:08 +0100 Subject: [PATCH 08/59] [IMP] Connection: new method to bind to a server. Must be called before login [IMP] loading of qweb/css/js files are now sequencial bzr revid: chs@openerp.com-20111115170408-u1i805s1854igyja --- addons/web/static/src/js/chrome.js | 36 +++++--- addons/web/static/src/js/core.js | 134 ++++++++++++++++++----------- 2 files changed, 107 insertions(+), 63 deletions(-) diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 2b838ee3743..31ea05b572b 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -977,12 +977,6 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie this._super(null, element_id); openerp.webclient = this; - var params = {}; - if(jQuery.param != undefined && jQuery.deparam(jQuery.param.querystring()).kitten != undefined) { - this.$element.addClass("kitten-mode-activated"); - } - this.$element.html(QWeb.render("Interface", params)); - this.notification = new openerp.web.Notification(this); this.loading = new openerp.web.Loading(this); this.crashmanager = new openerp.web.CrashManager(); @@ -997,8 +991,6 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie this.session.on_session_invalid.add_last(this.header.do_update); this.session.on_session_valid.add_last(this.on_logged); - this.menu = new openerp.web.Menu(this, "oe_menu", "oe_secondary_menu"); - this.menu.on_action.add(this.on_menu_action); this.url_internal_hashchange = false; this.url_external_hashchange = false; @@ -1007,12 +999,28 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie }, start: function() { this._super.apply(this, arguments); - this.notification.prependTo(this.$element); - this.loading.appendTo($('#oe_loading')); - this.header.appendTo($("#oe_header")); - this.session.start(); - this.login.appendTo($('#oe_login')); - this.menu.start(); + var self = this; + openerp.connection.bind(function() { + + var params = {}; + if(jQuery.param != undefined && jQuery.deparam(jQuery.param.querystring()).kitten != undefined) { + self.$element.addClass("kitten-mode-activated"); + } + self.$element.html(QWeb.render("Interface", params)); + openerp.connection.session_restore(); + + + // TODO nivification of menu Widget !!! + self.menu = new openerp.web.Menu(self, "oe_menu", "oe_secondary_menu"); + self.menu.on_action.add(self.on_menu_action); + + + self.notification.prependTo(self.$element); + self.loading.appendTo($('#oe_loading')); + self.header.appendTo($("#oe_header")); + self.login.appendTo($('#oe_login')); + self.menu.start(); + }); }, do_reload: function() { this.session.session_restore(); diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 7cd81d2a7c1..590438c09dc 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -346,29 +346,43 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. * @param {String} [server] JSON-RPC endpoint hostname * @param {String} [port] JSON-RPC endpoint port */ - init: function(server) { + init: function() { + + // FIXME need to be a real singleton. + // create more than one Connection on the same instance will not works + this._super(); - var hostname = _('%s//%s').sprintf(location.protocol, location.host); - this.server = _.rtrim((server == undefined) ? hostname : server, '/'); - this.rpc_mode = (this.server == hostname) ? "oe-json" : "oe-jsonp"; + this.server = null; this.debug = ($.deparam($.param.querystring()).debug != undefined); + // TODO: session should have an optional name indicating that they'll + // be saved to (and revived from) cookies + this.name = 'session'; + }, + + bind: function(server, continuation) { + + if(_.isFunction(server)) { + continuation = server; + server = null; + } + + if (this.server) { + throw new Error("Connection already bind to " + this.server); + } + var hostname = _.str.sprintf('%s//%s', location.protocol, location.host); + this.server = _.str.rtrim((!server) ? hostname : server, '/'); + this.rpc_mode = (this.server == hostname) ? "oe-json" : "oe-jsonp"; this.session_id = false; this.uid = false; this.user_context= {}; this.db = false; + this.module_loading = $.Deferred(); this.module_list = []; this.module_loaded = {"web": true}; this.context = {}; this.shortcuts = []; this.active_id = null; - // TODO: session should have an optional name indicating that they'll - // be saved to (and revived from) cookies - this.name = 'session'; - this.do_load_qweb(['/web/webclient/qweb']); - }, - - start: function() { - this.session_restore(); + this.do_load_qweb(['/web/webclient/qweb'], continuation); }, get_absolute_url: function(path) { @@ -377,7 +391,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. if (r_has_protocol.test(path)) { - if (!_(path).startsWith(this.server + '/')) { + if (!_.str.startsWith(path, this.server + '/')) { $.error('can only contact openerp.server'); } absolute_url = path; @@ -426,6 +440,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. }); }).then(success_callback, error_callback).promise(); }, + /** * Raw JSON-RPC call * @@ -491,9 +506,8 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. /** * The session is validated either by login or by restoration of a previous session */ - on_session_valid: function() { - if(!openerp._modules_loaded) - this.load_modules(); + on_session_valid: function(continuation) { + this.load_modules(continuation); }, on_session_invalid: function(contination) { }, @@ -509,15 +523,17 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. self.user_context = result.context; self.db = result.db; self.session_save(); - self.on_session_valid(); + + self.on_session_valid(success_callback); return true; - }).then(success_callback); + //}).done(success_callback); + }); }, login: function() { this.session_login.apply(this, arguments); }, /** * Reloads uid and session_id from local storage, if they exist */ - session_restore: function () { + session_restore: function (continuation) { var self = this; this.session_id = this.get_cookie('session_id'); return this.rpc("/web/session/get_session_info", {}).then(function(result) { @@ -525,11 +541,11 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. self.user_context = result.context; self.db = result.db; if (self.uid) - self.on_session_valid(); + self.on_session_valid(continuation); else - self.on_session_invalid(); + self.on_session_invalid(continuation); }, function() { - self.on_session_invalid(); + self.on_session_invalid(continuation); }); }, /** @@ -583,9 +599,17 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. }, /** * Load additional web addons of that instance and init them + * FIXME do all actions in sync... */ - load_modules: function() { + load_modules: function(continuation) { var self = this; + + this.module_loading.done(continuation); + //if (this.module_loading.state() !== "pending") { + if (this.module_loading.isResolved() || this.module_loading.isRejected()) { + return; + } + this.rpc('/web/session/modules', {}, function(result) { self.module_list = result; var lang = self.user_context.lang; @@ -597,16 +621,36 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. self.user_context.lang.replace("_", "-") + ".js" ]; - self.rpc('/web/webclient/qweblist', {"mods": modules}, self.do_load_qweb); - self.rpc('/web/webclient/csslist', {"mods": modules}, self.do_load_css); - self.rpc('/web/webclient/jslist', {"mods": modules}, function(files) { + /* + self.rpc('/web/webclient/qweblist', {mods: modules}, self.do_load_qweb); + self.rpc('/web/webclient/csslist', {mods: modules}, self.do_load_css); + self.rpc('/web/webclient/jslist', {mods: modules}, function(files) { self.do_load_js(file_list.concat(files)); }); openerp._modules_loaded = true; + // */ + + self.rpc('/web/webclient/qweblist', {mods: modules}, function(files) { + self.do_load_qweb(files, function() { + // once qweb files are loaded... + self.rpc('/web/webclient/csslist', {mods: modules}, function(files) { + self.do_load_css(files, function() { + // once css files are loaded + self.rpc('/web/webclient/jslist', {mods: modules}, function(files) { + self.do_load_js(file_list.concat(files), function() { + self.on_modules_loaded(); + self.module_loading.resolve(); + }); + }); + }); + }); + }); + }); + }); }); }, - do_load_css: function (files) { + do_load_css: function (files, callback) { var self = this; _.each(files, function (file) { $('head').append($('', { @@ -615,8 +659,9 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. 'type': 'text/css' })); }); + if (callback) { callback(); } }, - do_load_js: function(files) { + do_load_js: function(files, callback) { var self = this; if(files.length != 0) { var file = files.shift(); @@ -627,35 +672,26 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. if ( (tag.readyState && tag.readyState != "loaded" && tag.readyState != "complete") || tag.onload_done ) return; tag.onload_done = true; - self.do_load_js(files); + self.do_load_js(files, callback); }; var head = document.head || document.getElementsByTagName('head')[0]; head.appendChild(tag); } else { - this.on_modules_loaded(); + if (callback) { callback(); } } }, - do_load_qweb: function(files) { + do_load_qweb: function(files, callback) { var self = this; - _.each(files, function(file) { - self.rpc({ - //url: self.get_absolute_url(file), - url: '/web/jsonp/static_proxy', - async: false, - //dataType: 'text', - - }, - { - path: file, - }, - function(xml) { - //function(result) { - // console.log('do_load_qweb', result); - // var xml = result.result; - //}).then(function(xml) { - openerp.web.qweb.add_template(_(xml).trim()); + + if (files.length != 0) { + var file = files.shift(); + self.rpc('/web/jsonp/static_proxy', {path: file}, function(xml) { + openerp.web.qweb.add_template(_.str.trim(xml)); + self.do_load_qweb(files, callback); }); - }); + } else { + if (callback) { callback(); } + } }, on_modules_loaded: function() { for(var j=0; j Date: Thu, 17 Nov 2011 13:48:19 +0100 Subject: [PATCH 09/59] [FIX] typo bzr revid: chs@openerp.com-20111117124819-qmxoit9i2ryo8szo --- addons/web/static/src/js/core.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 590438c09dc..8d7bed56b5b 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -367,7 +367,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. } if (this.server) { - throw new Error("Connection already bind to " + this.server); + throw new Error("Connection already bound to " + this.server); } var hostname = _.str.sprintf('%s//%s', location.protocol, location.host); this.server = _.str.rtrim((!server) ? hostname : server, '/'); From 4e85f0762cc69af8efdb88ec857329ac955afe0b Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 17 Nov 2011 13:49:26 +0100 Subject: [PATCH 10/59] [IMP] Connection: add utility method that bind() then login() bzr revid: chs@openerp.com-20111117124926-y3z3osoq76va0kjy --- addons/web/static/src/js/core.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 8d7bed56b5b..113b83f57dc 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -385,6 +385,13 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. this.do_load_qweb(['/web/webclient/qweb'], continuation); }, + connect: function(server, db, login, password, continuation) { + var self = this; + this.bind(server, function() { + self.login(db, login, password, continuation); + }); + }, + get_absolute_url: function(path) { var r_has_protocol = /^https?:\/\//, r_absolute_internal = /^\/[^\/]/; // starts with / (but not //) From 8769c57e941652aafc910c9deb69bbe5c544f6fa Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 22 Nov 2011 13:08:06 +0100 Subject: [PATCH 11/59] [FIX] session merging bzr revid: chs@openerp.com-20111122120806-mlg170fohfnx8gk8 --- addons/web/common/http.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/addons/web/common/http.py b/addons/web/common/http.py index 7352a6f5cb9..aadae03832e 100644 --- a/addons/web/common/http.py +++ b/addons/web/common/http.py @@ -374,12 +374,14 @@ def session_context(request, storage_path, session_cookie='sessionid'): # either by login process or by HTTP requests without an OpenERP # session id, and are generally noise for key, value in request.session.items(): - if isinstance(value, session.OpenERPSession) and not value._uid and not value.jsonp_requests: + if (isinstance(value, session.OpenERPSession) + and not value._uid + and not value.jsonp_requests + ): _logger.info('remove session %s: %r', key, value.jsonp_requests) del request.session[key] with session_lock: - # FIXME: remove this when non-literals disappear if sid: # Re-load sessions from storage and merge non-literal # contexts and domains (they're indexed by hash of the @@ -402,6 +404,11 @@ def session_context(request, storage_path, session_cookie='sessionid'): v.domains_store.update(stored.domains_store) v.jsonp_requests.update(stored.jsonp_requests) + # add missing keys + for k, v in in_store.iteritems(): + if k not in request.session: + request.session[k] = v + session_store.save(request.session) #---------------------------------------------------------- From 2834e0f7bd2ec92430a3bd1f705f6e5dd33ab2ce Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 22 Nov 2011 13:16:55 +0100 Subject: [PATCH 12/59] [IMP] pop jsonp_requests to avoid memory overload bzr revid: chs@openerp.com-20111122121655-7nqn1rvcd2iwy4mg --- addons/web/common/http.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/common/http.py b/addons/web/common/http.py index aadae03832e..afad089f1d8 100644 --- a/addons/web/common/http.py +++ b/addons/web/common/http.py @@ -186,7 +186,7 @@ class JsonRequest(WebRequest): session_id = params.get('sid') if session_id: self.init_session(session_id) - stored_request = self.session.jsonp_requests.get(rid, {}) + stored_request = self.session.jsonp_requests.pop(rid, {}) else: stored_request = {} From 050d369f4aec38f7c876bbd5f307f3085a647b71 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 22 Nov 2011 13:18:33 +0100 Subject: [PATCH 13/59] [IMP] better debugging output bzr revid: chs@openerp.com-20111122121833-okbmche6lhw78d4d --- addons/web/common/http.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/addons/web/common/http.py b/addons/web/common/http.py index afad089f1d8..4d44f3175f8 100644 --- a/addons/web/common/http.py +++ b/addons/web/common/http.py @@ -165,6 +165,7 @@ class JsonRequest(WebRequest): requestf = self.httprequest.stream direct_json_request = None jsonp_callback = None + rid = None if requestf: direct_json_request = requestf.read() @@ -222,10 +223,12 @@ class JsonRequest(WebRequest): return werkzeug.exceptions.BadRequest() error = None + if not rid: + rid = self.jsonrequest.get('id') try: if _logger.isEnabledFor(logging.DEBUG): - _logger.debug("--> %s.%s\n%s", controller.__class__.__name__, method.__name__, pprint.pformat(self.jsonrequest)) - response['id'] = self.jsonrequest.get('id') + _logger.debug("[%s] --> %s.%s\n%s", rid, controller.__class__.__name__, method.__name__, pprint.pformat(self.jsonrequest)) + response['id'] = rid response["result"] = method(controller, self, **self.params) except openerplib.AuthenticationError: error = { @@ -260,9 +263,10 @@ class JsonRequest(WebRequest): } if error: response["error"] = error + _logger.error("[%s] <--\n%s", rid, pprint.pformat(response)) - if _logger.isEnabledFor(logging.DEBUG): - _logger.debug("<--\n%s", pprint.pformat(response)) + elif _logger.isEnabledFor(logging.DEBUG): + _logger.debug("[%s] <--\n%s", rid, pprint.pformat(response)) return build_response(response) From c5bcea713d360a71ca1d94d385d6e5110d1ff142 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 22 Nov 2011 13:20:16 +0100 Subject: [PATCH 14/59] [FIX] set correct session name bzr revid: chs@openerp.com-20111122122016-ykckmih2q7dfb4yb --- addons/web/static/src/js/core.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index e3f85a92503..0c3eaff56ed 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -360,7 +360,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. this.debug = ($.deparam($.param.querystring()).debug != undefined); // TODO: session should have an optional name indicating that they'll // be saved to (and revived from) cookies - this.name = 'session'; + this.name = openerp._session_id; }, bind: function(server, continuation) { From f7893968428df6cb518db4615e96b1d0e627d294 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 22 Nov 2011 13:20:46 +0100 Subject: [PATCH 15/59] [IMP] correct var name bzr revid: chs@openerp.com-20111122122046-kl6f4o4ej1mdcd1o --- addons/web/static/src/js/core.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 0c3eaff56ed..19607bc11a2 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -398,7 +398,8 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. }, get_absolute_url: function(path) { - var r_has_protocol = /^https?:\/\//, + var absolute_url, + r_has_protocol = /^https?:\/\//, r_absolute_internal = /^\/[^\/]/; // starts with / (but not //) @@ -416,7 +417,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. parts.push(path); absolute_url = this.server + parts.join('/'); } - return absolute_url + return absolute_url; }, /** @@ -488,7 +489,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. return; } self.uid = false; - self.on_session_invalid(function() { + self.on_session_invalid(function() { // retry self.rpc(url, payload, function() { deferred.resolve.apply(deferred, arguments); @@ -521,7 +522,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. on_session_valid: function(continuation) { this.load_modules(continuation); }, - on_session_invalid: function(contination) { + on_session_invalid: function(continuation) { }, session_is_valid: function() { return this.uid; From 64d223d4271a431457992a399e5cb65795ac4c11 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 22 Nov 2011 13:22:50 +0100 Subject: [PATCH 16/59] [ADD] EmbedClient widget for ease the use of embed code bzr revid: chs@openerp.com-20111122122250-v0cys6fdv42222l0 --- addons/web/__openerp__.py | 3 +- addons/web/static/src/js/boot.js | 2 +- addons/web/static/src/js/embed.js | 49 +++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 addons/web/static/src/js/embed.js diff --git a/addons/web/__openerp__.py b/addons/web/__openerp__.py index a9aeea1af31..43700b017a7 100644 --- a/addons/web/__openerp__.py +++ b/addons/web/__openerp__.py @@ -46,7 +46,8 @@ "static/src/js/view_list.js", "static/src/js/view_list_editable.js", "static/src/js/view_tree.js", - "static/src/js/view_editor.js" + "static/src/js/view_editor.js", + "static/src/js/embed.js", ], 'css' : [ "static/lib/jquery.superfish/css/superfish.css", diff --git a/addons/web/static/src/js/boot.js b/addons/web/static/src/js/boot.js index 58dcd922ea9..7440ae42dbc 100644 --- a/addons/web/static/src/js/boot.js +++ b/addons/web/static/src/js/boot.js @@ -59,7 +59,7 @@ openerp.web = function(instance) { openerp.web.formats(instance); openerp.web.chrome(instance); openerp.web.data(instance); - var files = ["views","search","list","form","list_editable","web_mobile","view_tree","data_export","data_import","view_editor"]; + var files = ["views","search","list","form","list_editable","web_mobile","view_tree","data_export","data_import","view_editor", 'embed']; for(var i=0; i Date: Wed, 23 Nov 2011 10:20:55 +0100 Subject: [PATCH 17/59] [FIX] generate absolute urls for images bzr revid: chs@openerp.com-20111123092055-iqwm3uy1sxw4iq5o --- addons/web/static/src/js/formats.js | 2 +- addons/web_kanban/static/src/js/kanban.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js index 3151b34636b..18b679bed3c 100644 --- a/addons/web/static/src/js/formats.js +++ b/addons/web/static/src/js/formats.js @@ -253,7 +253,7 @@ openerp.web.format_cell = function (row_data, column, value_if_empty, process_mo if (column.tag === 'button') { return [ '' ].join('') diff --git a/addons/web_kanban/static/src/js/kanban.js b/addons/web_kanban/static/src/js/kanban.js index a3755541548..f8a649e2064 100644 --- a/addons/web_kanban/static/src/js/kanban.js +++ b/addons/web_kanban/static/src/js/kanban.js @@ -109,7 +109,7 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({ node.children = [{ tag: 'img', attrs: { - src: '/web/static/src/img/icons/' + node.attrs['data-icon'] + '.png', + src: openerp.connection.server + '/web/static/src/img/icons/' + node.attrs['data-icon'] + '.png', width: '16', height: '16' } @@ -509,7 +509,7 @@ openerp.web_kanban.KanbanRecord = openerp.web.Widget.extend({ }, kanban_image: function(model, field, id) { id = id || ''; - return '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + id; + return openerp.connection.server + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + id; }, kanban_text_ellipsis: function(s, size) { size = size || 160; From 12296a03e496cde652a4c75f90153e5f7ff3c8f9 Mon Sep 17 00:00:00 2001 From: vishmita Date: Tue, 6 Dec 2011 16:11:28 +0530 Subject: [PATCH 18/59] [FIX]Readonly char fields should be grey. lp bug: https://launchpad.net/bugs/899076 fixed bzr revid: vja@vja-desktop-20111206104128-1xrurdtr6qyoybq4 --- addons/web/static/src/css/base.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index 00e8e1f5e55..c4beab3badc 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -1151,7 +1151,9 @@ label.error { .openerp .oe_forms select{ padding-top: 2px; } - +.openerp .oe_forms input[disabled] { + background: #EBEBE4; +} .openerp .oe_forms textarea { resize:vertical; } From 6cab87f87affc27c161186f8dd3acb8e2a767588 Mon Sep 17 00:00:00 2001 From: "Kunal Chavda (OpenERP)" Date: Wed, 7 Dec 2011 19:00:55 +0530 Subject: [PATCH 19/59] [ADD]Implement new linechart and areachart. bzr revid: kch@tinyerp.com-20111207133055-4l8x81bkwhqxek1t --- addons/web_graph/static/src/js/graph.js | 236 +++++++++++++++++++++++- 1 file changed, 233 insertions(+), 3 deletions(-) diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 8c330434075..d9e44992dc6 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -57,7 +57,7 @@ openerp.web_graph.GraphView = openerp.web.View.extend({ }); } return $.when( - this.dataset.call_and_eval('fields_get', [false, {}], null, 1), + this.dataset.call('fields_get', []), loaded) .then(function (fields_result, view_result) { self.fields = fields_result[0]; @@ -177,14 +177,243 @@ openerp.web_graph.GraphView = openerp.web.View.extend({ graph_data = _(graph_data).sortBy(function (point) { return point[self.abscissa] + '[[--]]' + point[self.group_field]; }); - if (this.chart == 'bar') { return this.schedule_bar(graph_data); } else if (this.chart == "pie") { return this.schedule_pie(graph_data); + } else if (this.chart == 'line') { + return this.schedule_line(graph_data); + } else if (this.chart == 'area') { + return this.schedule_area(graph_data); } }, + schedule_line: function(results) { + var self = this; + var group_list, view_chart; + if (!this.group_field) { + view_chart = "line"; + group_list = _(this.columns).map(function (column, index) { + return { + group: column.name, + text: self.fields[column.name].string, + color: COLOR_PALETTE[index % (COLOR_PALETTE.length)] + } + }); + } else { + view_chart = "line"; + group_list = _(results).chain() + .pluck(this.group_field) + .uniq() + .map(function (value, index) { + return { + group: self.ordinate + '_' + + value.toLowerCase().replace(/[\s\/]+/g,'_'), + text: value, + color: COLOR_PALETTE[index % COLOR_PALETTE.length] + }; + }).value(); + results = _(results).chain() + .groupBy(function (record) { return record[self.abscissa]; }) + .map(function (records) { + var r = {}; + // second argument is coerced to a str, no good for boolean + r[self.abscissa] = records[0][self.abscissa]; + _(records).each(function (record) { + var key = _.str.sprintf('%s_%s', + self.ordinate, + record[self.group_field].toLowerCase().replace(/[\s\/]+/g,'_')); + r[key] = record[self.ordinate]; + }); + return r; + }) + .value(); + } + var abscissa_description = { + title: "" + this.fields[this.abscissa].string + "", + template: function (obj) { + return obj[self.abscissa] || 'Undefined'; + } + }; + var ordinate_description = { + lines: true, + title: "" + this.fields[this.ordinate].string + "" + }; + + var x_axis, y_axis; + x_axis = abscissa_description; + y_axis = ordinate_description; + var renderer = function () { + if (self.$element.is(':hidden')) { + self.renderer = setTimeout(renderer, 100); + return; + } + self.renderer = null; + var line_chart = new dhtmlXChart({ + view: view_chart, + container: self.element_id+"-linechart", + value:"#"+group_list[0].group+"#", + item: { + borderColor: group_list[0].color, + color: "#000000" + }, + line: { + color: group_list[0].color, + width: 3 + }, + xAxis: x_axis, + yAxis: y_axis, + padding: { + left: 35, + bottom: 20 + }, + origin: 0, + values: group_list, + legend: { + layout: "x", + align: "left", + valign: "top", + marker: { + type: "round", + width: 12 + }, + values:group_list + } + }); + for (var m = 1; m" + this.fields[this.abscissa].string + "", + template: function (obj) { + return obj[self.abscissa] || 'Undefined'; + } + }; + var ordinate_description = { + lines: true, + title: "" + this.fields[this.ordinate].string + "" + }; + + var x_axis, y_axis; + x_axis = abscissa_description; + y_axis = ordinate_description; + var renderer = function () { + if (self.$element.is(':hidden')) { + self.renderer = setTimeout(renderer, 100); + return; + } + self.renderer = null; + var area_chart = new dhtmlXChart({ + view: view_chart, + container: self.element_id+"-areachart", + value:"#"+group_list[0].group+"#", + color:group_list[0].color, + alpha: 0.6, + padding: { + left: 75 + }, + yAxis: y_axis, + xAxis: x_axis, + legend: { + values: group_list, + width: 75, + layout: "x", + align: "left", + valign: "top", + marker: { + type: "round", + width: 12 + } + } + }); + for (var m = 1; m Date: Thu, 8 Dec 2011 12:18:18 +0530 Subject: [PATCH 20/59] [FIX]Improve code. lp bug: https://launchpad.net/bugs/899076 fixed bzr revid: vja@vja-desktop-20111208064818-08kpnp7b1y3ybwjp --- addons/web/static/src/css/base.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index c4beab3badc..de11e2d182a 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -1151,8 +1151,8 @@ label.error { .openerp .oe_forms select{ padding-top: 2px; } -.openerp .oe_forms input[disabled] { - background: #EBEBE4; +.openerp .oe_forms input[disabled],.openerp .oe_forms select[disabled], .openerp .oe_forms textarea[disabled]{ + background: #EBEBE4 !important; } .openerp .oe_forms textarea { resize:vertical; From 01668688c7cde29438a1ab55cc8b2146459959e0 Mon Sep 17 00:00:00 2001 From: "Kunal Chavda (OpenERP)" Date: Thu, 8 Dec 2011 12:30:02 +0530 Subject: [PATCH 21/59] [IMP]Improved code by removing duplicate code. bzr revid: kch@tinyerp.com-20111208070002-oqya5t5zcrrtl4qg --- addons/web_graph/static/src/js/graph.js | 289 ++++-------------------- 1 file changed, 41 insertions(+), 248 deletions(-) diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index d9e44992dc6..6363894292b 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -57,7 +57,7 @@ openerp.web_graph.GraphView = openerp.web.View.extend({ }); } return $.when( - this.dataset.call('fields_get', []), + this.dataset.call_and_eval('fields_get', [false, {}], null, 1), loaded) .then(function (fields_result, view_result) { self.fields = fields_result[0]; @@ -177,248 +177,20 @@ openerp.web_graph.GraphView = openerp.web.View.extend({ graph_data = _(graph_data).sortBy(function (point) { return point[self.abscissa] + '[[--]]' + point[self.group_field]; }); - if (this.chart == 'bar') { - return this.schedule_bar(graph_data); + if (this.chart == 'bar' || 'line' || 'area') { + return this.schedule_bar_line_area(graph_data); } else if (this.chart == "pie") { return this.schedule_pie(graph_data); - } else if (this.chart == 'line') { - return this.schedule_line(graph_data); - } else if (this.chart == 'area') { - return this.schedule_area(graph_data); } }, - schedule_line: function(results) { + schedule_bar_line_area: function(results) { var self = this; - var group_list, view_chart; + var group_list, + view_chart = (self.chart == 'line')?'line':(self.chart == 'area')?'area':''; if (!this.group_field) { - view_chart = "line"; - group_list = _(this.columns).map(function (column, index) { - return { - group: column.name, - text: self.fields[column.name].string, - color: COLOR_PALETTE[index % (COLOR_PALETTE.length)] - } - }); - } else { - view_chart = "line"; - group_list = _(results).chain() - .pluck(this.group_field) - .uniq() - .map(function (value, index) { - return { - group: self.ordinate + '_' + - value.toLowerCase().replace(/[\s\/]+/g,'_'), - text: value, - color: COLOR_PALETTE[index % COLOR_PALETTE.length] - }; - }).value(); - - results = _(results).chain() - .groupBy(function (record) { return record[self.abscissa]; }) - .map(function (records) { - var r = {}; - // second argument is coerced to a str, no good for boolean - r[self.abscissa] = records[0][self.abscissa]; - _(records).each(function (record) { - var key = _.str.sprintf('%s_%s', - self.ordinate, - record[self.group_field].toLowerCase().replace(/[\s\/]+/g,'_')); - r[key] = record[self.ordinate]; - }); - return r; - }) - .value(); - } - var abscissa_description = { - title: "" + this.fields[this.abscissa].string + "", - template: function (obj) { - return obj[self.abscissa] || 'Undefined'; + if (self.chart == 'bar'){ + view_chart = (this.orientation === 'horizontal') ? 'barH' : 'bar'; } - }; - var ordinate_description = { - lines: true, - title: "" + this.fields[this.ordinate].string + "" - }; - - var x_axis, y_axis; - x_axis = abscissa_description; - y_axis = ordinate_description; - var renderer = function () { - if (self.$element.is(':hidden')) { - self.renderer = setTimeout(renderer, 100); - return; - } - self.renderer = null; - var line_chart = new dhtmlXChart({ - view: view_chart, - container: self.element_id+"-linechart", - value:"#"+group_list[0].group+"#", - item: { - borderColor: group_list[0].color, - color: "#000000" - }, - line: { - color: group_list[0].color, - width: 3 - }, - xAxis: x_axis, - yAxis: y_axis, - padding: { - left: 35, - bottom: 20 - }, - origin: 0, - values: group_list, - legend: { - layout: "x", - align: "left", - valign: "top", - marker: { - type: "round", - width: 12 - }, - values:group_list - } - }); - for (var m = 1; m" + this.fields[this.abscissa].string + "", - template: function (obj) { - return obj[self.abscissa] || 'Undefined'; - } - }; - var ordinate_description = { - lines: true, - title: "" + this.fields[this.ordinate].string + "" - }; - - var x_axis, y_axis; - x_axis = abscissa_description; - y_axis = ordinate_description; - var renderer = function () { - if (self.$element.is(':hidden')) { - self.renderer = setTimeout(renderer, 100); - return; - } - self.renderer = null; - var area_chart = new dhtmlXChart({ - view: view_chart, - container: self.element_id+"-areachart", - value:"#"+group_list[0].group+"#", - color:group_list[0].color, - alpha: 0.6, - padding: { - left: 75 - }, - yAxis: y_axis, - xAxis: x_axis, - legend: { - values: group_list, - width: 75, - layout: "x", - align: "left", - valign: "top", - marker: { - type: "round", - width: 12 - } - } - }); - for (var m = 1; m 1) { + if (self.chart == 'bar' && (this.columns.length > 1)) { this.$element.text( 'OpenERP Web does not support combining grouping and ' + 'multiple columns in graph at this time.'); @@ -440,8 +212,10 @@ openerp.web_graph.GraphView = openerp.web.View.extend({ } // transform series for clustered charts into series for stacked // charts - view_chart = (this.orientation === 'horizontal') + if (self.chart == 'bar'){ + view_chart = (this.orientation === 'horizontal') ? 'stackedBarH' : 'stackedBar'; + } group_list = _(results).chain() .pluck(this.group_field) .uniq() @@ -482,7 +256,7 @@ openerp.web_graph.GraphView = openerp.web.View.extend({ }; var x_axis, y_axis; - if (self.orientation == 'horizontal') { + if (self.chart == 'bar' && self.orientation == 'horizontal') { x_axis = ordinate_description; y_axis = abscissa_description; } else { @@ -495,9 +269,9 @@ openerp.web_graph.GraphView = openerp.web.View.extend({ return; } self.renderer = null; - var bar_chart = new dhtmlXChart({ + var charts = new dhtmlXChart({ view: view_chart, - container: self.element_id+"-barchart", + container: self.element_id+"-"+self.chart+"chart", value:"#"+group_list[0].group+"#", gradient: "3d", border: false, @@ -525,10 +299,20 @@ openerp.web_graph.GraphView = openerp.web.View.extend({ } } }); + if (self.chart == 'line'){ + charts.define("item",{ + borderColor: group_list[0].color, + color: "#000000" + }); + charts.define("line",{ + color: group_list[0].color, + width: 3 + }); + } for (var m = 1; m Date: Fri, 9 Dec 2011 16:35:21 +0530 Subject: [PATCH 22/59] [IMP]Improved code for use different properties when different chart type. bzr revid: kch@tinyerp.com-20111209110521-nlxit0up8h814ms0 --- addons/web_graph/static/src/js/graph.js | 44 ++++++++++++------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 6363894292b..6cf9998fdda 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -273,7 +273,8 @@ openerp.web_graph.GraphView = openerp.web.View.extend({ view: view_chart, container: self.element_id+"-"+self.chart+"chart", value:"#"+group_list[0].group+"#", - gradient: "3d", + gradient: (self.chart == "bar") ? "3d" : "light", + alpha: (self.chart == "area") ? 0.6 : 1, border: false, width: 1024, tooltip:{ @@ -281,7 +282,15 @@ openerp.web_graph.GraphView = openerp.web.View.extend({ self.abscissa, group_list[0].text, group_list[0].group) }, radius: 0, - color:group_list[0].color, + color: (self.chart != "line") ? group_list[0].color : "", + item: (self.chart == "line") ? { + borderColor: group_list[0].color, + color: "#000000" + } : "", + line: (self.chart == "line") ? { + color: group_list[0].color, + width: 3 + } : "", origin:0, xAxis: x_axis, yAxis: y_axis, @@ -299,16 +308,7 @@ openerp.web_graph.GraphView = openerp.web.View.extend({ } } }); - if (self.chart == 'line'){ - charts.define("item",{ - borderColor: group_list[0].color, - color: "#000000" - }); - charts.define("line",{ - color: group_list[0].color, - width: 3 - }); - } + for (var m = 1; m Date: Mon, 12 Dec 2011 16:52:19 +0530 Subject: [PATCH 23/59] [FIX]fixed change color of readonly fields. bzr revid: vja@vja-desktop-20111212112219-1bx7xocogk6ji236 --- addons/web/static/src/css/base.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index de11e2d182a..f0bdc872176 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -1152,7 +1152,7 @@ label.error { padding-top: 2px; } .openerp .oe_forms input[disabled],.openerp .oe_forms select[disabled], .openerp .oe_forms textarea[disabled]{ - background: #EBEBE4 !important; + background: #E0E0E0; } .openerp .oe_forms textarea { resize:vertical; From 3ee8a2e4ce7bc44a534835553b3aaa2fe106d9a2 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Tue, 13 Dec 2011 17:22:35 +0100 Subject: [PATCH 24/59] [IMP] Use current month range search for calendar view bzr revid: fme@openerp.com-20111213162235-a5zz8jp0he9rd3n0 --- addons/web_calendar/static/src/js/calendar.js | 42 ++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/addons/web_calendar/static/src/js/calendar.js b/addons/web_calendar/static/src/js/calendar.js index 887bdc47780..aac3dcb4f3b 100644 --- a/addons/web_calendar/static/src/js/calendar.js +++ b/addons/web_calendar/static/src/js/calendar.js @@ -10,6 +10,7 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({ // Dhtmlx scheduler ? init: function(parent, dataset, view_id, options) { this._super(parent); + this.ready = $.Deferred(); this.set_default_options(options); this.dataset = dataset; this.model = dataset.model; @@ -26,6 +27,9 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({ '#905000', '#9b0000', '#840067', '#510090', '#0000c9', '#009b00', '#9abe00', '#ffc900' ]; this.color_map = {}; this.last_search = []; + this.range_start = null; + this.range_stop = null; + this.update_range_dates(Date.today()); }, start: function() { this._super(); @@ -126,9 +130,8 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({ scheduler.attachEvent('onClick', this.do_edit_event); scheduler.attachEvent('onLightbox', this.do_edit_event); - scheduler.attachEvent('onViewChange', function(mode, date) { - self.$element.removeClass('oe_cal_day oe_cal_week oe_cal_month').addClass('oe_cal_' + mode); - }); + scheduler.attachEvent('onViewChange', this.on_view_changed); + this.refresh_scheduler(); if (this.options.sidebar) { this.mini_calendar = scheduler.renderCalendar({ @@ -141,6 +144,18 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({ }); } }, + on_view_changed: function(mode, date) { + this.$element.removeClass('oe_cal_day oe_cal_week oe_cal_month').addClass('oe_cal_' + mode); + if (!date.between(this.range_start, this.range_stop)) { + this.update_range_dates(date); + this.do_ranged_search(); + } + this.ready.resolve(); + }, + update_range_dates: function(date) { + this.range_start = date.clone().moveToFirstDayOfMonth(); + this.range_stop = this.range_start.clone().addMonths(1).addSeconds(-1); + }, refresh_scheduler: function() { scheduler.setCurrentView(scheduler._date); }, @@ -345,23 +360,30 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({ return data; }, do_search: function(domain, context, group_by) { + this.last_search = arguments; + this.do_ranged_search(); + }, + do_ranged_search: function() { var self = this - if (!domain) { - this.do_search.apply(this, this.last_search); - } else { - this.last_search = [domain, context, group_by]; - } scheduler.clearAll(); - $.when(this.has_been_loaded).then(function() { + $.when(this.has_been_loaded, this.ready).then(function() { self.dataset.read_slice(_.keys(self.fields), { offset: 0, - limit: self.limit + domain: self.get_range_domain(), + context: self.last_search[1] }, function(events) { self.dataset_events = events; self.on_events_loaded(events); }); }); }, + get_range_domain: function() { + var format = openerp.web.date_to_str, + domain = this.last_search[0].slice(0); + domain.unshift([this.date_start, '>=', format(this.range_start.clone().addDays(-6))]); + domain.unshift([this.date_start, '<=', format(this.range_stop.clone().addDays(6))]); + return domain; + }, do_show: function () { var self = this; $.when(this.has_been_loaded).then(function() { From 731e775309e4a8c81356776b9c219536b51cfa53 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Tue, 13 Dec 2011 17:51:17 +0100 Subject: [PATCH 25/59] [FIX] Fixed dashboard creatable action default_view flag bzr revid: fme@openerp.com-20111213165117-tbj32662hr2tilco --- addons/web_dashboard/static/src/js/dashboard.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/web_dashboard/static/src/js/dashboard.js b/addons/web_dashboard/static/src/js/dashboard.js index c7132d7a9ef..f5fa0387adb 100644 --- a/addons/web_dashboard/static/src/js/dashboard.js +++ b/addons/web_dashboard/static/src/js/dashboard.js @@ -154,7 +154,7 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({ if (action_attrs.domain) { action.domain = action_attrs.domain; } - var action_orig = _.extend({}, action); + var action_orig = _.extend({ flags : {} }, action); if (view_mode && view_mode != action.view_mode) { var action_view_mode = action.view_mode.split(','); @@ -195,7 +195,7 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({ var action_id = parseInt(action_attrs.creatable, 10); $action.parent().find('button.oe_dashboard_button_create').click(function() { if (isNaN(action_id)) { - action.flags.default_view = 'form'; + action_orig.flags.default_view = 'form'; self.do_action(action_orig); } else { self.rpc('/web/action/load', { From 3be4f1f4cbc05eb5d06c0b874eb0076799151081 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Tue, 13 Dec 2011 17:57:01 +0100 Subject: [PATCH 26/59] [IMP] Dashboard: moved 'Create' button in title of action bzr revid: fme@openerp.com-20111213165701-gu40tdic2s17rpxk --- addons/web_dashboard/static/src/css/dashboard.css | 5 +++++ addons/web_dashboard/static/src/xml/web_dashboard.xml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/addons/web_dashboard/static/src/css/dashboard.css b/addons/web_dashboard/static/src/css/dashboard.css index 7ee47f4b88c..785de7d5b6b 100644 --- a/addons/web_dashboard/static/src/css/dashboard.css +++ b/addons/web_dashboard/static/src/css/dashboard.css @@ -39,6 +39,11 @@ padding-bottom: 2px; } +.openerp .oe_dashboard_button_create { + margin-left: 4px; + padding: 0 4px 0 4px; +} + .openerp a.oe-dashboard-action-rename { float: left; padding-right: 4px; diff --git a/addons/web_dashboard/static/src/xml/web_dashboard.xml b/addons/web_dashboard/static/src/xml/web_dashboard.xml index 5d05990c917..5f98df612d5 100644 --- a/addons/web_dashboard/static/src/xml/web_dashboard.xml +++ b/addons/web_dashboard/static/src/xml/web_dashboard.xml @@ -25,11 +25,11 @@

&nbsp; +

-
From 7099b809e70224b84ac7842ed30897e887298408 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 13 Dec 2011 17:11:44 +0100 Subject: [PATCH 27/59] [FIX] o2m uses weird class sets bzr revid: xmo@openerp.com-20111213161144-lwwr261r3ghs8wk4 --- addons/web/static/src/css/base.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index 00e8e1f5e55..0fa3a44a4cd 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -1108,7 +1108,8 @@ label.error { white-space: normal; } -.openerp .oe_form_field_one2many .oe-actions h3.oe_view_title { +.openerp .oe_form_field_one2many .oe-actions h3.oe_view_title, +.openerp .oe_form_field_one2many_list .oe-actions h3.oe_view_title{ display: inline; margin: 0 0.5em 0 0; } From 2a492cf3add2ef41dcd911feb4cb2c1af9049491 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 13 Dec 2011 17:27:30 +0100 Subject: [PATCH 28/59] [FIX] chs stupidity bzr revid: chs@openerp.com-20111213162730-w1p543ctjzpuf7f7 --- addons/web/static/src/xml/base.xml | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index f42d173a5bc..0a245fe0f38 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -928,12 +928,7 @@ t-att-id="widget.element_id" t-attf-class="field_#{widget.type}" style="width: 100%" -<<<<<<< TREE - > - -======= - > ->>>>>>> MERGE-SOURCE + >
@@ -941,12 +936,7 @@ - >>>>>> MERGE-SOURCE + />
From ddd1ea5d5d8b1ce383bf2340a23bd47f25cf8f4b Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 13 Dec 2011 17:34:46 +0100 Subject: [PATCH 29/59] [IMP] allow modification of options of action of EmbedClient bzr revid: chs@openerp.com-20111213163446-h6sy1yti92mcgg1f --- addons/web/static/src/js/embed.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/js/embed.js b/addons/web/static/src/js/embed.js index ce6ad8b60f9..1c261060da8 100644 --- a/addons/web/static/src/js/embed.js +++ b/addons/web/static/src/js/embed.js @@ -20,9 +20,10 @@ openerp.web.embed = function(session) { session.web.EmbedClient = session.web.Widget.extend({ template: 'EmptyComponent', - init: function(action_id) { + init: function(action_id, options) { this._super(); this.action_id = action_id; + this.options = options || {}; this.am = new session.web.ActionManager(); }, @@ -39,7 +40,7 @@ openerp.web.embed = function(session) { action_buttons : false, sidebar : false //pager : false - }, action.flags || {}); + }, self.options, action.flags || {}); self.am.do_action(action); }); From e0ac8e3fa48125c416dcca09c123026fa9203778 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 13 Dec 2011 18:47:28 +0100 Subject: [PATCH 30/59] [IMP] refactor request handler bzr revid: chs@openerp.com-20111213174728-gslcxtuuf9y506b3 --- addons/web/common/http.py | 51 ++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/addons/web/common/http.py b/addons/web/common/http.py index 81cded7d08b..9a9fb0293b9 100644 --- a/addons/web/common/http.py +++ b/addons/web/common/http.py @@ -146,11 +146,29 @@ class JsonRequest(WebRequest): assert self.jsonrequest.get('jsonrpc') == '2.0' self.init(self.jsonrequest.get("params", {})) response = {"jsonrpc": "2.0" } - return response - def _init_jsonp(self): + def build_response(response): + content = simplejson.dumps(response, cls=nonliterals.NonLiteralEncoder) + return werkzeug.wrappers.Response( + content, headers=[('Content-Type', 'application/json'), + ('Content-Length', len(content))]) + + return response, build_response + + def _init_jsonp(self, callback): self.init(self.jsonrequest) - return {} + + def build_response(response): + content = "%s(%s);" % (\ + callback, + simplejson.dumps(response, cls=nonliterals.NonLiteralEncoder), + ) + + return werkzeug.wrappers.Response( + content, headers=[('Content-Type', 'application/javascript'), + ('Content-Length', len(content))]) + + return {}, build_response def dispatch(self, controller, method): @@ -196,29 +214,9 @@ class JsonRequest(WebRequest): if self.jsonrequest.get('jsonrpc') == '2.0': - response = self._init_jsonrpc2() - - def build_response(response): - content = simplejson.dumps(response, cls=nonliterals.NonLiteralEncoder) - return werkzeug.wrappers.Response( - content, headers=[('Content-Type', 'application/json'), - ('Content-Length', len(content))]) - - + response, build_response = self._init_jsonrpc2() elif jsonp_callback: - - response = self._init_jsonp() - - def build_response(response): - content = "%s(%s);" % (\ - jsonp_callback, - simplejson.dumps(response, cls=nonliterals.NonLiteralEncoder), - ) - - return werkzeug.wrappers.Response( - content, headers=[('Content-Type', 'application/javascript'), - ('Content-Length', len(content))]) - + response, build_response = self._init_jsonp(jsonp_callback) else: return werkzeug.exceptions.BadRequest() @@ -439,9 +437,6 @@ class JSONP(Controller): @httprequest def post(self, req, request_id, params, callback): params = simplejson.loads(params, object_hook=nonliterals.non_literal_decoder) - params.update( - session_id=req.session.id, - ) params['session_id'] = req.session.id req.session.jsonp_requests[request_id] = { 'jsonp': callback, From 26f690fc5ea5dc4f5cbadcceb88b4dd64e8597bd Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Wed, 14 Dec 2011 10:29:33 +0100 Subject: [PATCH 31/59] [IMP] jsonp dispatch bzr revid: al@openerp.com-20111214092933-77vn7s5jxvi5i72f --- addons/web/common/http.py | 147 ++++++++++---------------------------- 1 file changed, 38 insertions(+), 109 deletions(-) diff --git a/addons/web/common/http.py b/addons/web/common/http.py index 9a9fb0293b9..425e11ddce1 100644 --- a/addons/web/common/http.py +++ b/addons/web/common/http.py @@ -89,21 +89,11 @@ class WebRequest(object): self.config = config self.session = None - def init_session(self, session_id): - if self.session: - assert self.session.id == session_id - return - - self.session_id = session_id or uuid.uuid4().hex - self.session = self.httpsession.setdefault(self.session_id, session.OpenERPSession(self.session_id)) - self.session.config = self.config - def init(self, params): self.params = dict(params) - - # OpenERP session setup - session_id = self.params.pop("session_id", None) - self.init_session(session_id) + self.session_id = self.params.pop("session_id", None) or uuid.uuid4().hex + self.session = self.httpsession.setdefault(self.session_id, session.OpenERPSession(self.session_id)) + self.session.config = self.config self.context = self.params.pop('context', None) self.debug = self.params.pop('debug', False) != False @@ -140,37 +130,6 @@ class JsonRequest(WebRequest): "id": null} """ - - - def _init_jsonrpc2(self): - assert self.jsonrequest.get('jsonrpc') == '2.0' - self.init(self.jsonrequest.get("params", {})) - response = {"jsonrpc": "2.0" } - - def build_response(response): - content = simplejson.dumps(response, cls=nonliterals.NonLiteralEncoder) - return werkzeug.wrappers.Response( - content, headers=[('Content-Type', 'application/json'), - ('Content-Length', len(content))]) - - return response, build_response - - def _init_jsonp(self, callback): - self.init(self.jsonrequest) - - def build_response(response): - content = "%s(%s);" % (\ - callback, - simplejson.dumps(response, cls=nonliterals.NonLiteralEncoder), - ) - - return werkzeug.wrappers.Response( - content, headers=[('Content-Type', 'application/javascript'), - ('Content-Length', len(content))]) - - return {}, build_response - - def dispatch(self, controller, method): """ Calls the method asked for by the JSON-RPC2 or JSONP request @@ -179,54 +138,36 @@ class JsonRequest(WebRequest): :returns: an utf8 encoded JSON-RPC2 or JSONP reply """ + method = self.httprequest.method + args = self.httprequest.args + jsonp = args.get('jsonp', False) - requestf = self.httprequest.stream - direct_json_request = None - jsonp_callback = None - rid = None - if requestf: - direct_json_request = requestf.read() - - if not direct_json_request: - params = self.httprequest.args - direct_json_request = params.get('r') - jsonp_callback = params.get('callback') - - if direct_json_request: - try: - self.jsonrequest = simplejson.loads(direct_json_request, object_hook=nonliterals.non_literal_decoder) - except Exception, e: - _logger.exception(e) - return werkzeug.exceptions.BadRequest(e) + if jsonp and args.get('r'): + # jsonp method GET + requestf = StringIO.StringIO(args.get('r')) + elif jsonp and method == 'POST': + # jsonp 2 steps step1 POST: save call + self.init(args) + req.session.jsonp_requests[args.get('id')] = self.httprequest.form['r'] + headers=[('Content-Type', 'text/plain; charset=utf-8')] + r = werkzeug.wrappers.Response(request_id, headers=headers) + return r + elif args['jsonp'] and args.get('id'): + # jsonp 2 steps step2 GET: run and return result + self.init(args) + requestf = StringIO.StringIO(self.session.jsonp_requests.pop(args.get(id), "")) else: - # no direct json request, try to get it from jsonp POST request - params = self.httprequest.args - rid = params.get('rid') - session_id = params.get('sid') - if session_id: - self.init_session(session_id) - stored_request = self.session.jsonp_requests.pop(rid, {}) - else: - stored_request = {} - - jsonp_callback = stored_request.get('jsonp') - self.jsonrequest = stored_request.get('params', {}) - - - if self.jsonrequest.get('jsonrpc') == '2.0': - response, build_response = self._init_jsonrpc2() - elif jsonp_callback: - response, build_response = self._init_jsonp(jsonp_callback) - else: - return werkzeug.exceptions.BadRequest() + # regular jsonrpc2 + requestf = self.httprequest.stream + self.init(self.jsonrequest.get("params", {})) + response = {"jsonrpc": "2.0" } error = None - if not rid: - rid = self.jsonrequest.get('id') try: + self.jsonrequest = simplejson.loads(direct_json_request, object_hook=nonliterals.non_literal_decoder) + self.init(self.jsonrequest.get("params", {})) if _logger.isEnabledFor(logging.DEBUG): _logger.debug("[%s] --> %s.%s\n%s", rid, controller.__class__.__name__, method.__name__, pprint.pformat(self.jsonrequest)) - response['id'] = rid response["result"] = method(controller, self, **self.params) except openerplib.AuthenticationError: error = { @@ -249,8 +190,6 @@ class JsonRequest(WebRequest): } } except Exception: - logging.getLogger(__name__ + '.JSONRequest.dispatch').exception\ - ("An error occured while handling a json request") error = { 'code': 300, 'message': "OpenERP WebClient Error", @@ -262,11 +201,18 @@ class JsonRequest(WebRequest): if error: response["error"] = error _logger.error("[%s] <--\n%s", rid, pprint.pformat(response)) - elif _logger.isEnabledFor(logging.DEBUG): _logger.debug("[%s] <--\n%s", rid, pprint.pformat(response)) - return build_response(response) + if jsonp: + mime = 'application/javascript' + body = "%s(%s);" % (jsonp, simplejson.dumps(response, cls=nonliterals.NonLiteralEncoder),) + else: + mime = 'application/json' + body = simplejson.dumps(response, cls=nonliterals.NonLiteralEncoder) + + r = werkzeug.wrappers.Response(body, headers=[('Content-Type', mime), ('Content-Length', len(body))]) + return r def jsonrequest(f): """ Decorator marking the decorated method as being a handler for a @@ -430,29 +376,12 @@ class ControllerType(type): class Controller(object): __metaclass__ = ControllerType - -class JSONP(Controller): - _cp_path = '/web/jsonp' - - @httprequest - def post(self, req, request_id, params, callback): - params = simplejson.loads(params, object_hook=nonliterals.non_literal_decoder) - params['session_id'] = req.session.id - req.session.jsonp_requests[request_id] = { - 'jsonp': callback, - 'params': params, - 'id': request_id, - } - - headers=[('Content-Type', 'text/plain; charset=utf-8')] - response = werkzeug.wrappers.Response(request_id, headers=headers) - return response +class Proxy(Controller): + _cp_path = '/web/proxy' @jsonrequest - def static_proxy(self, req, path): + def load(self, req, path): #req.config.socket_port - - #if not re.match('^/[^/]+/static/.*', path): # return werkzeug.exceptions.BadRequest() From 5cd5755495df46fbddf271d3664e38586c9b674c Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Wed, 14 Dec 2011 10:39:41 +0100 Subject: [PATCH 32/59] [IMP] jsonp dispatch fixes bzr revid: al@openerp.com-20111214093941-k5q77dh0gfavnsds --- addons/web/common/http.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/common/http.py b/addons/web/common/http.py index 425e11ddce1..da34b8a654e 100644 --- a/addons/web/common/http.py +++ b/addons/web/common/http.py @@ -2,6 +2,7 @@ #---------------------------------------------------------- # OpenERP Web HTTP layer #---------------------------------------------------------- +import StringIO import ast import contextlib import functools @@ -159,7 +160,6 @@ class JsonRequest(WebRequest): else: # regular jsonrpc2 requestf = self.httprequest.stream - self.init(self.jsonrequest.get("params", {})) response = {"jsonrpc": "2.0" } error = None From 228aed18bb62b35c26f3deee9a1041f472463e50 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 14 Dec 2011 10:51:23 +0100 Subject: [PATCH 33/59] [IMP] Remove bottom pager from o2m bzr revid: fme@openerp.com-20111214095123-1dwn1yld44pndzpz --- addons/web/static/src/xml/base.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 1894d351e40..a2cc9e1725f 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -619,6 +619,9 @@ this.removeAttr('t-if'); + + + this.removeAttr('t-if'); var $title = $(document.createElement('h3')).addClass('oe_view_title'); From 139f4f85a0fd34b945584ab603f589a46196bb59 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 14 Dec 2011 11:13:44 +0100 Subject: [PATCH 34/59] [IMP] Merge Advanced Filter button in select box and float it right bzr revid: fme@openerp.com-20111214101344-7jcltxvjd34no3q6 --- addons/web/static/src/css/base.css | 6 ++---- addons/web/static/src/js/search.js | 5 ++++- addons/web/static/src/xml/base.xml | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index 0fa3a44a4cd..4badc4d4690 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -717,11 +717,9 @@ label.error { .openerp .oe_search-view-buttons { padding: 10px 0 10px 0; } -.openerp .oe_search-view-custom-filter-btn span { - background: url(/web/static/src/img/icons/gtk-add.png) repeat-y; - padding-left: 18px; +.openerp .oe_search-view-filters-management { + float: right; } - .openerp .searchview_extended_add_proposition span { font-size: 0.9em; background: url(/web/static/src/img/icons/gtk-add.png) repeat-y; diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index d1e4b161b39..9b485b457cd 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -155,6 +155,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search var ext = new openerp.web.search.ExtendedSearch(this, this.model); lines.push([ext]); this.inputs.push(ext); + this.extended_search = ext; var render = QWeb.render("SearchView", { 'view': data.fields_view['arch'], @@ -163,7 +164,6 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search }); this.$element.html(render); - this.$element.find(".oe_search-view-custom-filter-btn").click(ext.on_activate); var f = this.$element.find('form'); this.$element.find('form') @@ -199,6 +199,9 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search var select = this.$element.find(".oe_search-view-filters-management"); var val = select.val(); switch(val) { + case 'advanced_filter': + this.extended_search.on_activate(); + break; case 'add_to_dashboard': this.on_add_to_dashboard(); break; diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index a2cc9e1725f..09472e38657 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -1151,7 +1151,6 @@
-
@@ -1165,6 +1164,7 @@
+ From b1f0142a21fac3bb2df3adacb48eb13633883c81 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 14 Dec 2011 11:43:01 +0100 Subject: [PATCH 35/59] [IMP] Hide secondary menu on home page client action bzr revid: fme@openerp.com-20111214104301-v1nxqqglhubpkdqc --- addons/web/static/src/js/chrome.js | 9 +++++++++ addons/web_dashboard/static/src/js/dashboard.js | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 4910d794876..8c8c3b5f7d6 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -916,6 +916,8 @@ openerp.web.Menu = openerp.web.Widget.extend(/** @lends openerp.web.Menu# */{ if (!(this.folded && manual)) { this.do_show_secondary($sub_menu, $main_menu); + } else { + this.do_show_secondary(); } if ($main_menu != $clicked_menu) { @@ -941,8 +943,15 @@ openerp.web.Menu = openerp.web.Widget.extend(/** @lends openerp.web.Menu# */{ } return false; }, + do_hide_secondary: function() { + this.$secondary_menu.hide(); + }, do_show_secondary: function($sub_menu, $main_menu) { var self = this; + this.$secondary_menu.show(); + if (!arguments.length) { + return; + } if (this.folded) { var css = $main_menu.position(), fold_width = this.$secondary_menu.width() + 2, diff --git a/addons/web_dashboard/static/src/js/dashboard.js b/addons/web_dashboard/static/src/js/dashboard.js index f5fa0387adb..b70217a1021 100644 --- a/addons/web_dashboard/static/src/js/dashboard.js +++ b/addons/web_dashboard/static/src/js/dashboard.js @@ -397,8 +397,8 @@ openerp.web_dashboard.ApplicationTiles = openerp.web.Widget.extend({ this._super(parent); }, start: function() { - // TODO menu hide var self = this; + openerp.webclient.menu.do_hide_secondary(); var domain = [['application','=',true], ['state','=','installed'], ['name', '!=', 'base']]; var ds = new openerp.web.DataSetSearch(this, 'ir.module.module',{},domain); ds.read_slice(['id'], {}, function(result) { From 4b1c8421286a5202ddfde7364eae7c58988fb7a4 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 14 Dec 2011 12:28:14 +0100 Subject: [PATCH 36/59] [FIX] Dashboard: merge domain & context of board action to loaded action bzr revid: fme@openerp.com-20111214112814-18y45kct686ristw --- addons/web_dashboard/static/src/js/dashboard.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/web_dashboard/static/src/js/dashboard.js b/addons/web_dashboard/static/src/js/dashboard.js index b70217a1021..ce7e877b73f 100644 --- a/addons/web_dashboard/static/src/js/dashboard.js +++ b/addons/web_dashboard/static/src/js/dashboard.js @@ -149,10 +149,11 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({ view_mode = action_attrs.view_mode; if (action_attrs.context) { - action.context = action_attrs.context; + action.context = _.extend((action.context || {}), action_attrs.context); } if (action_attrs.domain) { - action.domain = action_attrs.domain; + action.domain = action.domain || []; + action.domain.unshift.apply(action.domain, action_attrs.domain); } var action_orig = _.extend({ flags : {} }, action); From 6da5e9245e5f680866e4bf64c92e653127dfbb55 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 14 Dec 2011 13:56:58 +0100 Subject: [PATCH 37/59] [IMP] Rename EmbedClient to EmbeddedClient and move it to chrome.js. [IMP] move the currentScript function to root namespace bzr revid: chs@openerp.com-20111214125658-huw4955d7zo2y37g --- addons/web/__openerp__.py | 1 - addons/web/static/src/js/boot.js | 2 +- addons/web/static/src/js/chrome.js | 42 +++++++++++++++++++++++++ addons/web/static/src/js/embed.js | 50 ------------------------------ 4 files changed, 43 insertions(+), 52 deletions(-) delete mode 100644 addons/web/static/src/js/embed.js diff --git a/addons/web/__openerp__.py b/addons/web/__openerp__.py index 2beceba946b..74f4cdac3f7 100644 --- a/addons/web/__openerp__.py +++ b/addons/web/__openerp__.py @@ -53,7 +53,6 @@ "static/src/js/view_list_editable.js", "static/src/js/view_tree.js", "static/src/js/view_editor.js", - "static/src/js/embed.js", ], 'css' : [ "static/lib/jquery.superfish/css/superfish.css", diff --git a/addons/web/static/src/js/boot.js b/addons/web/static/src/js/boot.js index 14f50adb473..c2aea24276b 100644 --- a/addons/web/static/src/js/boot.js +++ b/addons/web/static/src/js/boot.js @@ -59,7 +59,7 @@ openerp.web = function(instance) { openerp.web.formats(instance); openerp.web.chrome(instance); openerp.web.data(instance); - var files = ["views","search","list","form", "page","list_editable","web_mobile","view_tree","data_export","data_import","view_editor","embed"]; + var files = ["views","search","list","form", "page","list_editable","web_mobile","view_tree","data_export","data_import","view_editor"]; for(var i=0; i Date: Wed, 14 Dec 2011 14:23:06 +0100 Subject: [PATCH 38/59] [FIX] Make Field boolean readonly inherit of form's view boolean Field bzr revid: fme@openerp.com-20111214132306-xtem0i3waxrucc4a --- addons/web/static/src/js/view_form.js | 28 ++++++++++++--------------- addons/web/static/src/js/view_page.js | 7 ++++--- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index fef32df4a90..5908dc67dc6 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -619,8 +619,8 @@ openerp.web.form.SidebarAttachments = openerp.web.Widget.extend({ var $e = $(e.target); if ($e.val() != '') { this.$element.find('form.oe-binary-form').submit(); - $e.parent().find('input[type=file]').attr('disabled', 'true'); - $e.parent().find('button').attr('disabled', 'true').find('img, span').toggle(); + $e.parent().find('input[type=file]').prop('disabled', true); + $e.parent().find('button').prop('disabled', true).find('img, span').toggle(); } }, on_attachment_delete: function(e) { @@ -1094,13 +1094,9 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({ this.check_disable(); }, check_disable: function() { - if (this.readonly || this.force_disabled || !this.view.is_interactible_record()) { - this.$element.find("button").attr("disabled", "disabled"); - this.$element.find("button").css("color", "grey"); - } else { - this.$element.find("button").removeAttr("disabled"); - this.$element.find("button").css("color", ""); - } + var disabled = (this.readonly || this.force_disabled || !this.view.is_interactible_record()); + this.$element.find('button').prop('disabled', disabled); + this.$element.find("button").css('color', disabled ? 'grey' : ''); } }); @@ -1268,7 +1264,7 @@ openerp.web.form.FieldChar = openerp.web.form.Field.extend({ }, update_dom: function() { this._super.apply(this, arguments); - this.$element.find('input').attr('disabled', this.readonly); + this.$element.find('input').prop('disabled', this.readonly); }, set_value_from_ui: function() { this.value = openerp.web.parse_value(this.$element.find('input').val(), this); @@ -1392,7 +1388,7 @@ openerp.web.DateTimeWidget = openerp.web.Widget.extend({ }, set_readonly: function(readonly) { this.readonly = readonly; - this.$input.attr('disabled', this.readonly); + this.$input.prop('disabled', this.readonly); this.$element.find('img.oe_datepicker_trigger').toggleClass('oe_input_icon_disabled', readonly); }, is_valid: function(required) { @@ -1479,7 +1475,7 @@ openerp.web.form.FieldText = openerp.web.form.Field.extend({ }, update_dom: function() { this._super.apply(this, arguments); - this.$element.find('textarea').attr('disabled', this.readonly); + this.$element.find('textarea').prop('disabled', this.readonly); }, set_value_from_ui: function() { this.value = openerp.web.parse_value(this.$element.find('textarea').val(), this); @@ -1516,7 +1512,7 @@ openerp.web.form.FieldBoolean = openerp.web.form.Field.extend({ }, update_dom: function() { this._super.apply(this, arguments); - this.$element.find('input').attr('disabled', this.readonly); + this.$element.find('input').prop('disabled', this.readonly); }, focus: function() { this.$element.find('input').focus(); @@ -1599,7 +1595,7 @@ openerp.web.form.FieldSelection = openerp.web.form.Field.extend({ }, update_dom: function() { this._super.apply(this, arguments); - this.$element.find('select').attr('disabled', this.readonly); + this.$element.find('select').prop('disabled', this.readonly); }, validate: function() { var value = this.values[this.$element.find('select')[0].selectedIndex]; @@ -1948,7 +1944,7 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({ }, update_dom: function() { this._super.apply(this, arguments); - this.$input.attr('disabled', this.readonly); + this.$input.prop('disabled', this.readonly); } }); @@ -2905,7 +2901,7 @@ openerp.web.form.FieldBinaryFile = openerp.web.form.FieldBinary.extend({ update_dom: function() { this._super.apply(this, arguments); this.$element.find('.oe-binary-file-set, .oe-binary-file-clear').toggle(!this.readonly); - this.$element.find('input[type=text]').attr('disabled', this.readonly); + this.$element.find('input[type=text]').prop('disabled', this.readonly); }, set_value: function(value) { this._super.apply(this, arguments); diff --git a/addons/web/static/src/js/view_page.js b/addons/web/static/src/js/view_page.js index abcfb5131dd..40ca1176c79 100644 --- a/addons/web/static/src/js/view_page.js +++ b/addons/web/static/src/js/view_page.js @@ -102,9 +102,10 @@ openerp.web.page = function (openerp) { this._super(s[2]); } }); - openerp.web.page.FieldBooleanReadonly = openerp.web.page.FieldCharReadonly.extend({ - set_value: function (value) { - this._super(value ? '\u2611' : '\u2610'); + openerp.web.page.FieldBooleanReadonly = openerp.web.form.FieldBoolean.extend({ + update_dom: function() { + this._super.apply(this, arguments); + this.$element.find('input').prop('disabled', true); } }); openerp.web.page.FieldSelectionReadonly = openerp.web.page.FieldReadonly.extend({ From 0b314b259610290d3a2cc1fe9f8a1a24848c4139 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 14 Dec 2011 14:45:12 +0100 Subject: [PATCH 39/59] [IMP] add session.server as a global variable for qweb temlates bzr revid: chs@openerp.com-20111214134512-byuq129f02t3fk4s --- addons/web/static/src/js/core.js | 1 + addons/web/static/src/xml/base.xml | 60 +++++++++++++++--------------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 7123fe2934b..e1591f46235 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -375,6 +375,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. } var hostname = _.str.sprintf('%s//%s', location.protocol, location.host); this.server = _.str.rtrim((!server) ? hostname : server, '/'); + openerp.web.qweb.default_dict['_s'] = this.server this.rpc_mode = (this.server == hostname) ? "oe-json" : "oe-jsonp"; this.session_id = false; this.uid = false; diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 0a245fe0f38..1894d351e40 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -266,7 +266,7 @@
- +
@@ -306,7 +306,7 @@ @@ -916,7 +916,7 @@ @@ -928,7 +928,7 @@ t-att-id="widget.element_id" t-attf-class="field_#{widget.type}" style="width: 100%" - > + >
@@ -936,7 +936,7 @@
@@ -956,9 +956,9 @@ - + - + @@ -1009,7 +1009,7 @@
- + Full featured
@@ -315,7 +315,7 @@
- + Open Source
@@ -324,7 +324,7 @@
- + User Friendly
@@ -352,13 +352,13 @@
  • - +
  • - +
  • - +
@@ -712,7 +712,7 @@ @@ -883,7 +883,7 @@ t-att-id="widget.element_id" t-attf-class="field_#{widget.type} #{_(['integer', 'float', 'float_time']).contains(widget.type) ? 'oe-number' : ''}" style="width: 100%" - /> + />
- @@ -1039,14 +1039,14 @@
@@ -1074,7 +1074,7 @@ @@ -1083,13 +1083,13 @@ @@ -1097,7 +1097,7 @@ - + Uploading ... @@ -1106,7 +1106,7 @@ @@ -1199,7 +1199,7 @@ t-att-title="attrs.help" t-att-class="classes.join(' ')" t-att-autofocus="attrs.default_focus === '1' ? 'autofocus' : undefined"> - +
@@ -1346,7 +1346,7 @@ - + @@ -1689,7 +1689,7 @@ From 05af07ad0ed9023cab93d2d33877a6f99f858c05 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 14 Dec 2011 15:17:29 +0100 Subject: [PATCH 40/59] [IMP] o2m: do not display viewmanager header when only one view defined bzr revid: fme@openerp.com-20111214141729-arebojkvaxajozlm --- addons/web/static/src/xml/base.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 09472e38657..fe5598ff6e9 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -483,6 +483,10 @@ + + + this.attr('t-if', 'views.length != 1'); + From e579d0fd712b40810be2c6d2951784d5d0b529de Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 14 Dec 2011 15:43:17 +0100 Subject: [PATCH 41/59] [FIX] don't display add/remove buttons in group_by_no_leaf views bzr revid: xmo@openerp.com-20111214144317-hfctv9rebwp5kvkp --- addons/web/static/src/js/view_list.js | 2 ++ addons/web/static/src/xml/base.xml | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index 059bc020682..bf423434ecc 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -79,6 +79,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView# self.compute_aggregates(); }); + this.no_leaf = false; }, /** * Retrieves the view's number of records per page (|| section) @@ -473,6 +474,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView# if (_.isEmpty(group_by) && !context['group_by_no_leaf']) { group_by = null; } + this.no_leaf = !!context['group_by_no_leaf']; this.reload_view(!!group_by, context).then( $.proxy(this, 'reload_content')); diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index fe5598ff6e9..a880293403d 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -573,7 +573,7 @@

@@ -1573,7 +1573,7 @@

- +
- +
-
+ From 12014ea02c818f0d51facf91197b7e5efad9ab30 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 14 Dec 2011 16:29:03 +0100 Subject: [PATCH 42/59] [IMP] Move flags to ViewManager level so it can be passed to its constructor bzr revid: fme@openerp.com-20111214152903-wpkbw0s45xkdpr2a --- addons/web/static/src/js/views.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 0ad49f69f7b..fcc8a4cc06c 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -200,7 +200,7 @@ session.web.ViewManager = session.web.Widget.extend(/** @lends session.web.View * @param dataset * @param views */ - init: function(parent, dataset, views) { + init: function(parent, dataset, views, flags) { this._super(parent); this.model = dataset ? dataset.model : undefined; this.dataset = dataset; @@ -208,7 +208,7 @@ session.web.ViewManager = session.web.Widget.extend(/** @lends session.web.View this.active_view = null; this.views_src = _.map(views, function(x) {return x instanceof Array? {view_id: x[0], view_type: x[1]} : x;}); this.views = {}; - this.flags = this.flags || {}; + this.flags = flags || {}; this.registry = session.web.views; this.views_history = []; }, @@ -415,19 +415,10 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner // dataset initialization will take the session from ``this``, so if we // do not have it yet (and we don't, because we've not called our own // ``_super()``) rpc requests will blow up. - this._super(parent, null, action.views); - this.session = parent.session; - this.action = action; - var dataset = new session.web.DataSetSearch(this, action.res_model, action.context, action.domain); - if (action.res_id) { - dataset.ids.push(action.res_id); - dataset.index = 0; - } - this.dataset = dataset; - this.flags = this.action.flags || {}; + var flags = action.flags || {}; if (action.res_model == 'board.board' && action.view_mode === 'form') { // Special case for Dashboards - _.extend(this.flags, { + _.extend(flags, { views_switcher : false, display_title : false, search_view : false, @@ -436,6 +427,15 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner action_buttons : false }); } + this._super(parent, null, action.views, flags); + this.session = parent.session; + this.action = action; + var dataset = new session.web.DataSetSearch(this, action.res_model, action.context, action.domain); + if (action.res_id) { + dataset.ids.push(action.res_id); + dataset.index = 0; + } + this.dataset = dataset; // setup storage for session-wise menu hiding if (this.session.hidden_menutips) { From 6c2d28cadb56e66df913811d0e396beea37b5697 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 14 Dec 2011 16:54:41 +0100 Subject: [PATCH 43/59] [IMP] o2m: do not display action buttons in views used by one2many bzr revid: fme@openerp.com-20111214155441-gnb0yqjxyq0uklfa --- addons/web/static/src/js/view_form.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 5908dc67dc6..0ac70e64a67 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -2055,7 +2055,9 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({ }); this.views = views; - this.viewmanager = new openerp.web.ViewManager(this, this.dataset, views); + this.viewmanager = new openerp.web.ViewManager(this, this.dataset, views, { + action_buttons : false + }); this.viewmanager.template = 'One2Many.viewmanager'; this.viewmanager.registry = openerp.web.views.clone({ list: 'openerp.web.form.One2ManyListView', @@ -2083,7 +2085,6 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({ controller.on_pager_action.add_first(function() { self.save_any_view(); }); - controller.$element.find(".oe_form_button_save").hide(); } else if (view_type == "graph") { self.reload_current_view() } From b53ee6fe2074fbbd7dc6932554631a5b3fbec185 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 14 Dec 2011 17:09:58 +0100 Subject: [PATCH 44/59] [WIP] better url management, only views are allowed to call this.do_push_state bzr revid: chs@openerp.com-20111214160958-xrtdubgh6jqn3mq3 --- addons/web/static/src/js/chrome.js | 10 ++----- addons/web/static/src/js/view_form.js | 3 ++ addons/web/static/src/js/views.js | 43 ++++++++++++++------------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 8c8c3b5f7d6..4b41d3adc54 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -1061,7 +1061,6 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie if(this.action_manager) this.action_manager.stop(); this.action_manager = new openerp.web.ActionManager(this); - this.action_manager.do_push_state.add(this.do_push_state); this.action_manager.appendTo($("#oe_app")); if (openerp._modules_loaded) { // TODO: find better option than this @@ -1076,7 +1075,7 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie }, on_logged_out: function() { $(window).unbind('hashchange', this.on_hashchange); - this.do_push_state({},true); + this.do_push_state({}); if(this.action_manager) this.action_manager.stop(); this.action_manager = null; @@ -1098,11 +1097,8 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie } this._current_state = state; }, - do_push_state: function(state, overwrite) { - if (!overwrite) { - var hash = $.deparam.fragment(true); - state = _.extend({}, hash, state); - } + do_push_state: function(state) { + console.log('dopushstate', state); var url = '#' + $.param(state); this._current_state = _.clone(state); $.bbq.pushState(url); diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 0ac70e64a67..b961b0089e3 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -175,6 +175,9 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# if (self.default_focus_field && !self.embedded_view) { self.default_focus_field.focus(); } + if (record.id) { + self.do_push_state({id:record.id}); + } }); }, on_form_changed: function() { diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index fcc8a4cc06c..af0f0f47aba 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -20,6 +20,7 @@ session.web.ActionManager = session.web.Widget.extend({ identifier_prefix: "actionmanager", init: function(parent) { this._super(parent); + this.action = null; this.inner_viewmanager = null; this.dialog = null; this.dialog_viewmanager = null; @@ -47,7 +48,15 @@ session.web.ActionManager = session.web.Widget.extend({ } }, - do_push_state: function(state, overwrite) { + do_push_state: function(state) { + if (this.wiget_parent && this.widget_parent.do_push_state) { + if (this.action.id) { + state = _.extend({}, state || {}, { + action_id: this.action.id, + }); + } + this.widget_parent.do_push_state(state); + } }, do_load_state: function(state) { @@ -95,6 +104,7 @@ session.web.ActionManager = session.web.Widget.extend({ console.error("Action manager can't handle action of type " + action.type, action); return; } + this.action = action; return this[type](action, on_close); }, null_action: function() { @@ -128,10 +138,6 @@ session.web.ActionManager = session.web.Widget.extend({ this.content_stop(); this.inner_action = action; this.inner_viewmanager = new session.web.ViewManagerAction(this, action); - this.inner_viewmanager.do_push_state.add(function(state,overwrite) { - state['action_id'] = action.id; - self.do_push_state(state,true); - }); this.inner_viewmanager.appendTo(this.$element); } }, @@ -154,10 +160,6 @@ session.web.ActionManager = session.web.Widget.extend({ this.content_stop(); var ClientWidget = session.web.client_actions.get_object(action.tag); (this.client_widget = new ClientWidget(this, action.params)).appendTo(this); - - var client_action = {tag: action.tag}; - if (action.params) _.extend(client_action, {params: action.params}); - this.do_push_state({client_action: client_action}, true); }, ir_actions_report_xml: function(action, on_closed) { var self = this; @@ -466,12 +468,6 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner var main_view_loaded = this._super(); - _.each(_.keys(this.views), function(view_type) { - $.when(self.views[view_type].deferred).done(function(view_type) { - self.views[view_type].controller.do_push_state.add(self.do_push_state); - }); - }); - var manager_ready = $.when(searchview_loaded, main_view_loaded); this.$element.find('.oe_debug_view').change(this.on_debug_changed); @@ -584,12 +580,16 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner } else { $search_prefix.remove(); } - - self.do_push_state({view_type: self.active_view}); }); }, - do_push_state: function(state, overwrite) { + do_push_state: function(state) { + if (this.wiget_parent && this.widget_parent.do_push_state) { + state = _.extend({}, state || {}, { + view_type: this.active_view + }); + this.widget_parent.do_push_state(state); + } }, do_load_state: function(state) { @@ -1146,11 +1146,12 @@ session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{ return $.Deferred().resolve({}).promise(); }, - do_push_state: function(state, overwrite) { + do_push_state: function(state) { + if (this.wiget_parent && this.widget_parent.do_push_state) { + this.widget_parent.do_push_state(state); + } }, - do_load_state: function(state) { - } }); session.web.json_node_to_xml = function(node, human_readable, indent) { From f6b2fc59e98fe31ebf6ee352a180b026a44d0d53 Mon Sep 17 00:00:00 2001 From: niv-openerp Date: Wed, 14 Dec 2011 18:03:56 +0100 Subject: [PATCH 45/59] [imp] now closes dialogs when using client actions bzr revid: nicolas.vanhoren@openerp.com-20111214170356-sljdibj73yy0maeu --- addons/web/static/src/js/chrome.js | 2 +- addons/web/static/src/js/data.js | 2 +- addons/web/static/src/js/views.js | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 8c8c3b5f7d6..41f1ac532c6 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -663,7 +663,7 @@ openerp.web.Header = openerp.web.Widget.extend(/** @lends openerp.web.Header# * self.$content.remove(); if (!self.session.uid) return; - var func = new openerp.web.Model(self.session, "res.users").get_func("read"); + var func = new openerp.web.Model("res.users").get_func("read"); return func(self.session.uid, ["name", "company_id"]).pipe(function(res) { self.$content = $(QWeb.render("Header-content", {widget: self, user: res})); self.$content.appendTo(self.$element); diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index 26147b4d4e0..aec701e6e67 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -811,7 +811,7 @@ openerp.web.ProxyDataSet = openerp.web.DataSetSearch.extend({ }); openerp.web.Model = openerp.web.CallbackEnabled.extend({ - init: function(_, model_name) { + init: function(model_name) { this._super(); this.model_name = model_name; }, diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index fcc8a4cc06c..116d7da3aef 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -152,6 +152,7 @@ session.web.ActionManager = session.web.Widget.extend({ }, ir_actions_client: function (action) { this.content_stop(); + this.dialog_stop(); var ClientWidget = session.web.client_actions.get_object(action.tag); (this.client_widget = new ClientWidget(this, action.params)).appendTo(this); From 1db085976809c6fd9276c80724712967ed2dc99e Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Wed, 14 Dec 2011 18:18:11 +0100 Subject: [PATCH 46/59] [IMP] factorise View.do_show do_hide bzr revid: al@openerp.com-20111214171811-6l9jqafkr8k9grut --- addons/web/static/src/js/view_form.js | 4 ++-- addons/web/static/src/js/view_list.js | 4 ++-- addons/web/static/src/js/views.js | 15 ++++++++++----- addons/web_calendar/static/src/js/calendar.js | 2 +- addons/web_diagram/static/src/js/diagram.js | 8 -------- addons/web_gantt/static/src/js/gantt.js | 8 -------- addons/web_graph/static/src/js/graph.js | 6 ------ addons/web_kanban/static/src/js/kanban.js | 6 ------ 8 files changed, 15 insertions(+), 38 deletions(-) diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 0ac70e64a67..79732296816 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -125,14 +125,14 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# } else { promise = this.dataset.read_index(_.keys(this.fields_view.fields)).pipe(this.on_record_loaded); } - this.$element.show(); + this._super(); if (this.sidebar) { this.sidebar.$element.show(); } return promise; }, do_hide: function () { - this.$element.hide(); + this._super(); if (this.sidebar) { this.sidebar.$element.hide(); } diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index bf423434ecc..ad253586591 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -402,13 +402,13 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView# }, this)); }, do_show: function () { - this.$element.show(); + this._super(); if (this.sidebar) { this.sidebar.$element.show(); } }, do_hide: function () { - this.$element.hide(); + this._super(); if (this.sidebar) { this.sidebar.$element.hide(); } diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 116d7da3aef..30b3cff6c96 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -1065,19 +1065,26 @@ session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{ this.embedded_view = embedded_view; this.options.sidebar = false; }, + do_show: function () { + this.$element.show(); + }, + do_hide: function () { + this.$element.hide(); + }, /** * Switches to a specific view type * * @param {String} view view type to switch to */ - do_switch_view: function(view) { }, + do_switch_view: function(view) { + }, /** * Cancels the switch to the current view, switches to the previous one */ - do_prev_view: function () { }, + do_prev_view: function () { + }, do_search: function(view) { }, - set_common_sidebar_sections: function(sidebar) { sidebar.add_default_sections(); }, @@ -1146,10 +1153,8 @@ session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{ sidebar_context: function () { return $.Deferred().resolve({}).promise(); }, - do_push_state: function(state, overwrite) { }, - do_load_state: function(state) { } }); diff --git a/addons/web_calendar/static/src/js/calendar.js b/addons/web_calendar/static/src/js/calendar.js index aac3dcb4f3b..1e253fc8f44 100644 --- a/addons/web_calendar/static/src/js/calendar.js +++ b/addons/web_calendar/static/src/js/calendar.js @@ -394,7 +394,7 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({ }); }, do_hide: function () { - this.$element.hide(); + this._super(); if (this.sidebar) { this.sidebar.$element.hide(); } diff --git a/addons/web_diagram/static/src/js/diagram.js b/addons/web_diagram/static/src/js/diagram.js index 08617efd073..7c2619cd5b9 100644 --- a/addons/web_diagram/static/src/js/diagram.js +++ b/addons/web_diagram/static/src/js/diagram.js @@ -298,14 +298,6 @@ openerp.web.DiagramView = openerp.web.View.extend({ } $pager.find('span.oe_pager_index').html(index); $pager.find('span.oe_pager_count').html(this.dataset.count); - }, - - do_show: function () { - this.$element.show(); - }, - - do_hide: function () { - this.$element.hide(); } }); }; diff --git a/addons/web_gantt/static/src/js/gantt.js b/addons/web_gantt/static/src/js/gantt.js index 71dba5da093..ccf2ac07bfb 100644 --- a/addons/web_gantt/static/src/js/gantt.js +++ b/addons/web_gantt/static/src/js/gantt.js @@ -459,14 +459,6 @@ openerp.web_gantt.GanttView = openerp.web.View.extend({ } }, - do_show: function () { - this.$element.show(); - }, - - do_hide: function () { - this.$element.hide(); - }, - convert_str_date: function (str) { if (typeof str == 'string') { if (str.length == 19) { diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 6cf9998fdda..acab0b73f5e 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -37,12 +37,6 @@ openerp.web_graph.GraphView = openerp.web.View.extend({ } this._super(); }, - do_show: function () { - this.$element.show(); - }, - do_hide: function () { - this.$element.hide(); - }, start: function() { var self = this; this._super(); diff --git a/addons/web_kanban/static/src/js/kanban.js b/addons/web_kanban/static/src/js/kanban.js index 7299a3ae63d..9f86d4d3383 100644 --- a/addons/web_kanban/static/src/js/kanban.js +++ b/addons/web_kanban/static/src/js/kanban.js @@ -258,12 +258,6 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({ }); } }, - do_show: function () { - this.$element.show(); - }, - do_hide: function () { - this.$element.hide(); - }, compute_groups_width: function() { var unfolded = 0; _.each(this.groups, function(group) { From cb4dbede99065b6e0bfa10163ce51579d77ec2e3 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Wed, 14 Dec 2011 19:04:42 +0100 Subject: [PATCH 47/59] [FIX] working urls bzr revid: al@openerp.com-20111214180442-gd1j369la1kss2wj --- addons/web/static/src/js/chrome.js | 1 - addons/web/static/src/js/view_form.js | 2 +- addons/web/static/src/js/views.js | 39 ++++++++++++--------------- 3 files changed, 18 insertions(+), 24 deletions(-) diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index e4bbf5f2503..0d0454c08e4 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -1098,7 +1098,6 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie this._current_state = state; }, do_push_state: function(state) { - console.log('dopushstate', state); var url = '#' + $.param(state); this._current_state = _.clone(state); $.bbq.pushState(url); diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 502778d0f28..eb5a310e154 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -125,7 +125,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# } else { promise = this.dataset.read_index(_.keys(this.fields_view.fields)).pipe(this.on_record_loaded); } - this._super(); + this.$element.show(); if (this.sidebar) { this.sidebar.$element.show(); } diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index e29d7761196..f97a09dee94 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -20,7 +20,7 @@ session.web.ActionManager = session.web.Widget.extend({ identifier_prefix: "actionmanager", init: function(parent) { this._super(parent); - this.action = null; + this.inner_action = null; this.inner_viewmanager = null; this.dialog = null; this.dialog_viewmanager = null; @@ -47,18 +47,14 @@ session.web.ActionManager = session.web.Widget.extend({ this.client_widget = null; } }, - do_push_state: function(state) { - if (this.wiget_parent && this.widget_parent.do_push_state) { - if (this.action.id) { - state = _.extend({}, state || {}, { - action_id: this.action.id, - }); + if (this.widget_parent && this.widget_parent.do_push_state) { + if (this.inner_action && this.inner_action.id) { + state['action_id'] = this.inner_action.id; } this.widget_parent.do_push_state(state); } }, - do_load_state: function(state) { if (state.action_id) { this.null_action(); @@ -78,7 +74,6 @@ session.web.ActionManager = session.web.Widget.extend({ this.inner_viewmanager.do_load_state(state); } }, - do_action: function(action, on_close) { if (_.isNumber(action)) { var self = this; @@ -104,7 +99,6 @@ session.web.ActionManager = session.web.Widget.extend({ console.error("Action manager can't handle action of type " + action.type, action); return; } - this.action = action; return this[type](action, on_close); }, null_action: function() { @@ -317,8 +311,6 @@ session.web.ViewManager = session.web.Widget.extend(/** @lends session.web.View }); return view_promise; }, - - /** * Returns to the view preceding the caller view in this manager's * navigation history (the navigation history is appended to via @@ -394,7 +386,8 @@ session.web.ViewManager = session.web.Widget.extend(/** @lends session.web.View /** * Called by children view after executing an action */ - on_action_executed: function () {}, + on_action_executed: function () { + }, display_title: function () { var view = this.views[this.active_view]; if (view) { @@ -583,23 +576,18 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner } }); }, - do_push_state: function(state) { - if (this.wiget_parent && this.widget_parent.do_push_state) { - state = _.extend({}, state || {}, { - view_type: this.active_view - }); + if (this.widget_parent && this.widget_parent.do_push_state) { + state["view_type"] = this.active_view; this.widget_parent.do_push_state(state); } }, - do_load_state: function(state) { var self = this; $.when(this.on_mode_switch(state.view_type, true)).done(function() { self.views[self.active_view].controller.do_load_state(state); }); }, - shortcut_check : function(view) { var self = this; var grandparent = this.widget_parent && this.widget_parent.widget_parent; @@ -1067,10 +1055,18 @@ session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{ }, do_show: function () { this.$element.show(); + this.do_push_state({}); }, do_hide: function () { this.$element.hide(); }, + do_push_state: function(state) { + if (this.widget_parent && this.widget_parent.do_push_state) { + this.widget_parent.do_push_state(state); + } + }, + do_load_state: function(state) { + }, /** * Switches to a specific view type * @@ -1152,8 +1148,7 @@ session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{ }, sidebar_context: function () { return $.Deferred().resolve({}).promise(); - }, - }, + } }); session.web.json_node_to_xml = function(node, human_readable, indent) { From 028f9cc9842f07c9b33337332051b7e2b31f9d22 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 15 Dec 2011 11:06:52 +0100 Subject: [PATCH 48/59] [FIX] translatability of addition button label in listview * Original label is evaluated very early (before translation database is loaded), defer its execution * Replacement 'add' label in m2m list views wasn't marked for translation * Also mark a few strings in form view lp bug: https://launchpad.net/bugs/903963 fixed bzr revid: xmo@openerp.com-20111215100652-ibgqod7ikwiz85ic --- addons/web/static/src/js/view_form.js | 8 ++++---- addons/web/static/src/js/view_list.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 502778d0f28..83f6768f292 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -140,7 +140,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# on_record_loaded: function(record) { var self = this, set_values = []; if (!record) { - throw("Form: No record received"); + throw new Error("Form: No record received"); } this.datarecord = record; @@ -629,7 +629,7 @@ openerp.web.form.SidebarAttachments = openerp.web.Widget.extend({ on_attachment_delete: function(e) { var self = this, $e = $(e.currentTarget); var name = _.str.trim($e.parent().find('a.oe-sidebar-attachments-link').text()); - if (confirm("Do you really want to delete the attachment " + name + " ?")) { + if (confirm(_.sprintf(_t("Do you really want to delete the attachment %s?"), name))) { this.rpc('/web/dataset/unlink', { model: 'ir.attachment', ids: [parseInt($e.attr('data-id'))] @@ -1051,7 +1051,7 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({ if (self.node.attrs.confirm) { var def = $.Deferred(); var dialog = $('
' + self.node.attrs.confirm + '
').dialog({ - title: 'Confirm', + title: _t('Confirm'), modal: true, buttons: { Ok: function() { @@ -2374,7 +2374,7 @@ openerp.web.form.FieldMany2Many = openerp.web.form.Field.extend({ load_view: function() { var self = this; this.list_view = new openerp.web.form.Many2ManyListView(this, this.dataset, false, { - 'addable': self.is_readonly() ? null : 'Add', + 'addable': self.is_readonly() ? null : _t("Add"), 'deletable': self.is_readonly() ? false : true, 'selectable': self.multi_selection }); diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index ad253586591..36dc71cc485 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -12,7 +12,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView# // whether the column headers should be displayed 'header': true, // display addition button, with that label - 'addable': _t("Create"), + 'addable': {toString: function () { return _t("Create"); }}, // whether the list view can be sorted, note that once a view has been // sorted it can not be reordered anymore 'sortable': true, From 334ed410ccad2d5a9a6fed3b87d6a28824e84a10 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 15 Dec 2011 11:08:27 +0100 Subject: [PATCH 49/59] [TNL] updated translation template files bzr revid: xmo@openerp.com-20111215100827-ygieteye9052xbqd --- addons/web/po/web.pot | 202 +++++++++++++--------- addons/web_calendar/po/web_calendar.pot | 6 +- addons/web_chat/po/web_chat.pot | 2 +- addons/web_dashboard/po/web_dashboard.pot | 2 +- addons/web_diagram/po/web_diagram.pot | 2 +- addons/web_gantt/po/web_gantt.pot | 2 +- addons/web_graph/po/web_graph.pot | 2 +- addons/web_hello/po/web_hello.pot | 2 +- addons/web_mobile/po/web_mobile.pot | 2 +- addons/web_rpc/po/web_rpc.pot | 2 +- 10 files changed, 127 insertions(+), 97 deletions(-) diff --git a/addons/web/po/web.pot b/addons/web/po/web.pot index 9f8390e71e8..286d75ebe1a 100644 --- a/addons/web/po/web.pot +++ b/addons/web/po/web.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-09 10:33+0100\n" +"POT-Creation-Date: 2011-12-15 11:07+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,8 +18,8 @@ msgstr "" "Generated-By: Babel 0.9.6\n" #: addons/web/static/src/js/data_import.js:73 -#: addons/web/static/src/js/view_form.js:2746 -#: addons/web/static/src/js/views.js:803 +#: addons/web/static/src/js/view_form.js:2741 +#: addons/web/static/src/js/views.js:849 msgid "Close" msgstr "" @@ -31,115 +31,115 @@ msgstr "" msgid "External ID" msgstr "" -#: addons/web/static/src/js/search.js:230 +#: addons/web/static/src/js/search.js:233 msgid "Filter Entry" msgstr "" -#: addons/web/static/src/js/search.js:232 -#: addons/web/static/src/js/search.js:273 addons/web/static/src/xml/base.xml:0 +#: addons/web/static/src/js/search.js:235 +#: addons/web/static/src/js/search.js:276 addons/web/static/src/xml/base.xml:0 msgid "Cancel" msgstr "" -#: addons/web/static/src/js/search.js:235 -#: addons/web/static/src/js/search.js:276 +#: addons/web/static/src/js/search.js:238 +#: addons/web/static/src/js/search.js:279 msgid "OK" msgstr "" -#: addons/web/static/src/js/search.js:271 addons/web/static/src/xml/base.xml:0 +#: addons/web/static/src/js/search.js:274 addons/web/static/src/xml/base.xml:0 msgid "Add to Dashboard" msgstr "" -#: addons/web/static/src/js/search.js:400 +#: addons/web/static/src/js/search.js:403 msgid "Invalid Search" msgstr "" -#: addons/web/static/src/js/search.js:400 +#: addons/web/static/src/js/search.js:403 msgid "triggered from search view" msgstr "" -#: addons/web/static/src/js/search.js:482 +#: addons/web/static/src/js/search.js:490 #, python-format msgid "Incorrect value for field %(fieldname)s: [%(value)s] is %(message)s" msgstr "" -#: addons/web/static/src/js/search.js:803 +#: addons/web/static/src/js/search.js:811 msgid "not a valid integer" msgstr "" -#: addons/web/static/src/js/search.js:817 +#: addons/web/static/src/js/search.js:825 msgid "not a valid number" msgstr "" -#: addons/web/static/src/js/search.js:1233 +#: addons/web/static/src/js/search.js:1241 msgid "contains" msgstr "" -#: addons/web/static/src/js/search.js:1234 +#: addons/web/static/src/js/search.js:1242 msgid "doesn't contain" msgstr "" -#: addons/web/static/src/js/search.js:1235 -#: addons/web/static/src/js/search.js:1250 -#: addons/web/static/src/js/search.js:1270 -#: addons/web/static/src/js/search.js:1290 -#: addons/web/static/src/js/search.js:1312 +#: addons/web/static/src/js/search.js:1243 +#: addons/web/static/src/js/search.js:1258 +#: addons/web/static/src/js/search.js:1278 +#: addons/web/static/src/js/search.js:1298 +#: addons/web/static/src/js/search.js:1320 msgid "is equal to" msgstr "" -#: addons/web/static/src/js/search.js:1236 -#: addons/web/static/src/js/search.js:1251 -#: addons/web/static/src/js/search.js:1271 -#: addons/web/static/src/js/search.js:1291 -#: addons/web/static/src/js/search.js:1313 +#: addons/web/static/src/js/search.js:1244 +#: addons/web/static/src/js/search.js:1259 +#: addons/web/static/src/js/search.js:1279 +#: addons/web/static/src/js/search.js:1299 +#: addons/web/static/src/js/search.js:1321 msgid "is not equal to" msgstr "" -#: addons/web/static/src/js/search.js:1237 -#: addons/web/static/src/js/search.js:1252 -#: addons/web/static/src/js/search.js:1272 -#: addons/web/static/src/js/search.js:1292 -#: addons/web/static/src/js/search.js:1314 +#: addons/web/static/src/js/search.js:1245 +#: addons/web/static/src/js/search.js:1260 +#: addons/web/static/src/js/search.js:1280 +#: addons/web/static/src/js/search.js:1300 +#: addons/web/static/src/js/search.js:1322 msgid "greater than" msgstr "" -#: addons/web/static/src/js/search.js:1238 -#: addons/web/static/src/js/search.js:1253 -#: addons/web/static/src/js/search.js:1273 -#: addons/web/static/src/js/search.js:1293 -#: addons/web/static/src/js/search.js:1315 +#: addons/web/static/src/js/search.js:1246 +#: addons/web/static/src/js/search.js:1261 +#: addons/web/static/src/js/search.js:1281 +#: addons/web/static/src/js/search.js:1301 +#: addons/web/static/src/js/search.js:1323 msgid "less than" msgstr "" -#: addons/web/static/src/js/search.js:1239 -#: addons/web/static/src/js/search.js:1254 -#: addons/web/static/src/js/search.js:1274 -#: addons/web/static/src/js/search.js:1294 -#: addons/web/static/src/js/search.js:1316 +#: addons/web/static/src/js/search.js:1247 +#: addons/web/static/src/js/search.js:1262 +#: addons/web/static/src/js/search.js:1282 +#: addons/web/static/src/js/search.js:1302 +#: addons/web/static/src/js/search.js:1324 msgid "greater or equal than" msgstr "" -#: addons/web/static/src/js/search.js:1240 -#: addons/web/static/src/js/search.js:1255 -#: addons/web/static/src/js/search.js:1275 -#: addons/web/static/src/js/search.js:1295 -#: addons/web/static/src/js/search.js:1317 +#: addons/web/static/src/js/search.js:1248 +#: addons/web/static/src/js/search.js:1263 +#: addons/web/static/src/js/search.js:1283 +#: addons/web/static/src/js/search.js:1303 +#: addons/web/static/src/js/search.js:1325 msgid "less or equal than" msgstr "" -#: addons/web/static/src/js/search.js:1306 -#: addons/web/static/src/js/search.js:1331 +#: addons/web/static/src/js/search.js:1314 +#: addons/web/static/src/js/search.js:1339 msgid "is" msgstr "" -#: addons/web/static/src/js/search.js:1332 +#: addons/web/static/src/js/search.js:1340 msgid "is not" msgstr "" -#: addons/web/static/src/js/search.js:1345 +#: addons/web/static/src/js/search.js:1353 msgid "is true" msgstr "" -#: addons/web/static/src/js/search.js:1346 +#: addons/web/static/src/js/search.js:1354 msgid "is false" msgstr "" @@ -151,41 +151,55 @@ msgstr "" msgid "Do you really want to remove this node?" msgstr "" -#: addons/web/static/src/js/view_form.js:387 +#: addons/web/static/src/js/view_form.js:386 msgid "Warning, the record has been modified, your changes will be discarded." msgstr "" -#: addons/web/static/src/js/view_form.js:595 +#: addons/web/static/src/js/view_form.js:594 msgid "Attachments" msgstr "" -#: addons/web/static/src/js/view_form.js:1823 +#: addons/web/static/src/js/view_form.js:632 +#, python-format +msgid "Do you really want to delete the attachment %s?" +msgstr "" + +#: addons/web/static/src/js/view_form.js:1054 +msgid "Confirm" +msgstr "" + +#: addons/web/static/src/js/view_form.js:1815 msgid "   Search More..." msgstr "" -#: addons/web/static/src/js/view_form.js:1836 +#: addons/web/static/src/js/view_form.js:1828 #, python-format msgid "   Create \"%s\"" msgstr "" -#: addons/web/static/src/js/view_form.js:1842 +#: addons/web/static/src/js/view_form.js:1834 msgid "   Create and Edit..." msgstr "" -#: addons/web/static/src/js/view_list.js:14 +#: addons/web/static/src/js/view_form.js:2377 +#: addons/web/static/src/xml/base.xml:0 +msgid "Add" +msgstr "" + +#: addons/web/static/src/js/view_list.js:15 #: addons/web/static/src/xml/base.xml:0 msgid "Create" msgstr "" -#: addons/web/static/src/js/view_list.js:263 +#: addons/web/static/src/js/view_list.js:265 msgid "Unlimited" msgstr "" -#: addons/web/static/src/js/view_list.js:483 +#: addons/web/static/src/js/view_list.js:488 msgid "Do you really want to remove these records?" msgstr "" -#: addons/web/static/src/js/view_list.js:1159 +#: addons/web/static/src/js/view_list.js:1167 msgid "Undefined" msgstr "" @@ -193,80 +207,80 @@ msgstr "" msgid "Do you really want to delete this record?" msgstr "" -#: addons/web/static/src/js/views.js:518 +#: addons/web/static/src/js/views.js:572 msgid "Search: " msgstr "" -#: addons/web/static/src/js/views.js:621 +#: addons/web/static/src/js/views.js:687 msgid "Customize" msgstr "" -#: addons/web/static/src/js/views.js:624 +#: addons/web/static/src/js/views.js:690 msgid "Manage Views" msgstr "" -#: addons/web/static/src/js/views.js:626 addons/web/static/src/js/views.js:630 -#: addons/web/static/src/js/views.js:635 +#: addons/web/static/src/js/views.js:692 addons/web/static/src/js/views.js:696 +#: addons/web/static/src/js/views.js:701 msgid "Manage views of the current object" msgstr "" -#: addons/web/static/src/js/views.js:628 +#: addons/web/static/src/js/views.js:694 msgid "Edit Workflow" msgstr "" -#: addons/web/static/src/js/views.js:633 +#: addons/web/static/src/js/views.js:699 msgid "Customize Object" msgstr "" -#: addons/web/static/src/js/views.js:637 +#: addons/web/static/src/js/views.js:703 msgid "Translate" msgstr "" -#: addons/web/static/src/js/views.js:639 +#: addons/web/static/src/js/views.js:705 msgid "Technical translation" msgstr "" -#: addons/web/static/src/js/views.js:644 +#: addons/web/static/src/js/views.js:710 msgid "Other Options" msgstr "" -#: addons/web/static/src/js/views.js:647 addons/web/static/src/xml/base.xml:0 +#: addons/web/static/src/js/views.js:713 addons/web/static/src/xml/base.xml:0 msgid "Import" msgstr "" -#: addons/web/static/src/js/views.js:650 addons/web/static/src/xml/base.xml:0 +#: addons/web/static/src/js/views.js:716 addons/web/static/src/xml/base.xml:0 msgid "Export" msgstr "" -#: addons/web/static/src/js/views.js:653 +#: addons/web/static/src/js/views.js:719 msgid "View Log" msgstr "" -#: addons/web/static/src/js/views.js:682 +#: addons/web/static/src/js/views.js:728 msgid "Reports" msgstr "" -#: addons/web/static/src/js/views.js:682 +#: addons/web/static/src/js/views.js:728 msgid "Actions" msgstr "" -#: addons/web/static/src/js/views.js:682 +#: addons/web/static/src/js/views.js:728 msgid "Links" msgstr "" -#: addons/web/static/src/js/views.js:762 +#: addons/web/static/src/js/views.js:808 msgid "You must choose at least one record." msgstr "" -#: addons/web/static/src/js/views.js:763 +#: addons/web/static/src/js/views.js:809 msgid "Warning" msgstr "" -#: addons/web/static/src/js/views.js:797 +#: addons/web/static/src/js/views.js:843 msgid "Translations" msgstr "" -#: addons/web/static/src/js/views.js:802 addons/web/static/src/xml/base.xml:0 +#: addons/web/static/src/js/views.js:848 addons/web/static/src/xml/base.xml:0 msgid "Save" msgstr "" @@ -481,11 +495,31 @@ msgid "Disable all tips" msgstr "" #: addons/web/static/src/xml/base.xml:0 -msgid "View#" +msgid "More…" msgstr "" #: addons/web/static/src/xml/base.xml:0 -msgid "More…" +msgid "Debug View#" +msgstr "" + +#: addons/web/static/src/xml/base.xml:0 +msgid "- Fields View Get" +msgstr "" + +#: addons/web/static/src/xml/base.xml:0 +msgid "- Edit" +msgstr "" + +#: addons/web/static/src/xml/base.xml:0 +msgid "View" +msgstr "" + +#: addons/web/static/src/xml/base.xml:0 +msgid "- Edit SearchView" +msgstr "" + +#: addons/web/static/src/xml/base.xml:0 +msgid "- Edit Action" msgstr "" #: addons/web/static/src/xml/base.xml:0 @@ -540,10 +574,6 @@ msgstr "" msgid "Duplicate" msgstr "" -#: addons/web/static/src/xml/base.xml:0 -msgid "Add" -msgstr "" - #: addons/web/static/src/xml/base.xml:0 msgid "Unhandled widget" msgstr "" diff --git a/addons/web_calendar/po/web_calendar.pot b/addons/web_calendar/po/web_calendar.pot index f92c598a0bf..702a7975524 100644 --- a/addons/web_calendar/po/web_calendar.pot +++ b/addons/web_calendar/po/web_calendar.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-09 10:33+0100\n" +"POT-Creation-Date: 2011-12-15 11:07+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,11 +17,11 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.6\n" -#: addons/web_calendar/static/src/js/calendar.js:412 +#: addons/web_calendar/static/src/js/calendar.js:444 msgid "Responsible" msgstr "" -#: addons/web_calendar/static/src/js/calendar.js:441 +#: addons/web_calendar/static/src/js/calendar.js:473 msgid "Navigator" msgstr "" diff --git a/addons/web_chat/po/web_chat.pot b/addons/web_chat/po/web_chat.pot index 070ea446394..6d003e7cedd 100644 --- a/addons/web_chat/po/web_chat.pot +++ b/addons/web_chat/po/web_chat.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-09 10:33+0100\n" +"POT-Creation-Date: 2011-12-15 11:07+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/addons/web_dashboard/po/web_dashboard.pot b/addons/web_dashboard/po/web_dashboard.pot index 201c979a547..a1a3c1d5e9a 100644 --- a/addons/web_dashboard/po/web_dashboard.pot +++ b/addons/web_dashboard/po/web_dashboard.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-09 10:33+0100\n" +"POT-Creation-Date: 2011-12-15 11:07+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/addons/web_diagram/po/web_diagram.pot b/addons/web_diagram/po/web_diagram.pot index 91d96431684..8a4e5029a26 100644 --- a/addons/web_diagram/po/web_diagram.pot +++ b/addons/web_diagram/po/web_diagram.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-09 10:33+0100\n" +"POT-Creation-Date: 2011-12-15 11:07+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/addons/web_gantt/po/web_gantt.pot b/addons/web_gantt/po/web_gantt.pot index 9c91dda7f30..b89e5c3d878 100644 --- a/addons/web_gantt/po/web_gantt.pot +++ b/addons/web_gantt/po/web_gantt.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-09 10:33+0100\n" +"POT-Creation-Date: 2011-12-15 11:07+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/addons/web_graph/po/web_graph.pot b/addons/web_graph/po/web_graph.pot index 070ea446394..6d003e7cedd 100644 --- a/addons/web_graph/po/web_graph.pot +++ b/addons/web_graph/po/web_graph.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-09 10:33+0100\n" +"POT-Creation-Date: 2011-12-15 11:07+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/addons/web_hello/po/web_hello.pot b/addons/web_hello/po/web_hello.pot index 070ea446394..6d003e7cedd 100644 --- a/addons/web_hello/po/web_hello.pot +++ b/addons/web_hello/po/web_hello.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-09 10:33+0100\n" +"POT-Creation-Date: 2011-12-15 11:07+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/addons/web_mobile/po/web_mobile.pot b/addons/web_mobile/po/web_mobile.pot index 6667eeb8d27..97d526efae7 100644 --- a/addons/web_mobile/po/web_mobile.pot +++ b/addons/web_mobile/po/web_mobile.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-09 10:33+0100\n" +"POT-Creation-Date: 2011-12-15 11:07+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/addons/web_rpc/po/web_rpc.pot b/addons/web_rpc/po/web_rpc.pot index 070ea446394..6d003e7cedd 100644 --- a/addons/web_rpc/po/web_rpc.pot +++ b/addons/web_rpc/po/web_rpc.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-09 10:33+0100\n" +"POT-Creation-Date: 2011-12-15 11:07+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" From 187216f8bdd055bc2dd3cdfa79245c8a2fbd754e Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 15 Dec 2011 11:40:31 +0100 Subject: [PATCH 50/59] [IMP] mark a bunch of dialog stuff as exportable (mostly buttons, but also dialog titles) bzr revid: xmo@openerp.com-20111215104031-zy56xwtb7cjwzcbj --- addons/web/static/src/js/chrome.js | 68 ++++---- addons/web/static/src/js/data_export.js | 17 +- addons/web/static/src/js/data_import.js | 2 +- addons/web/static/src/js/view_editor.js | 155 ++++++++---------- addons/web/static/src/js/view_form.js | 30 ++-- addons/web/static/src/js/views.js | 2 +- .../web_dashboard/static/src/js/dashboard.js | 5 +- addons/web_diagram/static/src/js/diagram.js | 24 +-- addons/web_process/static/src/js/process.js | 15 +- 9 files changed, 146 insertions(+), 172 deletions(-) diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 0d0454c08e4..22b8ff88c37 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -2,7 +2,8 @@ * OpenERP Web chrome *---------------------------------------------------------*/ openerp.web.chrome = function(openerp) { -var QWeb = openerp.web.qweb; +var QWeb = openerp.web.qweb, + _t = openerp.web._t; openerp.web.Notification = openerp.web.Widget.extend(/** @lends openerp.web.Notification# */{ template: 'Notification', @@ -157,11 +158,9 @@ openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({ on_managed_error: function(error) { $('
' + QWeb.render('DialogWarning', {error: error}) + '
').dialog({ title: "OpenERP " + _.str.capitalize(error.type), - buttons: { - Ok: function() { - $(this).dialog("close"); - } - } + buttons: [ + {text: _t("Ok"), click: function() { $(this).dialog("close"); }} + ] }); }, on_traceback: function(error) { @@ -172,11 +171,9 @@ openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({ height: '90%', min_width: '800px', min_height: '600px', - buttons: { - Ok: function() { - $(this).dialog("close"); - } - } + buttons: [ + {text: _t("Ok"), click: function() { $(this).dialog("close"); }} + ] }).start(); dialog.$element.html(QWeb.render('DialogTraceback', {error: error})); } @@ -368,11 +365,9 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database return $('
').dialog({ modal: true, title: error.title, - buttons: { - Ok: function() { - $(this).dialog("close"); - } - } + buttons: [ + {text: _t("Ok"), click: function() { $(this).dialog("close"); }} + ] }).html(error.error); }, do_create: function() { @@ -680,7 +675,7 @@ openerp.web.Header = openerp.web.Widget.extend(/** @lends openerp.web.Header# * self.rpc("/web/webclient/version_info", {}).then(function(res) { var $help = $(QWeb.render("About-Page", {version_info: res})); $help.dialog({autoOpen: true, - modal: true, width: 960, title: "About"}); + modal: true, width: 960, title: _t("About")}); }); }, shortcut_load :function(){ @@ -760,25 +755,22 @@ openerp.web.Header = openerp.web.Widget.extend(/** @lends openerp.web.Header# * }); this.dialog = new openerp.web.Dialog(this,{ modal: true, - title: 'Preferences', + title: _t("Preferences"), width: 600, height: 500, - buttons: { - "Change password": function(){ - self.change_password(); - }, - Cancel: function(){ - $(this).dialog('destroy'); - }, - Save: function(){ - var inner_viewmanager = action_manager.inner_viewmanager; - inner_viewmanager.views[inner_viewmanager.active_view].controller.do_save() - .then(function() { - self.dialog.stop(); - window.location.reload(); - }); + buttons: [ + {text: _t("Change password"), click: function(){ self.change_password(); }}, + {text: _t("Cancel"), click: function(){ $(this).dialog('destroy'); }}, + {text: _t("Save"), click: function(){ + var inner_viewmanager = action_manager.inner_viewmanager; + inner_viewmanager.views[inner_viewmanager.active_view].controller.do_save() + .then(function() { + self.dialog.stop(); + window.location.reload(); + }); + } } - } + ] }); this.dialog.start().open(); action_manager.appendTo(this.dialog); @@ -789,7 +781,7 @@ openerp.web.Header = openerp.web.Widget.extend(/** @lends openerp.web.Header# * var self = this; this.dialog = new openerp.web.Dialog(this,{ modal : true, - title : 'Change Password', + title: _t("Change Password"), width : 'auto', height : 'auto' }); @@ -814,11 +806,9 @@ openerp.web.Header = openerp.web.Widget.extend(/** @lends openerp.web.Header# * return $('
').dialog({ modal: true, title: error.title, - buttons: { - Ok: function() { - $(this).dialog("close"); - } - } + buttons: [ + {text: _("Ok"), click: function() { $(this).dialog("close"); }} + ] }).html(error.error); }, on_logout: function() { diff --git a/addons/web/static/src/js/data_export.js b/addons/web/static/src/js/data_export.js index ea142606b5b..8a2d2c8594b 100644 --- a/addons/web/static/src/js/data_export.js +++ b/addons/web/static/src/js/data_export.js @@ -1,8 +1,9 @@ openerp.web.data_export = function(openerp) { -var QWeb = openerp.web.qweb; +var QWeb = openerp.web.qweb, + _t = openerp.web._t; openerp.web.DataExport = openerp.web.Dialog.extend({ template: 'ExportTreeView', - dialog_title: 'Export Data', + dialog_title: {toString: function () { return _t("Export Data"); }}, init: function(parent, dataset) { this._super(parent); this.records = {}; @@ -18,14 +19,10 @@ openerp.web.DataExport = openerp.web.Dialog.extend({ width: '55%', height: 'auto', position: 'top', - buttons : { - "Close" : function() { - self.close(); - }, - "Export To File" : function() { - self.on_click_export_data(); - } - }, + buttons : [ + {text: _t("Close"), click: function() { self.close(); }}, + {text: _t("Export To File"), click: function() { self.on_click_export_data(); }} + ], close: function(event, ui){ self.close();} }); self.$element.removeClass('ui-dialog-content ui-widget-content'); diff --git a/addons/web/static/src/js/data_import.js b/addons/web/static/src/js/data_import.js index cd699c0481d..7f4af7b35bb 100644 --- a/addons/web/static/src/js/data_import.js +++ b/addons/web/static/src/js/data_import.js @@ -31,7 +31,7 @@ function jsonp(form, attributes, callback) { openerp.web.DataImport = openerp.web.Dialog.extend({ template: 'ImportDataView', - dialog_title: "Import Data", + dialog_title: {toString: function () { return _t("Import Data"); }}, init: function(parent, dataset){ var self = this; this._super(parent, {}); diff --git a/addons/web/static/src/js/view_editor.js b/addons/web/static/src/js/view_editor.js index 352856c2b6c..f925a6416eb 100644 --- a/addons/web/static/src/js/view_editor.js +++ b/addons/web/static/src/js/view_editor.js @@ -35,28 +35,19 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({ pager: false, radio: true, select_view_id: self.parent.fields_view.view_id - }, + } }; this.view_edit_dialog = new openerp.web.Dialog(this, { modal: true, - title: 'ViewEditor', + title: _t("ViewEditor"), width: 750, height: 500, - buttons: { - "Create": function(){ - self.on_create_view(); - }, - "Edit": function(){ - self.xml_element_id = 0; - self.get_arch(); - }, - "Remove": function(){ - self.do_delete_view(); - }, - "Close": function(){ - self.view_edit_dialog.close(); - } - }, + buttons: [ + {text: _t("Create"), click: function() { self.on_create_view(); }}, + {text: _t("Edit"), click: function() { self.xml_element_id = 0; self.get_arch(); }}, + {text: _t("Remove"), click: function() { self.do_delete_view(); }}, + {text: _t("Close"), click: function() { self.view_edit_dialog.close(); }} + ] }).start().open(); this.main_view_id = this.parent.fields_view.view_id; this.action_manager = new openerp.web.ActionManager(this); @@ -77,36 +68,34 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({ var self = this; this.create_view_dialog = new openerp.web.Dialog(this, { modal: true, - title: _.str.sprintf("Create a view (%s)", self.model), + title: _.str.sprintf(_t("Create a view (%s)"), self.model), width: 500, height: 400, - buttons: { - "Save": function(){ - var view_values = {}; - var warn = false; - _.each(self.create_view_widget, function(widget) { - if (widget.is_invalid) { - warn = true; - return false; - }; - if (widget.dirty && !widget.is_invalid) { - view_values[widget.name] = widget.get_value(); - } - }); - if (warn) { - self.on_valid_create_view(self.create_view_widget); - } else { - $.when(self.do_save_view(view_values)).then(function() { - self.create_view_dialog.close(); - var controller = self.action_manager.inner_viewmanager.views[self.action_manager.inner_viewmanager.active_view].controller; - controller.reload_content(); - }); + buttons: [ + {text: _t("Save"), click: function () { + var view_values = {}; + var warn = false; + _.each(self.create_view_widget, function(widget) { + if (widget.is_invalid) { + warn = true; + return false; } - }, - "Cancel": function(){ - self.create_view_dialog.close(); + if (widget.dirty && !widget.is_invalid) { + view_values[widget.name] = widget.get_value(); + } + }); + if (warn) { + self.on_valid_create_view(self.create_view_widget); + } else { + $.when(self.do_save_view(view_values)).then(function() { + self.create_view_dialog.close(); + var controller = self.action_manager.inner_viewmanager.views[self.action_manager.inner_viewmanager.active_view].controller; + controller.reload_content(); + }); } - } + }}, + {text: _t("Cancel"), click: function () { self.create_view_dialog.close(); }} + ] }); this.create_view_dialog.start().open(); var view_widget = [{'name': 'view_name', 'string':'View Name', 'type': 'char', 'required': true, 'value' : this.model + '.custom_' + Math.round(Math.random() * 1000)}, @@ -375,11 +364,11 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({ this.one_object = one_object; this.edit_xml_dialog = new openerp.web.Dialog(this, { modal: true, - title: _.str.sprintf("View Editor %d - %s", self.main_view_id, self.model), + title: _.str.sprintf(_t("View Editor %d - %s"), self.main_view_id, self.model), width: 750, height: 500, - buttons: { - "Preview": function() { + buttons: [ + {text: _t("Preview"), click: function() { var action = { context: self.session.user_context, res_model: self.model, @@ -389,16 +378,16 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({ flags: { sidebar: false, views_switcher: false, - action_buttons: false, - }, + action_buttons: false + } }; var action_manager = new openerp.web.ActionManager(self); action_manager.do_action(action); - }, - "Close": function(){ + }}, + {text: _t("Close"), click: function(){ self.edit_xml_dialog.close(); - } - } + }} + ] }).start().open(); var no_property_att = []; _.each(_PROPERTIES, function(val, key) { @@ -764,17 +753,17 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({ var self = this; this.edit_node_dialog = new openerp.web.Dialog(this,{ modal: true, - title: 'Properties', + title: _t("Properties"), width: 500, height: 400, - buttons: { - "Update": function(){ + buttons: [ + {text: _t("Update"), click: function () { var warn = false, update_values = []; _.each(self.edit_widget, function(widget) { if (widget.is_invalid) { warn = true; return false; - }; + } if (widget.dirty && !widget.is_invalid) { update_values.push([widget.name, widget.get_value()]); } @@ -785,11 +774,9 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({ self.do_save_update_arch("update_node", update_values); self.edit_node_dialog.close(); } - }, - "Cancel": function(){ - self.edit_node_dialog.close(); - } - } + }}, + {text: _t("Cancel"), click: function () { self.edit_node_dialog.close(); }} + ] }); this.edit_node_dialog.start().open(); var _PROPERTIES_ATTRIBUTES = { @@ -893,32 +880,32 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({ this.add_widget = []; this.add_node_dialog = new openerp.web.Dialog(this,{ modal: true, - title: 'Properties', + title: _t("Properties"), width: 450, height: 190, - buttons: { - "Update": function(){ - var check_add_node = true, values = {}; - _.each(self.add_widget, function(widget) { - values[widget.name] = widget.get_value() || false; - }); - (values.position == "Inside")? - check_add_node =(_.include(_CHILDREN[properties[0]],values.node_type))?true:false: - check_add_node =(_.include(_CHILDREN[properties[1]],values.node_type))?true:false; - if(values.node_type == "field" && check_add_node ) - {check_add_node = (values.field_value != " ")?true:false; - } - if(check_add_node){ - var tag = (values.node_type == "field")? - _.str.sprintf("<%s name='%s'> ",values.node_type,values.field_value,values.node_type): - _.str.sprintf("<%s> ",values.node_type,values.node_type); - self.do_save_update_arch("add_node", [tag, values.position]); - }else{alert("Can't Update View");} - }, - "Cancel": function(){ - self.add_node_dialog.close(); + buttons: [ + {text: _t("Update"), click: function() { + var check_add_node = true, values = {}; + _.each(self.add_widget, function(widget) { + values[widget.name] = widget.get_value() || false; + }); + (values.position == "Inside")? + check_add_node =(_.include(_CHILDREN[properties[0]],values.node_type))?true:false: + check_add_node =(_.include(_CHILDREN[properties[1]],values.node_type))?true:false; + if(values.node_type == "field" && check_add_node ) + {check_add_node = (values.field_value != " ")?true:false; } - } + if(check_add_node){ + var tag = (values.node_type == "field")? + _.str.sprintf("<%s name='%s'> ",values.node_type,values.field_value,values.node_type): + _.str.sprintf("<%s> ",values.node_type,values.node_type); + self.do_save_update_arch("add_node", [tag, values.position]); + } else { + alert("Can't Update View"); + } + }}, + {text: _t("Cancel"), click: function() { self.add_node_dialog.close(); }} + ] }).start().open(); this.add_node_dialog.$element.append('
'); var table_selector = self.add_node_dialog.$element.find('table[id=rec_table] tbody'); diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 83f6768f292..7be1cfec741 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -337,11 +337,9 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# if (!_.isEmpty(result.warning)) { $(QWeb.render("DialogWarning", result.warning)).dialog({ modal: true, - buttons: { - Ok: function() { - $(this).dialog("close"); - } - } + buttons: [ + {text: _t("Ok"), click: function() { $(this).dialog("close"); }} + ] }); } if (result.domain) { @@ -1053,18 +1051,20 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({ var dialog = $('
' + self.node.attrs.confirm + '
').dialog({ title: _t('Confirm'), modal: true, - buttons: { - Ok: function() { - self.on_confirmed().then(function() { - def.resolve(); - }); - $(this).dialog("close"); + buttons: [ + {text: _t("Ok"), click: function() { + self.on_confirmed().then(function() { + def.resolve(); + }); + $(this).dialog("close"); + } }, - Cancel: function() { - def.resolve(); - $(this).dialog("close"); + {text: _t("Cancel"), click: function() { + def.resolve(); + $(this).dialog("close"); + } } - } + ] }); return def.promise(); } else { diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index ba5ef2772e7..94972fcde31 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -840,7 +840,7 @@ session.web.Sidebar = session.web.Widget.extend({ }); session.web.TranslateDialog = session.web.Dialog.extend({ - dialog_title: _t("Translations"), + dialog_title: {toString: function () { return _t("Translations"); }}, init: function(view) { // TODO fme: should add the language to fields_view_get because between the fields view get // and the moment the user opens the translation dialog, the user language could have been changed diff --git a/addons/web_dashboard/static/src/js/dashboard.js b/addons/web_dashboard/static/src/js/dashboard.js index ce7e877b73f..28ea12796d2 100644 --- a/addons/web_dashboard/static/src/js/dashboard.js +++ b/addons/web_dashboard/static/src/js/dashboard.js @@ -1,5 +1,6 @@ openerp.web_dashboard = function(openerp) { -var QWeb = openerp.web.qweb; +var QWeb = openerp.web.qweb, + _t = openerp.web._t; if (!openerp.web_dashboard) { /** @namespace */ @@ -59,7 +60,7 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({ }; var $dialog = $('
').dialog({ modal: true, - title: 'Edit Layout', + title: _t("Edit Layout"), width: 'auto', height: 'auto' }).html(QWeb.render('DashBoard.layouts', qdict)); diff --git a/addons/web_diagram/static/src/js/diagram.js b/addons/web_diagram/static/src/js/diagram.js index 7c2619cd5b9..0572b7f6fed 100644 --- a/addons/web_diagram/static/src/js/diagram.js +++ b/addons/web_diagram/static/src/js/diagram.js @@ -3,7 +3,8 @@ *---------------------------------------------------------*/ openerp.web_diagram = function (openerp) { -var QWeb = openerp.web.qweb; +var QWeb = openerp.web.qweb, + _t = openerp.web._t; openerp.web.views.add('diagram', 'openerp.web.DiagramView'); openerp.web.DiagramView = openerp.web.View.extend({ searchable: false, @@ -203,19 +204,18 @@ openerp.web.DiagramView = openerp.web.View.extend({ var dialog = new openerp.web.Dialog(this, { width: 800, height: 600, - buttons : { - Cancel : function() { - $(this).dialog('destroy'); - }, - Save : function() { - var form_view = action_manager.inner_viewmanager.views.form.controller; + buttons : [ + {text: _t("Cancel"), click: function() { $(this).dialog('destroy'); }}, + {text: _t("Save"), click: function() { + var form_view = action_manager.inner_viewmanager.views.form.controller; - form_view.do_save(function() { - self.dataset.read_index(_.keys(self.fields_view.fields), self.on_diagram_loaded); - }); - $(this).dialog('destroy'); + form_view.do_save(function() { + self.dataset.read_index(_.keys(self.fields_view.fields), self.on_diagram_loaded); + }); + $(this).dialog('destroy'); + } } - } + ] }).start().open(); action_manager.appendTo(dialog.$element); action_manager.do_action({ diff --git a/addons/web_process/static/src/js/process.js b/addons/web_process/static/src/js/process.js index 9bf814aa4f4..e650530a914 100644 --- a/addons/web_process/static/src/js/process.js +++ b/addons/web_process/static/src/js/process.js @@ -1,5 +1,6 @@ openerp.web_process = function (openerp) { - var QWeb = openerp.web.qweb; + var QWeb = openerp.web.qweb, + _t = openerp.web._t; openerp.web.ViewManager.include({ start: function() { this._super(); @@ -275,19 +276,17 @@ openerp.web_process = function (openerp) { var dialog = new openerp.web.Dialog(this, { width: 800, height: 600, - buttons : { - Cancel : function() { - $(this).dialog('destroy'); - }, - Save : function() { + buttons : [ + {text: _t("Cancel"), click: function() { $(this).dialog('destroy'); }}, + {text: _t("Save"), click: function() { var form_view = action_manager.inner_viewmanager.views.form.controller; form_view.do_save(function() { self.initialize_process_view(); }); $(this).dialog('destroy'); - } - } + }} + ] }).start().open(); action_manager.appendTo(dialog.$element); From 3c0b9b459a944de97740ba5815b75110c5adae9e Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 15 Dec 2011 11:41:45 +0100 Subject: [PATCH 51/59] [EXP] export translation templates for strings marked during previous revision bzr revid: xmo@openerp.com-20111215104145-wc532n2jbws7a5rl --- addons/web/po/web.pot | 145 ++++++++++++++++------ addons/web_calendar/po/web_calendar.pot | 2 +- addons/web_chat/po/web_chat.pot | 2 +- addons/web_dashboard/po/web_dashboard.pot | 6 +- addons/web_diagram/po/web_diagram.pot | 10 +- addons/web_gantt/po/web_gantt.pot | 2 +- addons/web_graph/po/web_graph.pot | 2 +- addons/web_hello/po/web_hello.pot | 2 +- addons/web_mobile/po/web_mobile.pot | 2 +- addons/web_rpc/po/web_rpc.pot | 2 +- 10 files changed, 129 insertions(+), 46 deletions(-) diff --git a/addons/web/po/web.pot b/addons/web/po/web.pot index 286d75ebe1a..f0a41e2d16a 100644 --- a/addons/web/po/web.pot +++ b/addons/web/po/web.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-15 11:07+0100\n" +"POT-Creation-Date: 2011-12-15 11:40+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,12 +17,69 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.6\n" +#: addons/web/static/src/js/chrome.js:162 +#: addons/web/static/src/js/chrome.js:175 +#: addons/web/static/src/js/chrome.js:369 +#: addons/web/static/src/js/view_form.js:341 +#: addons/web/static/src/js/view_form.js:1055 +#: addons/web/static/src/xml/base.xml:0 +msgid "Ok" +msgstr "" + +#: addons/web/static/src/js/chrome.js:678 +msgid "About" +msgstr "" + +#: addons/web/static/src/js/chrome.js:758 +msgid "Preferences" +msgstr "" + +#: addons/web/static/src/js/chrome.js:762 +msgid "Change password" +msgstr "" + +#: addons/web/static/src/js/chrome.js:763 +#: addons/web/static/src/js/search.js:235 +#: addons/web/static/src/js/search.js:276 +#: addons/web/static/src/js/view_editor.js:97 +#: addons/web/static/src/js/view_editor.js:778 +#: addons/web/static/src/js/view_editor.js:907 +#: addons/web/static/src/js/view_form.js:1062 +#: addons/web/static/src/xml/base.xml:0 +msgid "Cancel" +msgstr "" + +#: addons/web/static/src/js/chrome.js:764 +#: addons/web/static/src/js/view_editor.js:75 +#: addons/web/static/src/js/views.js:848 addons/web/static/src/xml/base.xml:0 +msgid "Save" +msgstr "" + +#: addons/web/static/src/js/chrome.js:784 addons/web/static/src/xml/base.xml:0 +msgid "Change Password" +msgstr "" + +#: addons/web/static/src/js/data_export.js:6 +msgid "Export Data" +msgstr "" + +#: addons/web/static/src/js/data_export.js:23 #: addons/web/static/src/js/data_import.js:73 +#: addons/web/static/src/js/view_editor.js:49 +#: addons/web/static/src/js/view_editor.js:387 #: addons/web/static/src/js/view_form.js:2741 #: addons/web/static/src/js/views.js:849 msgid "Close" msgstr "" +#: addons/web/static/src/js/data_export.js:24 +msgid "Export To File" +msgstr "" + +#: addons/web/static/src/js/data_import.js:34 +msgid "Import Data" +msgstr "" + #: addons/web/static/src/js/data_import.js:74 msgid "Import File" msgstr "" @@ -35,11 +92,6 @@ msgstr "" msgid "Filter Entry" msgstr "" -#: addons/web/static/src/js/search.js:235 -#: addons/web/static/src/js/search.js:276 addons/web/static/src/xml/base.xml:0 -msgid "Cancel" -msgstr "" - #: addons/web/static/src/js/search.js:238 #: addons/web/static/src/js/search.js:279 msgid "OK" @@ -143,28 +195,72 @@ msgstr "" msgid "is false" msgstr "" -#: addons/web/static/src/js/view_editor.js:181 +#: addons/web/static/src/js/view_editor.js:42 +msgid "ViewEditor" +msgstr "" + +#: addons/web/static/src/js/view_editor.js:46 +#: addons/web/static/src/js/view_list.js:15 +#: addons/web/static/src/xml/base.xml:0 +msgid "Create" +msgstr "" + +#: addons/web/static/src/js/view_editor.js:47 +#: addons/web/static/src/xml/base.xml:0 +msgid "Edit" +msgstr "" + +#: addons/web/static/src/js/view_editor.js:48 +#: addons/web/static/src/xml/base.xml:0 +msgid "Remove" +msgstr "" + +#: addons/web/static/src/js/view_editor.js:71 +#, python-format +msgid "Create a view (%s)" +msgstr "" + +#: addons/web/static/src/js/view_editor.js:170 msgid "Do you really want to remove this view?" msgstr "" -#: addons/web/static/src/js/view_editor.js:453 +#: addons/web/static/src/js/view_editor.js:367 +#, python-format +msgid "View Editor %d - %s" +msgstr "" + +#: addons/web/static/src/js/view_editor.js:371 +msgid "Preview" +msgstr "" + +#: addons/web/static/src/js/view_editor.js:442 msgid "Do you really want to remove this node?" msgstr "" -#: addons/web/static/src/js/view_form.js:386 +#: addons/web/static/src/js/view_editor.js:756 +#: addons/web/static/src/js/view_editor.js:883 +msgid "Properties" +msgstr "" + +#: addons/web/static/src/js/view_editor.js:760 +#: addons/web/static/src/js/view_editor.js:887 +msgid "Update" +msgstr "" + +#: addons/web/static/src/js/view_form.js:384 msgid "Warning, the record has been modified, your changes will be discarded." msgstr "" -#: addons/web/static/src/js/view_form.js:594 +#: addons/web/static/src/js/view_form.js:592 msgid "Attachments" msgstr "" -#: addons/web/static/src/js/view_form.js:632 +#: addons/web/static/src/js/view_form.js:630 #, python-format msgid "Do you really want to delete the attachment %s?" msgstr "" -#: addons/web/static/src/js/view_form.js:1054 +#: addons/web/static/src/js/view_form.js:1052 msgid "Confirm" msgstr "" @@ -186,11 +282,6 @@ msgstr "" msgid "Add" msgstr "" -#: addons/web/static/src/js/view_list.js:15 -#: addons/web/static/src/xml/base.xml:0 -msgid "Create" -msgstr "" - #: addons/web/static/src/js/view_list.js:265 msgid "Unlimited" msgstr "" @@ -280,10 +371,6 @@ msgstr "" msgid "Translations" msgstr "" -#: addons/web/static/src/js/views.js:848 addons/web/static/src/xml/base.xml:0 -msgid "Save" -msgstr "" - #: addons/web/static/src/xml/base.xml:0 msgid "x" msgstr "" @@ -396,10 +483,6 @@ msgstr "" msgid "Confirm new master password:" msgstr "" -#: addons/web/static/src/xml/base.xml:0 -msgid "Change Password" -msgstr "" - #: addons/web/static/src/xml/base.xml:0 msgid "User:" msgstr "" @@ -566,10 +649,6 @@ msgstr "" msgid ">>" msgstr "" -#: addons/web/static/src/xml/base.xml:0 -msgid "Edit" -msgstr "" - #: addons/web/static/src/xml/base.xml:0 msgid "Duplicate" msgstr "" @@ -806,10 +885,6 @@ msgstr "" msgid "Save fields list" msgstr "" -#: addons/web/static/src/xml/base.xml:0 -msgid "Remove" -msgstr "" - #: addons/web/static/src/xml/base.xml:0 msgid "Remove All" msgstr "" @@ -826,10 +901,6 @@ msgstr "" msgid "Save as:" msgstr "" -#: addons/web/static/src/xml/base.xml:0 -msgid "Ok" -msgstr "" - #: addons/web/static/src/xml/base.xml:0 msgid "Saved exports:" msgstr "" diff --git a/addons/web_calendar/po/web_calendar.pot b/addons/web_calendar/po/web_calendar.pot index 702a7975524..bb96357ea66 100644 --- a/addons/web_calendar/po/web_calendar.pot +++ b/addons/web_calendar/po/web_calendar.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-15 11:07+0100\n" +"POT-Creation-Date: 2011-12-15 11:40+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/addons/web_chat/po/web_chat.pot b/addons/web_chat/po/web_chat.pot index 6d003e7cedd..9d965323f20 100644 --- a/addons/web_chat/po/web_chat.pot +++ b/addons/web_chat/po/web_chat.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-15 11:07+0100\n" +"POT-Creation-Date: 2011-12-15 11:40+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/addons/web_dashboard/po/web_dashboard.pot b/addons/web_dashboard/po/web_dashboard.pot index a1a3c1d5e9a..064b084acba 100644 --- a/addons/web_dashboard/po/web_dashboard.pot +++ b/addons/web_dashboard/po/web_dashboard.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-15 11:07+0100\n" +"POT-Creation-Date: 2011-12-15 11:40+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,6 +17,10 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.6\n" +#: addons/web_dashboard/static/src/js/dashboard.js:63 +msgid "Edit Layout" +msgstr "" + #: addons/web_dashboard/static/src/xml/web_dashboard.xml:0 msgid "Reset" msgstr "" diff --git a/addons/web_diagram/po/web_diagram.pot b/addons/web_diagram/po/web_diagram.pot index 8a4e5029a26..2c1fc4c6013 100644 --- a/addons/web_diagram/po/web_diagram.pot +++ b/addons/web_diagram/po/web_diagram.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-15 11:07+0100\n" +"POT-Creation-Date: 2011-12-15 11:40+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,6 +17,14 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.6\n" +#: addons/web_diagram/static/src/js/diagram.js:208 +msgid "Cancel" +msgstr "" + +#: addons/web_diagram/static/src/js/diagram.js:209 +msgid "Save" +msgstr "" + #: addons/web_diagram/static/src/xml/base_diagram.xml:0 msgid "New Node" msgstr "" diff --git a/addons/web_gantt/po/web_gantt.pot b/addons/web_gantt/po/web_gantt.pot index b89e5c3d878..2e05d9b703e 100644 --- a/addons/web_gantt/po/web_gantt.pot +++ b/addons/web_gantt/po/web_gantt.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-15 11:07+0100\n" +"POT-Creation-Date: 2011-12-15 11:40+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/addons/web_graph/po/web_graph.pot b/addons/web_graph/po/web_graph.pot index 6d003e7cedd..9d965323f20 100644 --- a/addons/web_graph/po/web_graph.pot +++ b/addons/web_graph/po/web_graph.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-15 11:07+0100\n" +"POT-Creation-Date: 2011-12-15 11:40+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/addons/web_hello/po/web_hello.pot b/addons/web_hello/po/web_hello.pot index 6d003e7cedd..9d965323f20 100644 --- a/addons/web_hello/po/web_hello.pot +++ b/addons/web_hello/po/web_hello.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-15 11:07+0100\n" +"POT-Creation-Date: 2011-12-15 11:40+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/addons/web_mobile/po/web_mobile.pot b/addons/web_mobile/po/web_mobile.pot index 97d526efae7..53c029ce5ad 100644 --- a/addons/web_mobile/po/web_mobile.pot +++ b/addons/web_mobile/po/web_mobile.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-15 11:07+0100\n" +"POT-Creation-Date: 2011-12-15 11:40+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/addons/web_rpc/po/web_rpc.pot b/addons/web_rpc/po/web_rpc.pot index 6d003e7cedd..9d965323f20 100644 --- a/addons/web_rpc/po/web_rpc.pot +++ b/addons/web_rpc/po/web_rpc.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-12-15 11:07+0100\n" +"POT-Creation-Date: 2011-12-15 11:40+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" From 31e65bdddf56510db08116029113d5966cd6a51f Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Thu, 15 Dec 2011 13:07:32 +0100 Subject: [PATCH 52/59] partial rework to merge trunk bzr revid: al@openerp.com-20111215120732-is7pab5e5rsfqpj0 --- addons/web/__openerp__.py | 2 +- addons/web/common/http.py | 41 ++++++-------- addons/web/common/session.py | 3 +- addons/web/controllers/main.py | 15 +++++ addons/web/static/src/js/core.js | 96 ++++++++------------------------ 5 files changed, 55 insertions(+), 102 deletions(-) diff --git a/addons/web/__openerp__.py b/addons/web/__openerp__.py index 74f4cdac3f7..a8dda8bcada 100644 --- a/addons/web/__openerp__.py +++ b/addons/web/__openerp__.py @@ -52,7 +52,7 @@ "static/src/js/view_list.js", "static/src/js/view_list_editable.js", "static/src/js/view_tree.js", - "static/src/js/view_editor.js", + "static/src/js/view_editor.js" ], 'css' : [ "static/lib/jquery.superfish/css/superfish.css", diff --git a/addons/web/common/http.py b/addons/web/common/http.py index da34b8a654e..abdd8683d0f 100644 --- a/addons/web/common/http.py +++ b/addons/web/common/http.py @@ -2,7 +2,6 @@ #---------------------------------------------------------- # OpenERP Web HTTP layer #---------------------------------------------------------- -import StringIO import ast import contextlib import functools @@ -88,12 +87,12 @@ class WebRequest(object): self.httpresponse = None self.httpsession = request.session self.config = config - self.session = None def init(self, params): self.params = dict(params) + # OpenERP session setup self.session_id = self.params.pop("session_id", None) or uuid.uuid4().hex - self.session = self.httpsession.setdefault(self.session_id, session.OpenERPSession(self.session_id)) + self.session = self.httpsession.setdefault(self.session_id, session.OpenERPSession()) self.session.config = self.config self.context = self.params.pop('context', None) self.debug = self.params.pop('debug', False) != False @@ -142,11 +141,10 @@ class JsonRequest(WebRequest): method = self.httprequest.method args = self.httprequest.args jsonp = args.get('jsonp', False) + requestf = None + request = None - if jsonp and args.get('r'): - # jsonp method GET - requestf = StringIO.StringIO(args.get('r')) - elif jsonp and method == 'POST': + if jsonp and method == 'POST': # jsonp 2 steps step1 POST: save call self.init(args) req.session.jsonp_requests[args.get('id')] = self.httprequest.form['r'] @@ -156,7 +154,10 @@ class JsonRequest(WebRequest): elif args['jsonp'] and args.get('id'): # jsonp 2 steps step2 GET: run and return result self.init(args) - requestf = StringIO.StringIO(self.session.jsonp_requests.pop(args.get(id), "")) + request = self.session.jsonp_requests.pop(args.get(id), "") + elif jsonp and args.get('r'): + # jsonp method GET + request = args.get('r') else: # regular jsonrpc2 requestf = self.httprequest.stream @@ -164,10 +165,15 @@ class JsonRequest(WebRequest): response = {"jsonrpc": "2.0" } error = None try: - self.jsonrequest = simplejson.loads(direct_json_request, object_hook=nonliterals.non_literal_decoder) + # Read POST content or POST Form Data named "request" + if requestf: + self.jsonrequest = simplejson.load(requestf, object_hook=nonliterals.non_literal_decoder) + else: + self.jsonrequest = simplejson.loads(request, object_hook=nonliterals.non_literal_decoder) self.init(self.jsonrequest.get("params", {})) if _logger.isEnabledFor(logging.DEBUG): - _logger.debug("[%s] --> %s.%s\n%s", rid, controller.__class__.__name__, method.__name__, pprint.pformat(self.jsonrequest)) + _logger.debug("--> %s.%s\n%s", controller.__class__.__name__, method.__name__, pprint.pformat(self.jsonrequest)) + response['id'] = self.jsonrequest.get('id') response["result"] = method(controller, self, **self.params) except openerplib.AuthenticationError: error = { @@ -376,21 +382,6 @@ class ControllerType(type): class Controller(object): __metaclass__ = ControllerType -class Proxy(Controller): - _cp_path = '/web/proxy' - - @jsonrequest - def load(self, req, path): - #req.config.socket_port - #if not re.match('^/[^/]+/static/.*', path): - # return werkzeug.exceptions.BadRequest() - - env = req.httprequest.environ - port = env['SERVER_PORT'] - - o = urllib.urlopen('http://127.0.0.1:%s%s' % (port, path)) - return o.read() - class Root(object): """Root WSGI application for the OpenERP Web Client. diff --git a/addons/web/common/session.py b/addons/web/common/session.py index 6947789a7b5..be1a2b749da 100644 --- a/addons/web/common/session.py +++ b/addons/web/common/session.py @@ -28,8 +28,7 @@ class OpenERPSession(object): Used to store references to non-literal domains which need to be round-tripped to the client browser. """ - def __init__(self, sid): - self.id = sid + def __init__(self): self.config = None self._db = False self._uid = False diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 81061ba5477..c286819ab86 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -242,6 +242,21 @@ class WebClient(openerpweb.Controller): "version": web.common.release.version } +class Proxy(openerpweb.Controller): + _cp_path = '/web/proxy' + + @jsonrequest + def load(self, req, path): + #req.config.socket_port + #if not re.match('^/[^/]+/static/.*', path): + # return werkzeug.exceptions.BadRequest() + + env = req.httprequest.environ + port = env['SERVER_PORT'] + + o = urllib.urlopen('http://127.0.0.1:%s%s' % (port, path)) + return o.read() + class Database(openerpweb.Controller): _cp_path = "/web/database" diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index e1591f46235..1f5e29a311a 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -362,7 +362,6 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. // be saved to (and revived from) cookies this.name = openerp._session_id; }, - bind: function(server, continuation) { if(_.isFunction(server)) { @@ -390,37 +389,12 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. this.active_id = null; this.do_load_qweb(['/web/webclient/qweb'], continuation); }, - connect: function(server, db, login, password, continuation) { var self = this; this.bind(server, function() { self.login(db, login, password, continuation); }); }, - - get_absolute_url: function(path) { - var absolute_url, - r_has_protocol = /^https?:\/\//, - r_absolute_internal = /^\/[^\/]/; // starts with / (but not //) - - - if (r_has_protocol.test(path)) { - if (!_.str.startsWith(path, this.server + '/')) { - $.error('can only contact openerp.server'); - } - absolute_url = path; - } else if (r_absolute_internal.test(path)) { - absolute_url = this.server + path; - } else { // relative url - // XXX is it correct to mix document.location and this.server ?? - var parts = document.location.pathname.split('/'); - parts.pop(); - parts.push(path); - absolute_url = this.server + parts.join('/'); - } - return absolute_url; - }, - /** * Executes an RPC call, registering the provided callbacks. * @@ -454,7 +428,6 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. }); }).then(success_callback, error_callback).promise(); }, - /** * Raw JSON-RPC call * @@ -521,7 +494,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. * The session is validated either by login or by restoration of a previous session */ on_session_valid: function(continuation) { - this.load_modules(continuation); + this.load_modules().then(function() { continuation() } ); }, on_session_invalid: function(continuation) { }, @@ -547,7 +520,9 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. //}).done(success_callback); }); }, - login: function() { this.session_authenticate.apply(this, arguments); }, + login: function() { + this.session_authenticate.apply(this, arguments); + }, /** * Reloads uid and session_id from local storage, if they exist */ @@ -628,17 +603,12 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. }, /** * Load additional web addons of that instance and init them - * FIXME do all actions in sync... */ - load_modules: function(continuation) { + load_modules: function() { var self = this; - - this.module_loading.done(continuation); - //if (this.module_loading.state() !== "pending") { - if (this.module_loading.isResolved() || this.module_loading.isRejected()) { - return; + if(openerp._modules_loaded) { + return $.when(); } - this.rpc('/web/session/modules', {}, function(result) { self.module_list = result; var lang = self.user_context.lang; @@ -649,37 +619,17 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. var file_list = ["/web/static/lib/datejs/globalization/" + self.user_context.lang.replace("_", "-") + ".js" ]; - - /* - self.rpc('/web/webclient/qweblist', {mods: modules}, self.do_load_qweb); - self.rpc('/web/webclient/csslist', {mods: modules}, self.do_load_css); - self.rpc('/web/webclient/jslist', {mods: modules}, function(files) { - self.do_load_js(file_list.concat(files)); - }); - openerp._modules_loaded = true; - // */ - - self.rpc('/web/webclient/qweblist', {mods: modules}, function(files) { - self.do_load_qweb(files, function() { - // once qweb files are loaded... - self.rpc('/web/webclient/csslist', {mods: modules}, function(files) { - self.do_load_css(files, function() { - // once css files are loaded - self.rpc('/web/webclient/jslist', {mods: modules}, function(files) { - self.do_load_js(file_list.concat(files), function() { - self.on_modules_loaded(); - self.module_loading.resolve(); - }); - }); - }); - }); - }); - }); - + return $.when( + self.rpc('/web/webclient/qweblist', {mods: modules}, self.do_load_qweb), + self.rpc('/web/webclient/csslist', {mods: modules}, self.do_load_css), + self.rpc('/web/webclient/jslist', {mods: modules}, function(files) { + self.do_load_js(file_list.concat(files)); + }) + ); }); }); }, - do_load_css: function (files, callback) { + do_load_css: function (files) { var self = this; _.each(files, function (file) { $('head').append($('', { @@ -688,9 +638,8 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. 'type': 'text/css' })); }); - if (callback) { callback(); } }, - do_load_js: function(files, callback) { + do_load_js: function(files) { var self = this; if(files.length != 0) { var file = files.shift(); @@ -706,21 +655,18 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. var head = document.head || document.getElementsByTagName('head')[0]; head.appendChild(tag); } else { - if (callback) { callback(); } + self.on_modules_loaded(); } }, - do_load_qweb: function(files, callback) { + do_load_qweb: function(files) { var self = this; - if (files.length != 0) { var file = files.shift(); - self.rpc('/web/jsonp/static_proxy', {path: file}, function(xml) { + self.rpc('/web/proxy/load', {path: file}, function(xml) { openerp.web.qweb.add_template(_.str.trim(xml)); self.do_load_qweb(files, callback); }); - } else { - if (callback) { callback(); } - } + } }, on_modules_loaded: function() { for(var j=0; j Date: Thu, 15 Dec 2011 14:33:05 +0100 Subject: [PATCH 53/59] move jq_ajax.js bzr revid: al@openerp.com-20111215133305-c7jgyqdes33drllk --- addons/web/__openerp__.py | 1 - addons/web/common/http.py | 1 - addons/web/static/src/js/chrome.js | 3 - addons/web/static/src/js/core.js | 181 ++++++++++++++++++++++++++++- 4 files changed, 177 insertions(+), 9 deletions(-) diff --git a/addons/web/__openerp__.py b/addons/web/__openerp__.py index a8dda8bcada..3767072ff9d 100644 --- a/addons/web/__openerp__.py +++ b/addons/web/__openerp__.py @@ -36,7 +36,6 @@ "static/lib/underscore/underscore.string.js", "static/lib/labjs/LAB.src.js", "static/lib/py.parse/lib/py.js", - "static/src/js/jq_ajax.js", "static/src/js/boot.js", "static/src/js/core.js", "static/src/js/dates.js", diff --git a/addons/web/common/http.py b/addons/web/common/http.py index abdd8683d0f..620e3a548dc 100644 --- a/addons/web/common/http.py +++ b/addons/web/common/http.py @@ -9,7 +9,6 @@ import logging import urllib import os import pprint -#import re import sys import threading import traceback diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 22b8ff88c37..b03c5965bf7 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -1014,7 +1014,6 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie this._super.apply(this, arguments); var self = this; openerp.connection.bind(function() { - var params = {}; if(jQuery.param != undefined && jQuery.deparam(jQuery.param.querystring()).kitten != undefined) { self.$element.addClass("kitten-mode-activated"); @@ -1022,8 +1021,6 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie self.$element.html(QWeb.render("Interface", params)); openerp.connection.session_restore(); - - // TODO nivification of menu Widget !!! self.menu = new openerp.web.Menu(self, "oe_menu", "oe_secondary_menu"); self.menu.on_action.add(self.on_menu_action); diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 1f5e29a311a..96e38b4e4d0 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -342,6 +342,183 @@ openerp.web.CallbackEnabled = openerp.web.Class.extend(/** @lends openerp.web.Ca } }); +$.ajaxSetup({ + converters: { + "json oe-jsonp": true, + "json oe-json": true, + } +}); + +// common preconditions checks +$.ajaxPrefilter("oe-json oe-jsonp", function(options, originalOptions, jqXHR) { + if (!$.isPlainObject(options.openerp)) { + console.error(options.openerp); + $.error('"openerp" option is required.'); + } + + if (!$.isPlainObject(options.data)) { + $.error('data must not be serialized'); + } + options.processData = false; +}); + +$.ajaxPrefilter("oe-json", function(options, originalOptions, jqXHR) { + options.data = JSON.stringify({ + jsonrpc: '2.0', + method: 'call', + params: options.data, + id: _.uniqueId('browser-client-') + }); + + return 'json'; +}); + +$.ajaxPrefilter("oe-jsonp", function(options, originalOptions, jqXHR) { + + options.crossDomain = true; + + var data = null; + if (options.data) { + data = $.param({r:JSON.stringify(options.data)}); + } + + + + var max_url_length = options.max_url_length || 1000, + absolute_url, full_url; + /* + var r_has_protocol = /^https?:\/\//, + r_absolute_internal = /^\/[^\/]/; // starts with / (but not //) + + + if (r_has_protocol.test(options.url)) { + if (!_(options.url).startsWith(options.openerp.server + '/')) { + $.error('can only contact openerp.server'); + } + absolute_url = options.url; + } else if (r_absolute_internal.test(options.url)) { + absolute_url = options.openerp.server + options.url; + } else { // relative url + var parts = document.location.pathname.split('/'); + parts.pop(); + parts.push(options.url); + absolute_url = options.openerp.server + parts.join('/'); + } + // */ + + var absolute_url = options.openerp.get_absolute_url(options.url); + + /// now, made the same url changes that jQuery will do... + var rquery = /\?/, + rts = /([?&])_=[^&]*/; + + full_url = absolute_url; + if (data) { + full_url += (rquery.test(full_url) ? "&" : "?") + data; + } + + // Add anti-cache in url if needed + if (!options.cache) { + var ts = $.now(), + // try replacing _= if it is there + ret = full_url.replace(rts, "$1_=" + ts); + + // if nothing was replaced, add timestamp to the end + full_url = ret + ((ret === full_url) ? (rquery.test(full_url) ? "&" : "?") + "_=" + ts : ""); + } + + options.url = absolute_url; + + if (full_url.length < max_url_length) { + options.type = "GET"; + options.data = data; + return "jsonp"; // classic jsonp query... + } +}); + +$.ajaxTransport("oe-jsonp", function(options, originalOptions, jqXHR) { + + var $iframe = null; + var $form = $('
') + .attr('method', 'POST') + .attr('enctype', "multipart/form-data") + .attr('action', options.openerp.server + "/web/jsonp/post") + .hide() + .appendTo($('body')) + ; + + function cleanUp() { + if ($iframe) { + $iframe.unbind("load").attr("src", "javascript:false;").remove(); + } + $form.remove(); + } + + return { + + send: function(headers, completeCallback) { + + var ifid = _.uniqueId('oe_jsonp_iframe_'); + var request_id = _.uniqueId('browser-client-'); + var oe_callback = _.uniqueId('oe_callback_'); + + window[oe_callback] = function(result) { + completeCallback(200, 'success', {json: result}); + }; + + + var display = options.openerp.debug ? 'block' : 'none'; + $iframe = $(_.str.sprintf("", ifid, ifid, display)); + + + // the first bind is fired up when the iframe is added to the DOM + $iframe.bind('load', function() { + // the second bind is fired up when the result of the form submission is received + $iframe.unbind('load').bind('load', function() { + // we cannot access the content of remote iframe. + // but we don't care, we try to get the result in any cases + + $.ajax({ + type: "GET", + url: options.url, + dataType: 'jsonp', + jsonp: false, // do not append callback=? argument on query string + jsonpCallback: oe_callback, + data: { + sid: options.openerp.session_id, + rid: request_id, + }, + }).always(function() { + cleanUp(); + }); + + }); + + + // now that the iframe can receive data, we fill and submit the form + var params = JSON.stringify(options.data); + + $form + .append($('').attr('value', options.openerp.session_id)) + .append($('').attr('value', request_id)) + .append($('').attr('value', params)) + .append($('').attr('value', oe_callback)) + .submit() + ; + + }); + + $form.attr('target', ifid) // set the iframe as target of the form + .after($iframe); // append the iframe to the DOM (will trigger the first load) + + }, + abort: function() { + cleanUp(); + }, + }; + +}); + openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.web.Connection# */{ /** * @constructs openerp.web.Connection @@ -351,10 +528,6 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. * @param {String} [port] JSON-RPC endpoint port */ init: function() { - - // FIXME need to be a real singleton. - // create more than one Connection on the same instance will not works - this._super(); this.server = null; this.debug = ($.deparam($.param.querystring()).debug != undefined); From 4206e4d2627be8ca252fdfce2f90654ff9db0055 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Thu, 15 Dec 2011 19:32:59 +0100 Subject: [PATCH 54/59] connection jsonp wip bzr revid: al@openerp.com-20111215183259-vam7tsjlkqhjam69 --- addons/web/static/src/js/chrome.js | 3 +- addons/web/static/src/js/core.js | 356 +++++++--------------- addons/web/static/src/js/formats.js | 2 +- addons/web/static/src/js/jq_ajax.js | 184 ----------- addons/web_kanban/static/src/js/kanban.js | 4 +- 5 files changed, 109 insertions(+), 440 deletions(-) delete mode 100644 addons/web/static/src/js/jq_ajax.js diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index b03c5965bf7..eb9328a6bd1 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -1013,7 +1013,7 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie start: function() { this._super.apply(this, arguments); var self = this; - openerp.connection.bind(function() { + openerp.connection.bind("",function() { var params = {}; if(jQuery.param != undefined && jQuery.deparam(jQuery.param.querystring()).kitten != undefined) { self.$element.addClass("kitten-mode-activated"); @@ -1103,7 +1103,6 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie }, }); - openerp.currentScript = function() { 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 96e38b4e4d0..55bce373330 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -342,183 +342,6 @@ openerp.web.CallbackEnabled = openerp.web.Class.extend(/** @lends openerp.web.Ca } }); -$.ajaxSetup({ - converters: { - "json oe-jsonp": true, - "json oe-json": true, - } -}); - -// common preconditions checks -$.ajaxPrefilter("oe-json oe-jsonp", function(options, originalOptions, jqXHR) { - if (!$.isPlainObject(options.openerp)) { - console.error(options.openerp); - $.error('"openerp" option is required.'); - } - - if (!$.isPlainObject(options.data)) { - $.error('data must not be serialized'); - } - options.processData = false; -}); - -$.ajaxPrefilter("oe-json", function(options, originalOptions, jqXHR) { - options.data = JSON.stringify({ - jsonrpc: '2.0', - method: 'call', - params: options.data, - id: _.uniqueId('browser-client-') - }); - - return 'json'; -}); - -$.ajaxPrefilter("oe-jsonp", function(options, originalOptions, jqXHR) { - - options.crossDomain = true; - - var data = null; - if (options.data) { - data = $.param({r:JSON.stringify(options.data)}); - } - - - - var max_url_length = options.max_url_length || 1000, - absolute_url, full_url; - /* - var r_has_protocol = /^https?:\/\//, - r_absolute_internal = /^\/[^\/]/; // starts with / (but not //) - - - if (r_has_protocol.test(options.url)) { - if (!_(options.url).startsWith(options.openerp.server + '/')) { - $.error('can only contact openerp.server'); - } - absolute_url = options.url; - } else if (r_absolute_internal.test(options.url)) { - absolute_url = options.openerp.server + options.url; - } else { // relative url - var parts = document.location.pathname.split('/'); - parts.pop(); - parts.push(options.url); - absolute_url = options.openerp.server + parts.join('/'); - } - // */ - - var absolute_url = options.openerp.get_absolute_url(options.url); - - /// now, made the same url changes that jQuery will do... - var rquery = /\?/, - rts = /([?&])_=[^&]*/; - - full_url = absolute_url; - if (data) { - full_url += (rquery.test(full_url) ? "&" : "?") + data; - } - - // Add anti-cache in url if needed - if (!options.cache) { - var ts = $.now(), - // try replacing _= if it is there - ret = full_url.replace(rts, "$1_=" + ts); - - // if nothing was replaced, add timestamp to the end - full_url = ret + ((ret === full_url) ? (rquery.test(full_url) ? "&" : "?") + "_=" + ts : ""); - } - - options.url = absolute_url; - - if (full_url.length < max_url_length) { - options.type = "GET"; - options.data = data; - return "jsonp"; // classic jsonp query... - } -}); - -$.ajaxTransport("oe-jsonp", function(options, originalOptions, jqXHR) { - - var $iframe = null; - var $form = $('') - .attr('method', 'POST') - .attr('enctype', "multipart/form-data") - .attr('action', options.openerp.server + "/web/jsonp/post") - .hide() - .appendTo($('body')) - ; - - function cleanUp() { - if ($iframe) { - $iframe.unbind("load").attr("src", "javascript:false;").remove(); - } - $form.remove(); - } - - return { - - send: function(headers, completeCallback) { - - var ifid = _.uniqueId('oe_jsonp_iframe_'); - var request_id = _.uniqueId('browser-client-'); - var oe_callback = _.uniqueId('oe_callback_'); - - window[oe_callback] = function(result) { - completeCallback(200, 'success', {json: result}); - }; - - - var display = options.openerp.debug ? 'block' : 'none'; - $iframe = $(_.str.sprintf("", ifid, ifid, display)); - - - // the first bind is fired up when the iframe is added to the DOM - $iframe.bind('load', function() { - // the second bind is fired up when the result of the form submission is received - $iframe.unbind('load').bind('load', function() { - // we cannot access the content of remote iframe. - // but we don't care, we try to get the result in any cases - - $.ajax({ - type: "GET", - url: options.url, - dataType: 'jsonp', - jsonp: false, // do not append callback=? argument on query string - jsonpCallback: oe_callback, - data: { - sid: options.openerp.session_id, - rid: request_id, - }, - }).always(function() { - cleanUp(); - }); - - }); - - - // now that the iframe can receive data, we fill and submit the form - var params = JSON.stringify(options.data); - - $form - .append($('').attr('value', options.openerp.session_id)) - .append($('').attr('value', request_id)) - .append($('').attr('value', params)) - .append($('').attr('value', oe_callback)) - .submit() - ; - - }); - - $form.attr('target', ifid) // set the iframe as target of the form - .after($iframe); // append the iframe to the DOM (will trigger the first load) - - }, - abort: function() { - cleanUp(); - }, - }; - -}); - openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.web.Connection# */{ /** * @constructs openerp.web.Connection @@ -529,26 +352,17 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. */ init: function() { this._super(); - this.server = null; - this.debug = ($.deparam($.param.querystring()).debug != undefined); // TODO: session should have an optional name indicating that they'll // be saved to (and revived from) cookies this.name = openerp._session_id; }, - bind: function(server, continuation) { - - if(_.isFunction(server)) { - continuation = server; - server = null; - } - - if (this.server) { - throw new Error("Connection already bound to " + this.server); - } - var hostname = _.str.sprintf('%s//%s', location.protocol, location.host); - this.server = _.str.rtrim((!server) ? hostname : server, '/'); - openerp.web.qweb.default_dict['_s'] = this.server - this.rpc_mode = (this.server == hostname) ? "oe-json" : "oe-jsonp"; + bind: function(host, protocol) { + this.host = (host == undefined) ? location.host : host; + this.protocol = (protocol == undefined) ? location.protocol : protocol; + this.prefix = this.protocol + '//' + this.host; + openerp.web.qweb.default_dict['_s'] = this.prefix + this.rpc_mode = (host == location.host) ? "json" : "jsonp"; + this.debug = (window.location.search.indexOf('?debug') !== -1); this.session_id = false; this.uid = false; this.username = false; @@ -562,12 +376,6 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. this.active_id = null; this.do_load_qweb(['/web/webclient/qweb'], continuation); }, - connect: function(server, db, login, password, continuation) { - var self = this; - this.bind(server, function() { - self.login(db, login, password, continuation); - }); - }, /** * Executes an RPC call, registering the provided callbacks. * @@ -583,79 +391,130 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. */ rpc: function(url, params, success_callback, error_callback) { var self = this; + // url can be an $.ajax option object + if (_.isString(url)) { + url = { url: url }; + } // Construct a JSON-RPC2 request, method is currently unused params.session_id = this.session_id; if (this.debug) params.debug = 1; - + var payload = { + jsonrpc: '2.0', + method: 'call', + params: params, + id: _.uniqueId('oe-') + }; // Call using the rpc_mode var deferred = $.Deferred(); - this.rpc_ajax(url, params) - .then(function () {deferred.resolve.apply(deferred, arguments);}, - function(error) {deferred.reject(error, $.Event());}); - return deferred.fail(function() { + this.on_rpc_request(); + this.rpc_json(url, payload).then( + function (response, textStatus, jqXHR) { + self.on_rpc_response(); + if (!response.error) { + deferred.resolve(response["result"], textStatus, jqXHR); + } else if (response.error.data.type === "session_invalid") { + self.uid = false; + self.on_session_invalid(function() { + self.rpc(url, payload.params, + function() { deferred.resolve.apply(deferred, arguments); }, + function() { deferred.reject.apply(deferred, arguments); }); + }); + } else { + deferred.reject(response.error, $.Event()); + } + }, + function(jqXHR, textStatus, errorThrown) { + self.on_rpc_response(); + var error = { + code: -32098, + message: "XmlHttpRequestError " + errorThrown, + data: {type: "xhr"+textStatus, debug: jqXHR.responseText, objects: [jqXHR, errorThrown] } + }; + deferred.reject(error, $.Event()); + }); + // Allow deferred user to disable on_rpc_error in fail + deferred.fail(function() { deferred.fail(function(error, event) { if (!event.isDefaultPrevented()) { self.on_rpc_error(error, event); } }); }).then(success_callback, error_callback).promise(); + return deferred; }, /** * Raw JSON-RPC call * * @returns {jQuery.Deferred} ajax-webd deferred object */ - rpc_ajax: function(url, payload) { + rpc_json: function(url, payload) { var self = this; - this.on_rpc_request(); - // url can be an $.ajax option object - if (_.isString(url)) { - url = { - url: url - } - } var ajax = _.extend({ type: "POST", - url: url, - dataType: this.rpc_mode, + dataType: 'json', contentType: 'application/json', - data: payload, + data: JSON.stringify(payload), processData: false, - openerp: _.extend({}, this), // need a plainObject }, url); - var deferred = $.Deferred(); - $.ajax(ajax).done(function(response, textStatus, jqXHR) { - self.on_rpc_response(); - if (!response.error) { - deferred.resolve(response["result"], textStatus, jqXHR); - return; + return $.ajax(ajax); + }, + rpc_jsonp: function(url, payload) { + var self = this; + var ajax = _.extend({ + type: "GET", + dataType: 'jsonp', + jsonp: 'jsonp', + cache: false, + data: { + session_id: this.session_id, + id: payload.id, } - if (response.error.data.type !== "session_invalid") { - deferred.reject(response.error); - return; - } - self.uid = false; - self.on_session_invalid(function() { // retry - self.rpc(url, payload, - function() { - deferred.resolve.apply(deferred, arguments); - }, - function(error, event) { - event.preventDefault(); - deferred.reject.apply(deferred, arguments); - }); - }); - }).fail(function(jqXHR, textStatus, errorThrown) { - self.on_rpc_response(); - var error = { - code: -32098, - message: "XmlHttpRequestError " + errorThrown, - data: {type: "xhr"+textStatus, debug: jqXHR.responseText, objects: [jqXHR, errorThrown] } + }, url); + var payload_str = JSON.stringify(payload); + var payload_url = $.param({r:payload_str}); + if(playload_url.length < 2000) { + // Direct json request + ajax.data.r = payload_str; + return $.ajax(ajax); + } else { + // Indirect json request + var ifid = _.uniqueId('oe_rpc_iframe_'); + var display = options.openerp.debug ? 'block' : 'none'; + var $iframe = $(_.str.sprintf("", ifid, ifid, display)); + var $form = $('') + .attr('method', 'POST') + .attr('target', ifid) + .attr('enctype', "multipart/form-data") + .attr('action', ajax.url) + .append($('').attr('value', payload_str)) + .hide() + .appendTo($('body')); + var cleanUp = function() { + if ($iframe) { + $iframe.unbind("load").attr("src", "javascript:false;").remove(); + } + $form.remove(); }; - deferred.reject(error); - }); - return deferred.promise(); + var deferred = $.Deferred(); + // the first bind is fired up when the iframe is added to the DOM + $iframe.bind('load', function() { + // the second bind is fired up when the result of the form submission is received + $iframe.unbind('load').bind('load', function() { + $.ajax(ajax).always(function() { + cleanUp(); + }).then( + function() { deferred.resolve.apply(deferred, arguments); }, + function() { deferred.reject.apply(deferred, arguments); } + ); + }); + // now that the iframe can receive data, we fill and submit the form + $form.submit(); + }); + // append the iframe to the DOM (will trigger the first load) + $form.after($iframe); + return deffered; + } }, on_rpc_request: function() { }, @@ -687,15 +546,10 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. username: result.login }); self.session_save(); - self.on_session_valid(success_callback); return true; - //}).done(success_callback); }); }, - login: function() { - this.session_authenticate.apply(this, arguments); - }, /** * Reloads uid and session_id from local storage, if they exist */ diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js index 13cceaeba8d..264cc836e2d 100644 --- a/addons/web/static/src/js/formats.js +++ b/addons/web/static/src/js/formats.js @@ -254,7 +254,7 @@ openerp.web.format_cell = function (row_data, column, value_if_empty, process_mo if (column.tag === 'button') { return [ '' ].join('') diff --git a/addons/web/static/src/js/jq_ajax.js b/addons/web/static/src/js/jq_ajax.js deleted file mode 100644 index 611ab1e1e22..00000000000 --- a/addons/web/static/src/js/jq_ajax.js +++ /dev/null @@ -1,184 +0,0 @@ - - $.ajaxSetup({ - converters: { - "json oe-jsonp": true, - "json oe-json": true, - } - }); - - - // common preconditions checks - $.ajaxPrefilter("oe-json oe-jsonp", function(options, originalOptions, jqXHR) { - if (!$.isPlainObject(options.openerp)) { - console.error(options.openerp); - $.error('"openerp" option is required.'); - } - - if (!$.isPlainObject(options.data)) { - $.error('data must not be serialized'); - } - options.processData = false; - }); - - - - $.ajaxPrefilter("oe-json", function(options, originalOptions, jqXHR) { - options.data = JSON.stringify({ - jsonrpc: '2.0', - method: 'call', - params: options.data, - id: _.uniqueId('browser-client-') - }); - - return 'json'; - }); - - - $.ajaxPrefilter("oe-jsonp", function(options, originalOptions, jqXHR) { - - options.crossDomain = true; - - var data = null; - if (options.data) { - data = $.param({r:JSON.stringify(options.data)}); - } - - - - var max_url_length = options.max_url_length || 1000, - absolute_url, full_url; - /* - var r_has_protocol = /^https?:\/\//, - r_absolute_internal = /^\/[^\/]/; // starts with / (but not //) - - - if (r_has_protocol.test(options.url)) { - if (!_(options.url).startsWith(options.openerp.server + '/')) { - $.error('can only contact openerp.server'); - } - absolute_url = options.url; - } else if (r_absolute_internal.test(options.url)) { - absolute_url = options.openerp.server + options.url; - } else { // relative url - var parts = document.location.pathname.split('/'); - parts.pop(); - parts.push(options.url); - absolute_url = options.openerp.server + parts.join('/'); - } - // */ - - var absolute_url = options.openerp.get_absolute_url(options.url); - - /// now, made the same url changes that jQuery will do... - var rquery = /\?/, - rts = /([?&])_=[^&]*/; - - full_url = absolute_url; - if (data) { - full_url += (rquery.test(full_url) ? "&" : "?") + data; - } - - // Add anti-cache in url if needed - if (!options.cache) { - var ts = $.now(), - // try replacing _= if it is there - ret = full_url.replace(rts, "$1_=" + ts); - - // if nothing was replaced, add timestamp to the end - full_url = ret + ((ret === full_url) ? (rquery.test(full_url) ? "&" : "?") + "_=" + ts : ""); - } - - options.url = absolute_url; - - if (full_url.length < max_url_length) { - options.type = "GET"; - options.data = data; - return "jsonp"; // classic jsonp query... - } - }); - - - $.ajaxTransport("oe-jsonp", function(options, originalOptions, jqXHR) { - - var $iframe = null; - var $form = $('') - .attr('method', 'POST') - .attr('enctype', "multipart/form-data") - .attr('action', options.openerp.server + "/web/jsonp/post") - .hide() - .appendTo($('body')) - ; - - function cleanUp() { - if ($iframe) { - $iframe.unbind("load").attr("src", "javascript:false;").remove(); - } - $form.remove(); - } - - return { - - send: function(headers, completeCallback) { - - var ifid = _.uniqueId('oe_jsonp_iframe_'); - var request_id = _.uniqueId('browser-client-'); - var oe_callback = _.uniqueId('oe_callback_'); - - window[oe_callback] = function(result) { - completeCallback(200, 'success', {json: result}); - }; - - - var display = options.openerp.debug ? 'block' : 'none'; - $iframe = $(_.str.sprintf("", ifid, ifid, display)); - - - // the first bind is fired up when the iframe is added to the DOM - $iframe.bind('load', function() { - // the second bind is fired up when the result of the form submission is received - $iframe.unbind('load').bind('load', function() { - // we cannot access the content of remote iframe. - // but we don't care, we try to get the result in any cases - - $.ajax({ - type: "GET", - url: options.url, - dataType: 'jsonp', - jsonp: false, // do not append callback=? argument on query string - jsonpCallback: oe_callback, - data: { - sid: options.openerp.session_id, - rid: request_id, - }, - }).always(function() { - cleanUp(); - }); - - }); - - - // now that the iframe can receive data, we fill and submit the form - var params = JSON.stringify(options.data); - - $form - .append($('').attr('value', options.openerp.session_id)) - .append($('').attr('value', request_id)) - .append($('').attr('value', params)) - .append($('').attr('value', oe_callback)) - .submit() - ; - - }); - - $form.attr('target', ifid) // set the iframe as target of the form - .after($iframe); // append the iframe to the DOM (will trigger the first load) - - }, - abort: function() { - cleanUp(); - }, - }; - - }); - - diff --git a/addons/web_kanban/static/src/js/kanban.js b/addons/web_kanban/static/src/js/kanban.js index 9f86d4d3383..053e1cdfd00 100644 --- a/addons/web_kanban/static/src/js/kanban.js +++ b/addons/web_kanban/static/src/js/kanban.js @@ -106,7 +106,7 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({ node.children = [{ tag: 'img', attrs: { - src: openerp.connection.server + '/web/static/src/img/icons/' + node.attrs['data-icon'] + '.png', + src: openerp.connection.prefix + '/web/static/src/img/icons/' + node.attrs['data-icon'] + '.png', width: '16', height: '16' } @@ -524,7 +524,7 @@ openerp.web_kanban.KanbanRecord = openerp.web.Widget.extend({ }, kanban_image: function(model, field, id) { id = id || ''; - return openerp.connection.server + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + id; + return openerp.connection.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + id; }, kanban_text_ellipsis: function(s, size) { size = size || 160; From 8721df9d549e72b7154ae34dff53aa4b82718b85 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Fri, 16 Dec 2011 01:44:02 +0100 Subject: [PATCH 55/59] [IMP] massive connection deferrization, json works again bzr revid: al@openerp.com-20111216004402-q6v26822swarra7r --- addons/web/common/http.py | 15 ++-- addons/web/controllers/main.py | 5 +- addons/web/static/src/js/chrome.js | 44 ++++------ addons/web/static/src/js/core.js | 128 +++++++++++++---------------- 4 files changed, 84 insertions(+), 108 deletions(-) diff --git a/addons/web/common/http.py b/addons/web/common/http.py index 620e3a548dc..4bdd87a6764 100644 --- a/addons/web/common/http.py +++ b/addons/web/common/http.py @@ -6,12 +6,12 @@ import ast import contextlib import functools import logging -import urllib import os import pprint import sys import threading import traceback +import urllib import uuid import xmlrpclib @@ -137,20 +137,19 @@ class JsonRequest(WebRequest): :returns: an utf8 encoded JSON-RPC2 or JSONP reply """ - method = self.httprequest.method args = self.httprequest.args jsonp = args.get('jsonp', False) requestf = None request = None - if jsonp and method == 'POST': + if jsonp and self.httprequest.method == 'POST': # jsonp 2 steps step1 POST: save call self.init(args) req.session.jsonp_requests[args.get('id')] = self.httprequest.form['r'] headers=[('Content-Type', 'text/plain; charset=utf-8')] r = werkzeug.wrappers.Response(request_id, headers=headers) return r - elif args['jsonp'] and args.get('id'): + elif jsonp and args.get('id'): # jsonp 2 steps step2 GET: run and return result self.init(args) request = self.session.jsonp_requests.pop(args.get(id), "") @@ -195,6 +194,8 @@ class JsonRequest(WebRequest): } } except Exception: + logging.getLogger(__name__ + '.JSONRequest.dispatch').exception\ + ("An error occured while handling a json request") error = { 'code': 300, 'message': "OpenERP WebClient Error", @@ -205,9 +206,9 @@ class JsonRequest(WebRequest): } if error: response["error"] = error - _logger.error("[%s] <--\n%s", rid, pprint.pformat(response)) - elif _logger.isEnabledFor(logging.DEBUG): - _logger.debug("[%s] <--\n%s", rid, pprint.pformat(response)) + + if _logger.isEnabledFor(logging.DEBUG): + _logger.debug("<--\n%s", pprint.pformat(response)) if jsonp: mime = 'application/javascript' diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index e745020c594..9c6edcf378a 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -10,6 +10,7 @@ import os import re import simplejson import time +import urllib2 import xmlrpclib import zlib from xml.etree import ElementTree @@ -245,7 +246,7 @@ class WebClient(openerpweb.Controller): class Proxy(openerpweb.Controller): _cp_path = '/web/proxy' - @jsonrequest + @openerpweb.jsonrequest def load(self, req, path): #req.config.socket_port #if not re.match('^/[^/]+/static/.*', path): @@ -254,7 +255,7 @@ class Proxy(openerpweb.Controller): env = req.httprequest.environ port = env['SERVER_PORT'] - o = urllib.urlopen('http://127.0.0.1:%s%s' % (port, path)) + o = urllib2.urlopen('http://127.0.0.1:%s%s' % (port, path)) return o.read() class Database(openerpweb.Controller): diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 70beb7ecc34..cbf475af44e 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -1004,20 +1004,12 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie this.header.on_logout.add(this.login.on_logout); this.header.on_action.add(this.on_menu_action); - this.session.on_session_invalid.add(this.login.do_ask_login); - this.session.on_session_valid.add_last(this.header.do_update); - this.session.on_session_invalid.add_last(this.header.do_update); - this.session.on_session_valid.add_last(this.on_logged); - this.session.on_session_invalid.add_last(this.on_logged_out); - - this._current_state = null; - }, start: function() { this._super.apply(this, arguments); var self = this; - openerp.connection.bind("",function() { + this.session.bind().then(function() { var params = {}; if (jQuery.param != undefined && jQuery.deparam(jQuery.param.querystring()).kitten != undefined) { this.$element.addClass("kitten-mode-activated"); @@ -1026,17 +1018,25 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie }); } self.$element.html(QWeb.render("Interface", params)); - openerp.connection.session_restore(); - self.menu = new openerp.web.Menu(self, "oe_menu", "oe_secondary_menu"); self.menu.on_action.add(self.on_menu_action); - self.notification.prependTo(self.$element); self.loading.appendTo($('#oe_loading')); self.header.appendTo($("#oe_header")); self.login.appendTo($('#oe_login')); self.menu.start(); + self.login.on_login_invalid(); + }); + this.session.ready.then(function() { + self.login.on_login_valid(); + self.header.do_update(); + self.menu.do_reload(); + if(self.action_manager) + self.action_manager.stop(); + self.action_manager = new openerp.web.ActionManager(this); + self.action_manager.appendTo($("#oe_app")); + self.bind_hashchange(); }); }, do_reload: function() { @@ -1050,24 +1050,8 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie var n = this.notification; n.warn.apply(n, arguments); }, - on_logged: function() { - this.menu.do_reload(); - if(this.action_manager) - this.action_manager.stop(); - this.action_manager = new openerp.web.ActionManager(this); - this.action_manager.appendTo($("#oe_app")); - - if (openerp._modules_loaded) { // TODO: find better option than this - this.bind_hashchange(); - } else { - this.session.on_modules_loaded.add({ // XXX what about a $.Deferred ? - callback: $.proxy(this, 'bind_hashchange'), - unique: true, - position: 'last' - }) - } - }, - on_logged_out: function() { + on_loggued_out: function() { + this.header.do_update(); $(window).unbind('hashchange', this.on_hashchange); this.do_push_state({}); if(this.action_manager) diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 55bce373330..f28d0adfc03 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -352,11 +352,11 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. */ init: function() { this._super(); - // TODO: session should have an optional name indicating that they'll - // be saved to (and revived from) cookies + // TODO: session store in cookie should be optional this.name = openerp._session_id; }, bind: function(host, protocol) { + var self = this; this.host = (host == undefined) ? location.host : host; this.protocol = (protocol == undefined) ? location.protocol : protocol; this.prefix = this.protocol + '//' + this.host; @@ -368,13 +368,13 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. this.username = false; this.user_context= {}; this.db = false; - this.module_loading = $.Deferred(); this.module_list = []; this.module_loaded = {"web": true}; this.context = {}; this.shortcuts = []; this.active_id = null; - this.do_load_qweb(['/web/webclient/qweb'], continuation); + this.ready = $.Deferred(); + return this.session_restore(); }, /** * Executes an RPC call, registering the provided callbacks. @@ -522,74 +522,52 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. }, on_rpc_error: function(error) { }, + /** + * Init a session, reloads from cookie, if it exists + */ + session_restore: function () { + var self = this; + // TODO: session store in cookie should be optional + this.session_id = this.get_cookie('session_id'); + return this.rpc("/web/session/get_session_info", {}).pipe(function(result) { + // If immediately follows a login (triggered by trying to restore + // an invalid session or no session at all), refresh session data + // (should not change, but just in case...) + _.extend(self, { + db: result.db, + username: result.login, + uid: result.uid, + user_context: result.context + }); + var deferred = self.do_load_qweb(['/web/webclient/qweb']); + if(self.uid) { + return deferred.then(self.load_modules()); + } + return deferred; + }); + }, /** * The session is validated either by login or by restoration of a previous session */ - on_session_valid: function(continuation) { - this.load_modules().then(function() { continuation() } ); - }, - on_session_invalid: function(continuation) { - }, - session_is_valid: function() { - return this.uid; - }, - session_authenticate: function(db, login, password, success_callback) { + session_authenticate: function(db, login, password) { var self = this; var base_location = document.location.protocol + '//' + document.location.host; var params = { db: db, login: login, password: password, base_location: base_location }; - return this.rpc("/web/session/authenticate", params, function(result) { + return this.rpc("/web/session/authenticate", params).pipe(function(result) { _.extend(self, { session_id: result.session_id, - uid: result.uid, - user_context: result.context, db: result.db, - username: result.login + username: result.login, + uid: result.uid, + user_context: result.context }); - self.session_save(); - self.on_session_valid(success_callback); - return true; + // TODO: session store in cookie should be optional + self.set_cookie('session_id', this.session_id); + return self.load_modules(); }); }, - /** - * Reloads uid and session_id from local storage, if they exist - */ - session_restore: function (continuation) { - var self = this; - this.session_id = this.get_cookie('session_id'); - return this.rpc("/web/session/get_session_info", {}).then(function(result) { - // If immediately follows a login (triggered by trying to restore - // an invalid session or no session at all), refresh session data - // (should not change, but just in case...) but should not call - // on_session_valid again as it triggers reloading the menu - var already_logged = self.uid; - _.extend(self, { - uid: result.uid, - user_context: result.context, - db: result.db, - username: result.login - }); - if (!already_logged) { - if (self.uid) { - self.on_session_valid(continuation); - } else { - self.on_session_invalid(continuation); - } - } - }, function() { - self.on_session_invalid(continuation); - }); - }, - /** - * Saves the session id and uid locally - */ - session_save: function () { - this.set_cookie('session_id', this.session_id); - }, - logout: function() { + session_logout: function() { this.set_cookie('session_id', ''); - this.reload_client(); - }, - reload_client: function() { window.location.reload(); }, /** @@ -640,19 +618,21 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. self.module_list = result; var lang = self.user_context.lang; var params = { mods: ["web"].concat(result), lang: lang}; - self.rpc('/web/webclient/translations',params).then(function(transs) { + self.rpc('/web/webclient/translations',params).pipe(function(transs) { openerp.web._t.database.set_bundle(transs); var modules = self.module_list.join(','); var file_list = ["/web/static/lib/datejs/globalization/" + self.user_context.lang.replace("_", "-") + ".js" ]; return $.when( - self.rpc('/web/webclient/qweblist', {mods: modules}, self.do_load_qweb), self.rpc('/web/webclient/csslist', {mods: modules}, self.do_load_css), - self.rpc('/web/webclient/jslist', {mods: modules}, function(files) { + self.rpc('/web/webclient/qweblist', {mods: modules}).pipe(self.do_load_qweb), + self.rpc('/web/webclient/jslist', {mods: modules}).pipe(function(files) { self.do_load_js(file_list.concat(files)); }) - ); + ).then(function() { + self.ready.resolve(); + }); }); }); }, @@ -660,7 +640,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. var self = this; _.each(files, function (file) { $('head').append($('', { - 'href': self.get_absolute_url(file), + 'href': self.get_url(file), 'rel': 'stylesheet', 'type': 'text/css' })); @@ -668,32 +648,39 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. }, do_load_js: function(files) { var self = this; + var d = $.Deferred(); if(files.length != 0) { var file = files.shift(); var tag = document.createElement('script'); tag.type = 'text/javascript'; - tag.src = self.get_absolute_url(file); + tag.src = self.get_url(file); tag.onload = tag.onreadystatechange = function() { if ( (tag.readyState && tag.readyState != "loaded" && tag.readyState != "complete") || tag.onload_done ) return; tag.onload_done = true; - self.do_load_js(files, callback); + self.do_load_js(files).then(function () { + d.resolve(); + }); }; var head = document.head || document.getElementsByTagName('head')[0]; head.appendChild(tag); } else { self.on_modules_loaded(); + d.resolve(); } + return d; }, do_load_qweb: function(files) { var self = this; if (files.length != 0) { var file = files.shift(); - self.rpc('/web/proxy/load', {path: file}, function(xml) { + return self.rpc('/web/proxy/load', {path: file}).pipe(function(xml) { openerp.web.qweb.add_template(_.str.trim(xml)); - self.do_load_qweb(files, callback); + return self.do_load_qweb(files); }); - } + } else { + return $.when(); + } }, on_modules_loaded: function() { for(var j=0; j Date: Fri, 16 Dec 2011 01:48:23 +0100 Subject: [PATCH 56/59] [IMP] minor changes bzr revid: al@openerp.com-20111216004823-s3lh80nymv2xu6fs --- addons/web/static/src/js/chrome.js | 2 +- addons/web/static/src/js/core.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index cbf475af44e..90c51571d3d 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -1040,7 +1040,7 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie }); }, do_reload: function() { - return $.when(this.session.session_restore(),this.menu.do_reload()); + return $.when(this.session.session_init(),this.menu.do_reload()); }, do_notify: function() { var n = this.notification; diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index f28d0adfc03..695a833da81 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -374,7 +374,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. this.shortcuts = []; this.active_id = null; this.ready = $.Deferred(); - return this.session_restore(); + return this.session_init(); }, /** * Executes an RPC call, registering the provided callbacks. @@ -415,6 +415,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. deferred.resolve(response["result"], textStatus, jqXHR); } else if (response.error.data.type === "session_invalid") { self.uid = false; + // TODO deprecate or use a deferred on login.do_ask_login() self.on_session_invalid(function() { self.rpc(url, payload.params, function() { deferred.resolve.apply(deferred, arguments); }, @@ -525,7 +526,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. /** * Init a session, reloads from cookie, if it exists */ - session_restore: function () { + session_init: function () { var self = this; // TODO: session store in cookie should be optional this.session_id = this.get_cookie('session_id'); From d315489256557498de4e3c641a7cc28e6550d575 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Fri, 16 Dec 2011 02:25:42 +0100 Subject: [PATCH 57/59] [FIX] session cookie and logout bzr revid: al@openerp.com-20111216012542-svbiuf64x017wll5 --- addons/web/controllers/main.py | 1 - addons/web/static/src/js/chrome.js | 9 ++++----- addons/web/static/src/js/core.js | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 9c6edcf378a..fc9ae1dec16 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -375,7 +375,6 @@ class Session(openerpweb.Controller): @openerpweb.jsonrequest def get_session_info(self, req): - req.session.assert_valid(force=True) return { "uid": req.session._uid, "context": req.session.get_context() if req.session._uid else False, diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 90c51571d3d..50fb8018918 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -629,9 +629,6 @@ openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{ callback: continuation || function() {} }); }, - on_logout: function() { - this.session.logout(); - } }); openerp.web.Header = openerp.web.Widget.extend(/** @lends openerp.web.Header# */{ @@ -1001,7 +998,7 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie this.header = new openerp.web.Header(this); this.login = new openerp.web.Login(this); - this.header.on_logout.add(this.login.on_logout); + this.header.on_logout.add(this.on_logout); this.header.on_action.add(this.on_menu_action); this._current_state = null; @@ -1050,7 +1047,9 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie var n = this.notification; n.warn.apply(n, arguments); }, - on_loggued_out: function() { + on_logout: function() { + this.session.session_logout(); + this.login.on_login_invalid(); this.header.do_update(); $(window).unbind('hashchange', this.on_hashchange); this.do_push_state({}); diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 695a833da81..a46f7d5cac8 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -563,7 +563,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. user_context: result.context }); // TODO: session store in cookie should be optional - self.set_cookie('session_id', this.session_id); + self.set_cookie('session_id', self.session_id); return self.load_modules(); }); }, From 770a738b9b0e773506c38af0a14e91476ae14e1b Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Fri, 16 Dec 2011 02:30:51 +0100 Subject: [PATCH 58/59] [FIX] more deferred bzr revid: al@openerp.com-20111216013051-x45j314u7d4zvfoq --- addons/web/static/src/js/core.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index a46f7d5cac8..7efd673f124 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -629,7 +629,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. self.rpc('/web/webclient/csslist', {mods: modules}, self.do_load_css), self.rpc('/web/webclient/qweblist', {mods: modules}).pipe(self.do_load_qweb), self.rpc('/web/webclient/jslist', {mods: modules}).pipe(function(files) { - self.do_load_js(file_list.concat(files)); + return self.do_load_js(file_list.concat(files)); }) ).then(function() { self.ready.resolve(); From 28715cfaab85970c3bbabf49bc12a5dfa2efc200 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Fri, 16 Dec 2011 02:49:45 +0100 Subject: [PATCH 59/59] [FIX] jsonp fixes currently untested bzr revid: al@openerp.com-20111216014945-mhq4eee2hy9mip27 --- addons/web/static/src/js/core.js | 35 +++++++++++++++++--------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 7efd673f124..3d66c4f4ccf 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -361,7 +361,8 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. this.protocol = (protocol == undefined) ? location.protocol : protocol; this.prefix = this.protocol + '//' + this.host; openerp.web.qweb.default_dict['_s'] = this.prefix - this.rpc_mode = (host == location.host) ? "json" : "jsonp"; + this.rpc_mode = (this.host == location.host) ? "json" : "jsonp"; + this.rpc_function = (this.host == location.host) ? this.rpc_json : this.rpc_jsonp; this.debug = (window.location.search.indexOf('?debug') !== -1); this.session_id = false; this.uid = false; @@ -403,12 +404,11 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. jsonrpc: '2.0', method: 'call', params: params, - id: _.uniqueId('oe-') + id: _.uniqueId('r') }; - // Call using the rpc_mode var deferred = $.Deferred(); this.on_rpc_request(); - this.rpc_json(url, payload).then( + this.rpc_function(url, payload).then( function (response, textStatus, jqXHR) { self.on_rpc_response(); if (!response.error) { @@ -462,32 +462,35 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. }, rpc_jsonp: function(url, payload) { var self = this; + // extracted from payload to set on the url + var data = { + session_id: this.session_id, + id: payload.id, + }; + url.url = this.get_url(url.url); var ajax = _.extend({ type: "GET", dataType: 'jsonp', jsonp: 'jsonp', cache: false, - data: { - session_id: this.session_id, - id: payload.id, - } + data: data }, url); var payload_str = JSON.stringify(payload); var payload_url = $.param({r:payload_str}); if(playload_url.length < 2000) { - // Direct json request + // Direct jsonp request ajax.data.r = payload_str; return $.ajax(ajax); } else { - // Indirect json request - var ifid = _.uniqueId('oe_rpc_iframe_'); + // Indirect jsonp request + var ifid = _.uniqueId('oe_rpc_iframe'); var display = options.openerp.debug ? 'block' : 'none'; var $iframe = $(_.str.sprintf("", ifid, ifid, display)); var $form = $('') .attr('method', 'POST') .attr('target', ifid) .attr('enctype', "multipart/form-data") - .attr('action', ajax.url) + .attr('action', ajax.url + '?' + $.param(data)) .append($('').attr('value', payload_str)) .hide() .appendTo($('body')); @@ -514,7 +517,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. }); // append the iframe to the DOM (will trigger the first load) $form.after($iframe); - return deffered; + return deferred; } }, on_rpc_request: function() { @@ -696,6 +699,9 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. } } }, + get_url: function (file) { + return this.prefix + file; + }, /** * Cooperative file download implementation, for ajaxy APIs. * @@ -716,9 +722,6 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp. * @param {Function} [options.error] callback in case of request error, provided with the error body * @param {Function} [options.complete] called after both ``success`` and ``error` callbacks have executed */ - get_url: function (file) { - return this.prefix + file; - }, get_file: function (options) { // need to detect when the file is done downloading (not used // yet, but we'll need it to fix the UI e.g. with a throbber