details: https://code.tryton.org/tryton/commit/6c39c9437f47
branch: default
user: Cédric Krier <[email protected]>
date: Wed Oct 21 12:36:12 2026 +0200
description:
Replace ~indexOf and contains by includes in JavaScript
diffstat:
sao/src/common.js | 164 +++++++++++++++++++++++-----------------------
sao/src/model.js | 60 ++++++++--------
sao/src/pyson.js | 19 +++--
sao/src/rpc.js | 2 +-
sao/src/sao.js | 8 +-
sao/src/screen.js | 40 +++++-----
sao/src/tab.js | 8 +-
sao/src/view/form.js | 16 ++-
sao/src/view/list_form.js | 4 +-
sao/src/view/tree.js | 8 +-
sao/src/window.js | 8 +-
sao/tests/sao.js | 2 +-
12 files changed, 169 insertions(+), 170 deletions(-)
diffs (1260 lines):
diff -r 1952a66929ee -r 6c39c9437f47 sao/src/common.js
--- a/sao/src/common.js Fri Oct 30 16:00:00 2026 +0100
+++ b/sao/src/common.js Wed Oct 21 12:36:12 2026 +0200
@@ -466,7 +466,7 @@
var parts = text.split(' ');
for (var i = 0; i < parts.length; i++) {
var part = parts[i];
- if (part.contains(':')) {
+ if (part.includes(':')) {
var subparts = part.split(':');
var subconverter = [
converter.h, converter.m, converter.s];
@@ -502,7 +502,7 @@
}
}
}
- if (text.contains('-')) {
+ if (text.includes('-')) {
seconds *= -1;
}
return Sao.TimeDelta(null, seconds);
@@ -602,8 +602,8 @@
this._models = models;
});
},
- contains: function(model) {
- return ~this._models.indexOf(model);
+ includes: function(model) {
+ return this._models.includes(model);
}
});
Sao.common.MODELHISTORY = new Sao.common.ModelHistory();
@@ -943,7 +943,7 @@
var _model_evaluator = function(allowed_models) {
return function(value) {
- return ~allowed_models.indexOf(value[0]) ||
+ return allowed_models.includes(value[0]) ||
jQuery.isEmptyObject(allowed_models);
};
};
@@ -1132,21 +1132,21 @@
if (!nextchar) {
this.state = null; // end of file
break;
- } else if (this.whitespace.contains(nextchar)) {
+ } else if (this.whitespace.includes(nextchar)) {
if (this.token || quoted) {
break; // emit current token
} else {
continue;
}
- } else if (this.commenters.contains(nextchar)) {
+ } else if (this.commenters.includes(nextchar)) {
// TODO readline
- } else if (this.escape.contains(nextchar)) {
+ } else if (this.escape.includes(nextchar)) {
escapedstate = 'a';
this.state = nextchar;
- } else if (!~this.nowordchars.indexOf(nextchar)) {
+ } else if (!this.nowordchars.includes(nextchar)) {
this.token = nextchar;
this.state = 'a';
- } else if (this.quotes.contains(nextchar)) {
+ } else if (this.quotes.includes(nextchar)) {
this.state = nextchar;
} else if (this.whitespace_split) {
this.token = nextchar;
@@ -1159,25 +1159,25 @@
continue;
}
}
- } else if (this.quotes.contains(this.state)) {
+ } else if (this.quotes.includes(this.state)) {
quoted = true;
if (!nextchar) { // end of file
throw 'no closing quotation';
}
if (nextchar == this.state) {
this.state = 'a';
- } else if (this.escape.contains(nextchar) &&
- this.escapedquotes.contains(this.state)) {
+ } else if (this.escape.includes(nextchar) &&
+ this.escapedquotes.includes(this.state)) {
escapedstate = this.state;
this.state = nextchar;
} else {
this.token = this.token + nextchar;
}
- } else if (this.escape.contains(this.state)) {
+ } else if (this.escape.includes(this.state)) {
if (!nextchar) { // end of file
throw 'no escaped character';
}
- if (this.quotes.contains(escapedstate) &&
+ if (this.quotes.includes(escapedstate) &&
(nextchar != this.state) &&
(nextchar != escapedstate)) {
this.token = this.token + this.state;
@@ -1188,22 +1188,22 @@
if (!nextchar) {
this.state = null; // end of file
break;
- } else if (this.whitespace.contains(nextchar)) {
+ } else if (this.whitespace.includes(nextchar)) {
this.state = ' ';
if (this.token || quoted) {
break; // emit current token
} else {
continue;
}
- } else if (this.commenters.contains(nextchar)) {
+ } else if (this.commenters.includes(nextchar)) {
// TODO
- } else if (this.quotes.contains(nextchar)) {
+ } else if (this.quotes.includes(nextchar)) {
this.state = nextchar;
- } else if (this.escape.contains(nextchar)) {
+ } else if (this.escape.includes(nextchar)) {
escapedstate = 'a';
this.state = nextchar;
- } else if ((!~this.nowordchars.indexOf(nextchar)) ||
- this.quotes.contains(nextchar) ||
+ } else if ((!this.nowordchars.includes(nextchar)) ||
+ this.quotes.includes(nextchar) ||
this.whitespace_split) {
this.token = this.token + nextchar;
} else {
@@ -1294,7 +1294,7 @@
var is_array = function(e) {
return e instanceof Array;
};
- if ((~['AND', 'OR'].indexOf(clause[0]) ||
+ if ((['AND', 'OR'].includes(clause[0]) ||
(is_array(clause[0]))) &&
clause.slice(1).every(is_array)) {
return this.stringable(clause);
@@ -1306,8 +1306,8 @@
}
if (name in this.fields) {
var field = this.fields[name];
- if (~['many2one', 'one2one', 'one2many', 'many2many']
- .indexOf(field.type)) {
+ if (['many2one', 'one2one', 'one2many', 'many2many']
+ .includes(field.type)) {
var test = function(value) {
return ((typeof value == 'string') ||
(value === null));
@@ -1332,7 +1332,7 @@
if (!domain) {
return true;
}
- if (~['AND', 'OR'].indexOf(domain[0])) {
+ if (['AND', 'OR'].includes(domain[0])) {
domain = domain.slice(1);
}
return domain.every(stringable_);
@@ -1344,7 +1344,7 @@
return '';
}
if ((typeof clause[0] != 'string') ||
- ~['AND', 'OR'].indexOf(clause[0])) {
+ ['AND', 'OR'].includes(clause[0])) {
return '(' + this.string(clause) + ')';
}
var name = clause[0];
@@ -1365,7 +1365,7 @@
if (clause.length > 3) {
target = clause[3];
}
- if (operator.contains('ilike')) {
+ if (operator.includes('ilike')) {
if (this.is_full_text(value)) {
value = value.slice(1, -1);
} else if (!this.is_like(value)) {
@@ -1380,14 +1380,14 @@
var def_operator = this.default_operator(field);
if (def_operator == operator.trim()) {
operator = '';
- if (~this.OPERATORS.indexOf(value)) {
+ if (this.OPERATORS.includes(value)) {
// As the value could be interpreted as an operator
// the default operator must be forced
operator = '"" ';
}
- } else if ((operator.contains(def_operator) &&
- (operator.contains('not') ||
- operator.contains('!')))) {
+ } else if ((operator.includes(def_operator) &&
+ (operator.includes('not') ||
+ operator.includes('!')))) {
operator = operator.replace(def_operator, '')
.replace('not', '!').trim();
}
@@ -1407,9 +1407,9 @@
}
}
var formatted_value = this.format_value(field, value, target);
- if (~this.OPERATORS.indexOf(operator) &&
- ~['char', 'text', 'selection']
- .indexOf(field.type) &&
+ if (this.OPERATORS.includes(operator) &&
+ ['char', 'text', 'selection']
+ .includes(field.type) &&
(value === '')) {
formatted_value = '""';
}
@@ -1519,7 +1519,7 @@
escaped = value.replace(/%%/g, '__');
if (escaped.startsWith('%') || escaped.endsWith('%')) {
value = escaped.substring(1, escaped.length - 1);
- } else if (~escaped.indexOf('%')) {
+ } else if (escaped.includes('%')) {
value = value.replace(/%%/g, '%');
}
operator = null;
@@ -1704,7 +1704,7 @@
var result = [];
for (const nex of tokens.slice(1)) {
if ((nex == '=') && cur &&
- ~this.OPERATORS.indexOf(cur + nex)) {
+ this.OPERATORS.includes(cur + nex)) {
result.push(cur + nex);
cur = null;
} else {
@@ -1749,7 +1749,7 @@
result.push(clause);
};
var i = parts.indexOf(':');
- if (!~i) {
+ if (i < 0) {
parts.forEach(push_result);
return result;
}
@@ -1785,7 +1785,7 @@
// empty string is also the default operator
var operators = [''].concat(this.OPERATORS);
if (((i + 1) < parts.length) &&
- (~operators.indexOf(parts[i + 1]))) {
+ (operators.includes(parts[i + 1]))) {
name = name.concat([parts[i + 1]]);
i += 1;
} else {
@@ -1961,11 +1961,11 @@
operator = '=';
}
}
- if (~[
+ if ([
'integer', 'float', 'numeric',
'datetime', 'timestamp', 'date',
- 'time'].indexOf(field.type)) {
- if ((typeof value == 'string') &&
value.contains('..')) {
+ 'time'].includes(field.type)) {
+ if ((typeof value == 'string') &&
value.includes('..')) {
var values = value.split('..', 2);
var lvalue = this.convert_value(field, values[0],
this.context);
var rvalue = this.convert_value(field, values[1],
this.context);
@@ -2012,7 +2012,7 @@
} else {
value = this.convert_value(field, value, this.context);
}
- if (operator.contains('like')) {
+ if (operator.includes('like')) {
value = this.likify(value);
}
if (target) {
@@ -2034,7 +2034,7 @@
var escaped = value
.replace(escape + '%', '')
.replace(escape + '_', '');
- if (escaped.contains('%') || escaped.contains('_')) {
+ if (escaped.includes('%') || escaped.includes('_')) {
return value;
} else {
return '%' + value + '%';
@@ -2050,7 +2050,7 @@
escaped = escaped
.replace(escape + '%', '')
.replace(escape + '_', '');
- if (escaped.contains('%') || escaped.contains('_')) {
+ if (escaped.includes('%') || escaped.includes('_')) {
return false;
}
return value.startsWith('%') && value.endsWith('%');
@@ -2060,7 +2060,7 @@
var escaped = value
.replace(escape + '%', '')
.replace(escape + '_', '');
- return escaped.contains('%') || escaped.contains('_');
+ return escaped.includes('%') || escaped.includes('_');
},
unescape: function(value, escape) {
escape = escape || '\\';
@@ -2075,24 +2075,24 @@
if (empty && value === '') {
return '""';
}
- if (value.contains('\\')) {
+ if (value.includes('\\')) {
value = value.replace(new RegExp('\\\\', 'g'), '\\\\');
}
- if (value.contains('"')) {
+ if (value.includes('"')) {
value = value.replace(new RegExp('"', 'g'), '\\"');
}
var tests = [':', ' ', '(', ')'].concat(this.OPERATORS);
for (var i = 0; i < tests.length; i++) {
var test = tests[i];
- if (value.contains(test)) {
+ if (value.includes(test)) {
return '"' + value + '"';
}
}
return value;
},
default_operator: function(field) {
- if (~['char', 'text', 'many2one', 'many2many', 'one2many',
- 'reference', 'one2one'].indexOf(field.type)) {
+ if (['char', 'text', 'many2one', 'many2many', 'one2many',
+ 'reference', 'one2one'].includes(field.type)) {
return 'ilike';
} else if (field.type == 'multiselection') {
return 'in';
@@ -2273,12 +2273,12 @@
}
var digit = 0;
var string = String(value);
- if (string.contains('e')) {
+ if (string.includes('e')) {
var exp = string.split('e')[1];
string = string.split('e')[0];
digit -= parseInt(exp);
}
- if (string.contains('.')) {
+ if (string.includes('.')) {
digit += string.replace(/0+$/, '').split('.')[1].length;
}
var factor = Number(field.factor || 1);
@@ -2458,7 +2458,7 @@
if (expression === field_name) {
return locale_name;
}
- if (expression.contains('.')) {
+ if (expression.includes('.')) {
return expression.split('.').slice(1).join('.');
}
return expression;
@@ -2485,21 +2485,21 @@
var field = part[0];
var operand = part[1];
var value = part[2];
- if (field.contains('.')) {
+ if (field.includes('.')) {
// In the case where the leaf concerns a m2o then having a
// value in the evaluation context is deemed suffisant
return Boolean(context[field.split('.')[0]]);
}
var context_field = context[field];
- if (!~['=', '!='].indexOf(operand) &&
+ if (!['=', '!='].includes(operand) &&
((context_field === null) ||
(context_field === undefined) ||
(value === null) ||
(value === undefined)) &&
- !(~['in', 'not in'].indexOf(operand) &&
+ !(['in', 'not in'].includes(operand) &&
((context_field === null) ||
(context_field === undefined)) &&
- ((value instanceof Array) && ~value.indexOf(null)))) {
+ ((value instanceof Array) && value.includes(null)))) {
return;
}
if (moment.isMoment(context_field) && !value) {
@@ -2526,7 +2526,7 @@
(typeof value == 'string') && context_field.length == 2) {
context_field = context_field.join(',');
}
- if (~['=', '!='].indexOf(operand) &&
+ if (['=', '!='].includes(operand) &&
context_field instanceof Array &&
typeof value == 'number') {
operand = {
@@ -2541,10 +2541,10 @@
}
},
inverse_leaf: function(domain) {
- if (~['AND', 'OR'].indexOf(domain)) {
+ if (['AND', 'OR'].includes(domain)) {
return domain;
} else if (this.is_leaf(domain)) {
- if (domain[1].contains('child_of') &&
!domain[0].contains('.')) {
+ if (domain[1].includes('child_of') &&
!domain[0].includes('.')) {
if (domain.length == 3) {
return domain;
} else {
@@ -2557,7 +2557,7 @@
}
},
filter_leaf: function(domain, field, model) {
- if (~['AND', 'OR'].indexOf(domain)) {
+ if (['AND', 'OR'].includes(domain)) {
return domain;
} else if (this.is_leaf(domain)) {
if (domain[0].startsWith(field) && (domain.length > 3)) {
@@ -2591,10 +2591,10 @@
}
},
localize_domain: function(domain, field_name, strip_target) {
- if (~['AND', 'OR', true, false].indexOf(domain)) {
+ if (['AND', 'OR', true, false].includes(domain)) {
return domain;
} else if (this.is_leaf(domain)) {
- if (domain[1].contains('child_of')) {
+ if (domain[1].includes('child_of')) {
if (domain[0].split('.').length > 1) {
var target = domain[0].split('.').slice(1).join('.');
return [target].concat(domain.slice(1));
@@ -2623,7 +2623,7 @@
return [0, domain];
} else if (this.is_leaf(domain)) {
return [1, domain];
- } else if (~['AND', 'OR'].indexOf(domain)) {
+ } else if (['AND', 'OR'].includes(domain)) {
return [0, domain];
} else {
var content = domain.map(this._sort_key.bind(this));
@@ -2659,7 +2659,7 @@
return [];
} else if (this.is_leaf(domain)) {
return domain;
- } else if (~['AND', 'OR'].indexOf(domain)) {
+ } else if (['AND', 'OR'].includes(domain)) {
return domain;
} else {
var sorted_elements = domain.map(this.sort.bind(this));
@@ -2675,7 +2675,7 @@
var value2reference = function(value) {
var model = null;
var ref_id = null;
- if ((typeof(value) == 'string') && value.contains(',')) {
+ if ((typeof(value) == 'string') && value.includes(',')) {
var split = value.split(',');
var result = split.splice(0, 1);
result.push(split.join(','));
@@ -2701,7 +2701,7 @@
return [model, ref_id];
};
- if (~['AND', 'OR'].indexOf(domain)) {
+ if (['AND', 'OR'].includes(domain)) {
return domain;
} else if (this.is_leaf(domain)) {
if (domain[0] == reference) {
@@ -2749,7 +2749,7 @@
}
for (model in model_values) {
ref_ids = model_values[model];
- if (~ref_ids.indexOf('%')) {
+ if (ref_ids.includes('%')) {
if (domain[1] == 'in') {
new_domain.push(
[reference + '.id', '!=', null,
@@ -2777,7 +2777,7 @@
}
},
extract_reference_models: function(domain, field_name) {
- if (~['AND', 'OR'].indexOf(domain)) {
+ if (['AND', 'OR'].includes(domain)) {
return [];
} else if (this.is_leaf(domain)) {
var local_part = domain[0].split('.', 1)[0];
@@ -2793,7 +2793,7 @@
d, field_name);
for (var i=0, len=new_models.length; i < len; i++) {
var model = new_models[i];
- if (!~models.indexOf(model)) {
+ if (!models.includes(model)) {
models.push(model);
}
}
@@ -2843,7 +2843,7 @@
simplify_duplicate: function(domain) {
var dedup_branches = [];
var bool_op = null;
- if (~['AND', 'OR'].indexOf(domain[0])) {
+ if (['AND', 'OR'].includes(domain[0])) {
bool_op = domain[0];
domain = domain.slice(1);
}
@@ -2904,7 +2904,7 @@
},
merge: function(domain, domoperator) {
if (jQuery.isEmptyObject(domain) ||
- ~['AND', 'OR'].indexOf(domain)) {
+ ['AND', 'OR'].includes(domain)) {
return [];
}
var domain_type = domain[0] == 'OR' ? 'OR' : 'AND';
@@ -2974,7 +2974,7 @@
},
domain_inversion: function(domain, symbol, context={}) {
var expression = this.parse(domain);
- if (!~expression.variables.indexOf(symbol)) {
+ if (!expression.variables.includes(symbol)) {
return true;
}
return expression.inverse(symbol, context);
@@ -3001,16 +3001,16 @@
if (a instanceof Array) {
if (b instanceof Array) {
for (var i = 0, len = a.length; i < len; i++) {
- if (~b.indexOf(a[i])) {
+ if (b.includes(a[i])) {
return true;
}
}
return false;
} else {
- return Boolean(~a.indexOf(b));
+ return a.includes(b);
}
} else {
- return Boolean(~b.indexOf(a));
+ return b.includes(a);
}
};
Sao.common.DomainInversion.sql_like = function(value, pattern, ignore_case)
@@ -3068,7 +3068,7 @@
}
},
base: function(expression) {
- if (!expression.contains('.')) {
+ if (!expression.includes('.')) {
return expression;
} else {
return expression.split('.')[0];
@@ -3082,7 +3082,7 @@
if (part instanceof DomainInversion.And) {
var part_inversion = part.inverse(symbol, context);
var evaluated = typeof part_inversion == 'boolean';
- if (!~part.variables.indexOf(symbol)) {
+ if (!part.variables.includes(symbol)) {
continue;
}
if (!evaluated) {
@@ -3135,7 +3135,7 @@
if (part instanceof DomainInversion.And) {
var part_inversion = part.inverse(symbol, context);
var evaluated = typeof part_inversion == 'boolean';
- if (!~part.variables.indexOf(symbol)) {
+ if (!part.variables.includes(symbol)) {
if (evaluated && part_inversion) {
return true;
}
@@ -3314,7 +3314,7 @@
if (url !== undefined) {
return jQuery.when(url);
}
- if (~Sao.common.LOCAL_ICONS.indexOf(icon_name)) {
+ if (Sao.common.LOCAL_ICONS.includes(icon_name)) {
return jQuery.get('images/' + icon_name + '.svg', null, null,
'text')
.then(icon => {
var img_url = this._convert(icon);
@@ -4120,7 +4120,7 @@
if (!element.is(':visible')) {
return null;
}
- if (~['input', 'select', 'textarea'].indexOf(
+ if (['input', 'select', 'textarea'].includes(
element[0].tagName.toLowerCase()) &&
!element.prop('readonly')) {
return element;
@@ -4245,7 +4245,7 @@
for (var i=0; i < string.length; i++) {
var c = string.charAt(i).toLowerCase();
// Skip sao and browser shortcuts
- if (!~['d', 'e', 'f', 'i', 'n', 't', 'w'].indexOf(c)) {
+ if (!['d', 'e', 'f', 'i', 'n', 't', 'w'].includes(c)) {
return c;
}
}
diff -r 1952a66929ee -r 6c39c9437f47 sao/src/model.js
--- a/sao/src/model.js Fri Oct 30 16:00:00 2026 +0100
+++ b/sao/src/model.js Wed Oct 21 12:36:12 2026 +0200
@@ -132,14 +132,14 @@
// Remove previously removed or deleted records
var record_removed = [];
for (const record of this.record_removed) {
- if (!~ids.indexOf(record.id)) {
+ if (!ids.includes(record.id)) {
record_removed.push(record);
}
}
this.record_removed = record_removed;
var record_deleted = [];
for (const record of this.record_deleted) {
- if (!~ids.indexOf(record.id)) {
+ if (!ids.includes(record.id)) {
record_deleted.push(record);
}
}
@@ -175,7 +175,7 @@
if (record.group != this) {
record.group = this;
}
- if (this.indexOf(record) < 0) {
+ if (!this.includes(record)) {
this.splice(position, 0, record);
}
for (var record_rm of this.record_removed) {
@@ -211,19 +211,19 @@
record, remove, force_remove=false, modified=true) {
if (record.id >= 0) {
if (remove) {
- if (~this.record_deleted.indexOf(record)) {
+ if (this.record_deleted.includes(record)) {
this.record_deleted.splice(
this.record_deleted.indexOf(record), 1);
}
- if (!~this.record_removed.indexOf(record)) {
+ if (!this.record_removed.includes(record)) {
this.record_removed.push(record);
}
} else {
- if (~this.record_removed.indexOf(record)) {
+ if (this.record_removed.includes(record)) {
this.record_removed.splice(
this.record_removed.indexOf(record), 1);
}
- if (!~this.record_deleted.indexOf(record)) {
+ if (!this.record_deleted.includes(record)) {
this.record_deleted.push(record);
}
}
@@ -291,7 +291,7 @@
return record.id;
});
return root_group.on_write_ids(record_ids).then(reload_ids => {
- reload_ids = reload_ids.filter(e => !~record_ids.indexOf(e));
+ reload_ids = reload_ids.filter(e => !record_ids.includes(e));
return this.model.execute('delete', [record_ids], context)
.then(() => {
for (const record of records) {
@@ -333,7 +333,7 @@
ids = [ids];
}
return this.on_write_ids(ids).then(to_reload => {
- to_reload = to_reload.filter(e => !~ids.indexOf(e));
+ to_reload = to_reload.filter(e => !ids.includes(e));
this.root_group.reload(to_reload);
});
};
@@ -393,7 +393,7 @@
array.destroy = function() {
if (this.parent) {
var i = this.parent.group.children.indexOf(this);
- if (~i) {
+ if (i >= 0) {
this.parent.group.children.splice(i, 1);
}
}
@@ -458,7 +458,7 @@
var inversion = new Sao.common.DomainInversion();
var head = domain[0];
var tail = domain.slice(1);
- if (~['AND', 'OR'].indexOf(head)) {
+ if (['AND', 'OR'].includes(head)) {
// pass
} else if (inversion.is_leaf(head)) {
var field = head[0];
@@ -722,9 +722,9 @@
const selection_fields = ['selection', 'multiselection'];
for (const fname of fnames) {
var fdescription = this.model.fields[fname].description;
- if (~rec_named_fields.indexOf(fdescription.type))
+ if (rec_named_fields.includes(fdescription.type))
fnames_to_fetch.push(fname + '.rec_name');
- else if (~selection_fields.indexOf(fdescription.type) &&
+ else if (selection_fields.includes(fdescription.type) &&
((fdescription.loading || 'lazy') == 'eager')) {
fnames_to_fetch.push(fname + ':string');
} else if (
@@ -737,7 +737,7 @@
}
}
}
- if (!~fnames.indexOf('rec_name')) {
+ if (!fnames.includes('rec_name')) {
fnames_to_fetch.push('rec_name');
}
fnames_to_fetch.push('_timestamp');
@@ -777,7 +777,7 @@
filter = filter_group;
}
var idx = group.indexOf(this);
- if (~idx) {
+ if (idx >= 0) {
var length = group.length;
var n = 1;
while ((Object.keys(id2record).length < limit) &&
@@ -1064,7 +1064,7 @@
get_on_change_value: function(skip) {
var value = {};
for (var key in this.model.fields) {
- if (skip && ~skip.indexOf(key)) {
+ if (skip && skip.includes(key)) {
continue;
}
if ((this.id >= 0) &&
@@ -1150,7 +1150,7 @@
continue;
}
for (var i = 0; i < field_names.length; i++) {
- if (~on_change_with.indexOf(field_names[i])) {
+ if (on_change_with.includes(field_names[i])) {
break;
}
}
@@ -1262,7 +1262,7 @@
for (var fname in this.model.fields) {
var field = this.model.fields[fname];
var autocomplete = field.description.autocomplete || [];
- if (!~autocomplete.indexOf(fieldname)) {
+ if (!autocomplete.includes(fieldname)) {
continue;
}
this.do_autocomplete(fname);
@@ -1333,7 +1333,7 @@
var result = true;
for (var fname in this.model.fields) {
var field = this.model.fields[fname];
- if (field_names && !~field_names.indexOf(fname)) {
+ if (field_names && !field_names.includes(fname)) {
continue;
}
if (!this.get_loaded([fname])) {
@@ -1443,10 +1443,10 @@
return group;
},
get deleted() {
- return Boolean(~this.group.record_deleted.indexOf(this));
+ return this.group.record_deleted.includes(this);
},
get removed() {
- return Boolean(~this.group.record_removed.indexOf(this));
+ return this.group.record_removed.includes(this);
},
get readonly() {
return (this.deleted ||
@@ -1793,7 +1793,7 @@
}
var domain_readonly = original_domain[0] == 'AND';
let setdefault;
- if (leftpart.contains('.')) {
+ if (leftpart.includes('.')) {
let localpart = leftpart.split('.').slice(1).join('.');
setdefault = localpart == 'id';
} else {
@@ -2285,8 +2285,8 @@
let field_names = new Set();
for (const fieldname of value_fields) {
if (!(fieldname in group.model.fields) &&
- (!~fieldname.indexOf('.')) &&
- (!~fieldname.indexOf(':')) &&
+ (!fieldname.includes('.')) &&
+ (!fieldname.includes(':')) &&
(!fieldname.startsWith('_'))) {
field_names.add(fieldname);
}
@@ -2330,7 +2330,7 @@
if (mode == 'list ids') {
var records_to_remove = [];
for (const old_record of group) {
- if (!~value.indexOf(old_record.id)) {
+ if (!value.includes(old_record.id)) {
records_to_remove.push(old_record);
}
}
@@ -2394,8 +2394,8 @@
var to_create = [];
var to_write = [];
for (const record2 of group) {
- if (~record_removed.indexOf(record2) ||
- ~record_deleted.indexOf(record2)) {
+ if (record_removed.includes(record2) ||
+ record_deleted.includes(record2)) {
continue;
}
var values;
@@ -2491,7 +2491,7 @@
for (const f of Object.keys(v)) {
if (!(f in fields) &&
(f != 'id') &&
- (!~f.indexOf('.'))) {
+ (!f.includes('.'))) {
new_field_names[f] = true;
}
}
@@ -2626,8 +2626,8 @@
var record_removed = group.record_removed;
var record_deleted = group.record_deleted;
for (const record2 of group) {
- if (~record_removed.indexOf(record2) ||
- ~record_deleted.indexOf(record2))
+ if (record_removed.includes(record2) ||
+ record_deleted.includes(record2))
continue;
result.push(record2.id);
}
diff -r 1952a66929ee -r 6c39c9437f47 sao/src/pyson.js
--- a/sao/src/pyson.js Fri Oct 30 16:00:00 2026 +0100
+++ b/sao/src/pyson.js Wed Oct 21 12:36:12 2026 +0200
@@ -39,8 +39,11 @@
in_(obj) {
return new Sao.PYSON.In(this, obj);
}
+ includes(k) {
+ return new Sao.PYSON.In(k, this);
+ }
contains(k) {
- return new Sao.PYSON.In(k, this);
+ return this.includes(k);
}
toString() {
const params = this.__string_params__();
@@ -437,7 +440,7 @@
'date, datetime or timedelta';
}
} else {
- if (!~['number', 'object'].indexOf(typeof statement)) {
+ if (!['number', 'object'].includes(typeof statement)) {
throw 'statement must be an integer, float, ' +
'date, datetime or timedelta';
}
@@ -566,13 +569,13 @@
}
if (this._else_statement instanceof Sao.PYSON.PYSON) {
for (const type of this._else_statement.types()) {
- if (!~types.indexOf(type)) {
+ if (!types.includes(type)) {
types.push(type);
}
}
} else {
const type = typeof this._else_statement;
- if (!~types.indexOf(type)) {
+ if (!types.includes(type)) {
types.push(type);
}
}
@@ -673,7 +676,7 @@
throw 'key must be a string or a number';
}
} else {
- if (!~['string', 'number'].indexOf(typeof key)) {
+ if (!['string', 'number'].includes(typeof key)) {
throw 'key must be a string or a number';
}
}
@@ -704,7 +707,7 @@
if (params[1] instanceof Sao.PYSON.PYSON) {
const args = params.slice().map(Sao.PYSON.toString);
args.splice(1, 1);
- return `${params[1]}.contains(` + args.join(', ') + ')';
+ return `${params[1]}.includes(` + args.join(', ') + ')';
} else {
return super.toString();
}
@@ -716,8 +719,8 @@
Sao.PYSON.In.eval_ = function(value, context) {
if (value.v) {
- if (value.v.indexOf) {
- return Boolean(~value.v.indexOf(value.k));
+ if (value.v.includes) {
+ return value.v.includes(value.k);
} else {
return !!value.v[value.k];
}
diff -r 1952a66929ee -r 6c39c9437f47 sao/src/rpc.js
--- a/sao/src/rpc.js Fri Oct 30 16:00:00 2026 +0100
+++ b/sao/src/rpc.js Wed Oct 21 12:36:12 2026 +0200
@@ -49,7 +49,7 @@
description = data.error[1][2];
Sao.common.userwarning.run(description, msg)
.then(function(result) {
- if (!~['always', 'ok'].indexOf(result)) {
+ if (!['always', 'ok'].includes(result)) {
dfd.reject();
return;
}
diff -r 1952a66929ee -r 6c39c9437f47 sao/src/sao.js
--- a/sao/src/sao.js Fri Oct 30 16:00:00 2026 +0100
+++ b/sao/src/sao.js Wed Oct 21 12:36:12 2026 +0200
@@ -10,12 +10,6 @@
(function() {
'use strict';
- if (!('contains' in String.prototype)) {
- String.prototype.contains = function(str, startIndex) {
- return -1 !== String.prototype.indexOf.call(this, str, startIndex);
- };
- }
-
// Browser compatibility: polyfill
if (!Set.prototype.intersection) {
Set.prototype.intersection = function(other) {
@@ -379,7 +373,7 @@
}
Sao.i18n.loadJSON(data);
}, function() {
- if (~lang.indexOf('_')) {
+ if (lang.includes('_')) {
return Sao.i18n.setlang(lang.split('_').slice(0,
-1).join('_'));
}
});
diff -r 1952a66929ee -r 6c39c9437f47 sao/src/screen.js
--- a/sao/src/screen.js Fri Oct 30 16:00:00 2026 +0100
+++ b/sao/src/screen.js Wed Oct 21 12:36:12 2026 +0200
@@ -470,7 +470,7 @@
for (var f in domain_parser.fields) {
const field = domain_parser.fields[f];
if ((field.searchable || field.searchable === undefined) &&
- !field.name.contains('.')) {
+ !field.name.includes('.')) {
fields.push(field);
}
}
@@ -748,7 +748,7 @@
build_entry: function(placeholder, el) {
var entry = Sao.ScreenContainer.Times._super.build_entry.call(
this, placeholder, el);
- if (~navigator.userAgent.indexOf("Firefox")) {
+ if (navigator.userAgent.includes("Firefox")) {
// time input on Firefox does not have a pop-up
entry.find('.icon-input').sao_hide();
}
@@ -997,7 +997,7 @@
if (this.current_view) {
this.current_view.set_value();
if (this.current_record &&
- !~this.current_record.group.indexOf(
+ !this.current_record.group.includes(
this.current_record)) {
this.current_record = null;
}
@@ -1025,8 +1025,8 @@
result &= this.current_view.creatable == creatable;
}
if (searchable !== null) {
- result &= Boolean(~['tree', 'graph', 'calendar'].indexOf(
- this.current_view.view_type)) == searchable;
+ result &= ['tree', 'graph', 'calendar'].includes(
+ this.current_view.view_type) == searchable;
}
return result;
};
@@ -1417,8 +1417,8 @@
var deferreds = [];
if (this.views && this.current_view) {
var search_prm = this.search_active(
- ~['tree', 'graph', 'calendar'].indexOf(
- this.current_view.view_type));
+ ['tree', 'graph', 'calendar'].includes(
+ this.current_view.view_type));
deferreds.push(search_prm);
for (const view of this.views) {
if (view &&
@@ -1454,7 +1454,7 @@
_get_next_record: function() {
var view = this.current_view;
if (view &&
- ~['tree', 'form', 'list-form'].indexOf(view.view_type) &&
+ ['tree', 'form', 'list-form'].includes(view.view_type) &&
this.current_record && this.current_record.group) {
var group = this.current_record.group;
var record = this.current_record;
@@ -1499,7 +1499,7 @@
_get_previous_record: function() {
var view = this.current_view;
if (view &&
- ~['tree', 'form', 'list-form'].indexOf(view.view_type) &&
+ ['tree', 'form', 'list-form'].includes(view.view_type) &&
this.current_record && this.current_record.group) {
var group = this.current_record.group;
var record = this.current_record;
@@ -1556,7 +1556,7 @@
},
get listed_records() {
if (this.current_view &&
- ~['tree', 'calendar', 'list-form'].indexOf(
+ ['tree', 'calendar', 'list-form'].includes(
this.current_view.view_type)) {
return this.current_view.listed_records;
} else if (this.current_record) {
@@ -1675,7 +1675,7 @@
},
set_on_write: function(name) {
if(name) {
- if (!~this.group.on_write.indexOf(name)) {
+ if (!this.group.on_write.includes(name)) {
this.group.on_write.push(name);
}
}
@@ -1750,8 +1750,8 @@
set_cursor: function(new_, reset_view) {
if (!this.current_view) {
return;
- } else if (~['tree', 'form', 'list-form'].indexOf(
- this.current_view.view_type)) {
+ } else if (['tree', 'form', 'list-form']
+ .includes(this.current_view.view_type)) {
this.current_view.set_cursor(new_, reset_view);
}
},
@@ -1808,11 +1808,11 @@
if (record.group.parent) {
prms.push(record.group.parent.save(false));
}
- if (~record.group.record_deleted.indexOf(record)) {
+ if (record.group.record_deleted.includes(record)) {
record.group.record_deleted.splice(
record.group.record_deleted.indexOf(record),
1);
}
- if (~record.group.record_removed.indexOf(record)) {
+ if (record.group.record_removed.includes(record)) {
record.group.record_removed.splice(
record.group.record_removed.indexOf(record),
1);
}
@@ -2181,7 +2181,7 @@
return this.switch_view.apply(this, action.split(' ',
3).slice(1));
} else if (action == 'reload') {
if (this.current_view &&
- ~['tree', 'graph',
'calendar'].indexOf(this.current_view.view_type) &&
+ ['tree', 'graph',
'calendar'].includes(this.current_view.view_type) &&
!this.group.parent) {
return
this.search_filter(this.screen_container.get_text());
}
@@ -2292,7 +2292,7 @@
view.children_field || null] = [
[], [[this.current_record.id]]];
}
- } else if (~['tree', 'list-form'].indexOf(view.view_type)) {
+ } else if (['tree', 'list-form'].includes(view.view_type)) {
var paths;
if (view.view_type == 'tree') {
view.save_width();
@@ -2345,18 +2345,18 @@
if (!view) {
return jQuery.when();
}
- if (!~['tree', 'form', 'list-form'].indexOf(view.view_type)) {
+ if (!['tree', 'form', 'list-form'].includes(view.view_type)) {
return jQuery.when();
}
- if (~this.tree_states_done.indexOf(view)) {
+ if (this.tree_states_done.includes(view)) {
return jQuery.when();
}
if (view.view_type == 'form' &&
!jQuery.isEmptyObject(this.tree_states_done)) {
return jQuery.when();
}
- if ((~['tree', 'list-form'].indexOf(view.view_type)) &&
+ if ((['tree', 'list-form'].includes(view.view_type)) &&
!parseInt(view.attributes.tree_state, 10)) {
this.tree_states_done.push(view);
}
diff -r 1952a66929ee -r 6c39c9437f47 sao/src/tab.js
--- a/sao/src/tab.js Fri Oct 30 16:00:00 2026 +0100
+++ b/sao/src/tab.js Wed Oct 21 12:36:12 2026 +0200
@@ -70,7 +70,7 @@
label: Sao.i18n.gettext('View Logs...'),
}, {
id: (this.screen &&
-
Sao.common.MODELHISTORY.contains(this.screen.model_name)) ?
+
Sao.common.MODELHISTORY.includes(this.screen.model_name)) ?
'revision': null,
icon: 'tryton-history',
label: Sao.i18n.gettext('Show revisions...'),
@@ -407,7 +407,7 @@
if (Sao.Tab.tabs.length) {
var tab = Sao.Tab.tabs[0];
return tab.close().then(function() {
- if (!~Sao.Tab.tabs.indexOf(tab)) {
+ if (!Sao.Tab.tabs.includes(tab)) {
return Sao.Tab.tabs.close();
} else {
return jQuery.Deferred().reject();
@@ -587,8 +587,8 @@
if (screen.current_view.view_type == 'form') {
screen.new_();
}
- if (~['tree', 'graph', 'calendar'].indexOf(
- screen.current_view.view_type)) {
+ if (['tree', 'graph', 'calendar']
+ .includes(screen.current_view.view_type)) {
screen.search_filter();
}
}
diff -r 1952a66929ee -r 6c39c9437f47 sao/src/view/form.js
--- a/sao/src/view/form.js Fri Oct 30 16:00:00 2026 +0100
+++ b/sao/src/view/form.js Wed Oct 21 12:36:12 2026 +0200
@@ -120,7 +120,7 @@
widget.labelled.uniqueId();
widget.labelled.attr('aria-labelledby', label.el.attr('id'));
widget.labelled.attr('accesskey', accesskey);
- if (~['INPUT', 'SELECT'].indexOf(
+ if (['INPUT', 'SELECT'].includes(
widget.labelled.get(0).tagName)) {
jQuery('<span/>', {
'data-accesskey': accesskey,
@@ -1868,7 +1868,7 @@
value = this._parse(this._input_format, value);
value = this._format(this.get_format(), value);
this.date.val(value).change();
- if (!~navigator.userAgent.indexOf("Firefox")) {
+ if (!navigator.userAgent.includes("Firefox")) {
// Firefox triggers change when navigate by month/year
this.date.focus();
}
@@ -2002,7 +2002,7 @@
_parse: Sao.common.parse_time,
init: function(view, attributes) {
Sao.View.Form.Time._super.init.call(this, view, attributes);
- if (~navigator.userAgent.indexOf("Firefox")) {
+ if (navigator.userAgent.includes("Firefox")) {
// time input on Firefox does not have a pop-up
this.input.parent().sao_hide();
}
@@ -3020,7 +3020,7 @@
this.read_access) {
event_.preventDefault();
this.edit();
- } else if (~activate_keys.indexOf(event_.which) && editable) {
+ } else if (activate_keys.includes(event_.which) && editable) {
if (!this.attributes.completion ||
this.attributes.completion == "1") {
if (this.el.find('.dropdown').hasClass('open')) {
@@ -3032,7 +3032,7 @@
this.field_name)) && editable) {
var value = this.get_text();
if ((value != this.entry.val()) ||
- ~delete_keys.indexOf(event_.which)) {
+ delete_keys.includes(event_.which)) {
this.entry.val('');
this.record.field_set_client(this.field_name,
this.value_from_id(null, ''));
@@ -4055,7 +4055,8 @@
if (!this.wid_completion) {
activate_keys.push(Sao.common.RETURN_KEYCODE);
}
- if (~activate_keys.indexOf(event_.which) &&
this.wid_text.val()) {
+ if (activate_keys.includes(event_.which) &&
+ this.wid_text.val()) {
this.add(event_);
}
}
@@ -4468,7 +4469,8 @@
} else if (event_.which == Sao.common.F2_KEYCODE) {
event_.preventDefault();
this.add();
- } else if (~activate_keys.indexOf(event_.which) &&
this.entry.val()) {
+ } else if (activate_keys.includes(event_.which)
+ && this.entry.val()) {
this.add();
}
},
diff -r 1952a66929ee -r 6c39c9437f47 sao/src/view/list_form.js
--- a/sao/src/view/list_form.js Fri Oct 30 16:00:00 2026 +0100
+++ b/sao/src/view/list_form.js Wed Oct 21 12:36:12 2026 +0200
@@ -56,8 +56,8 @@
view_form.record = record;
}
- if (~this.group.record_deleted.indexOf(record) ||
- ~this.group.record_removed.indexOf(record)) {
+ if (this.group.record_deleted.includes(record) ||
+ this.group.record_removed.includes(record)) {
view_form_frame.addClass('disabled');
} else {
view_form_frame.removeClass('disabled');
diff -r 1952a66929ee -r 6c39c9437f47 sao/src/view/tree.js
--- a/sao/src/view/tree.js Fri Oct 30 16:00:00 2026 +0100
+++ b/sao/src/view/tree.js Wed Oct 21 12:36:12 2026 +0200
@@ -36,8 +36,8 @@
column.suffixes.push(
new Sao.View.Tree.Symbol(attributes, 1));
}
- if (~['url', 'email', 'callto', 'sip'
- ].indexOf(attributes.widget)) {
+ if (['url', 'email', 'callto', 'sip']
+ .includes(attributes.widget)) {
column.prefixes.push(
new Sao.View.Tree.Affix(attributes, attributes.widget));
}
@@ -1296,8 +1296,8 @@
}else {
sum_ += value;
}
- if (~records_ids.indexOf(record.id) ||
- !selected_records){
+ if (records_ids.includes(record.id) ||
+ !selected_records) {
if (selected_sum === null){
selected_sum = value;
}else {
diff -r 1952a66929ee -r 6c39c9437f47 sao/src/window.js
--- a/sao/src/window.js Fri Oct 30 16:00:00 2026 +0100
+++ b/sao/src/window.js Wed Oct 21 12:36:12 2026 +0200
@@ -147,7 +147,7 @@
var revision = this.screen.context._datetime;
var label;
if (revision &&
-
Sao.common.MODELHISTORY.contains(this.screen.model_name)) {
+
Sao.common.MODELHISTORY.includes(this.screen.model_name)) {
var date_format = Sao.common.date_format(
this.screen.context.date_format);
var time_format = '%H:%M:%S.%f';
@@ -577,7 +577,7 @@
var result;
this.screen.current_view.set_value();
var readonly = this.screen.group.readonly;
- if (~['RESPONSE_OK', 'RESPONSE_ACCEPT'].indexOf(response_id) &&
+ if (['RESPONSE_OK', 'RESPONSE_ACCEPT'].includes(response_id) &&
!readonly &&
this.screen.current_record) {
jQuery.when(this.screen.current_record.validate()).then(validate => {
@@ -2138,7 +2138,7 @@
this.fields[path] = node;
// Insert relation only to real field
- if (item.name.indexOf('.') == -1) {
+ if (!item.name.includes('.')) {
if (item.field.relation) {
node.children = {};
} else if (item.field.translate) {
@@ -2780,7 +2780,7 @@
for (var print_id in this.print_actions) {
var check = this.print_actions[print_id];
check.prop(
- 'checked', ~print_ids.indexOf(parseInt(print_id, 10)));
+ 'checked', print_ids.includes(parseInt(print_id, 10)));
}
});
},
diff -r 1952a66929ee -r 6c39c9437f47 sao/tests/sao.js
--- a/sao/tests/sao.js Fri Oct 30 16:00:00 2026 +0100
+++ b/sao/tests/sao.js Wed Oct 21 12:36:12 2026 +0200
@@ -1232,7 +1232,7 @@
['id', '=', -1]));
QUnit.assert.strictEqual(expr.toString(),
- 'If(Not(Eval("context", {}).contains("company")), "=", "!=")');
+ 'If(Not(Eval("context", {}).includes("company")), "=", "!=")');
});
QUnit.test('PYSON noeval', function() {
var decoder = new Sao.PYSON.Decoder({}, true);