summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorChristophe Simonis <chs@openerp.com>2012-11-06 17:41:49 +0100
committerChristophe Simonis <chs@openerp.com>2012-11-06 17:41:49 +0100
commitc09a6600a582f1e032e34215b9c3e14e576af8a0 (patch)
tree0ba9e87b51b168132a5bc553febad56a1ae4ebed /addons/web/static/src
parent595a2b3bb160351bca19c40414ede990f45376ea (diff)
parent660443885c68b1e86536bafe7e7b01400f04f1e2 (diff)
merge upstream
bzr revid: chs@openerp.com-20121106164149-hgj1250avzf12u68
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/css/base.css3
-rw-r--r--addons/web/static/src/css/base.sass2
-rw-r--r--addons/web/static/src/js/chrome.js18
-rw-r--r--addons/web/static/src/js/search.js201
-rw-r--r--addons/web/static/src/js/view_form.js4
-rw-r--r--addons/web/static/src/js/view_list.js8
-rw-r--r--addons/web/static/src/js/views.js6
7 files changed, 121 insertions, 121 deletions
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css
index b030d0712f0..c97b59ec6fe 100644
--- a/addons/web/static/src/css/base.css
+++ b/addons/web/static/src/css/base.css
@@ -2777,6 +2777,9 @@
content: "}";
color: #e0e0e0;
}
+.openerp .oe_list_content .oe_list_field_progressbar progress {
+ width: 100%;
+}
.openerp .tree_header {
background-color: #f0f0f0;
border-bottom: 1px solid #cacaca;
diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass
index 79a688cf823..18451352370 100644
--- a/addons/web/static/src/css/base.sass
+++ b/addons/web/static/src/css/base.sass
@@ -2193,6 +2193,8 @@ $sheet-padding: 16px
.oe_list_handle
@include text-to-entypo-icon("}",#E0E0E0,18px)
margin-right: 7px
+ .oe_list_field_progressbar progress
+ width: 100%
// }}}
// Tree view {{{
.tree_header
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js
index 5dd22a3212b..1b90ff3ff44 100644
--- a/addons/web/static/src/js/chrome.js
+++ b/addons/web/static/src/js/chrome.js
@@ -504,13 +504,13 @@ instance.web.Login = instance.web.Widget.extend({
template: "Login",
remember_credentials: true,
- init: function(parent, params) {
+ init: function(parent, action) {
this._super(parent);
this.has_local_storage = typeof(localStorage) != 'undefined';
this.db_list = null;
this.selected_db = null;
this.selected_login = null;
- this.params = params || {};
+ this.params = action.params || {};
if (this.params.login_successful) {
this.on('login_successful', this, this.params.login_successful);
@@ -641,9 +641,9 @@ instance.web._relocate = function(url, wait) {
* If params has an entry 'menu_id', it opens the given menu entry.
* If params has an entry 'wait', reload will wait the openerp server to be reachable before reloading
*/
-instance.web.Reload = function(parent, params) {
-
- var menu_id = (params && params.menu_id) || false;
+instance.web.Reload = function(parent, action) {
+ var params = action.params || {};
+ var menu_id = params.menu_id || false;
var l = window.location;
var sobj = $.deparam(l.search.substr(1));
@@ -656,7 +656,7 @@ instance.web.Reload = function(parent, params) {
}
var url = l.protocol + "//" + l.host + l.pathname + search + hash;
- instance.web._relocate(url, params && params.wait);
+ instance.web._relocate(url, params.wait);
};
instance.web.client_actions.add("reload", "instance.web.Reload");
@@ -664,7 +664,7 @@ instance.web.client_actions.add("reload", "instance.web.Reload");
* Client action to go back in breadcrumb history.
* If can't go back in history stack, will go back to home.
*/
-instance.web.HistoryBack = function(parent, params) {
+instance.web.HistoryBack = function(parent) {
if (!parent.history_back()) {
instance.web.Home(parent);
}
@@ -674,9 +674,9 @@ instance.web.client_actions.add("history_back", "instance.web.HistoryBack");
/**
* Client action to go back home.
*/
-instance.web.Home = function(parent, params) {
+instance.web.Home = function(parent, action) {
var url = '/' + (window.location.search || '');
- instance.web._relocate(url, params && params.wait);
+ instance.web._relocate(url, action.params && action.params.wait);
};
instance.web.client_actions.add("home", "instance.web.Home");
diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js
index 520dcd9169f..b2ded00c105 100644
--- a/addons/web/static/src/js/search.js
+++ b/addons/web/static/src/js/search.js
@@ -124,19 +124,10 @@ function assert(condition, message) {
}
my.InputView = instance.web.Widget.extend({
template: 'SearchView.InputView',
- start: function () {
- var p = this._super.apply(this, arguments);
- this.$el.on('focus', this.proxy('onFocus'));
- this.$el.on('blur', this.proxy('onBlur'));
- this.$el.on('keydown', this.proxy('onKeydown'));
- return p;
- },
- onFocus: function () {
- this.trigger('focused', this);
- },
- onBlur: function () {
- this.$el.text('');
- this.trigger('blurred', this);
+ events: {
+ focus: function () { this.trigger('focused', this); },
+ blur: function () { this.$el.text(''); this.trigger('blurred', this); },
+ keydown: 'onKeydown'
},
getSelection: function () {
// get Text node
@@ -212,6 +203,27 @@ my.InputView = instance.web.Widget.extend({
});
my.FacetView = instance.web.Widget.extend({
template: 'SearchView.FacetView',
+ events: {
+ 'focus': function () { this.trigger('focused', this); },
+ 'blur': function () { this.trigger('blurred', this); },
+ 'click': function (e) {
+ if ($(e.target).is('.oe_facet_remove')) {
+ this.model.destroy();
+ return false;
+ }
+ this.$el.focus();
+ e.stopPropagation();
+ },
+ 'keydown': function (e) {
+ var keys = $.ui.keyCode;
+ switch (e.which) {
+ case keys.BACKSPACE:
+ case keys.DELETE:
+ this.model.destroy();
+ return false;
+ }
+ }
+ },
init: function (parent, model) {
this._super(parent);
this.model = model;
@@ -223,33 +235,11 @@ my.FacetView = instance.web.Widget.extend({
},
start: function () {
var self = this;
- this.$el.on('focus', function () { self.trigger('focused', self); });
- this.$el.on('blur', function () { self.trigger('blurred', self); });
- this.$el.on('click', function (e) {
- if ($(e.target).is('.oe_facet_remove')) {
- self.model.destroy();
- return false;
- }
- self.$el.focus();
- e.stopPropagation();
- });
- this.$el.on('keydown', function (e) {
- var keys = $.ui.keyCode;
- switch (e.which) {
- case keys.BACKSPACE:
- case keys.DELETE:
- self.model.destroy();
- return false;
- }
- });
- var $e = self.$el.find('> span:last-child');
- var q = $.when(this._super());
- return q.pipe(function () {
- var values = self.model.values.map(function (value) {
+ var $e = this.$('> span:last-child');
+ return $.when(this._super()).pipe(function () {
+ return $.when.apply(null, self.model.values.map(function (value) {
return new my.FacetValueView(self, value).appendTo($e);
- });
-
- return $.when.apply(null, values);
+ }));
});
},
model_changed: function () {
@@ -274,6 +264,48 @@ my.FacetValueView = instance.web.Widget.extend({
instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.SearchView# */{
template: "SearchView",
+ events: {
+ // focus last input if view itself is clicked
+ 'click': function (e) {
+ if (e.target === this.$('.oe_searchview_facets')[0]) {
+ this.$('.oe_searchview_input:last').focus();
+ }
+ },
+ // when the completion list opens/refreshes, automatically select the
+ // first completion item so if the user just hits [RETURN] or [TAB] it
+ // automatically selects it
+ 'autocompleteopen': function () {
+ var menu = this.$el.data('autocomplete').menu;
+ menu.activate(
+ $.Event({ type: "mouseenter" }),
+ menu.element.children().first());
+ },
+ // search button
+ 'click button.oe_searchview_search': function (e) {
+ e.stopImmediatePropagation();
+ this.do_search();
+ },
+ 'click .oe_searchview_clear': function (e) {
+ e.stopImmediatePropagation();
+ this.query.reset();
+ },
+ 'click .oe_searchview_unfold_drawer': function (e) {
+ e.stopImmediatePropagation();
+ this.$el.toggleClass('oe_searchview_open_drawer');
+ },
+ 'keydown .oe_searchview_input, .oe_searchview_facet': function (e) {
+ switch(e.which) {
+ case $.ui.keyCode.LEFT:
+ this.focusPreceding(this);
+ e.preventDefault();
+ break;
+ case $.ui.keyCode.RIGHT:
+ this.focusFollowing(this);
+ e.preventDefault();
+ break;
+ }
+ }
+ },
/**
* @constructs instance.web.SearchView
* @extends instance.web.Widget
@@ -331,55 +363,11 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
});
}
- // Launch a search on clicking the oe_searchview_search button
- this.$el.on('click', 'button.oe_searchview_search', function (e) {
- e.stopImmediatePropagation();
- self.do_search();
- });
-
- this.$el.on('keydown',
- '.oe_searchview_input, .oe_searchview_facet', function (e) {
- switch(e.which) {
- case $.ui.keyCode.LEFT:
- self.focusPreceding(this);
- e.preventDefault();
- break;
- case $.ui.keyCode.RIGHT:
- self.focusFollowing(this);
- e.preventDefault();
- break;
- }
- });
-
- this.$el.on('click', '.oe_searchview_clear', function (e) {
- e.stopImmediatePropagation();
- self.query.reset();
- });
- this.$el.on('click', '.oe_searchview_unfold_drawer', function (e) {
- e.stopImmediatePropagation();
- self.$el.toggleClass('oe_searchview_open_drawer');
- });
instance.web.bus.on('click', this, function(ev) {
if ($(ev.target).parents('.oe_searchview').length === 0) {
self.$el.removeClass('oe_searchview_open_drawer');
}
});
- // Focus last input if the view itself is clicked (empty section of
- // facets element)
- this.$el.on('click', function (e) {
- if (e.target === self.$el.find('.oe_searchview_facets')[0]) {
- self.$el.find('.oe_searchview_input:last').focus();
- }
- });
- // when the completion list opens/refreshes, automatically select the
- // first completion item so if the user just hits [RETURN] or [TAB] it
- // automatically selects it
- this.$el.on('autocompleteopen', function () {
- var menu = self.$el.data('autocomplete').menu;
- menu.activate(
- $.Event({ type: "mouseenter" }),
- menu.element.children().first());
- });
return $.when(p, this.ready);
},
@@ -480,7 +468,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
* div[contenteditable].oe_searchview_input)
*/
currentInputValue: function () {
- return this.$el.find('div.oe_searchview_input:focus').text();
+ return this.$('div.oe_searchview_input:focus').text();
},
/**
* Provide auto-completion result for req.term (an array to `resp`)
@@ -510,7 +498,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
var input_index = _(this.input_subviews).indexOf(
this.subviewForRoot(
- this.$el.find('div.oe_searchview_input:focus')[0]));
+ this.$('div.oe_searchview_input:focus')[0]));
this.query.add(ui.item.facet, {at: input_index / 2});
},
childFocused: function () {
@@ -539,7 +527,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
// _2: undefined if event=change, otherwise model
var self = this;
var started = [];
- var $e = this.$el.find('div.oe_searchview_facets');
+ var $e = this.$('div.oe_searchview_facets');
_.invoke(this.input_subviews, 'destroy');
this.input_subviews = [];
@@ -664,7 +652,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
// build drawer
var drawer_started = $.when.apply(
null, _(this.select_for_drawer()).invoke(
- 'appendTo', this.$el.find('.oe_searchview_drawer')));
+ 'appendTo', this.$('.oe_searchview_drawer')));
// load defaults
var defaults_fetched = $.when.apply(null, _(this.inputs).invoke(
@@ -736,6 +724,9 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
*
* If at least one field failed its validation, triggers
* :js:func:`instance.web.SearchView.on_invalid` instead.
+ *
+ * @param [_query]
+ * @param {Object} [options]
*/
do_search: function (_query, options) {
if (options && options.preventSearch) {
@@ -961,7 +952,7 @@ instance.web.search.FilterGroup = instance.web.search.Input.extend(/** @lends in
*/
search_change: function () {
var self = this;
- var $filters = this.$el.find('> li').removeClass('oe_selected');
+ var $filters = this.$('> li').removeClass('oe_selected');
var facet = this.view.query.find(_.bind(this.match_facet, this));
if (!facet) { return; }
facet.values.each(function (v) {
@@ -1512,7 +1503,7 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
}).pipe(this.proxy('set_filters'));
},
clear_selection: function () {
- this.$el.find('li.oe_selected').removeClass('oe_selected');
+ this.$('li.oe_selected').removeClass('oe_selected');
},
append_filter: function (filter) {
var self = this;
@@ -1524,7 +1515,7 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
} else {
var id = filter.id;
$filter = this.filters[key] = $('<li></li>')
- .appendTo(this.$el.find('.oe_searchview_custom_list'))
+ .appendTo(this.$('.oe_searchview_custom_list'))
.addClass(filter.user_id ? 'oe_searchview_custom_private'
: 'oe_searchview_custom_public')
.text(filter.name);
@@ -1559,8 +1550,8 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
},
save_current: function () {
var self = this;
- var $name = this.$el.find('input:first');
- var private_filter = !this.$el.find('input:last').prop('checked');
+ var $name = this.$('input:first');
+ var private_filter = !this.$('input:last').prop('checked');
var search = this.view.build_search_data();
this.rpc('/web/session/eval_domain_and_context', {
@@ -1666,7 +1657,7 @@ instance.web.search.Advanced = instance.web.search.Input.extend({
},
append_proposition: function () {
return (new instance.web.search.ExtendedSearchProposition(this, this.fields))
- .appendTo(this.$el.find('ul'));
+ .appendTo(this.$('ul'));
},
commit_search: function () {
var self = this;
@@ -1699,6 +1690,13 @@ instance.web.search.Advanced = instance.web.search.Input.extend({
instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @lends instance.web.search.ExtendedSearchProposition# */{
template: 'SearchView.extended_search.proposition',
+ events: {
+ 'change .searchview_extended_prop_field': 'changed',
+ 'click .searchview_extended_delete_prop': function (e) {
+ e.stopPropagation();
+ this.destroy();
+ }
+ },
/**
* @constructs instance.web.search.ExtendedSearchProposition
* @extends instance.web.Widget
@@ -1716,17 +1714,10 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
this.value = null;
},
start: function () {
- var _this = this;
- this.$el.find(".searchview_extended_prop_field").change(function() {
- _this.changed();
- });
- this.$el.find('.searchview_extended_delete_prop').click(function () {
- _this.destroy();
- });
this.changed();
},
changed: function() {
- var nval = this.$el.find(".searchview_extended_prop_field").val();
+ var nval = this.$(".searchview_extended_prop_field").val();
if(this.attrs.selected == null || nval != this.attrs.selected.name) {
this.select_field(_.detect(this.fields, function(x) {return x.name == nval;}));
}
@@ -1741,7 +1732,7 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
if(this.attrs.selected != null) {
this.value.destroy();
this.value = null;
- this.$el.find('.searchview_extended_prop_op').html('');
+ this.$('.searchview_extended_prop_op').html('');
}
this.attrs.selected = field;
if(field == null) {
@@ -1757,9 +1748,9 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
_.each(this.value.operators, function(operator) {
$('<option>', {value: operator.value})
.text(String(operator.text))
- .appendTo(self.$el.find('.searchview_extended_prop_op'));
+ .appendTo(self.$('.searchview_extended_prop_op'));
});
- var $value_loc = this.$el.find('.searchview_extended_prop_value').empty();
+ var $value_loc = this.$('.searchview_extended_prop_value').empty();
this.value.appendTo($value_loc);
},
@@ -1767,7 +1758,7 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
if ( this.attrs.selected == null)
return null;
var field = this.attrs.selected;
- var op = this.$el.find('.searchview_extended_prop_op')[0];
+ var op = this.$('.searchview_extended_prop_op')[0];
var operator = op.options[op.selectedIndex];
return {
label: _.str.sprintf(_t('%(field)s %(operator)s "%(value)s"'), {
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index 9dd6e34c161..07c237ae0d8 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -4332,13 +4332,14 @@ instance.web.form.AbstractFormPopup = instance.web.Widget.extend({
this.dataset.create_function = function(data, sup) {
var fct = self.options.create_function || sup;
return fct.call(this, data).then(function(r) {
+ self.trigger('create_completed saved', r);
self.created_elements.push(r);
});
};
this.dataset.write_function = function(id, data, options, sup) {
var fct = self.options.write_function || sup;
return fct.call(this, id, data, options).then(function() {
- self.trigger('write_completed');
+ self.trigger('write_completed saved');
});
};
this.dataset.parent_view = this.options.parent_view;
@@ -4415,6 +4416,7 @@ instance.web.form.AbstractFormPopup = instance.web.Widget.extend({
this.select_elements(this.created_elements);
this.created_elements = [];
}
+ this.trigger('closed');
this.destroy();
},
destroy: function () {
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index fd74fd8922b..ab50ae933d9 100644
--- a/addons/web/static/src/js/view_list.js
+++ b/addons/web/static/src/js/view_list.js
@@ -970,7 +970,7 @@ instance.web.ListView.List = instance.web.Class.extend( /** @lends instance.web.
// set) a human-readable version. m2o does not have this issue
// because the non-human-readable is just a number, where the
// human-readable version is a pair
- if (value && (ref_match = /([\w\.]+),(\d+)/.exec(value))) {
+ if (value && (ref_match = /^([\w\.]+),(\d+)$/.exec(value))) {
// reference values are in the shape "$model,$id" (as a
// string), we need to split and name_get this pair in order
// to get a correctly displayable value in the field
@@ -1306,9 +1306,11 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we
process_modifiers: false
});
} catch (e) {
- group_label = row_data[group_column.id].value;
+ group_label = _.str.escapeHTML(row_data[group_column.id].value);
}
- $group_column.text(_.str.sprintf("%s (%d)",
+ // group_label is html-clean (through format or explicit
+ // escaping if format failed), can inject straight into HTML
+ $group_column.html(_.str.sprintf("%s (%d)",
group_label, group.length));
if (group.length && group.openable) {
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index bf7166eb7cf..2fec7178839 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -247,7 +247,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
action_menu_id: null,
});
if (_.isString(action) && instance.web.client_actions.contains(action)) {
- var action_client = { type: "ir.actions.client", tag: action };
+ var action_client = { type: "ir.actions.client", tag: action, params: {} };
return this.do_action(action_client, options);
} else if (_.isNumber(action) || _.isString(action)) {
var self = this;
@@ -346,14 +346,14 @@ instance.web.ActionManager = instance.web.Widget.extend({
if (!(ClientWidget.prototype instanceof instance.web.Widget)) {
var next;
- if (next = ClientWidget(this, action.params)) {
+ if (next = ClientWidget(this, action)) {
return this.do_action(next, options);
}
return $.when();
}
return this.ir_actions_common({
- widget: function () { return new ClientWidget(self, action.params); },
+ widget: function () { return new ClientWidget(self, action); },
action: action,
klass: 'oe_act_client',
post_process: function(widget) {