[FIX] *: fix a bunch of incorrectly documented docstring

Fix a bunch of ill-documented/incomplete/incorrect method docs
Without this, the automatic doc generation does not work.
This commit is contained in:
Xavier Morel
2017-09-18 11:54:39 +02:00
committed by Géry Debongnie
parent 313f69e948
commit f1a85ba70a
58 changed files with 396 additions and 330 deletions
@@ -124,7 +124,7 @@ var AccountSetupBarModel = KanbanModel.extend({
/** /**
* @abstract * @abstract
* @returns {Deferred -> Object} resolves to the required dashboard data * @returns {Deferred<Object>} resolves to the required dashboard data
*/ */
_fetchDashboardData: function () { _fetchDashboardData: function () {
return $.when(this._rpc({ return $.when(this._rpc({
@@ -136,7 +136,7 @@ var AccountSetupBarModel = KanbanModel.extend({
/** /**
* @private * @private
* @param {Deferred} super_def a deferred that resolves with a dataPoint id * @param {Deferred} super_def a deferred that resolves with a dataPoint id
* @returns {Deferred -> string} resolves to the dataPoint id * @returns {Deferred<string>} resolves to the dataPoint id
*/ */
_loadDashboard: function (super_def) { _loadDashboard: function (super_def) {
var self = this; var self = this;
@@ -12,7 +12,7 @@ var _t = core._t;
* Model use to fetch, format and update 'account.bank.statement' and * Model use to fetch, format and update 'account.bank.statement' and
* 'account.bank.statement.line' datas allowing reconciliation * 'account.bank.statement.line' datas allowing reconciliation
* *
* The statement internal structure: * The statement internal structure::
* *
* { * {
* valuenow: integer * valuenow: integer
@@ -25,7 +25,7 @@ var _t = core._t;
* accounts: {id: code} * accounts: {id: code}
* } * }
* *
* The internal structure of each line is: * The internal structure of each line is::
* *
* { * {
* balance: { * balance: {
@@ -114,7 +114,7 @@ var StatementModel = BasicModel.extend({
* account type * account type
* *
* @param {string} handle * @param {string} handle
* @param {number} mv_lines id * @param {number} mv_line_id
* @returns {Deferred} * @returns {Deferred}
*/ */
addProposition: function (handle, mv_line_id) { addProposition: function (handle, mv_line_id) {
@@ -167,13 +167,15 @@ var StatementModel = BasicModel.extend({
* change the mode line ('inactive', 'match', 'create'), and fetch the new * change the mode line ('inactive', 'match', 'create'), and fetch the new
* matched lines or prepare to create a new line * matched lines or prepare to create a new line
* *
* 'match': display the matched lines, the user can select the lines to * ``match``
* apply there as proposition * display the matched lines, the user can select the lines to apply
* 'create': display fields and quick create button to create a new * there as proposition
* proposition for the reconciliation * ``create``
* display fields and quick create button to create a new proposition
* for the reconciliation
* *
* @param {string} handle * @param {string} handle
* @param {string} mode * @param {'inactive' | 'match' | 'create'} mode
* @returns {Deferred} * @returns {Deferred}
*/ */
changeMode: function (handle, mode) { changeMode: function (handle, mode) {
@@ -316,7 +318,7 @@ var StatementModel = BasicModel.extend({
/** /**
* get the line data for this handle * get the line data for this handle
* *
* @param {OdooEvent} event * @param {Object} handle
* @returns {Object} * @returns {Object}
*/ */
getLine: function (handle) { getLine: function (handle) {
@@ -324,6 +326,7 @@ var StatementModel = BasicModel.extend({
}, },
/** /**
* load data from * load data from
*
* - 'account.bank.statement' fetch the line id and bank_statement_id info * - 'account.bank.statement' fetch the line id and bank_statement_id info
* - 'account.reconcile.model' fetch all reconcile model (for quick add) * - 'account.reconcile.model' fetch all reconcile model (for quick add)
* - 'account.account' fetch all account code * - 'account.account' fetch all account code
@@ -430,7 +433,7 @@ var StatementModel = BasicModel.extend({
* 'amount_type' * 'amount_type'
* *
* @param {string} handle * @param {string} handle
* @param {integer} reconcile model id * @param {integer} reconcileModelId
* @returns {Deferred} * @returns {Deferred}
*/ */
quickCreateProposition: function (handle, reconcileModelId) { quickCreateProposition: function (handle, reconcileModelId) {
@@ -460,7 +463,7 @@ var StatementModel = BasicModel.extend({
* Remove a proposition and switch to an active mode ('create' or 'match') * Remove a proposition and switch to an active mode ('create' or 'match')
* *
* @param {string} handle * @param {string} handle
* @param {number} proposition id (move line id) * @param {number} id (move line id)
* @returns {Deferred} * @returns {Deferred}
*/ */
removeProposition: function (handle, id) { removeProposition: function (handle, id) {
@@ -519,7 +522,7 @@ var StatementModel = BasicModel.extend({
* Then the total is recomputed to have 100%. * Then the total is recomputed to have 100%.
* *
* @param {string} handle * @param {string} handle
* @param {number[]} context.statement_ids * @param {*} values
* @returns {Deferred} * @returns {Deferred}
*/ */
updateProposition: function (handle, values) { updateProposition: function (handle, values) {
@@ -636,7 +639,7 @@ var StatementModel = BasicModel.extend({
* stop the editable proposition line and remove it if it's invalid then * stop the editable proposition line and remove it if it's invalid then
* compute the line * compute the line
* *
* @see '_computeLine' * See :func:`_computeLine`
* *
* @private * @private
* @param {string} handle * @param {string} handle
@@ -679,7 +682,7 @@ var StatementModel = BasicModel.extend({
* Check the taxes server side for each updated propositions with tax_id * Check the taxes server side for each updated propositions with tax_id
* *
* @private * @private
* @param {Object} * @param {Object} line
* @returns {Deferred} * @returns {Deferred}
*/ */
_computeLine: function (line) { _computeLine: function (line) {
@@ -771,7 +774,7 @@ var StatementModel = BasicModel.extend({
* *
* @private * @private
* @param {string} handle * @param {string} handle
* @param {integer} reconcile model id * @param {integer} reconcileModelId
*/ */
_computeReconcileModels: function (handle, reconcileModelId) { _computeReconcileModels: function (handle, reconcileModelId) {
var line = this.getLine(handle); var line = this.getLine(handle);
@@ -788,8 +791,7 @@ var StatementModel = BasicModel.extend({
* format a name_get into an object {id, display_name}, idempotent * format a name_get into an object {id, display_name}, idempotent
* *
* @private * @private
* @param {Object|Array} data or name_get * @param {Object|Array} [value] data or name_get
* @param {Object|false} {id, display_name}
*/ */
_formatNameGet: function (value) { _formatNameGet: function (value) {
return value ? (value.id ? value : {'id': value[0], 'display_name': value[1]}) : false; return value ? (value.id ? value : {'id': value[0], 'display_name': value[1]}) : false;
@@ -798,8 +800,8 @@ var StatementModel = BasicModel.extend({
* Format each propositions (amount, label, account_id) * Format each propositions (amount, label, account_id)
* *
* @private * @private
* @param {Object} * @param {Object} line
* @param {Object[]} * @param {Object[]} props
*/ */
_formatLineProposition: function (line, props) { _formatLineProposition: function (line, props) {
var self = this; var self = this;
@@ -818,7 +820,7 @@ var StatementModel = BasicModel.extend({
* @see '_computeLine' * @see '_computeLine'
* *
* @private * @private
* @param {Object[]} * @param {Object[]} lines
* @returns {Deferred} * @returns {Deferred}
*/ */
_formatLine: function (lines) { _formatLine: function (lines) {
@@ -845,7 +847,7 @@ var StatementModel = BasicModel.extend({
* *
* @private * @private
* @param {string} handle * @param {string} handle
* @param {Object[]} * @param {Object[]} mv_lines
* @returns {Deferred} * @returns {Deferred}
*/ */
_formatMoveLine: function (handle, mv_lines) { _formatMoveLine: function (handle, mv_lines) {
@@ -869,8 +871,8 @@ var StatementModel = BasicModel.extend({
* base_amount with the decimal number from the currency * base_amount with the decimal number from the currency
* *
* @private * @private
* @param {Object} * @param {Object} line
* @param {Object} * @param {Object} values
* @returns {Object} * @returns {Object}
*/ */
_formatQuickCreate: function (line, values) { _formatQuickCreate: function (line, values) {
@@ -980,7 +982,7 @@ var StatementModel = BasicModel.extend({
* *
* @private * @private
* @param {object} line * @param {object} line
* @param {object} proposition * @param {object} prop
* @returns {object} * @returns {object}
*/ */
_formatToProcessReconciliation: function (line, prop) { _formatToProcessReconciliation: function (line, prop) {
@@ -1216,7 +1218,7 @@ var ManualModel = StatementModel.extend({
* *
* @override * @override
* @private * @private
* @param {Object} * @param {Object} line
* @returns {Deferred} * @returns {Deferred}
*/ */
_computeLine: function (line) { _computeLine: function (line) {
@@ -1237,8 +1239,8 @@ var ManualModel = StatementModel.extend({
* @see '_computeLine' * @see '_computeLine'
* *
* @private * @private
* @param {string} 'customers', 'suppliers' or 'accounts' * @param {'customers' | 'suppliers' | 'accounts'} type
* @param {Object} * @param {Object} data
* @returns {Deferred} * @returns {Deferred}
*/ */
_formatLine: function (type, data) { _formatLine: function (type, data) {
@@ -1264,8 +1266,8 @@ var ManualModel = StatementModel.extend({
* *
* @override * @override
* @private * @private
* @param {Object} * @param {Object} line
* @param {Object} * @param {Object} props
*/ */
_formatLineProposition: function (line, props) { _formatLineProposition: function (line, props) {
var self = this; var self = this;
@@ -1330,4 +1332,4 @@ return {
StatementModel: StatementModel, StatementModel: StatementModel,
ManualModel: ManualModel, ManualModel: ManualModel,
}; };
}); });
@@ -182,9 +182,12 @@ var BarcodeEvents = core.Class.extend(mixins.PropertiesMixin, {
}); });
return { return {
// Singleton that emits barcode_scanned events on core.bus /** Singleton that emits barcode_scanned events on core.bus */
BarcodeEvents: new BarcodeEvents(), BarcodeEvents: new BarcodeEvents(),
// List of barcode prefixes that are reserved for internal purposes /**
* List of barcode prefixes that are reserved for internal purposes
* @type Array
*/
ReservedBarcodePrefixes: ['O-CMD'], ReservedBarcodePrefixes: ['O-CMD'],
}; };
+7 -6
View File
@@ -136,12 +136,13 @@ bus.Bus = Widget.extend({
* one in the list of open tabs. This one start polling for the other. When a notification is recieved from the poll, it * one in the list of open tabs. This one start polling for the other. When a notification is recieved from the poll, it
* is signaling through the localStorage too. * is signaling through the localStorage too.
* *
* localStorage used keys are : * localStorage used keys are:
* - bus.channels : shared public channel list to listen during the poll *
* - bus.options : shared options * - bus.channels : shared public channel list to listen during the poll
* - bus.notification : the received notifications from the last poll * - bus.options : shared options
* - bus.tab_list : list of opened tab ids * - bus.notification : the received notifications from the last poll
* - bus.tab_master : generated id of the master tab * - bus.tab_list : list of opened tab ids
* - bus.tab_master : generated id of the master tab
*/ */
var CrossTabBus = bus.Bus.extend({ var CrossTabBus = bus.Bus.extend({
init: function(){ init: function(){
+1 -1
View File
@@ -13,7 +13,7 @@ var _t = core._t;
/** /**
* Set the 'label_delay' entry in activity data according to the deadline date * Set the 'label_delay' entry in activity data according to the deadline date
* @param {Array} list of activity Object * @param {Array} activities list of activity Object
* @return {Array} : list of modified activity Object * @return {Array} : list of modified activity Object
*/ */
var setDelayLabel = function(activities){ var setDelayLabel = function(activities){
@@ -89,7 +89,7 @@ var ChatterComposer = composer.BasicComposer.extend({
/** /**
* Get the list of selected suggested partners * Get the list of selected suggested partners
* @returns Array() : list of 'recipient' selected partners (may not be created in db) * @returns {Array} list of 'recipient' selected partners (may not be created in db)
**/ **/
get_checked_suggested_partners: function () { get_checked_suggested_partners: function () {
var self = this; var self = this;
@@ -106,8 +106,8 @@ var ChatterComposer = composer.BasicComposer.extend({
/** /**
* Check the additional partners (not necessary registered partners), and open a popup form view * Check the additional partners (not necessary registered partners), and open a popup form view
* for the ones who informations is missing. * for the ones who informations is missing.
* @param Array : list of 'recipient' partners to complete informations or validate * @param {Array} checked_suggested_partners list of 'recipient' partners to complete informations or validate
* @returns Deferred resolved with the list of checked suggested partners (real partner) * @returns {Deferred} resolved with the list of checked suggested partners (real partner)
**/ **/
check_suggested_partners: function (checked_suggested_partners) { check_suggested_partners: function (checked_suggested_partners) {
var self = this; var self = this;
+1 -1
View File
@@ -34,7 +34,7 @@ var DocumentViewer = Widget.extend({
* Documents that are not of type image or video are filtered out. * Documents that are not of type image or video are filtered out.
* *
* @override * @override
* @param {Array[Object]} attachments list of attachments * @param {Array<Object>} attachments list of attachments
* @param {integer} activeAttachmentID * @param {integer} activeAttachmentID
*/ */
init: function (parent, attachments, activeAttachmentID) { init: function (parent, attachments, activeAttachmentID) {
+5 -5
View File
@@ -130,11 +130,11 @@ var Thread = Widget.extend({
}, },
/** /**
* Modifies $element to add the 'read more/read less' functionality * Modifies $element to add the 'read more/read less' functionality
* All element nodes with "data-o-mail-quote" attribute are concerned. * All element nodes with "data-o-mail-quote" attribute are concerned.
* All text nodes after a ""#stopSpelling" element are concerned. * All text nodes after a ``#stopSpelling`` element are concerned.
* Those text nodes need to be wrapped in a span (toggle functionality). * Those text nodes need to be wrapped in a span (toggle functionality).
* All consecutive elements are joined in one 'read more/read less'. * All consecutive elements are joined in one 'read more/read less'.
*/ */
insert_read_more: function ($element) { insert_read_more: function ($element) {
var self = this; var self = this;
@@ -18,7 +18,6 @@ var _t = core._t;
var Mutex = concurrency.Mutex; var Mutex = concurrency.Mutex;
var round_di = utils.round_decimals; var round_di = utils.round_decimals;
var round_pr = utils.round_precision; var round_pr = utils.round_precision;
var Backbone = window.Backbone;
var exports = {}; var exports = {};
+16 -14
View File
@@ -135,21 +135,23 @@ var ConfirmPopupWidget = PopupWidget.extend({
gui.define_popup({name:'confirm', widget: ConfirmPopupWidget}); gui.define_popup({name:'confirm', widget: ConfirmPopupWidget});
/** /**
* A popup that allows the user to select one item from a list. * A popup that allows the user to select one item from a list.
* *
* show_popup('selection',{ * Example::
* title: "Popup Title", *
* list: [ * show_popup('selection',{
* { label: 'foobar', item: 45 }, * title: "Popup Title",
* { label: 'bar foo', item: 'stuff' }, * list: [
* ], * { label: 'foobar', item: 45 },
* confirm: function(item) { * { label: 'bar foo', item: 'stuff' },
* // get the item selected by the user. * ],
* }, * confirm: function(item) {
* cancel: function(){ * // get the item selected by the user.
* // user chose nothing * },
* } * cancel: function(){
* }); * // user chose nothing
* }
* });
*/ */
var SelectionPopupWidget = PopupWidget.extend({ var SelectionPopupWidget = PopupWidget.extend({
@@ -76,7 +76,7 @@ var PortalChatter = Widget.extend({
* Fetch the messages and the message count from the server for the * Fetch the messages and the message count from the server for the
* current page and current domain. * current page and current domain.
* *
* @param {Array} * @param {Array} domain
* @returns {Deferred} * @returns {Deferred}
*/ */
messageFetch: function(domain){ messageFetch: function(domain){
@@ -101,7 +101,7 @@ var PlanAction = Widget.extend(ControlPanelMixin, {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
/** /**
* Refresh the DOM html * Refresh the DOM html
* @param {string|html} * @param {string|html} dom
* @private * @private
*/ */
_refreshPlan: function(dom){ _refreshPlan: function(dom){
@@ -733,6 +733,7 @@ var data = {
DataSet: DataSet, DataSet: DataSet,
DataSetStatic: DataSetStatic, DataSetStatic: DataSetStatic,
DataSetSearch: DataSetSearch, DataSetSearch: DataSetSearch,
/** @type String */
noDisplayContent: "<em class=\"text-warning\">" + _t("Unnamed") + "</em>", noDisplayContent: "<em class=\"text-warning\">" + _t("Unnamed") + "</em>",
}; };
@@ -206,16 +206,17 @@ var AbstractWebClient = Widget.extend(mixins.ServiceProvider, {
// Window title handling // Window title handling
// -------------------------------------------------------------- // --------------------------------------------------------------
/** /**
Sets the first part of the title of the window, dedicated to the current action. * Sets the first part of the title of the window, dedicated to the current action.
*/ */
set_title: function (title) { set_title: function (title) {
this.set_title_part("action", title); this.set_title_part("action", title);
}, },
/** /**
Sets an arbitrary part of the title of the window. Title parts are identified by strings. Each time * Sets an arbitrary part of the title of the window. Title parts are
a title part is changed, all parts are gathered, ordered by alphabetical order and displayed in the * identified by strings. Each time a title part is changed, all parts
title of the window separated by '-'. * are gathered, ordered by alphabetical order and displayed in the title
*/ * of the window separated by ``-``.
*/
set_title_part: function (part, title) { set_title_part: function (part, title) {
var tmp = _.clone(this.get("title_part")); var tmp = _.clone(this.get("title_part"));
tmp[part] = title; tmp[part] = title;
@@ -67,7 +67,7 @@ var Action = core.Class.extend({
}, },
/** /**
* Stores the DOM fragment of the action * Stores the DOM fragment of the action
* @param {jQuery} [fragment] the DOM fragment * @param {jQuery} [$fragment] the DOM fragment
*/ */
set_fragment: function($fragment) { set_fragment: function($fragment) {
this.$fragment = $fragment; this.$fragment = $fragment;
@@ -300,11 +300,11 @@ var ActionManager = Widget.extend({
/** /**
* Add a new action to the action manager * Add a new action to the action manager
* *
* widget: typically, widgets added are openerp.web.ViewManager. The action manager * @param {Widget} widget typically, widgets added are openerp.web.ViewManager. The action manager uses the stack of actions to handle the breadcrumbs.
* uses the stack of actions to handle the breadcrumbs. * @param {Object} action_descr new action description
* action_descr: new action description * @param {Object} options
* options.on_reverse_breadcrumb: will be called when breadcrumb is clicked on * @param options.on_reverse_breadcrumb will be called when breadcrumb is clicked on
* options.clear_breadcrumbs: boolean, if true, action stack is destroyed * @param options.clear_breadcrumbs: boolean, if true, action stack is destroyed
*/ */
push_action: function(widget, action_descr, options) { push_action: function(widget, action_descr, options) {
var self = this; var self = this;
@@ -613,7 +613,7 @@ var ActionManager = Widget.extend({
/** /**
* Execute an OpenERP action * Execute an OpenERP action
* *
* @param {Number|String|String|Object} Can be either an action id, an action XML id, a client action tag or an action descriptor. * @param {Number|String|String|Object} action Can be either an action id, an action XML id, a client action tag or an action descriptor.
* @param {Object} [options] * @param {Object} [options]
* @param {Boolean} [options.clear_breadcrumbs=false] Clear the breadcrumbs history list * @param {Boolean} [options.clear_breadcrumbs=false] Clear the breadcrumbs history list
* @param {Boolean} [options.replace_breadcrumb=false] Replace the current breadcrumb with the action * @param {Boolean} [options.replace_breadcrumb=false] Replace the current breadcrumb with the action
@@ -96,7 +96,7 @@ var ExtendedSearchProposition = Widget.extend(/** @lends instance.web.search.Ext
}, },
}); });
ExtendedSearchProposition.Field = Widget.extend({ var Field = Widget.extend({
init: function (parent, field) { init: function (parent, field) {
this._super(parent); this._super(parent);
this.field = field; this.field = field;
@@ -153,7 +153,7 @@ ExtendedSearchProposition.Field = Widget.extend({
} }
}); });
ExtendedSearchProposition.Char = ExtendedSearchProposition.Field.extend({ var Char = Field.extend({
tagName: 'input', tagName: 'input',
className: 'o_input', className: 'o_input',
attributes: { attributes: {
@@ -172,7 +172,7 @@ ExtendedSearchProposition.Char = ExtendedSearchProposition.Field.extend({
} }
}); });
ExtendedSearchProposition.DateTime = ExtendedSearchProposition.Field.extend({ var DateTime = Field.extend({
tagName: 'span', tagName: 'span',
attributes: { attributes: {
type: 'datetime' type: 'datetime'
@@ -241,7 +241,7 @@ ExtendedSearchProposition.DateTime = ExtendedSearchProposition.Field.extend({
}, },
}); });
ExtendedSearchProposition.Date = ExtendedSearchProposition.DateTime.extend({ var Date = DateTime.extend({
attributes: { attributes: {
type: 'date' type: 'date'
}, },
@@ -250,7 +250,7 @@ ExtendedSearchProposition.Date = ExtendedSearchProposition.DateTime.extend({
}, },
}); });
ExtendedSearchProposition.Integer = ExtendedSearchProposition.Field.extend({ var Integer = Field.extend({
tagName: 'input', tagName: 'input',
className: 'o_input', className: 'o_input',
attributes: { attributes: {
@@ -280,11 +280,11 @@ ExtendedSearchProposition.Integer = ExtendedSearchProposition.Field.extend({
} }
}); });
ExtendedSearchProposition.Id = ExtendedSearchProposition.Integer.extend({ var Id = Integer.extend({
operators: [{value: "=", text: _lt("is")}] operators: [{value: "=", text: _lt("is")}]
}); });
ExtendedSearchProposition.Float = ExtendedSearchProposition.Field.extend({ var Float = Field.extend({
template: 'SearchView.extended_search.proposition.float', template: 'SearchView.extended_search.proposition.float',
operators: [ operators: [
{value: "=", text: _lt("is equal to")}, {value: "=", text: _lt("is equal to")},
@@ -313,7 +313,7 @@ ExtendedSearchProposition.Float = ExtendedSearchProposition.Field.extend({
} }
}); });
ExtendedSearchProposition.Selection = ExtendedSearchProposition.Field.extend({ var Selection = Field.extend({
template: 'SearchView.extended_search.proposition.selection', template: 'SearchView.extended_search.proposition.selection',
operators: [ operators: [
{value: "=", text: _lt("is")}, {value: "=", text: _lt("is")},
@@ -331,7 +331,7 @@ ExtendedSearchProposition.Selection = ExtendedSearchProposition.Field.extend({
} }
}); });
ExtendedSearchProposition.Boolean = ExtendedSearchProposition.Field.extend({ var Boolean = Field.extend({
tagName: 'span', tagName: 'span',
operators: [ operators: [
{value: "=", text: _lt("is true")}, {value: "=", text: _lt("is true")},
@@ -347,19 +347,19 @@ ExtendedSearchProposition.Boolean = ExtendedSearchProposition.Field.extend({
}); });
core.search_filters_registry core.search_filters_registry
.add('char', ExtendedSearchProposition.Char) .add('char', Char)
.add('text', ExtendedSearchProposition.Char) .add('text', Char)
.add('one2many', ExtendedSearchProposition.Char) .add('one2many', Char)
.add('many2one', ExtendedSearchProposition.Char) .add('many2one', Char)
.add('many2many', ExtendedSearchProposition.Char) .add('many2many', Char)
.add('datetime', ExtendedSearchProposition.DateTime) .add('datetime', DateTime)
.add('date', ExtendedSearchProposition.Date) .add('date', Date)
.add('integer', ExtendedSearchProposition.Integer) .add('integer', Integer)
.add('float', ExtendedSearchProposition.Float) .add('float', Float)
.add('monetary', ExtendedSearchProposition.Float) .add('monetary', Float)
.add('boolean', ExtendedSearchProposition.Boolean) .add('boolean', Boolean)
.add('selection', ExtendedSearchProposition.Selection) .add('selection', Selection)
.add('id', ExtendedSearchProposition.Id); .add('id', Id);
return { return {
ExtendedSearchProposition: ExtendedSearchProposition ExtendedSearchProposition: ExtendedSearchProposition
@@ -265,7 +265,7 @@ var SearchView = Widget.extend({
* *
* @param parent * @param parent
* @param dataset * @param dataset
* @param fields_view * @param fvg
* @param {Object} [options] * @param {Object} [options]
* @param {Boolean} [options.hidden=false] hide the search view * @param {Boolean} [options.hidden=false] hide the search view
* @param {Boolean} [options.disable_custom_filters=false] do not load custom filters from ir.filters * @param {Boolean} [options.disable_custom_filters=false] do not load custom filters from ir.filters
@@ -499,8 +499,8 @@ var SearchView = Widget.extend({
.$el.focus(); .$el.focus();
}, },
/** /**
* @param {openerp.web.search.SearchQuery | undefined} Undefined if event is change * @param {openerp.web.search.SearchQuery | undefined} collection Undefined if event is change
* @param {openerp.web.search.Facet} * @param {openerp.web.search.Facet} model
* @param {Object} [options] * @param {Object} [options]
*/ */
renderFacets: function (collection, model, options) { renderFacets: function (collection, model, options) {
@@ -232,8 +232,9 @@ var ViewManager = Widget.extend(ControlPanelMixin, {
}, },
/** /**
* Returns the default view with the following fallbacks: * Returns the default view with the following fallbacks:
* - use the default_view defined in the flags, if any *
* - use the first view in the view_order * - use the default_view defined in the flags, if any
* - use the first view in the view_order
* *
* @returns {Object} the default view * @returns {Object} the default view
*/ */
+1 -1
View File
@@ -211,7 +211,7 @@ var loadJS = (function () {
* @param {HTMLFormElement} [options.form] the form to submit in order to fetch the file * @param {HTMLFormElement} [options.form] the form to submit in order to fetch the file
* @param {Function} [options.success] callback in case of download success * @param {Function} [options.success] callback in case of download success
* @param {Function} [options.error] callback in case of request error, provided with the error body * @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 * @param {Function} [options.complete] called after both ``success`` and ``error`` callbacks have executed
*/ */
function get_file(options) { function get_file(options) {
// need to detect when the file is done downloading (not used // need to detect when the file is done downloading (not used
+2
View File
@@ -6,6 +6,8 @@ var mixins = require('web.mixins');
/** /**
* Event Bus used to bind events scoped in the current instance * Event Bus used to bind events scoped in the current instance
*
* @class Bus
*/ */
return Class.extend(mixins.EventDispatcherMixin, { return Class.extend(mixins.EventDispatcherMixin, {
init: function() { init: function() {
+29 -28
View File
@@ -12,46 +12,47 @@ odoo.define('web.Class', function () {
* Defines The Class object. That object can be used to define and inherit classes using * Defines The Class object. That object can be used to define and inherit classes using
* the extend() method. * the extend() method.
* *
* Example: * Example::
* *
* var Person = Class.extend({ * var Person = Class.extend({
* init: function(isDancing){ * init: function(isDancing){
* this.dancing = isDancing; * this.dancing = isDancing;
* }, * },
* dance: function(){ * dance: function(){
* return this.dancing; * return this.dancing;
* } * }
* }); * });
* *
* The init() method act as a constructor. This class can be instancied this way: * The init() method act as a constructor. This class can be instanced this way::
* *
* var person = new Person(true); * var person = new Person(true);
* person.dance(); * person.dance();
* *
* The Person class can also be extended again: * The Person class can also be extended again:
* *
* var Ninja = Person.extend({ * var Ninja = Person.extend({
* init: function(){ * init: function(){
* this._super( false ); * this._super( false );
* }, * },
* dance: function(){ * dance: function(){
* // Call the inherited version of dance() * // Call the inherited version of dance()
* return this._super(); * return this._super();
* }, * },
* swingSword: function(){ * swingSword: function(){
* return true; * return true;
* } * }
* }); * });
* *
* When extending a class, each re-defined method can use this._super() to call the previous * When extending a class, each re-defined method can use this._super() to call the previous
* implementation of that method. * implementation of that method.
*
* @class Class
*/ */
function OdooClass(){}
var initializing = false; var initializing = false;
var fnTest = /xyz/.test(function(){xyz();}) ? /\b_super\b/ : /.*/; var fnTest = /xyz/.test(function(){xyz();}) ? /\b_super\b/ : /.*/;
// The web Class implementation (does nothing)
function OdooClass(){};
/** /**
* Subclass an existing class * Subclass an existing class
* *
+8 -7
View File
@@ -122,7 +122,7 @@ return {
* the last operation. * the last operation.
* *
* For example, let us say that we have a _fetch method on a widget which * For example, let us say that we have a _fetch method on a widget which
* fetches data. We want to rerender the widget after. We could do this: * fetches data. We want to rerender the widget after. We could do this::
* *
* this._fetch().then(function (result) { * this._fetch().then(function (result) {
* self.state = result; * self.state = result;
@@ -130,17 +130,18 @@ return {
* }); * });
* *
* Now, we have at least two problems: * Now, we have at least two problems:
*
* - if this code is called twice and the second _fetch completes before the * - if this code is called twice and the second _fetch completes before the
* first, the end state will be the result of the first _fetch, which is * first, the end state will be the result of the first _fetch, which is
* not what we expect * not what we expect
* - in any cases, the user interface will rerender twice, which is bad. * - in any cases, the user interface will rerender twice, which is bad.
* *
* Now, if we have a DropPrevious: * Now, if we have a DropPrevious::
* *
* this.dropPrevious = new DropPrevious(); * this.dropPrevious = new DropPrevious();
* *
* Then we can wrap the _fetch in a DropPrevious and have the expected * Then we can wrap the _fetch in a DropPrevious and have the expected
* result: * result::
* *
* this.dropPrevious * this.dropPrevious
* .add(this._fetch()) * .add(this._fetch())
@@ -153,7 +154,7 @@ return {
/** /**
* Registers a new deferred and rejects the previous one * Registers a new deferred and rejects the previous one
* *
* @param {Deferred} the new deferred * @param {Deferred} deferred the new deferred
* @returns {Promise} * @returns {Promise}
*/ */
add: function (deferred) { add: function (deferred) {
@@ -171,7 +172,7 @@ return {
* *
* Imagine that we have a function to fetch some data _load(), which returns * Imagine that we have a function to fetch some data _load(), which returns
* a deferred which resolves to something useful. Now, we have some code * a deferred which resolves to something useful. Now, we have some code
* looking like this: * looking like this::
* *
* return this._load().then(function (result) { * return this._load().then(function (result) {
* this.state = result; * this.state = result;
@@ -179,11 +180,11 @@ return {
* *
* If this code is run twice, but the second execution ends before the * If this code is run twice, but the second execution ends before the
* first, then the final state will be the result of the first call to * first, then the final state will be the result of the first call to
* _load. However, if we have a mutex: * _load. However, if we have a mutex::
* *
* this.mutex = new Mutex(); * this.mutex = new Mutex();
* *
* and if we wrap the calls to _load in a mutex: * and if we wrap the calls to _load in a mutex::
* *
* return this.mutex.exec(function() { * return this.mutex.exec(function() {
* return this._load().then(function (result) { * return this._load().then(function (result) {
+7 -7
View File
@@ -9,17 +9,17 @@ var QWeb = core.qweb;
var _t = core._t; var _t = core._t;
/** /**
A useful class to handle dialogs. * A useful class to handle dialogs.
* Attributes:
Attributes: *
- $footer: A jQuery element targeting a dom part where buttons can be added. It always exists * ``$footer``
during the lifecycle of the dialog. * A jQuery element targeting a dom part where buttons can be added. It
*/ * always exists during the lifecycle of the dialog.
**/
var Dialog = Widget.extend({ var Dialog = Widget.extend({
xmlDependencies: ['/web/static/src/xml/dialog.xml'], xmlDependencies: ['/web/static/src/xml/dialog.xml'],
/** /**
* @constructor
* @param {Widget} parent * @param {Widget} parent
* @param {Object} [options] * @param {Object} [options]
* @param {string} [options.title=Odoo] * @param {string} [options.title=Odoo]
+6 -2
View File
@@ -115,10 +115,14 @@ return {
} }
}, },
/** /**
* jQuery find function behavior is: * jQuery find function behavior is::
*
* $('A').find('A B') <=> $('A A B') * $('A').find('A B') <=> $('A A B')
* The searches behavior to find options' DOM needs to be *
* The searches behavior to find options' DOM needs to be::
*
* $('A').find('A B') <=> $('A B') * $('A').find('A B') <=> $('A B')
*
* This is what this function does. * This is what this function does.
* *
* @param {jQuery} $from - the jQuery element(s) from which to search * @param {jQuery} $from - the jQuery element(s) from which to search
+39 -25
View File
@@ -10,6 +10,9 @@ var AbstractService = require('web.AbstractService');
* relationship. Each object can a have a parent and multiple children. * relationship. Each object can a have a parent and multiple children.
* When an object is destroyed, all its children are destroyed too releasing * When an object is destroyed, all its children are destroyed too releasing
* any resource they could have reserved before. * any resource they could have reserved before.
*
* @name ParentedMixin
* @mixin
*/ */
var ParentedMixin = { var ParentedMixin = {
__parentedMixin : true, __parentedMixin : true,
@@ -57,21 +60,21 @@ var ParentedMixin = {
return this.__parentedDestroyed; return this.__parentedDestroyed;
}, },
/** /**
Utility method to only execute asynchronous actions if the current * Utility method to only execute asynchronous actions if the current
object has not been destroyed. * object has not been destroyed.
*
@param {$.Deferred} promise The promise representing the asynchronous * @param {$.Deferred} promise The promise representing the asynchronous
action. * action.
@param {bool} [reject=false] If true, the returned promise will be * @param {bool} [reject=false] If true, the returned promise will be
rejected with no arguments if the current * rejected with no arguments if the current
object is destroyed. If false, the * object is destroyed. If false, the
returned promise will never be resolved * returned promise will never be resolved
or rejected. * or rejected.
@returns {$.Deferred} A promise that will mirror the given promise if * @returns {$.Deferred} A promise that will mirror the given promise if
everything goes fine but will either be rejected * everything goes fine but will either be rejected
with no arguments or never resolved if the * with no arguments or never resolved if the
current object is destroyed. * current object is destroyed.
*/ */
alive: function (promise, reject) { alive: function (promise, reject) {
var self = this; var self = this;
return $.Deferred(function (def) { return $.Deferred(function (def) {
@@ -228,13 +231,16 @@ var Events = Class.extend({
}); });
/** /**
Mixin containing an event system. Events are also registered by specifying the target object * Mixin containing an event system. Events are also registered by specifying the target object
(the object which will receive the event when it is raised). Both the event-emitting object * (the object which will receive the event when it is raised). Both the event-emitting object
and the target object store or reference to each other. This is used to correctly remove all * and the target object store or reference to each other. This is used to correctly remove all
reference to the event handler when any of the object is destroyed (when the destroy() method * reference to the event handler when any of the object is destroyed (when the destroy() method
from ParentedMixin is called). Removing those references is necessary to avoid memory leak * from ParentedMixin is called). Removing those references is necessary to avoid memory leak
and phantom events (events which are raised and sent to a previously destroyed object). * and phantom events (events which are raised and sent to a previously destroyed object).
*/ *
* @name EventDispatcherMixin
* @mixin
*/
var EventDispatcherMixin = _.extend({}, ParentedMixin, { var EventDispatcherMixin = _.extend({}, ParentedMixin, {
__eventDispatcherMixin: true, __eventDispatcherMixin: true,
custom_events: {}, custom_events: {},
@@ -349,6 +355,10 @@ var EventDispatcherMixin = _.extend({}, ParentedMixin, {
} }
}); });
/**
* @name PropertiesMixin
* @mixin
*/
var PropertiesMixin = _.extend({}, EventDispatcherMixin, { var PropertiesMixin = _.extend({}, EventDispatcherMixin, {
init: function () { init: function () {
EventDispatcherMixin.init.call(this); EventDispatcherMixin.init.call(this);
@@ -432,6 +442,10 @@ odoo.define('web.ServicesMixin', function (require) {
var rpc = require('web.rpc'); var rpc = require('web.rpc');
/**
* @mixin
* @name ServicesMixin
*/
var ServicesMixin = { var ServicesMixin = {
call: function (service, method) { call: function (service, method) {
var args = Array.prototype.slice.call(arguments, 2); var args = Array.prototype.slice.call(arguments, 2);
@@ -450,9 +464,9 @@ var ServicesMixin = {
* Builds and executes RPC query. Returns a deferred's promise resolved with * Builds and executes RPC query. Returns a deferred's promise resolved with
* the RPC result. * the RPC result.
* *
* @param {string} arg1 either a route or a model * @param {string} params either a route or a model
* @param {string} method if a model is given, this argument is a method * @param {string} options if a model is given, this argument is a method
* @returns {Deferred's Promise} * @returns {Promise}
*/ */
_rpc: function (params, options) { _rpc: function (params, options) {
var query = rpc.buildQuery(params); var query = rpc.buildQuery(params);
+5 -5
View File
@@ -530,11 +530,11 @@ datetime.date = py.type('date', null, {
}), }),
}); });
/** /**
Returns the current local date, which means the date on the client (which can be different * Returns the current local date, which means the date on the client (which can be different
compared to the date of the server). * compared to the date of the server).
*
@return {datetime.date} * @return {datetime.date}
*/ */
function context_today() { function context_today() {
var d = new Date(); var d = new Date();
return py.PY_call( return py.PY_call(
+1 -3
View File
@@ -321,8 +321,6 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, {
* @param {String} url RPC endpoint * @param {String} url RPC endpoint
* @param {Object} params call parameters * @param {Object} params call parameters
* @param {Object} options additional options for rpc call * @param {Object} options additional options for rpc call
* @param {Function} success_callback function to execute on RPC call success
* @param {Function} error_callback function to execute on RPC call failure
* @returns {jQuery.Deferred} jquery-provided ajax deferred * @returns {jQuery.Deferred} jquery-provided ajax deferred
*/ */
rpc: function (url, params, options) { rpc: function (url, params, options) {
@@ -413,7 +411,7 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, {
* (host system settings) to UTC, for a given date. The offset is positive * (host system settings) to UTC, for a given date. The offset is positive
* if the local timezone is behind UTC, and negative if it is ahead. * if the local timezone is behind UTC, and negative if it is ahead.
* *
* @param {string || moment} date a valid string date or moment instance * @param {string | moment} date a valid string date or moment instance
* @returns {integer} * @returns {integer}
*/ */
getTZOffset: function (date) { getTZOffset: function (date) {
@@ -71,6 +71,16 @@ var TranslationDataBase = Class.extend(/** @lends instance.TranslationDataBase#
} }
}); });
/**
* Eager translation function, performs translation immediately at call
* site. Beware using this outside of method bodies (before the
* translation database is loaded), you probably want :func:`_lt`
* instead.
*
* @function _t
* @param {String} source string to translate
* @returns {String} source translated into the current locale
*/
var _t = new TranslationDataBase().build_translation_function(); var _t = new TranslationDataBase().build_translation_function();
/** /**
* Lazy translation function, only performs the translation when actually * Lazy translation function, only performs the translation when actually
+6 -6
View File
@@ -107,7 +107,7 @@ var utils = {
/** /**
* Returns a human readable size * Returns a human readable size
* *
* @param {Number} number of bytes * @param {Number} size number of bytes
*/ */
human_size: function (size) { human_size: function (size) {
var units = _t("Bytes,Kb,Mb,Gb,Tb,Pb,Eb,Zb,Yb").split(','); var units = _t("Bytes,Kb,Mb,Gb,Tb,Pb,Eb,Zb,Yb").split(',');
@@ -271,8 +271,8 @@ var utils = {
/** /**
* performs a half up rounding with a fixed amount of decimals, correcting for float loss of precision * performs a half up rounding with a fixed amount of decimals, correcting for float loss of precision
* See the corresponding float_round() in server/tools/float_utils.py for more info * See the corresponding float_round() in server/tools/float_utils.py for more info
* @param {Number} the value to be rounded * @param {Number} value the value to be rounded
* @param {Number} the number of decimals. eg: round_decimals(3.141592,2) -> 3.14 * @param {Number} decimals the number of decimals. eg: round_decimals(3.141592,2) -> 3.14
*/ */
round_decimals: function (value, decimals) { round_decimals: function (value, decimals) {
return utils.round_precision(value, Math.pow(10,-decimals)); return utils.round_precision(value, Math.pow(10,-decimals));
@@ -319,9 +319,9 @@ var utils = {
}, },
/** /**
* Create a cookie * Create a cookie
* @param {String} name : the name of the cookie * @param {String} name the name of the cookie
* @param {String} value : the value stored in the cookie * @param {String} value the value stored in the cookie
* @param {Integer} ttl : time to live of the cookie in millis. -1 to erase the cookie. * @param {Integer} ttl time to live of the cookie in millis. -1 to erase the cookie.
*/ */
set_cookie: function (name, value, ttl) { set_cookie: function (name, value, ttl) {
ttl = ttl || 24*60*60*365; ttl = ttl || 24*60*60*365;
+34 -34
View File
@@ -7,50 +7,51 @@ var mixins = require('web.mixins');
var ServicesMixin = require('web.ServicesMixin'); var ServicesMixin = require('web.ServicesMixin');
/** /**
* Base class for all visual components. Provides a lot of functionalities helpful * Base class for all visual components. Provides a lot of functions helpful
* for the management of a part of the DOM. * for the management of a part of the DOM.
* *
* Widget handles: * Widget handles:
*
* - Rendering with QWeb. * - Rendering with QWeb.
* - Life-cycle management and parenting (when a parent is destroyed, all its children are * - Life-cycle management and parenting (when a parent is destroyed, all its
* destroyed too). * children are destroyed too).
* - Insertion in DOM. * - Insertion in DOM.
* *
* Guide to create implementations of the Widget class: * **Guide to create implementations of the Widget class**
* ==============================================
* *
* Here is a sample child class: * Here is a sample child class::
* *
* MyWidget = openerp.base.Widget.extend({ * var MyWidget = openerp.base.Widget.extend({
* // the name of the QWeb template to use for rendering * // the name of the QWeb template to use for rendering
* template: "MyQWebTemplate", * template: "MyQWebTemplate",
* *
* init: function(parent) { * init: function(parent) {
* this._super(parent); * this._super(parent);
* // stuff that you want to init before the rendering * // stuff that you want to init before the rendering
* }, * },
* start: function() { * start: function() {
* // stuff you want to make after the rendering, `this.$el` holds a correct value * // stuff you want to make after the rendering, `this.$el` holds a correct value
* this.$(".my_button").click(/* an example of event binding * /); * this.$(".my_button").click(/* an example of event binding * /);
* *
* // if you have some asynchronous operations, it's a good idea to return * // if you have some asynchronous operations, it's a good idea to return
* // a promise in start() * // a promise in start()
* var promise = this._rpc(...); * var promise = this._rpc(...);
* return promise; * return promise;
* } * }
* }); * });
* *
* Now this class can simply be used with the following syntax: * Now this class can simply be used with the following syntax::
* *
* var my_widget = new MyWidget(this); * var my_widget = new MyWidget(this);
* my_widget.appendTo($(".some-div")); * my_widget.appendTo($(".some-div"));
* *
* With these two lines, the MyWidget instance was inited, rendered, it was inserted into the * With these two lines, the MyWidget instance was initialized, rendered,
* DOM inside the ".some-div" div and its events were binded. * inserted into the DOM inside the ``.some-div`` div and its events were
* bound.
* *
* And of course, when you don't need that widget anymore, just do: * And of course, when you don't need that widget anymore, just do::
* *
* my_widget.destroy(); * my_widget.destroy();
* *
* That will kill the widget in a clean way and erase its content from the dom. * That will kill the widget in a clean way and erase its content from the dom.
*/ */
@@ -67,7 +68,7 @@ var Widget = core.Class.extend(mixins.PropertiesMixin, ServicesMixin, {
* The name of the QWeb template that will be used for rendering. Must be * The name of the QWeb template that will be used for rendering. Must be
* redefined in subclasses or the default render() method can not be used. * redefined in subclasses or the default render() method can not be used.
* *
* @type string * @type {String}
*/ */
template: null, template: null,
/** /**
@@ -82,8 +83,6 @@ var Widget = core.Class.extend(mixins.PropertiesMixin, ServicesMixin, {
/** /**
* Constructs the widget and sets its parent if a parent is given. * Constructs the widget and sets its parent if a parent is given.
* *
* @constructs openerp.Widget
*
* @param {openerp.Widget} parent Binds the current instance to the given Widget instance. * @param {openerp.Widget} parent Binds the current instance to the given Widget instance.
* When that widget is destroyed by calling destroy(), the current instance will be * When that widget is destroyed by calling destroy(), the current instance will be
* destroyed too. Can be null. * destroyed too. Can be null.
@@ -238,7 +237,7 @@ var Widget = core.Class.extend(mixins.PropertiesMixin, ServicesMixin, {
* (if any) by the new one in the DOM. * (if any) by the new one in the DOM.
* *
* @param {HTMLElement | jQuery} $el * @param {HTMLElement | jQuery} $el
* @returns {*} this * @returns {Widget} this
*/ */
replaceElement: function ($el) { replaceElement: function ($el) {
var $oldel = this.$el; var $oldel = this.$el;
@@ -257,13 +256,14 @@ var Widget = core.Class.extend(mixins.PropertiesMixin, ServicesMixin, {
* Re-sets the widget's root element (el/$el/$el). * Re-sets the widget's root element (el/$el/$el).
* *
* Includes: * Includes:
*
* * re-delegating events * * re-delegating events
* * re-binding sub-elements * * re-binding sub-elements
* * if the widget already had a root element, replacing the pre-existing * * if the widget already had a root element, replacing the pre-existing
* element in the DOM * element in the DOM
* *
* @param {HTMLElement | jQuery} element new root element for the widget * @param {HTMLElement | jQuery} element new root element for the widget
* @return {*} this * @return {Widget} this
*/ */
setElement: function (element) { setElement: function (element) {
// NB: completely useless, as WidgetMixin#init creates a $el // NB: completely useless, as WidgetMixin#init creates a $el
@@ -59,6 +59,8 @@ var AbstractField = Widget.extend({
specialData: false, specialData: false,
/** /**
* to override to indicate which field types are supported by the widget * to override to indicate which field types are supported by the widget
*
* @type Array<String>
*/ */
supportedFieldTypes: [], supportedFieldTypes: [],
@@ -196,7 +198,7 @@ var AbstractField = Widget.extend({
* will have the cursor at the very end. * will have the cursor at the very end.
* *
* @param {Object} [options] * @param {Object} [options]
* @param {boolean} [noselect=false] if false and the input * @param {boolean} [options.noselect=false] if false and the input
* is of type text or textarea, the content will also be selected * is of type text or textarea, the content will also be selected
* @param {Event} [options.event] the event which fired this activation * @param {Event} [options.event] the event which fired this activation
* @returns {boolean} true if the widget was activated, false if the * @returns {boolean} true if the widget was activated, false if the
@@ -1741,10 +1741,9 @@ var FieldPercentPie = AbstractField.extend({
}); });
/** /**
* FieldProgressBar * Node options:
* parameters *
* - title: title of the bar, displayed on top of the bar * - title: title of the bar, displayed on top of the bar options
* options
* - editable: boolean if value is editable * - editable: boolean if value is editable
* - current_value: get the current_value from the field that must be present in the view * - current_value: get the current_value from the field that must be present in the view
* - max_value: get the max_value from the field that must be present in the view * - max_value: get the max_value from the field that must be present in the view
@@ -80,7 +80,7 @@ function formatChar(value, field, options) {
* Returns a string representing a date. If the value is false, then we return * Returns a string representing a date. If the value is false, then we return
* an empty string. Note that this is dependant on the localization settings * an empty string. Note that this is dependant on the localization settings
* *
* @param {Moment|false} * @param {Moment|false} value
* @param {Object} [field] * @param {Object} [field]
* a description of the field (note: this parameter is ignored) * a description of the field (note: this parameter is ignored)
* @param {Object} [options] additional options * @param {Object} [options] additional options
@@ -258,7 +258,7 @@ function formatX2Many(value) {
* @param {Object} [options] * @param {Object} [options]
* additional options to override the values in the python description of * additional options to override the values in the python description of
* the field. * the field.
* @param {Object} [options.currency] - the description of the currency to use * @param {Object} [options.currency] the description of the currency to use
* @param {integer} [options.currency_id] * @param {integer} [options.currency_id]
* the id of the 'res.currency' to use (ignored if options.currency) * the id of the 'res.currency' to use (ignored if options.currency)
* @param {string} [options.currency_field] * @param {string} [options.currency_field]
@@ -336,7 +336,7 @@ function formatSelection(value, field, options) {
* Create an Date object * Create an Date object
* The method toJSON return the formated value to send value server side * The method toJSON return the formated value to send value server side
* *
* @param {string} * @param {string} value
* @param {Object} [field] * @param {Object} [field]
* a description of the field (note: this parameter is ignored) * a description of the field (note: this parameter is ignored)
* @param {Object} [options] additional options * @param {Object} [options] additional options
@@ -375,7 +375,7 @@ function parseDate(value, field, options) {
* Create an Date object * Create an Date object
* The method toJSON return the formated value to send value server side * The method toJSON return the formated value to send value server side
* *
* @param {string} * @param {string} value
* @param {Object} [field] * @param {Object} [field]
* a description of the field (note: this parameter is ignored) * a description of the field (note: this parameter is ignored)
* @param {Object} [options] additional options * @param {Object} [options] additional options
@@ -10,10 +10,10 @@ var _t = core._t;
/** /**
* This widget is intended to display a warning near a label of a 'timezone' field * This widget is intended to display a warning near a label of a 'timezone' field
* indicating if the browser timezone is identical (or not) to the selected timezone. * indicating if the browser timezone is identical (or not) to the selected timezone.
* This widget depends on a field given with the param 'tz_offset_field', which contains * This widget depends on a field given with the param 'tz_offset_field', which contains
* the time difference between UTC time and local time, in minutes. * the time difference between UTC time and local time, in minutes.
*/ */
var FieldTimezoneMismatch = FieldSelection.extend({ var FieldTimezoneMismatch = FieldSelection.extend({
/** /**
@@ -112,7 +112,7 @@ var AbstractFieldUpgrade = {
/** /**
* @private * @private
* @param {MouseEvent} * @param {MouseEvent} event
*/ */
_onInputClicked: function (event) { _onInputClicked: function (event) {
if ($(event.currentTarget).prop("checked")) { if ($(event.currentTarget).prop("checked")) {
@@ -16,23 +16,31 @@ var config = {
/** /**
* debug is a boolean flag. It is only considered true if the flag is set * debug is a boolean flag. It is only considered true if the flag is set
* in the url * in the url
*
* @type Boolean
*/ */
debug: ($.deparam($.param.querystring()).debug !== undefined), debug: ($.deparam($.param.querystring()).debug !== undefined),
device: { device: {
/** /**
* touch is a boolean, true if the device supports touch interaction * touch is a boolean, true if the device supports touch interaction
*
* @type Boolean
*/ */
touch: 'ontouchstart' in window || 'onmsgesturechange' in window, touch: 'ontouchstart' in window || 'onmsgesturechange' in window,
/** /**
* size_class is an integer: 0, 1, 2 or 3, depending on the (current) * size_class is an integer: 0, 1, 2 or 3, depending on the (current)
* size of the device. This is a dynamic property, updated whenever the * size of the device. This is a dynamic property, updated whenever the
* browser is resized * browser is resized
*
* @type Number
*/ */
size_class: null, size_class: null,
/** /**
* A frequent use case is to have a different render in 'mobile' mode, * A frequent use case is to have a different render in 'mobile' mode,
* meaning when the screen is small. This flag (boolean) is true when * meaning when the screen is small. This flag (boolean) is true when
* the size is not 3. It is also updated dynamically. * the size is not 3. It is also updated dynamically.
*
* @type Boolean
*/ */
isMobile: null, isMobile: null,
/** /**
+9 -1
View File
@@ -7,6 +7,11 @@ var QWeb = require('web.QWeb');
var Registry = require('web.Registry'); var Registry = require('web.Registry');
var translation = require('web.translation'); var translation = require('web.translation');
/**
* Whether the client is currently in "debug" mode
*
* @type Boolean
*/
var debug = $.deparam($.param.querystring()).debug !== undefined; var debug = $.deparam($.param.querystring()).debug !== undefined;
var bus = new Bus (); var bus = new Bus ();
@@ -43,8 +48,11 @@ return {
one2many_view_registry: new Registry(), one2many_view_registry: new Registry(),
search_filters_registry: new Registry(), search_filters_registry: new Registry(),
search_widgets_registry: new Registry(), search_widgets_registry: new Registry(),
/**
* @type {String}
*/
csrf_token: odoo.csrf_token, csrf_token: odoo.csrf_token,
a_thing: 42,
}; };
}); });
@@ -161,19 +161,19 @@ var CrashManager = core.Class.extend({
}); });
/** /**
An interface to implement to handle exceptions. Register implementation in instance.web.crash_manager_registry. * An interface to implement to handle exceptions. Register implementation in instance.web.crash_manager_registry.
*/ */
var ExceptionHandler = { var ExceptionHandler = {
/** /**
@param parent The parent. * @param parent The parent.
@param error The error object as returned by the JSON-RPC implementation. * @param error The error object as returned by the JSON-RPC implementation.
*/ */
init: function(parent, error) {}, init: function(parent, error) {},
/** /**
Called to inform to display the widget, if necessary. A typical way would be to implement * Called to inform to display the widget, if necessary. A typical way would be to implement
this interface in a class extending instance.web.Dialog and simply display the dialog in this * this interface in a class extending instance.web.Dialog and simply display the dialog in this
method. * method.
*/ */
display: function() {}, display: function() {},
}; };
@@ -64,9 +64,11 @@ return core.Class.extend({
* Loads various information concerning views: fields_view for each view, * Loads various information concerning views: fields_view for each view,
* the fields of the corresponding model, and optionally the filters. * the fields of the corresponding model, and optionally the filters.
* *
* @param {Object} [dataset] the dataset for which the views are loaded * @param {Object} params
* @param {Array} [views_descr] array of [view_id, view_type] * @param {String} params.model
* @param {Object} [options] dictionnary of various options: * @param {Object} params.context
* @param {Array} params.views_descr array of [view_id, view_type]
* @param {Object} [options] dictionary of various options:
* - options.load_filters: whether or not to load the filters, * - options.load_filters: whether or not to load the filters,
* - options.action_id: the action_id (required to load filters), * - options.action_id: the action_id (required to load filters),
* - options.toolbar: whether or not a toolbar will be displayed, * - options.toolbar: whether or not a toolbar will be displayed,
@@ -9,6 +9,9 @@ odoo.define('web.AbstractRenderer', function (require) {
var Widget = require('web.Widget'); var Widget = require('web.Widget');
/**
* @class AbstractRenderer
*/
return Widget.extend({ return Widget.extend({
/** /**
* @constructor * @constructor
@@ -114,7 +114,7 @@ var BasicController = AbstractController.extend(FieldManagerMixin, {
/** /**
* Method that will be overriden by the views with the ability to have selected ids * Method that will be overriden by the views with the ability to have selected ids
* *
* @returns [] * @returns {Array}
*/ */
getSelectedIds: function () { getSelectedIds: function () {
return []; return [];
@@ -517,7 +517,7 @@ var BasicController = AbstractController.extend(FieldManagerMixin, {
* in readonly (e.g. Priority). * in readonly (e.g. Priority).
* *
* @private * @private
* @param {OdooEvent} * @param {OdooEvent} ev
*/ */
_onFieldChanged: function (ev) { _onFieldChanged: function (ev) {
if (this.mode === 'readonly') { if (this.mode === 'readonly') {
@@ -200,7 +200,7 @@ var BasicModel = AbstractModel.extend({
* *
* @param {string} id local resource id of a record * @param {string} id local resource id of a record
* @param {string} viewType the current viewType * @param {string} viewType the current viewType
* @returns {Deferred -> string} resolves to the id of the record * @returns {Deferred<string>} resolves to the id of the record
*/ */
applyRawChanges: function (recordID, viewType) { applyRawChanges: function (recordID, viewType) {
var record = this.localData[recordID]; var record = this.localData[recordID];
@@ -277,7 +277,7 @@ var BasicModel = AbstractModel.extend({
* Duplicate a record (by calling the 'copy' route) * Duplicate a record (by calling the 'copy' route)
* *
* @param {string} recordID id for a local resource * @param {string} recordID id for a local resource
* @returns {Deferred -> string} resolves to the id of duplicate record * @returns {Deferred<string>} resolves to the id of duplicate record
*/ */
duplicateRecord: function (recordID) { duplicateRecord: function (recordID) {
var self = this; var self = this;
@@ -544,7 +544,7 @@ var BasicModel = AbstractModel.extend({
* @param {Object} params.fields contains the description of each field * @param {Object} params.fields contains the description of each field
* @param {string} [params.type] 'record' or 'list' * @param {string} [params.type] 'record' or 'list'
* @param {string} [params.recordID] an ID for an existing resource. * @param {string} [params.recordID] an ID for an existing resource.
* @returns {Deferred -> string} resolves to a local id, or handle * @returns {Deferred<string>} resolves to a local id, or handle
*/ */
load: function (params) { load: function (params) {
params.type = params.type || (params.res_id !== undefined ? 'record' : 'list'); params.type = params.type || (params.res_id !== undefined ? 'record' : 'list');
@@ -694,7 +694,7 @@ var BasicModel = AbstractModel.extend({
* @param {Object} [options] * @param {Object} [options]
* @param {boolean} [options.keepChanges=false] if true, doesn't discard the * @param {boolean} [options.keepChanges=false] if true, doesn't discard the
* changes on the record before reloading it * changes on the record before reloading it
* @returns {Deferred -> string} resolves to the id of the resource * @returns {Deferred<string>} resolves to the id of the resource
*/ */
reload: function (id, options) { reload: function (id, options) {
options = options || {}; options = options || {};
@@ -784,7 +784,7 @@ var BasicModel = AbstractModel.extend({
* Resequences records. * Resequences records.
* *
* @param {string} modelName the resIDs model * @param {string} modelName the resIDs model
* @param {Array[integer]} resIDs the new sequence of ids * @param {Array<integer>} resIDs the new sequence of ids
* @param {string} parentID the localID of the parent * @param {string} parentID the localID of the parent
* @param {object} [options] * @param {object} [options]
* @param {integer} [options.offset] * @param {integer} [options.offset]
@@ -834,8 +834,7 @@ var BasicModel = AbstractModel.extend({
* - it needs to check all changes, * - it needs to check all changes,
* - generate commands for x2many fields, * - generate commands for x2many fields,
* - call the /create or /write method according to the record status * - call the /create or /write method according to the record status
* - After that, it has to reload all data, in case something changed, * - After that, it has to reload all data, in case something changed, server side.
* server side.
* *
* @param {string} record_id local resource * @param {string} record_id local resource
* @param {Object} [options] * @param {Object} [options]
@@ -1006,7 +1005,7 @@ var BasicModel = AbstractModel.extend({
* data * data
* *
* @param {string} groupId * @param {string} groupId
* @returns {Deferred -> string} resolves to the group id * @returns {Deferred<string>} resolves to the group id
*/ */
toggleGroup: function (groupId) { toggleGroup: function (groupId) {
var self = this; var self = this;
@@ -1048,7 +1047,7 @@ var BasicModel = AbstractModel.extend({
* @param {Object} [options] * @param {Object} [options]
* @param {string} [options.position=top] if the new record should be added * @param {string} [options.position=top] if the new record should be added
* on top or on bottom of the list * on top or on bottom of the list
* @returns {Deferred -> string} resolves to the new record id * @returns {Deferred<string>} resolves to the new record id
*/ */
_addX2ManyDefaultRecord: function (list, options) { _addX2ManyDefaultRecord: function (list, options) {
var self = this; var self = this;
@@ -1760,7 +1759,7 @@ var BasicModel = AbstractModel.extend({
* @param {string} [optinos.viewType] the type of view for which the record * @param {string} [optinos.viewType] the type of view for which the record
* is fetched (usefull to load the adequate fields), by defaults, uses * is fetched (usefull to load the adequate fields), by defaults, uses
* record.viewType * record.viewType
* @returns {Deferred -> Object} resolves to the record or is rejected in * @returns {Deferred<Object>} resolves to the record or is rejected in
* case no id given were valid ids * case no id given were valid ids
*/ */
_fetchRecord: function (record, options) { _fetchRecord: function (record, options) {
@@ -2221,7 +2220,7 @@ var BasicModel = AbstractModel.extend({
* Fetch all data in a ungrouped list * Fetch all data in a ungrouped list
* *
* @param {Object} list a valid resource object * @param {Object} list a valid resource object
* @returns {Deferred -> Object} resolves to the fecthed list * @returns {Deferred<Object>} resolves to the fecthed list
*/ */
_fetchUngroupedList: function (list) { _fetchUngroupedList: function (list) {
var self = this; var self = this;
@@ -3029,7 +3028,7 @@ var BasicModel = AbstractModel.extend({
* @param {Object} params.fields contains the description of each field * @param {Object} params.fields contains the description of each field
* @param {Object} params.context the context for the new record * @param {Object} params.context the context for the new record
* @param {string} params.viewType the key in fieldsInfo of the fields to load * @param {string} params.viewType the key in fieldsInfo of the fields to load
* @returns {Deferred -> string} resolves to the id for the created resource * @returns {Deferred<string>} resolves to the id for the created resource
*/ */
_makeDefaultRecord: function (modelName, params) { _makeDefaultRecord: function (modelName, params) {
var self = this; var self = this;
@@ -3318,7 +3317,7 @@ var BasicModel = AbstractModel.extend({
* *
* @param {Object} record * @param {Object} record
* @param {Object} record * @param {Object} record
* @returns {Deferred -> Object} resolves to the finished resource * @returns {Deferred<Object>} resolves to the finished resource
*/ */
_postprocess: function (record, options) { _postprocess: function (record, options) {
var self = this; var self = this;
@@ -3455,7 +3454,7 @@ var BasicModel = AbstractModel.extend({
* instead of a /search_read. * instead of a /search_read.
* *
* @param {Object} list a valid resource object * @param {Object} list a valid resource object
* @returns {Deferred -> Object} resolves to the fetched list object * @returns {Deferred<Object>} resolves to the fetched list object
*/ */
_readUngroupedList: function (list) { _readUngroupedList: function (list) {
var self = this; var self = this;
@@ -79,7 +79,7 @@ var FormRenderer = BasicRenderer.extend({
* Show a warning message if the user modified a translated field. For each * Show a warning message if the user modified a translated field. For each
* field, the notification provides a link to edit the field's translations. * field, the notification provides a link to edit the field's translations.
* *
* @param {Object[]} alertFields: field list * @param {Object[]} alertFields field list
*/ */
displayTranslationAlert: function (alertFields) { displayTranslationAlert: function (alertFields) {
this.$('.o_notification_box').remove(); this.$('.o_notification_box').remove();
@@ -99,7 +99,7 @@ var KanbanRecord = Widget.extend({
* Generates the color classname from a given variable * Generates the color classname from a given variable
* *
* @private * @private
* @param {number || string} variable * @param {number | string} variable
* @return {string} the classname * @return {string} the classname
*/ */
_getColorClassname: function (variable) { _getColorClassname: function (variable) {
@@ -110,7 +110,7 @@ var KanbanRecord = Widget.extend({
* Computes a color id between 0 and 10 from a given value * Computes a color id between 0 and 10 from a given value
* *
* @private * @private
* @param {number || string} variable * @param {number | string} variable
* @returns {integer} the color id * @returns {integer} the color id
*/ */
_getColorID: function (variable) { _getColorID: function (variable) {
@@ -1,13 +1,19 @@
odoo.define('web.StandaloneFieldManagerMixin', function (require) { odoo.define('web.StandaloneFieldManagerMixin', function (require) {
"use strict"; "use strict";
var FieldManagerMixin = require('web.FieldManagerMixin');
/** /**
* The StandaloneFieldManagerMixin is a mixin, designed to be used by a widget * The StandaloneFieldManagerMixin is a mixin, designed to be used by a widget
* that instanciates its own field widgets. * that instanciates its own field widgets.
*
* @mixin
* @name StandaloneFieldManagerMixin
* @mixes FieldManagerMixin
* @property {Function} _confirmChange
* @property {Function} _registerWidget
*/ */
var FieldManagerMixin = require('web.FieldManagerMixin');
var StandaloneFieldManagerMixin = _.extend({}, FieldManagerMixin, { var StandaloneFieldManagerMixin = _.extend({}, FieldManagerMixin, {
/** /**
@@ -104,7 +104,7 @@ var DateWidget = Widget.extend({
} }
}, },
/** /**
* @param {Moment|false} * @param {Moment|false} value
*/ */
setValue: function (value) { setValue: function (value) {
this.set({'value': value}); this.set({'value': value});
@@ -121,7 +121,7 @@ var DateWidget = Widget.extend({
/** /**
* @private * @private
* @param {Moment} * @param {Moment} v
* @returns {string} * @returns {string}
*/ */
_formatClient: function (v) { _formatClient: function (v) {
@@ -129,7 +129,7 @@ var DateWidget = Widget.extend({
}, },
/** /**
* @private * @private
* @param {string|false} * @param {string|false} v
* @returns {Moment} * @returns {Moment}
*/ */
_parseClient: function (v) { _parseClient: function (v) {
@@ -137,7 +137,7 @@ var DateWidget = Widget.extend({
}, },
/** /**
* @private * @private
* @param {boolean} * @param {boolean} readonly
*/ */
_setReadonly: function (readonly) { _setReadonly: function (readonly) {
this.readonly = readonly; this.readonly = readonly;
@@ -51,7 +51,6 @@ var DomainNode = Widget.extend({
"mouseleave button": "_onButtonLeft", "mouseleave button": "_onButtonLeft",
}, },
/** /**
* @constructor
* A DomainNode needs a model and domain to work. It can also receive a set * A DomainNode needs a model and domain to work. It can also receive a set
* of options. * of options.
* *
@@ -427,11 +426,12 @@ var DomainTree = DomainNode.extend({
* DomainTree specialization to use to have a fully working widget. * DomainTree specialization to use to have a fully working widget.
* *
* Known limitations: * Known limitations:
* - Some operators like "child_of", "parent_of", "like", "not like", *
* "=like", "=ilike" will come only if you use them from demo data or * - Some operators like "child_of", "parent_of", "like", "not like",
* debug input. * "=like", "=ilike" will come only if you use them from demo data or
* - Some kind of domain can not be build right now * debug input.
* e.g ("country_id", "in", [1,2,3]) but you can insert from debug input. * - Some kind of domain can not be build right now
* e.g ("country_id", "in", [1,2,3]) but you can insert from debug input.
*/ */
var DomainSelector = DomainTree.extend({ var DomainSelector = DomainTree.extend({
template: "DomainSelector", template: "DomainSelector",
@@ -7,6 +7,9 @@ var DomainSelector = require("web.DomainSelector");
var _t = core._t; var _t = core._t;
/**
* @class DomainSelectorDialog
*/
return Dialog.extend({ return Dialog.extend({
init: function (parent, model, domain, options) { init: function (parent, model, domain, options) {
this.model = model; this.model = model;
@@ -6,7 +6,8 @@ var Widget = require('web.Widget');
/** /**
* Generic widget to create an iframe that listens for clicks * Generic widget to create an iframe that listens for clicks
* *
* It should be extended by overwritting the methods: * It should be extended by overwriting the methods::
*
* init: function(parent) { * init: function(parent) {
* this._super(parent, <url_of_iframe>); * this._super(parent, <url_of_iframe>);
* }, * },
@@ -33,7 +33,8 @@ var SnippetEditor = Widget.extend({
/** /**
* @constructor * @constructor
* @param {Widget} parent * @param {Widget} parent
* @param {DOMElement} target * @param {Element} target
* @param templateOptions
*/ */
init: function (parent, target, templateOptions) { init: function (parent, target, templateOptions) {
this._super.apply(this, arguments); this._super.apply(this, arguments);
@@ -640,7 +641,7 @@ var SnippetsMenu = Widget.extend({
* @private * @private
* @param {jQuery} [$selectorSiblings] * @param {jQuery} [$selectorSiblings]
* elements which must have siblings drop zones * elements which must have siblings drop zones
* @param {jQuery} [$selectorSiblings] * @param {jQuery} [$selectorChildren]
* elements which must have child drop zones between each of existing * elements which must have child drop zones between each of existing
* child * child
*/ */
@@ -790,7 +790,7 @@ var ViewEditor = Widget.extend({
* is toggled -> reloads the resources accordingly. * is toggled -> reloads the resources accordingly.
* *
* @private * @private
* @param {Event} * @param {Event} ev
*/ */
_onIncludeAllLessChange: function (ev) { _onIncludeAllLessChange: function (ev) {
this.options.includeAllLess = $(ev.target).prop('checked'); this.options.includeAllLess = $(ev.target).prop('checked');
@@ -801,7 +801,7 @@ var ViewEditor = Widget.extend({
* included is toggled -> reloads the resources accordingly. * included is toggled -> reloads the resources accordingly.
* *
* @private * @private
* @param {Event} * @param {Event} ev
*/ */
_onIncludeBundlesChange: function (ev) { _onIncludeBundlesChange: function (ev) {
this.options.includeBundles = $(ev.target).prop('checked'); this.options.includeBundles = $(ev.target).prop('checked');
@@ -391,11 +391,15 @@ var ImageDialog = Widget.extend({
}, },
}); });
/* list of font icons to load by editor. The icons are displayed in the media editor and /**
* list of font icons to load by editor. The icons are displayed in the media editor and
* identified like font and image (can be colored, spinned, resized with fa classes). * identified like font and image (can be colored, spinned, resized with fa classes).
* To add font, push a new object {base, parser} * To add font, push a new object {base, parser}
*
* - base: class who appear on all fonts (eg: fa fa-refresh) * - base: class who appear on all fonts (eg: fa fa-refresh)
* - parser: regular expression used to select all font in css style sheets * - parser: regular expression used to select all font in css style sheets
*
* @type Array
*/ */
var fontIcons = [{'base': 'fa', 'parser': /(?=^|\s)(\.fa-[0-9a-z_-]+::?before)/i}]; var fontIcons = [{'base': 'fa', 'parser': /(?=^|\s)(\.fa-[0-9a-z_-]+::?before)/i}];
@@ -6,21 +6,20 @@ var field_registry = require('web.field_registry');
var utils = require('web.utils'); var utils = require('web.utils');
/** /**
* Field widget: GaugeWidget
* options * options
*
* - max_value: maximum value of the gauge [default: 100] * - max_value: maximum value of the gauge [default: 100]
* - max_field: get the max_value from the field that must be present in the * - max_field: get the max_value from the field that must be present in the
* view; takes over max_value * view; takes over max_value
* - gauge_value_field: if set, the value displayed below the gauge is taken * - gauge_value_field: if set, the value displayed below the gauge is taken
from this field instead of the base field used for * from this field instead of the base field used for
the gauge. This allows to display a number different * the gauge. This allows to display a number different
from the gauge. * from the gauge.
* - label: lable of the gauge, displayed below the gauge value * - label: lable of the gauge, displayed below the gauge value
* - label_field: get the label from the field that must be present in the * - label_field: get the label from the field that must be present in the
view; takes over label * view; takes over label
* - title: title of the gauge, displayed on top of the gauge * - title: title of the gauge, displayed on top of the gauge
* - style: custom style * - style: custom style
*
*/ */
var GaugeWidget = AbstractField.extend({ var GaugeWidget = AbstractField.extend({
+3 -2
View File
@@ -11,7 +11,8 @@ var Tip = Widget.extend({
mouseleave: "_to_bubble_mode", mouseleave: "_to_bubble_mode",
}, },
/** /**
* @param {info} [Object] description of the tip, containing the following keys: * @param {Widget} parent
* @param {Object} [info] description of the tip, containing the following keys:
* - content [String] the html content of the tip * - content [String] the html content of the tip
* - event_handlers [Object] description of optional event handlers to bind to the tip: * - event_handlers [Object] description of optional event handlers to bind to the tip:
* - event [String] the event name * - event [String] the event name
@@ -40,7 +41,7 @@ var Tip = Widget.extend({
}; };
}, },
/** /**
* @param {$anchor} [JQuery] the node on which the tip should be placed * @param {jQuery} $anchor the node on which the tip should be placed
*/ */
attach_to: function ($anchor) { attach_to: function ($anchor) {
this.$anchor = $anchor; this.$anchor = $anchor;
@@ -23,6 +23,16 @@ var CallService = Class.extend(mixins.EventDispatcherMixin, mixins.ServiceProvid
}, },
}); });
/**
* @namespace
* @property {Object} active_tooltips
* @property {Object} tours
* @property {Array} consumed_tours
* @property {String} running_tour
* @property {Number} running_step_delay
* @property {'community' | 'enterprise'} edition
* @property {Array} _log
*/
return session.is_bound.then(function () { return session.is_bound.then(function () {
var defs = []; var defs = [];
// Load the list of consumed tours and the tip template only if we are admin, in the frontend, // Load the list of consumed tours and the tip template only if we are admin, in the frontend,
@@ -61,6 +61,9 @@ var Dashboard = Widget.extend(ControlPanelMixin, {
}); });
}, },
/**
* Fetches dashboard data
*/
fetch_data: function() { fetch_data: function() {
var self = this; var self = this;
return this._rpc({ return this._rpc({
@@ -87,7 +87,7 @@ odoo.define('website_rating.thread', function(require) {
/** /**
* Update the messages format * Update the messages format
* *
* @param {Array<Object>} * @param {Array<Object>} messages
* @returns {Array} * @returns {Array}
*/ */
preprocessMessages: function(messages){ preprocessMessages: function(messages){
@@ -102,17 +102,20 @@ odoo.define('website_rating.thread', function(require) {
}, },
/** /**
* Round the given value with a precision of 0.5. * Round the given value with a precision of 0.5.
* Example : 1.2 --> 1.0 *
* 1.7 --> 1.5 * Examples:
* 1.9 --> 2.0 * - 1.2 --> 1.0
* @param Float * - 1.7 --> 1.5
* @returns Float * - 1.9 --> 2.0
*
* @param {Number} value
* @returns Number
**/ **/
round_to_half: function(value) { round_to_half: function(value) {
var converted = parseFloat(value); // Make sure we have a number var converted = parseFloat(value); // Make sure we have a number
var decimal = (converted - parseInt(converted, 10)); var decimal = (converted - parseInt(converted, 10));
decimal = Math.round(decimal * 10); decimal = Math.round(decimal * 10);
if(decimal == 5){ if(decimal === 5){
return (parseInt(converted, 10)+0.5); return (parseInt(converted, 10)+0.5);
} }
if((decimal < 3) || (decimal > 7)){ if((decimal < 3) || (decimal > 7)){
@@ -1,26 +0,0 @@
odoo.define('website_sale.rating', function (require) {
"use strict";
var core = require('web.core');
var ajax = require('web.ajax');
var rating = require('rating.rating');
var WebsiteMailThread = require('website_mail.thread');
var qweb = core.qweb;
ajax.loadXML('/rating/static/src/xml/rating_common.xml', qweb);
WebsiteMailThread.include({
prepend_message: function(message_data){
var $elem = this._super.call(this, message_data);
if(message_data['rating_default_value']){
var rating_star = new rating.RatingStarWidget(this, {
'rating_default_value': message_data['rating_default_value'],
'rating_disabled': message_data['rating_disabled'],
});
rating_star.appendTo($elem.find('h5'));
this.$('.stars i').mouseout();
}
},
});
});