[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
* @returns {Deferred -> Object} resolves to the required dashboard data
* @returns {Deferred<Object>} resolves to the required dashboard data
*/
_fetchDashboardData: function () {
return $.when(this._rpc({
@@ -136,7 +136,7 @@ var AccountSetupBarModel = KanbanModel.extend({
/**
* @private
* @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) {
var self = this;
@@ -12,7 +12,7 @@ var _t = core._t;
* Model use to fetch, format and update 'account.bank.statement' and
* 'account.bank.statement.line' datas allowing reconciliation
*
* The statement internal structure:
* The statement internal structure::
*
* {
* valuenow: integer
@@ -25,7 +25,7 @@ var _t = core._t;
* accounts: {id: code}
* }
*
* The internal structure of each line is:
* The internal structure of each line is::
*
* {
* balance: {
@@ -114,7 +114,7 @@ var StatementModel = BasicModel.extend({
* account type
*
* @param {string} handle
* @param {number} mv_lines id
* @param {number} mv_line_id
* @returns {Deferred}
*/
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
* matched lines or prepare to create a new line
*
* 'match': display the matched lines, the user can select the lines to
* apply there as proposition
* 'create': display fields and quick create button to create a new
* proposition for the reconciliation
* ``match``
* display the matched lines, the user can select the lines to apply
* there as proposition
* ``create``
* display fields and quick create button to create a new proposition
* for the reconciliation
*
* @param {string} handle
* @param {string} mode
* @param {'inactive' | 'match' | 'create'} mode
* @returns {Deferred}
*/
changeMode: function (handle, mode) {
@@ -316,7 +318,7 @@ var StatementModel = BasicModel.extend({
/**
* get the line data for this handle
*
* @param {OdooEvent} event
* @param {Object} handle
* @returns {Object}
*/
getLine: function (handle) {
@@ -324,6 +326,7 @@ var StatementModel = BasicModel.extend({
},
/**
* load data from
*
* - 'account.bank.statement' fetch the line id and bank_statement_id info
* - 'account.reconcile.model' fetch all reconcile model (for quick add)
* - 'account.account' fetch all account code
@@ -430,7 +433,7 @@ var StatementModel = BasicModel.extend({
* 'amount_type'
*
* @param {string} handle
* @param {integer} reconcile model id
* @param {integer} reconcileModelId
* @returns {Deferred}
*/
quickCreateProposition: function (handle, reconcileModelId) {
@@ -460,7 +463,7 @@ var StatementModel = BasicModel.extend({
* Remove a proposition and switch to an active mode ('create' or 'match')
*
* @param {string} handle
* @param {number} proposition id (move line id)
* @param {number} id (move line id)
* @returns {Deferred}
*/
removeProposition: function (handle, id) {
@@ -519,7 +522,7 @@ var StatementModel = BasicModel.extend({
* Then the total is recomputed to have 100%.
*
* @param {string} handle
* @param {number[]} context.statement_ids
* @param {*} values
* @returns {Deferred}
*/
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
* compute the line
*
* @see '_computeLine'
* See :func:`_computeLine`
*
* @private
* @param {string} handle
@@ -679,7 +682,7 @@ var StatementModel = BasicModel.extend({
* Check the taxes server side for each updated propositions with tax_id
*
* @private
* @param {Object}
* @param {Object} line
* @returns {Deferred}
*/
_computeLine: function (line) {
@@ -771,7 +774,7 @@ var StatementModel = BasicModel.extend({
*
* @private
* @param {string} handle
* @param {integer} reconcile model id
* @param {integer} reconcileModelId
*/
_computeReconcileModels: function (handle, reconcileModelId) {
var line = this.getLine(handle);
@@ -788,8 +791,7 @@ var StatementModel = BasicModel.extend({
* format a name_get into an object {id, display_name}, idempotent
*
* @private
* @param {Object|Array} data or name_get
* @param {Object|false} {id, display_name}
* @param {Object|Array} [value] data or name_get
*/
_formatNameGet: function (value) {
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)
*
* @private
* @param {Object}
* @param {Object[]}
* @param {Object} line
* @param {Object[]} props
*/
_formatLineProposition: function (line, props) {
var self = this;
@@ -818,7 +820,7 @@ var StatementModel = BasicModel.extend({
* @see '_computeLine'
*
* @private
* @param {Object[]}
* @param {Object[]} lines
* @returns {Deferred}
*/
_formatLine: function (lines) {
@@ -845,7 +847,7 @@ var StatementModel = BasicModel.extend({
*
* @private
* @param {string} handle
* @param {Object[]}
* @param {Object[]} mv_lines
* @returns {Deferred}
*/
_formatMoveLine: function (handle, mv_lines) {
@@ -869,8 +871,8 @@ var StatementModel = BasicModel.extend({
* base_amount with the decimal number from the currency
*
* @private
* @param {Object}
* @param {Object}
* @param {Object} line
* @param {Object} values
* @returns {Object}
*/
_formatQuickCreate: function (line, values) {
@@ -980,7 +982,7 @@ var StatementModel = BasicModel.extend({
*
* @private
* @param {object} line
* @param {object} proposition
* @param {object} prop
* @returns {object}
*/
_formatToProcessReconciliation: function (line, prop) {
@@ -1216,7 +1218,7 @@ var ManualModel = StatementModel.extend({
*
* @override
* @private
* @param {Object}
* @param {Object} line
* @returns {Deferred}
*/
_computeLine: function (line) {
@@ -1237,8 +1239,8 @@ var ManualModel = StatementModel.extend({
* @see '_computeLine'
*
* @private
* @param {string} 'customers', 'suppliers' or 'accounts'
* @param {Object}
* @param {'customers' | 'suppliers' | 'accounts'} type
* @param {Object} data
* @returns {Deferred}
*/
_formatLine: function (type, data) {
@@ -1264,8 +1266,8 @@ var ManualModel = StatementModel.extend({
*
* @override
* @private
* @param {Object}
* @param {Object}
* @param {Object} line
* @param {Object} props
*/
_formatLineProposition: function (line, props) {
var self = this;
@@ -1330,4 +1332,4 @@ return {
StatementModel: StatementModel,
ManualModel: ManualModel,
};
});
});
@@ -182,9 +182,12 @@ var BarcodeEvents = core.Class.extend(mixins.PropertiesMixin, {
});
return {
// Singleton that emits barcode_scanned events on core.bus
/** Singleton that emits barcode_scanned events on core.bus */
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'],
};
+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
* is signaling through the localStorage too.
*
* localStorage used keys are :
* - bus.channels : shared public channel list to listen during the poll
* - bus.options : shared options
* - bus.notification : the received notifications from the last poll
* - bus.tab_list : list of opened tab ids
* - bus.tab_master : generated id of the master tab
* localStorage used keys are:
*
* - bus.channels : shared public channel list to listen during the poll
* - bus.options : shared options
* - bus.notification : the received notifications from the last poll
* - bus.tab_list : list of opened tab ids
* - bus.tab_master : generated id of the master tab
*/
var CrossTabBus = bus.Bus.extend({
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
* @param {Array} list of activity Object
* @param {Array} activities list of activity Object
* @return {Array} : list of modified activity Object
*/
var setDelayLabel = function(activities){
@@ -89,7 +89,7 @@ var ChatterComposer = composer.BasicComposer.extend({
/**
* 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 () {
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
* for the ones who informations is missing.
* @param Array : list of 'recipient' partners to complete informations or validate
* @returns Deferred resolved with the list of checked suggested partners (real partner)
* @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)
**/
check_suggested_partners: function (checked_suggested_partners) {
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.
*
* @override
* @param {Array[Object]} attachments list of attachments
* @param {Array<Object>} attachments list of attachments
* @param {integer} 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
* All element nodes with "data-o-mail-quote" attribute are concerned.
* All text nodes after a ""#stopSpelling" element are concerned.
* Those text nodes need to be wrapped in a span (toggle functionality).
* All consecutive elements are joined in one 'read more/read less'.
* Modifies $element to add the 'read more/read less' functionality
* All element nodes with "data-o-mail-quote" attribute are concerned.
* All text nodes after a ``#stopSpelling`` element are concerned.
* Those text nodes need to be wrapped in a span (toggle functionality).
* All consecutive elements are joined in one 'read more/read less'.
*/
insert_read_more: function ($element) {
var self = this;
@@ -18,7 +18,6 @@ var _t = core._t;
var Mutex = concurrency.Mutex;
var round_di = utils.round_decimals;
var round_pr = utils.round_precision;
var Backbone = window.Backbone;
var exports = {};
+16 -14
View File
@@ -135,21 +135,23 @@ var ConfirmPopupWidget = PopupWidget.extend({
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',{
* title: "Popup Title",
* list: [
* { label: 'foobar', item: 45 },
* { label: 'bar foo', item: 'stuff' },
* ],
* confirm: function(item) {
* // get the item selected by the user.
* },
* cancel: function(){
* // user chose nothing
* }
* });
* Example::
*
* show_popup('selection',{
* title: "Popup Title",
* list: [
* { label: 'foobar', item: 45 },
* { label: 'bar foo', item: 'stuff' },
* ],
* confirm: function(item) {
* // get the item selected by the user.
* },
* cancel: function(){
* // user chose nothing
* }
* });
*/
var SelectionPopupWidget = PopupWidget.extend({
@@ -76,7 +76,7 @@ var PortalChatter = Widget.extend({
* Fetch the messages and the message count from the server for the
* current page and current domain.
*
* @param {Array}
* @param {Array} domain
* @returns {Deferred}
*/
messageFetch: function(domain){
@@ -101,7 +101,7 @@ var PlanAction = Widget.extend(ControlPanelMixin, {
//--------------------------------------------------------------------------
/**
* Refresh the DOM html
* @param {string|html}
* @param {string|html} dom
* @private
*/
_refreshPlan: function(dom){
@@ -733,6 +733,7 @@ var data = {
DataSet: DataSet,
DataSetStatic: DataSetStatic,
DataSetSearch: DataSetSearch,
/** @type String */
noDisplayContent: "<em class=\"text-warning\">" + _t("Unnamed") + "</em>",
};
@@ -206,16 +206,17 @@ var AbstractWebClient = Widget.extend(mixins.ServiceProvider, {
// 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) {
this.set_title_part("action", title);
},
/**
Sets an arbitrary part of the title of the window. Title parts are identified by strings. Each time
a title part is changed, all parts are gathered, ordered by alphabetical order and displayed in the
title of the window separated by '-'.
*/
* Sets an arbitrary part of the title of the window. Title parts are
* identified by strings. Each time a title part is changed, all parts
* are gathered, ordered by alphabetical order and displayed in the title
* of the window separated by ``-``.
*/
set_title_part: function (part, title) {
var tmp = _.clone(this.get("title_part"));
tmp[part] = title;
@@ -67,7 +67,7 @@ var Action = core.Class.extend({
},
/**
* Stores the DOM fragment of the action
* @param {jQuery} [fragment] the DOM fragment
* @param {jQuery} [$fragment] the DOM fragment
*/
set_fragment: function($fragment) {
this.$fragment = $fragment;
@@ -300,11 +300,11 @@ var ActionManager = Widget.extend({
/**
* Add a new action to the action manager
*
* widget: typically, widgets added are openerp.web.ViewManager. The action manager
* uses the stack of actions to handle the breadcrumbs.
* action_descr: new action description
* options.on_reverse_breadcrumb: will be called when breadcrumb is clicked on
* options.clear_breadcrumbs: boolean, if true, action stack is destroyed
* @param {Widget} widget typically, widgets added are openerp.web.ViewManager. The action manager uses the stack of actions to handle the breadcrumbs.
* @param {Object} action_descr new action description
* @param {Object} options
* @param options.on_reverse_breadcrumb will be called when breadcrumb is clicked on
* @param options.clear_breadcrumbs: boolean, if true, action stack is destroyed
*/
push_action: function(widget, action_descr, options) {
var self = this;
@@ -613,7 +613,7 @@ var ActionManager = Widget.extend({
/**
* 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 {Boolean} [options.clear_breadcrumbs=false] Clear the breadcrumbs history list
* @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) {
this._super(parent);
this.field = field;
@@ -153,7 +153,7 @@ ExtendedSearchProposition.Field = Widget.extend({
}
});
ExtendedSearchProposition.Char = ExtendedSearchProposition.Field.extend({
var Char = Field.extend({
tagName: 'input',
className: 'o_input',
attributes: {
@@ -172,7 +172,7 @@ ExtendedSearchProposition.Char = ExtendedSearchProposition.Field.extend({
}
});
ExtendedSearchProposition.DateTime = ExtendedSearchProposition.Field.extend({
var DateTime = Field.extend({
tagName: 'span',
attributes: {
type: 'datetime'
@@ -241,7 +241,7 @@ ExtendedSearchProposition.DateTime = ExtendedSearchProposition.Field.extend({
},
});
ExtendedSearchProposition.Date = ExtendedSearchProposition.DateTime.extend({
var Date = DateTime.extend({
attributes: {
type: 'date'
},
@@ -250,7 +250,7 @@ ExtendedSearchProposition.Date = ExtendedSearchProposition.DateTime.extend({
},
});
ExtendedSearchProposition.Integer = ExtendedSearchProposition.Field.extend({
var Integer = Field.extend({
tagName: 'input',
className: 'o_input',
attributes: {
@@ -280,11 +280,11 @@ ExtendedSearchProposition.Integer = ExtendedSearchProposition.Field.extend({
}
});
ExtendedSearchProposition.Id = ExtendedSearchProposition.Integer.extend({
var Id = Integer.extend({
operators: [{value: "=", text: _lt("is")}]
});
ExtendedSearchProposition.Float = ExtendedSearchProposition.Field.extend({
var Float = Field.extend({
template: 'SearchView.extended_search.proposition.float',
operators: [
{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',
operators: [
{value: "=", text: _lt("is")},
@@ -331,7 +331,7 @@ ExtendedSearchProposition.Selection = ExtendedSearchProposition.Field.extend({
}
});
ExtendedSearchProposition.Boolean = ExtendedSearchProposition.Field.extend({
var Boolean = Field.extend({
tagName: 'span',
operators: [
{value: "=", text: _lt("is true")},
@@ -347,19 +347,19 @@ ExtendedSearchProposition.Boolean = ExtendedSearchProposition.Field.extend({
});
core.search_filters_registry
.add('char', ExtendedSearchProposition.Char)
.add('text', ExtendedSearchProposition.Char)
.add('one2many', ExtendedSearchProposition.Char)
.add('many2one', ExtendedSearchProposition.Char)
.add('many2many', ExtendedSearchProposition.Char)
.add('datetime', ExtendedSearchProposition.DateTime)
.add('date', ExtendedSearchProposition.Date)
.add('integer', ExtendedSearchProposition.Integer)
.add('float', ExtendedSearchProposition.Float)
.add('monetary', ExtendedSearchProposition.Float)
.add('boolean', ExtendedSearchProposition.Boolean)
.add('selection', ExtendedSearchProposition.Selection)
.add('id', ExtendedSearchProposition.Id);
.add('char', Char)
.add('text', Char)
.add('one2many', Char)
.add('many2one', Char)
.add('many2many', Char)
.add('datetime', DateTime)
.add('date', Date)
.add('integer', Integer)
.add('float', Float)
.add('monetary', Float)
.add('boolean', Boolean)
.add('selection', Selection)
.add('id', Id);
return {
ExtendedSearchProposition: ExtendedSearchProposition
@@ -265,7 +265,7 @@ var SearchView = Widget.extend({
*
* @param parent
* @param dataset
* @param fields_view
* @param fvg
* @param {Object} [options]
* @param {Boolean} [options.hidden=false] hide the search view
* @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();
},
/**
* @param {openerp.web.search.SearchQuery | undefined} Undefined if event is change
* @param {openerp.web.search.Facet}
* @param {openerp.web.search.SearchQuery | undefined} collection Undefined if event is change
* @param {openerp.web.search.Facet} model
* @param {Object} [options]
*/
renderFacets: function (collection, model, options) {
@@ -232,8 +232,9 @@ var ViewManager = Widget.extend(ControlPanelMixin, {
},
/**
* 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
*/
+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 {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.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) {
// 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
*
* @class Bus
*/
return Class.extend(mixins.EventDispatcherMixin, {
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
* the extend() method.
*
* Example:
* Example::
*
* var Person = Class.extend({
* init: function(isDancing){
* this.dancing = isDancing;
* },
* dance: function(){
* return this.dancing;
* }
* });
* var Person = Class.extend({
* init: function(isDancing){
* this.dancing = isDancing;
* },
* dance: function(){
* 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);
* person.dance();
* var person = new Person(true);
* person.dance();
*
* The Person class can also be extended again:
* The Person class can also be extended again:
*
* var Ninja = Person.extend({
* init: function(){
* this._super( false );
* },
* dance: function(){
* // Call the inherited version of dance()
* return this._super();
* },
* swingSword: function(){
* return true;
* }
* });
* var Ninja = Person.extend({
* init: function(){
* this._super( false );
* },
* dance: function(){
* // Call the inherited version of dance()
* return this._super();
* },
* swingSword: function(){
* return true;
* }
* });
*
* When extending a class, each re-defined method can use this._super() to call the previous
* implementation of that method.
*
* @class Class
*/
function OdooClass(){}
var initializing = false;
var fnTest = /xyz/.test(function(){xyz();}) ? /\b_super\b/ : /.*/;
// The web Class implementation (does nothing)
function OdooClass(){};
/**
* Subclass an existing class
*
+8 -7
View File
@@ -122,7 +122,7 @@ return {
* the last operation.
*
* 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) {
* self.state = result;
@@ -130,17 +130,18 @@ return {
* });
*
* Now, we have at least two problems:
*
* - 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
* not what we expect
* - 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();
*
* Then we can wrap the _fetch in a DropPrevious and have the expected
* result:
* result::
*
* this.dropPrevious
* .add(this._fetch())
@@ -153,7 +154,7 @@ return {
/**
* Registers a new deferred and rejects the previous one
*
* @param {Deferred} the new deferred
* @param {Deferred} deferred the new deferred
* @returns {Promise}
*/
add: function (deferred) {
@@ -171,7 +172,7 @@ return {
*
* 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
* looking like this:
* looking like this::
*
* return this._load().then(function (result) {
* this.state = result;
@@ -179,11 +180,11 @@ return {
*
* 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
* _load. However, if we have a mutex:
* _load. However, if we have a 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._load().then(function (result) {
+7 -7
View File
@@ -9,17 +9,17 @@ var QWeb = core.qweb;
var _t = core._t;
/**
A useful class to handle dialogs.
Attributes:
- $footer: A jQuery element targeting a dom part where buttons can be added. It always exists
during the lifecycle of the dialog.
*/
* A useful class to handle dialogs.
* Attributes:
*
* ``$footer``
* 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({
xmlDependencies: ['/web/static/src/xml/dialog.xml'],
/**
* @constructor
* @param {Widget} parent
* @param {Object} [options]
* @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')
* 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')
*
* This is what this function does.
*
* @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.
* When an object is destroyed, all its children are destroyed too releasing
* any resource they could have reserved before.
*
* @name ParentedMixin
* @mixin
*/
var ParentedMixin = {
__parentedMixin : true,
@@ -57,21 +60,21 @@ var ParentedMixin = {
return this.__parentedDestroyed;
},
/**
Utility method to only execute asynchronous actions if the current
object has not been destroyed.
@param {$.Deferred} promise The promise representing the asynchronous
action.
@param {bool} [reject=false] If true, the returned promise will be
rejected with no arguments if the current
object is destroyed. If false, the
returned promise will never be resolved
or rejected.
@returns {$.Deferred} A promise that will mirror the given promise if
everything goes fine but will either be rejected
with no arguments or never resolved if the
current object is destroyed.
*/
* Utility method to only execute asynchronous actions if the current
* object has not been destroyed.
*
* @param {$.Deferred} promise The promise representing the asynchronous
* action.
* @param {bool} [reject=false] If true, the returned promise will be
* rejected with no arguments if the current
* object is destroyed. If false, the
* returned promise will never be resolved
* or rejected.
* @returns {$.Deferred} A promise that will mirror the given promise if
* everything goes fine but will either be rejected
* with no arguments or never resolved if the
* current object is destroyed.
*/
alive: function (promise, reject) {
var self = this;
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
(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
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
and phantom events (events which are raised and sent to a previously destroyed 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
* 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
* 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).
*
* @name EventDispatcherMixin
* @mixin
*/
var EventDispatcherMixin = _.extend({}, ParentedMixin, {
__eventDispatcherMixin: true,
custom_events: {},
@@ -349,6 +355,10 @@ var EventDispatcherMixin = _.extend({}, ParentedMixin, {
}
});
/**
* @name PropertiesMixin
* @mixin
*/
var PropertiesMixin = _.extend({}, EventDispatcherMixin, {
init: function () {
EventDispatcherMixin.init.call(this);
@@ -432,6 +442,10 @@ odoo.define('web.ServicesMixin', function (require) {
var rpc = require('web.rpc');
/**
* @mixin
* @name ServicesMixin
*/
var ServicesMixin = {
call: function (service, method) {
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
* the RPC result.
*
* @param {string} arg1 either a route or a model
* @param {string} method if a model is given, this argument is a method
* @returns {Deferred's Promise}
* @param {string} params either a route or a model
* @param {string} options if a model is given, this argument is a method
* @returns {Promise}
*/
_rpc: function (params, options) {
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
compared to the date of the server).
@return {datetime.date}
*/
* Returns the current local date, which means the date on the client (which can be different
* compared to the date of the server).
*
* @return {datetime.date}
*/
function context_today() {
var d = new Date();
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 {Object} params call parameters
* @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
*/
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
* 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}
*/
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();
/**
* Lazy translation function, only performs the translation when actually
+6 -6
View File
@@ -107,7 +107,7 @@ var utils = {
/**
* Returns a human readable size
*
* @param {Number} number of bytes
* @param {Number} size number of bytes
*/
human_size: function (size) {
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
* See the corresponding float_round() in server/tools/float_utils.py for more info
* @param {Number} the value to be rounded
* @param {Number} the number of decimals. eg: round_decimals(3.141592,2) -> 3.14
* @param {Number} value the value to be rounded
* @param {Number} decimals the number of decimals. eg: round_decimals(3.141592,2) -> 3.14
*/
round_decimals: function (value, decimals) {
return utils.round_precision(value, Math.pow(10,-decimals));
@@ -319,9 +319,9 @@ var utils = {
},
/**
* Create a cookie
* @param {String} name : the name of 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 {String} name the name of 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.
*/
set_cookie: function (name, value, ttl) {
ttl = ttl || 24*60*60*365;
+34 -34
View File
@@ -7,50 +7,51 @@ var mixins = require('web.mixins');
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.
*
* Widget handles:
*
* - Rendering with QWeb.
* - Life-cycle management and parenting (when a parent is destroyed, all its children are
* destroyed too).
* - Life-cycle management and parenting (when a parent is destroyed, all its
* children are destroyed too).
* - 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({
* // the name of the QWeb template to use for rendering
* template: "MyQWebTemplate",
* var MyWidget = openerp.base.Widget.extend({
* // the name of the QWeb template to use for rendering
* template: "MyQWebTemplate",
*
* init: function(parent) {
* this._super(parent);
* // stuff that you want to init before the rendering
* },
* start: function() {
* // stuff you want to make after the rendering, `this.$el` holds a correct value
* this.$(".my_button").click(/* an example of event binding * /);
* init: function(parent) {
* this._super(parent);
* // stuff that you want to init before the rendering
* },
* start: function() {
* // stuff you want to make after the rendering, `this.$el` holds a correct value
* this.$(".my_button").click(/* an example of event binding * /);
*
* // if you have some asynchronous operations, it's a good idea to return
* // a promise in start()
* var promise = this._rpc(...);
* return promise;
* }
* });
* // if you have some asynchronous operations, it's a good idea to return
* // a promise in start()
* var promise = this._rpc(...);
* 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);
* my_widget.appendTo($(".some-div"));
* var my_widget = new MyWidget(this);
* my_widget.appendTo($(".some-div"));
*
* With these two lines, the MyWidget instance was inited, rendered, it was inserted into the
* DOM inside the ".some-div" div and its events were binded.
* With these two lines, the MyWidget instance was initialized, rendered,
* 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.
*/
@@ -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
* redefined in subclasses or the default render() method can not be used.
*
* @type string
* @type {String}
*/
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 openerp.Widget
*
* @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
* 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.
*
* @param {HTMLElement | jQuery} $el
* @returns {*} this
* @returns {Widget} this
*/
replaceElement: function ($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).
*
* Includes:
*
* * re-delegating events
* * re-binding sub-elements
* * if the widget already had a root element, replacing the pre-existing
* element in the DOM
*
* @param {HTMLElement | jQuery} element new root element for the widget
* @return {*} this
* @return {Widget} this
*/
setElement: function (element) {
// NB: completely useless, as WidgetMixin#init creates a $el
@@ -59,6 +59,8 @@ var AbstractField = Widget.extend({
specialData: false,
/**
* to override to indicate which field types are supported by the widget
*
* @type Array<String>
*/
supportedFieldTypes: [],
@@ -196,7 +198,7 @@ var AbstractField = Widget.extend({
* will have the cursor at the very end.
*
* @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
* @param {Event} [options.event] the event which fired this activation
* @returns {boolean} true if the widget was activated, false if the
@@ -1741,10 +1741,9 @@ var FieldPercentPie = AbstractField.extend({
});
/**
* FieldProgressBar
* parameters
* - title: title of the bar, displayed on top of the bar
* options
* Node options:
*
* - title: title of the bar, displayed on top of the bar options
* - editable: boolean if value is editable
* - 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
@@ -80,7 +80,7 @@ function formatChar(value, field, options) {
* 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
*
* @param {Moment|false}
* @param {Moment|false} value
* @param {Object} [field]
* a description of the field (note: this parameter is ignored)
* @param {Object} [options] additional options
@@ -258,7 +258,7 @@ function formatX2Many(value) {
* @param {Object} [options]
* additional options to override the values in the python description of
* 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]
* the id of the 'res.currency' to use (ignored if options.currency)
* @param {string} [options.currency_field]
@@ -336,7 +336,7 @@ function formatSelection(value, field, options) {
* Create an Date object
* The method toJSON return the formated value to send value server side
*
* @param {string}
* @param {string} value
* @param {Object} [field]
* a description of the field (note: this parameter is ignored)
* @param {Object} [options] additional options
@@ -375,7 +375,7 @@ function parseDate(value, field, options) {
* Create an Date object
* The method toJSON return the formated value to send value server side
*
* @param {string}
* @param {string} value
* @param {Object} [field]
* a description of the field (note: this parameter is ignored)
* @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
* 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
* the time difference between UTC time and local time, in minutes.
* 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.
* 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.
*/
var FieldTimezoneMismatch = FieldSelection.extend({
/**
@@ -112,7 +112,7 @@ var AbstractFieldUpgrade = {
/**
* @private
* @param {MouseEvent}
* @param {MouseEvent} event
*/
_onInputClicked: function (event) {
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
* in the url
*
* @type Boolean
*/
debug: ($.deparam($.param.querystring()).debug !== undefined),
device: {
/**
* touch is a boolean, true if the device supports touch interaction
*
* @type Boolean
*/
touch: 'ontouchstart' in window || 'onmsgesturechange' in window,
/**
* 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
* browser is resized
*
* @type Number
*/
size_class: null,
/**
* 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
* the size is not 3. It is also updated dynamically.
*
* @type Boolean
*/
isMobile: null,
/**
+9 -1
View File
@@ -7,6 +7,11 @@ var QWeb = require('web.QWeb');
var Registry = require('web.Registry');
var translation = require('web.translation');
/**
* Whether the client is currently in "debug" mode
*
* @type Boolean
*/
var debug = $.deparam($.param.querystring()).debug !== undefined;
var bus = new Bus ();
@@ -43,8 +48,11 @@ return {
one2many_view_registry: new Registry(),
search_filters_registry: new Registry(),
search_widgets_registry: new Registry(),
/**
* @type {String}
*/
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 = {
/**
@param parent The parent.
@param error The error object as returned by the JSON-RPC implementation.
*/
* @param parent The parent.
* @param error The error object as returned by the JSON-RPC implementation.
*/
init: function(parent, error) {},
/**
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
method.
*/
* 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
* method.
*/
display: function() {},
};
@@ -64,9 +64,11 @@ return core.Class.extend({
* Loads various information concerning views: fields_view for each view,
* the fields of the corresponding model, and optionally the filters.
*
* @param {Object} [dataset] the dataset for which the views are loaded
* @param {Array} [views_descr] array of [view_id, view_type]
* @param {Object} [options] dictionnary of various options:
* @param {Object} params
* @param {String} params.model
* @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.action_id: the action_id (required to load filters),
* - 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');
/**
* @class AbstractRenderer
*/
return Widget.extend({
/**
* @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
*
* @returns []
* @returns {Array}
*/
getSelectedIds: function () {
return [];
@@ -517,7 +517,7 @@ var BasicController = AbstractController.extend(FieldManagerMixin, {
* in readonly (e.g. Priority).
*
* @private
* @param {OdooEvent}
* @param {OdooEvent} ev
*/
_onFieldChanged: function (ev) {
if (this.mode === 'readonly') {
@@ -200,7 +200,7 @@ var BasicModel = AbstractModel.extend({
*
* @param {string} id local resource id of a record
* @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) {
var record = this.localData[recordID];
@@ -277,7 +277,7 @@ var BasicModel = AbstractModel.extend({
* Duplicate a record (by calling the 'copy' route)
*
* @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) {
var self = this;
@@ -544,7 +544,7 @@ var BasicModel = AbstractModel.extend({
* @param {Object} params.fields contains the description of each field
* @param {string} [params.type] 'record' or 'list'
* @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) {
params.type = params.type || (params.res_id !== undefined ? 'record' : 'list');
@@ -694,7 +694,7 @@ var BasicModel = AbstractModel.extend({
* @param {Object} [options]
* @param {boolean} [options.keepChanges=false] if true, doesn't discard the
* 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) {
options = options || {};
@@ -784,7 +784,7 @@ var BasicModel = AbstractModel.extend({
* Resequences records.
*
* @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 {object} [options]
* @param {integer} [options.offset]
@@ -834,8 +834,7 @@ var BasicModel = AbstractModel.extend({
* - it needs to check all changes,
* - generate commands for x2many fields,
* - call the /create or /write method according to the record status
* - After that, it has to reload all data, in case something changed,
* server side.
* - After that, it has to reload all data, in case something changed, server side.
*
* @param {string} record_id local resource
* @param {Object} [options]
@@ -1006,7 +1005,7 @@ var BasicModel = AbstractModel.extend({
* data
*
* @param {string} groupId
* @returns {Deferred -> string} resolves to the group id
* @returns {Deferred<string>} resolves to the group id
*/
toggleGroup: function (groupId) {
var self = this;
@@ -1048,7 +1047,7 @@ var BasicModel = AbstractModel.extend({
* @param {Object} [options]
* @param {string} [options.position=top] if the new record should be added
* 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) {
var self = this;
@@ -1760,7 +1759,7 @@ var BasicModel = AbstractModel.extend({
* @param {string} [optinos.viewType] the type of view for which the record
* is fetched (usefull to load the adequate fields), by defaults, uses
* 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
*/
_fetchRecord: function (record, options) {
@@ -2221,7 +2220,7 @@ var BasicModel = AbstractModel.extend({
* Fetch all data in a ungrouped list
*
* @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) {
var self = this;
@@ -3029,7 +3028,7 @@ var BasicModel = AbstractModel.extend({
* @param {Object} params.fields contains the description of each field
* @param {Object} params.context the context for the new record
* @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) {
var self = this;
@@ -3318,7 +3317,7 @@ var BasicModel = AbstractModel.extend({
*
* @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) {
var self = this;
@@ -3455,7 +3454,7 @@ var BasicModel = AbstractModel.extend({
* instead of a /search_read.
*
* @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) {
var self = this;
@@ -79,7 +79,7 @@ var FormRenderer = BasicRenderer.extend({
* 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.
*
* @param {Object[]} alertFields: field list
* @param {Object[]} alertFields field list
*/
displayTranslationAlert: function (alertFields) {
this.$('.o_notification_box').remove();
@@ -99,7 +99,7 @@ var KanbanRecord = Widget.extend({
* Generates the color classname from a given variable
*
* @private
* @param {number || string} variable
* @param {number | string} variable
* @return {string} the classname
*/
_getColorClassname: function (variable) {
@@ -110,7 +110,7 @@ var KanbanRecord = Widget.extend({
* Computes a color id between 0 and 10 from a given value
*
* @private
* @param {number || string} variable
* @param {number | string} variable
* @returns {integer} the color id
*/
_getColorID: function (variable) {
@@ -1,13 +1,19 @@
odoo.define('web.StandaloneFieldManagerMixin', function (require) {
"use strict";
var FieldManagerMixin = require('web.FieldManagerMixin');
/**
* The StandaloneFieldManagerMixin is a mixin, designed to be used by a widget
* 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, {
/**
@@ -104,7 +104,7 @@ var DateWidget = Widget.extend({
}
},
/**
* @param {Moment|false}
* @param {Moment|false} value
*/
setValue: function (value) {
this.set({'value': value});
@@ -121,7 +121,7 @@ var DateWidget = Widget.extend({
/**
* @private
* @param {Moment}
* @param {Moment} v
* @returns {string}
*/
_formatClient: function (v) {
@@ -129,7 +129,7 @@ var DateWidget = Widget.extend({
},
/**
* @private
* @param {string|false}
* @param {string|false} v
* @returns {Moment}
*/
_parseClient: function (v) {
@@ -137,7 +137,7 @@ var DateWidget = Widget.extend({
},
/**
* @private
* @param {boolean}
* @param {boolean} readonly
*/
_setReadonly: function (readonly) {
this.readonly = readonly;
@@ -51,7 +51,6 @@ var DomainNode = Widget.extend({
"mouseleave button": "_onButtonLeft",
},
/**
* @constructor
* A DomainNode needs a model and domain to work. It can also receive a set
* of options.
*
@@ -427,11 +426,12 @@ var DomainTree = DomainNode.extend({
* DomainTree specialization to use to have a fully working widget.
*
* 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
* 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.
*
* - Some operators like "child_of", "parent_of", "like", "not like",
* "=like", "=ilike" will come only if you use them from demo data or
* 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({
template: "DomainSelector",
@@ -7,6 +7,9 @@ var DomainSelector = require("web.DomainSelector");
var _t = core._t;
/**
* @class DomainSelectorDialog
*/
return Dialog.extend({
init: function (parent, model, domain, options) {
this.model = model;
@@ -6,7 +6,8 @@ var Widget = require('web.Widget');
/**
* 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) {
* this._super(parent, <url_of_iframe>);
* },
@@ -33,7 +33,8 @@ var SnippetEditor = Widget.extend({
/**
* @constructor
* @param {Widget} parent
* @param {DOMElement} target
* @param {Element} target
* @param templateOptions
*/
init: function (parent, target, templateOptions) {
this._super.apply(this, arguments);
@@ -640,7 +641,7 @@ var SnippetsMenu = Widget.extend({
* @private
* @param {jQuery} [$selectorSiblings]
* elements which must have siblings drop zones
* @param {jQuery} [$selectorSiblings]
* @param {jQuery} [$selectorChildren]
* elements which must have child drop zones between each of existing
* child
*/
@@ -790,7 +790,7 @@ var ViewEditor = Widget.extend({
* is toggled -> reloads the resources accordingly.
*
* @private
* @param {Event}
* @param {Event} ev
*/
_onIncludeAllLessChange: function (ev) {
this.options.includeAllLess = $(ev.target).prop('checked');
@@ -801,7 +801,7 @@ var ViewEditor = Widget.extend({
* included is toggled -> reloads the resources accordingly.
*
* @private
* @param {Event}
* @param {Event} ev
*/
_onIncludeBundlesChange: function (ev) {
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).
* To add font, push a new object {base, parser}
*
* - base: class who appear on all fonts (eg: fa fa-refresh)
* - 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}];
@@ -6,21 +6,20 @@ var field_registry = require('web.field_registry');
var utils = require('web.utils');
/**
* Field widget: GaugeWidget
* options
*
* - max_value: maximum value of the gauge [default: 100]
* - 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
from this field instead of the base field used for
the gauge. This allows to display a number different
from the gauge.
* from this field instead of the base field used for
* the gauge. This allows to display a number different
* from the gauge.
* - label: lable of the gauge, displayed below the gauge value
* - 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
* - style: custom style
*
*/
var GaugeWidget = AbstractField.extend({
+3 -2
View File
@@ -11,7 +11,8 @@ var Tip = Widget.extend({
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
* - event_handlers [Object] description of optional event handlers to bind to the tip:
* - 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) {
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 () {
var defs = [];
// 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() {
var self = this;
return this._rpc({
@@ -87,7 +87,7 @@ odoo.define('website_rating.thread', function(require) {
/**
* Update the messages format
*
* @param {Array<Object>}
* @param {Array<Object>} messages
* @returns {Array}
*/
preprocessMessages: function(messages){
@@ -102,17 +102,20 @@ odoo.define('website_rating.thread', function(require) {
},
/**
* Round the given value with a precision of 0.5.
* Example : 1.2 --> 1.0
* 1.7 --> 1.5
* 1.9 --> 2.0
* @param Float
* @returns Float
*
* Examples:
* - 1.2 --> 1.0
* - 1.7 --> 1.5
* - 1.9 --> 2.0
*
* @param {Number} value
* @returns Number
**/
round_to_half: function(value) {
var converted = parseFloat(value); // Make sure we have a number
var decimal = (converted - parseInt(converted, 10));
decimal = Math.round(decimal * 10);
if(decimal == 5){
if(decimal === 5){
return (parseInt(converted, 10)+0.5);
}
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();
}
},
});
});