[REF] *: Replace underscore _.each() by native JS
Replaced _.each() functions (average 235 occurences) Description of the refactoring this PR addresses: Current behavior before PR: There are underscore.js function enumerated above used in odoo. Desired behavior after PR is merged: These functions has been replaced by native javascript prototypes/methods/functions. TaskId : 3246238 closes odoo/odoo#118565 Signed-off-by: Georis François (fge) <fge@odoo.com>
This commit is contained in:
@@ -18,7 +18,7 @@ QUnit.test("add_link utility function", function (assert) {
|
||||
"https://tenor.com/view/chỗgiặt-dog-smile-gif-13860250": true,
|
||||
"http://www.boîtenoire.be": true,
|
||||
};
|
||||
_.each(testInputs, function (willLinkify, content) {
|
||||
for (const [content, willLinkify] of Object.entries(testInputs)) {
|
||||
const output = utils.parseAndTransform(content, utils.addLink);
|
||||
if (willLinkify) {
|
||||
assert.strictEqual(output.indexOf("<a "), 0);
|
||||
@@ -26,7 +26,7 @@ QUnit.test("add_link utility function", function (assert) {
|
||||
} else {
|
||||
assert.strictEqual(output.indexOf("<a "), -1);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test("addLink: utility function and special entities", function (assert) {
|
||||
@@ -51,10 +51,11 @@ QUnit.test("addLink: utility function and special entities", function (assert) {
|
||||
// special character in smileys should be escaped
|
||||
"<3": "<3",
|
||||
};
|
||||
_.each(testInputs, function (result, content) {
|
||||
|
||||
for (const [content, result] of Object.entries(testInputs)) {
|
||||
const output = utils.parseAndTransform(content, utils.addLink);
|
||||
assert.strictEqual(output, result);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test("addLink: linkify inside text node (1 occurrence)", function (assert) {
|
||||
|
||||
@@ -485,7 +485,7 @@ export class MassMailingHtmlField extends HtmlField {
|
||||
const $layout = this.wysiwyg.$iframeBody.find(".o_layout");
|
||||
let selectedTheme = false;
|
||||
if ($layout.length !== 0) {
|
||||
_.each(themesParams, function (themeParams) {
|
||||
themesParams.forEach((themeParams) => {
|
||||
if ($layout.hasClass(themeParams.className)) {
|
||||
selectedTheme = themeParams;
|
||||
}
|
||||
|
||||
@@ -1024,7 +1024,7 @@ export class PosGlobalState extends PosModel {
|
||||
return orm
|
||||
.call("pos.order", "create_from_ui", [orders, options.draft || false])
|
||||
.then(function (server_ids) {
|
||||
_.each(order_ids_to_sync, function (order_id) {
|
||||
order_ids_to_sync.forEach((order_id) => {
|
||||
self.db.remove_order(order_id);
|
||||
});
|
||||
self.failed = false;
|
||||
@@ -3160,7 +3160,7 @@ export class Order extends PosModel {
|
||||
this.pricelist = pricelist;
|
||||
|
||||
var lines_to_recompute = this.get_orderlines().filter((line) => !line.price_manually_set);
|
||||
_.each(lines_to_recompute, function (line) {
|
||||
lines_to_recompute.forEach((line) => {
|
||||
line.set_unit_price(
|
||||
line.product.get_price(self.pricelist, line.get_quantity(), line.get_price_extra())
|
||||
);
|
||||
|
||||
@@ -102,7 +102,7 @@ var PortalChatter = publicWidget.Widget.extend({
|
||||
* @returns {Array}
|
||||
*/
|
||||
preprocessMessages(messages) {
|
||||
_.each(messages, function (m) {
|
||||
messages.forEach((m) => {
|
||||
m['author_avatar_url'] = sprintf('/web/image/%s/%s/author_avatar/50x50', 'mail.message', m.id);
|
||||
m['published_date_str'] = sprintf(_t('Published on %s'), moment(time.str_to_datetime(m.date)).format('MMMM Do YYYY, h:mm:ss a'));
|
||||
m['body'] = Markup(m.body);
|
||||
|
||||
@@ -52,7 +52,7 @@ var PortalComposer = publicWidget.Widget.extend({
|
||||
return this._super.apply(this, arguments).then(function () {
|
||||
if (self.options.default_attachment_ids) {
|
||||
self.attachments = self.options.default_attachment_ids || [];
|
||||
_.each(self.attachments, function(attachment) {
|
||||
self.attachments.forEach((attachment) => {
|
||||
attachment.state = 'done';
|
||||
});
|
||||
self._updateAttachments();
|
||||
|
||||
@@ -28,8 +28,8 @@ var PortalSidebar = publicWidget.Widget.extend({
|
||||
* @private
|
||||
*/
|
||||
_setDelayLabel: function () {
|
||||
var $sidebarTimeago = this.$el.find('.o_portal_sidebar_timeago');
|
||||
_.each($sidebarTimeago, function (el) {
|
||||
var $sidebarTimeago = this.$el.find('.o_portal_sidebar_timeago').toArray();
|
||||
$sidebarTimeago.forEach((el) => {
|
||||
var dateTime = moment(time.auto_str_to_date($(el).attr('datetime'))),
|
||||
today = moment().startOf('day'),
|
||||
diff = dateTime.diff(today, 'days', true),
|
||||
|
||||
@@ -65,7 +65,7 @@ PortalChatter.include({
|
||||
var self = this;
|
||||
messages = this._super.apply(this, arguments);
|
||||
if (this.options['display_rating']) {
|
||||
_.each(messages, function (m, i) {
|
||||
messages.forEach((m, i) => {
|
||||
m.rating_value = self.roundToHalf(m['rating_value']);
|
||||
m.rating = self._preprocessCommentData(m.rating, i);
|
||||
});
|
||||
@@ -136,12 +136,14 @@ PortalChatter.include({
|
||||
'avg': Math.round(result['rating_stats']['avg'] * 100) / 100,
|
||||
'percent': [],
|
||||
};
|
||||
_.each(_.sortBy(Object.keys(result['rating_stats']['percent'])).reverse(), function (rating) {
|
||||
ratingData['percent'].push({
|
||||
'num': self.roundToHalf(rating),
|
||||
'percent': utils.round_precision(result['rating_stats']['percent'][rating], 0.01),
|
||||
_.sortBy(Object.keys(result["rating_stats"]["percent"]))
|
||||
.reverse()
|
||||
.forEach((rating) => {
|
||||
ratingData["percent"].push({
|
||||
num: self.roundToHalf(rating),
|
||||
percent: utils.round_precision(result["rating_stats"]["percent"][rating], 0.01),
|
||||
});
|
||||
});
|
||||
});
|
||||
this.set('rating_card_values', ratingData);
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -59,35 +59,19 @@ publicWidget.registry.PurchasePortalSidebar = PortalSidebar.extend({
|
||||
"id",
|
||||
""
|
||||
);
|
||||
_.each(this.spyWatched.find("#quote_content h2, #quote_content h3"), function (el) {
|
||||
var id, text;
|
||||
switch (el.tagName.toLowerCase()) {
|
||||
case "h2":
|
||||
id = self._setElementId("quote_header_", el);
|
||||
text = self._extractText($(el));
|
||||
if (!text) {
|
||||
break;
|
||||
}
|
||||
lastLI = $("<li class='nav-item'>")
|
||||
.append(
|
||||
$(
|
||||
'<a class="nav-link" style="max-width: 200px;" href="#' + id + '"/>'
|
||||
).text(text)
|
||||
)
|
||||
.appendTo($bsSidenav);
|
||||
lastUL = false;
|
||||
break;
|
||||
case "h3":
|
||||
id = self._setElementId("quote_", el);
|
||||
text = self._extractText($(el));
|
||||
if (!text) {
|
||||
break;
|
||||
}
|
||||
if (lastLI) {
|
||||
if (!lastUL) {
|
||||
lastUL = $("<ul class='nav flex-column'>").appendTo(lastLI);
|
||||
this.spyWatched
|
||||
.find("#quote_content h2, #quote_content h3")
|
||||
.toArray()
|
||||
.forEach((el) => {
|
||||
var id, text;
|
||||
switch (el.tagName.toLowerCase()) {
|
||||
case "h2":
|
||||
id = self._setElementId("quote_header_", el);
|
||||
text = self._extractText($(el));
|
||||
if (!text) {
|
||||
break;
|
||||
}
|
||||
$("<li class='nav-item'>")
|
||||
lastLI = $("<li class='nav-item'>")
|
||||
.append(
|
||||
$(
|
||||
'<a class="nav-link" style="max-width: 200px;" href="#' +
|
||||
@@ -95,12 +79,33 @@ publicWidget.registry.PurchasePortalSidebar = PortalSidebar.extend({
|
||||
'"/>'
|
||||
).text(text)
|
||||
)
|
||||
.appendTo(lastUL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
el.setAttribute("data-anchor", true);
|
||||
});
|
||||
.appendTo($bsSidenav);
|
||||
lastUL = false;
|
||||
break;
|
||||
case "h3":
|
||||
id = self._setElementId("quote_", el);
|
||||
text = self._extractText($(el));
|
||||
if (!text) {
|
||||
break;
|
||||
}
|
||||
if (lastLI) {
|
||||
if (!lastUL) {
|
||||
lastUL = $("<ul class='nav flex-column'>").appendTo(lastLI);
|
||||
}
|
||||
$("<li class='nav-item'>")
|
||||
.append(
|
||||
$(
|
||||
'<a class="nav-link" style="max-width: 200px;" href="#' +
|
||||
id +
|
||||
'"/>'
|
||||
).text(text)
|
||||
)
|
||||
.appendTo(lastUL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
el.setAttribute("data-anchor", true);
|
||||
});
|
||||
this.trigger_up("widgets_start_request", { $target: $bsSidenav });
|
||||
},
|
||||
/**
|
||||
@@ -113,19 +118,22 @@ publicWidget.registry.PurchasePortalSidebar = PortalSidebar.extend({
|
||||
_extractText: function ($node) {
|
||||
var self = this;
|
||||
var rawText = [];
|
||||
_.each($node.contents(), function (el) {
|
||||
var current = $(el);
|
||||
if ($.trim(current.text())) {
|
||||
var tagName = current.prop("tagName");
|
||||
if (
|
||||
_.isUndefined(tagName) ||
|
||||
(!_.isUndefined(tagName) &&
|
||||
_.contains(self.authorizedTextTag, tagName.toLowerCase()))
|
||||
) {
|
||||
rawText.push($.trim(current.text()));
|
||||
$node
|
||||
.contents()
|
||||
.toArray()
|
||||
.forEach((el) => {
|
||||
var current = $(el);
|
||||
if ($.trim(current.text())) {
|
||||
var tagName = current.prop("tagName");
|
||||
if (
|
||||
_.isUndefined(tagName) ||
|
||||
(!_.isUndefined(tagName) &&
|
||||
_.contains(self.authorizedTextTag, tagName.toLowerCase()))
|
||||
) {
|
||||
rawText.push($.trim(current.text()));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
return rawText.join(" ");
|
||||
},
|
||||
});
|
||||
|
||||
@@ -61,7 +61,7 @@ publicWidget.registry.SalePortalSidebar = PortalSidebar.extend({
|
||||
$bsSidenav = this.$el.find('.bs-sidenav');
|
||||
|
||||
$("#quote_content [id^=quote_header_], #quote_content [id^=quote_]", this.spyWatched).attr("id", "");
|
||||
_.each(this.spyWatched.find("#quote_content h2, #quote_content h3"), function (el) {
|
||||
this.spyWatched.find("#quote_content h2, #quote_content h3").toArray().forEach((el) => {
|
||||
var id, text;
|
||||
switch (el.tagName.toLowerCase()) {
|
||||
case "h2":
|
||||
@@ -101,7 +101,7 @@ publicWidget.registry.SalePortalSidebar = PortalSidebar.extend({
|
||||
_extractText: function ($node) {
|
||||
var self = this;
|
||||
var rawText = [];
|
||||
_.each($node.contents(), function (el) {
|
||||
$node.contents().toArray().forEach((el) => {
|
||||
var current = $(el);
|
||||
if ($.trim(current.text())) {
|
||||
var tagName = current.prop("tagName");
|
||||
|
||||
@@ -295,7 +295,7 @@ var VariantMixin = {
|
||||
'input.js_variant_change:checked',
|
||||
'select.js_variant_change'
|
||||
];
|
||||
_.each($container.find(variantsValuesSelectors.join(', ')), function (el) {
|
||||
$container.find(variantsValuesSelectors.join(', ')).toArray().forEach((el) => {
|
||||
values.push(+$(el).val());
|
||||
});
|
||||
|
||||
@@ -383,10 +383,10 @@ var VariantMixin = {
|
||||
// for each of them, contains array with the other ptav they exclude
|
||||
if (combinationData.exclusions) {
|
||||
// browse all the currently selected attributes
|
||||
_.each(combination, function (current_ptav) {
|
||||
Object.values(combination).forEach((current_ptav) => {
|
||||
if (combinationData.exclusions.hasOwnProperty(current_ptav)) {
|
||||
// for each exclusion of the current attribute:
|
||||
_.each(combinationData.exclusions[current_ptav], function (excluded_ptav) {
|
||||
Object.values(combinationData.exclusions[current_ptav]).forEach((excluded_ptav) => {
|
||||
// disable the excluded input (even when not already selected)
|
||||
// to give a visual feedback before click
|
||||
self._disableInput(
|
||||
@@ -439,10 +439,11 @@ var VariantMixin = {
|
||||
}
|
||||
|
||||
// parent exclusions (tell which attributes are excluded from parent)
|
||||
_.each(combinationData.parent_exclusions, function (exclusions, excluded_by){
|
||||
for (const [excluded_by, exclusions] of Object.entries(
|
||||
combinationData.parent_exclusions || {}
|
||||
)) {
|
||||
// check that the selected combination is in the parent exclusions
|
||||
_.each(exclusions, function (ptav) {
|
||||
|
||||
exclusions.forEach((ptav) => {
|
||||
// disable the excluded input (even when not already selected)
|
||||
// to give a visual feedback before click
|
||||
self._disableInput(
|
||||
@@ -453,7 +454,7 @@ var VariantMixin = {
|
||||
combinationData.parent_product_name
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Extracted to a method to be extendable by other modules
|
||||
|
||||
@@ -146,8 +146,8 @@ export const OptionalProductsModal = Dialog.extend(ServicesMixin, VariantMixin,
|
||||
this.$el.find('input[name="add_qty"]').val(this.rootProduct.quantity);
|
||||
|
||||
// set a unique id to each row for options hierarchy
|
||||
var $products = this.$el.find('tr.js_product');
|
||||
_.each($products, function (el) {
|
||||
var $products = this.$el.find('tr.js_product').toArray();
|
||||
$products.forEach((el) => {
|
||||
var $el = $(el);
|
||||
var uniqueId = self._getUniqueId(el);
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ patch(SaleOrderLineProductField.prototype, 'sale_product_configurator', {
|
||||
var customAttributeValues = mainProduct.product_custom_attribute_values;
|
||||
var customValuesCommands = [{ operation: "DELETE_ALL" }];
|
||||
if (customAttributeValues && customAttributeValues.length !== 0) {
|
||||
_.each(customAttributeValues, function (customValue) {
|
||||
customAttributeValues.forEach((customValue) => {
|
||||
customValuesCommands.push({
|
||||
operation: "CREATE",
|
||||
context: [
|
||||
|
||||
@@ -75,8 +75,8 @@ import BrowserDetection from "web.BrowserDetection";
|
||||
if (this.options.skipRenderOverlay) {
|
||||
return;
|
||||
}
|
||||
var accesskeyElements = $(document).find('[accesskey]').filter(':visible');
|
||||
_.each(accesskeyElements, function (elem) {
|
||||
var accesskeyElements = $(document).find('[accesskey]').filter(':visible').toArray();
|
||||
accesskeyElements.forEach((elem) => {
|
||||
var overlay = $(`<div class='o_web_accesskey_overlay font-sans-serif'>${$(elem).attr('accesskey').toUpperCase()}</div>`);
|
||||
|
||||
var $overlayParent;
|
||||
@@ -167,7 +167,7 @@ import BrowserDetection from "web.BrowserDetection";
|
||||
.not('[accesskey]')
|
||||
.not('[disabled]')
|
||||
.not('[tabindex="-1"]');
|
||||
_.each(buttonsWithoutAccessKey, function (elem) {
|
||||
buttonsWithoutAccessKey.toArray().forEach((elem) => {
|
||||
var buttonString = [elem.innerText, elem.title, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"].join('');
|
||||
for (var letterIndex = 0; letterIndex < buttonString.length; letterIndex++) {
|
||||
var candidateAccessKey = buttonString[letterIndex].toUpperCase();
|
||||
@@ -182,7 +182,7 @@ import BrowserDetection from "web.BrowserDetection";
|
||||
}
|
||||
|
||||
var elementsWithoutAriaKeyshortcut = this.$el.find('[accesskey]').not('[aria-keyshortcuts]');
|
||||
_.each(elementsWithoutAriaKeyshortcut, function (elem) {
|
||||
elementsWithoutAriaKeyshortcut.toArray().forEach((elem) => {
|
||||
elem.setAttribute('aria-keyshortcuts', 'Alt+Shift+' + elem.accessKey);
|
||||
});
|
||||
this._addAccessKeyOverlays();
|
||||
|
||||
@@ -164,9 +164,9 @@ function get_file(options) {
|
||||
} else {
|
||||
xhr.open('POST', options.url);
|
||||
data = new FormData();
|
||||
_.each(options.data || {}, function (v, k) {
|
||||
for (const [k, v] of Object.entries(options.data || {})) {
|
||||
data.append(k, v);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (core.csrf_token) {
|
||||
data.append('csrf_token', core.csrf_token);
|
||||
|
||||
@@ -73,7 +73,7 @@ OdooClass.extend = function() {
|
||||
initializing = false;
|
||||
|
||||
// Copy the properties over onto the new prototype
|
||||
_.each(prop, function(val, name) {
|
||||
Object.keys(prop).forEach((name) => {
|
||||
// Check if we're overwriting an existing function
|
||||
prototype[name] = typeof prop[name] == "function" &&
|
||||
fnTest.test(prop[name]) ?
|
||||
@@ -110,7 +110,7 @@ OdooClass.extend = function() {
|
||||
return this;
|
||||
}
|
||||
Class.include = function (properties) {
|
||||
_.each(properties, function(val, name) {
|
||||
Object.keys(properties).forEach((name) => {
|
||||
if (typeof properties[name] !== 'function'
|
||||
|| !fnTest.test(properties[name])) {
|
||||
prototype[name] = properties[name];
|
||||
|
||||
@@ -9,9 +9,7 @@ var Context = Class.extend({
|
||||
this.__contexts = [];
|
||||
this.__eval_context = null;
|
||||
var self = this;
|
||||
_.each(arguments, function (x) {
|
||||
self.add(x);
|
||||
});
|
||||
Object.values(arguments).forEach((x) => self.add(x));
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -220,7 +220,7 @@ var Domain = collections.Tree.extend({
|
||||
this._children.push(subdomain);
|
||||
} else {
|
||||
var self = this;
|
||||
_.each(subdomain._children, function (childDomain) {
|
||||
subdomain._children.forEach((childDomain) => {
|
||||
self._children.push(childDomain);
|
||||
});
|
||||
}
|
||||
@@ -330,7 +330,7 @@ var Domain = collections.Tree.extend({
|
||||
}
|
||||
|
||||
var stack = [];
|
||||
_.each(domain, function (dom) {
|
||||
domain.forEach((dom) => {
|
||||
if (dom === '|' || dom === '&') {
|
||||
stack.push(dom);
|
||||
} else {
|
||||
|
||||
@@ -31,7 +31,7 @@ var Throbber = Widget.extend({
|
||||
return;
|
||||
var seconds = (new Date().getTime() - self.start_time) / 1000;
|
||||
var mes;
|
||||
_.each(messages_by_seconds(), function(el) {
|
||||
messages_by_seconds().forEach((el) => {
|
||||
if (seconds >= el[0])
|
||||
mes = el[1];
|
||||
});
|
||||
@@ -58,7 +58,7 @@ if ($.blockUI) {
|
||||
function blockAccessKeys() {
|
||||
var elementWithAccessKey = [];
|
||||
elementWithAccessKey = document.querySelectorAll('[accesskey]');
|
||||
_.each(elementWithAccessKey, function (elem) {
|
||||
elementWithAccessKey.forEach((elem) => {
|
||||
elem.setAttribute("data-accesskey",elem.getAttribute('accesskey'));
|
||||
elem.removeAttribute('accesskey');
|
||||
});
|
||||
@@ -67,7 +67,7 @@ function blockAccessKeys() {
|
||||
function unblockAccessKeys() {
|
||||
var elementWithDataAccessKey = [];
|
||||
elementWithDataAccessKey = document.querySelectorAll('[data-accesskey]');
|
||||
_.each(elementWithDataAccessKey, function (elem) {
|
||||
elementWithDataAccessKey.forEach((elem) => {
|
||||
elem.setAttribute('accesskey', elem.getAttribute('data-accesskey'));
|
||||
elem.removeAttribute('data-accesskey');
|
||||
});
|
||||
|
||||
@@ -185,12 +185,12 @@ var Events = Class.extend({
|
||||
|
||||
callbackList: function () {
|
||||
var lst = [];
|
||||
_.each(this._callbacks || {}, function (el, eventName) {
|
||||
for (const [eventName, el] of Object.entries(this._callbacks || {})) {
|
||||
var node = el;
|
||||
while ((node = node.next) && node.next) {
|
||||
lst.push([eventName, node.callback, node.context]);
|
||||
}
|
||||
});
|
||||
}
|
||||
return lst;
|
||||
},
|
||||
|
||||
@@ -291,7 +291,7 @@ var EventDispatcherMixin = Object.assign({}, ParentedMixin, {
|
||||
throw new Error("Event handler must be a function.");
|
||||
}
|
||||
events = events.split(/\s+/);
|
||||
_.each(events, function (eventName) {
|
||||
events.forEach((eventName) => {
|
||||
self.__edispatcherEvents.on(eventName, func, dest);
|
||||
if (dest && dest.__eventDispatcherMixin) {
|
||||
dest.__edispatcherRegisteredEvents.push({name: eventName, func: func, source: self});
|
||||
@@ -302,7 +302,7 @@ var EventDispatcherMixin = Object.assign({}, ParentedMixin, {
|
||||
off: function (events, dest, func) {
|
||||
var self = this;
|
||||
events = events.split(/\s+/);
|
||||
_.each(events, function (eventName) {
|
||||
events.forEach((eventName) => {
|
||||
self.__edispatcherEvents.off(eventName, func, dest);
|
||||
if (dest && dest.__eventDispatcherMixin) {
|
||||
dest.__edispatcherRegisteredEvents = dest.__edispatcherRegisteredEvents.filter(el => {
|
||||
@@ -342,16 +342,18 @@ var EventDispatcherMixin = Object.assign({}, ParentedMixin, {
|
||||
},
|
||||
destroy: function () {
|
||||
var self = this;
|
||||
_.each(this.__edispatcherRegisteredEvents, function (event) {
|
||||
this.__edispatcherRegisteredEvents.forEach((event) => {
|
||||
event.source.__edispatcherEvents.off(event.name, event.func, self);
|
||||
});
|
||||
this.__edispatcherRegisteredEvents = [];
|
||||
_.each(this.__edispatcherEvents.callbackList(), function (cal) {
|
||||
this.off(cal[0], cal[2], cal[1]);
|
||||
}, this);
|
||||
this.__edispatcherEvents.callbackList().forEach(
|
||||
((cal) => {
|
||||
this.off(cal[0], cal[2], cal[1]);
|
||||
}).bind(this)
|
||||
);
|
||||
this.__edispatcherEvents.off();
|
||||
ParentedMixin.destroy.call(this);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -376,7 +378,7 @@ var PropertiesMixin = Object.assign({}, EventDispatcherMixin, {
|
||||
}
|
||||
var self = this;
|
||||
var changed = false;
|
||||
_.each(map, function (val, key) {
|
||||
for (const [key, val] of Object.entries(map)) {
|
||||
var tmp = self.__getterSetterInternalMap[key];
|
||||
if (tmp === val)
|
||||
return;
|
||||
@@ -399,7 +401,7 @@ var PropertiesMixin = Object.assign({}, EventDispatcherMixin, {
|
||||
oldValue: tmp,
|
||||
newValue: val
|
||||
});
|
||||
});
|
||||
}
|
||||
if (changed)
|
||||
self.trigger("change", self);
|
||||
},
|
||||
|
||||
@@ -175,7 +175,7 @@ function eval_domains(domains, evaluation_context) {
|
||||
*/
|
||||
function get_normalized_domain(domain_array) {
|
||||
var expected = 1; // Holds the number of expected domain expressions
|
||||
_.each(domain_array, function (item) {
|
||||
domain_array.forEach((item) => {
|
||||
if (item === "&" || item === "|") {
|
||||
expected++;
|
||||
} else if (item !== "!") {
|
||||
|
||||
@@ -24,7 +24,7 @@ var TranslationDataBase = Class.extend(/** @lends instance.TranslationDataBase#
|
||||
if (_.include(modules, "web")) {
|
||||
modules = ["web"].concat(_.without(modules, "web"));
|
||||
}
|
||||
_.each(modules, function(name) {
|
||||
modules.forEach((name) => {
|
||||
self.add_module_translation(translation_bundle.modules[name]);
|
||||
});
|
||||
if (translation_bundle.lang_parameters) {
|
||||
@@ -34,7 +34,7 @@ var TranslationDataBase = Class.extend(/** @lends instance.TranslationDataBase#
|
||||
},
|
||||
add_module_translation: function(mod) {
|
||||
var self = this;
|
||||
_.each(mod.messages, function(message) {
|
||||
mod.messages.forEach((message) => {
|
||||
self.db[message.id] = message.string;
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1077,7 +1077,9 @@ const utils = {
|
||||
*/
|
||||
traverse: function (tree, f) {
|
||||
if (f(tree)) {
|
||||
_.each(tree.children, function (c) { utils.traverse(c, f); });
|
||||
Object.values(tree.children || {}).forEach((c) => {
|
||||
utils.traverse(c, f);
|
||||
});
|
||||
}
|
||||
},
|
||||
/**
|
||||
@@ -1090,7 +1092,7 @@ const utils = {
|
||||
traversePath: function (tree, f, path) {
|
||||
path = path || [];
|
||||
f(tree, path);
|
||||
_.each(tree.children, function (node) {
|
||||
Object.values(tree.children || {}).forEach((node) => {
|
||||
utils.traversePath(node, f, path.concat(tree));
|
||||
});
|
||||
},
|
||||
|
||||
@@ -254,7 +254,7 @@ var FieldMany2One = AbstractField.extend({
|
||||
this.$input.autocomplete({
|
||||
source: function (req, resp) {
|
||||
self.suggestions = [];
|
||||
_.each(self._autocompleteSources, function (source) {
|
||||
self._autocompleteSources.forEach((source) => {
|
||||
// Resets the results for this source
|
||||
source.results = [];
|
||||
|
||||
@@ -357,7 +357,7 @@ var FieldMany2One = AbstractField.extend({
|
||||
*/
|
||||
_concatenateAutocompleteResults: function () {
|
||||
var results = [];
|
||||
_.each(this._autocompleteSources, function (source) {
|
||||
this._autocompleteSources.forEach((source) => {
|
||||
if (source.results && source.results.length) {
|
||||
results = results.concat(source.results);
|
||||
} else if (source.loading) {
|
||||
@@ -1630,7 +1630,7 @@ var FieldRadio = FieldSelection.extend({
|
||||
this.$el.empty();
|
||||
this.$el.attr('role', 'radiogroup')
|
||||
.attr('aria-label', this.string);
|
||||
_.each(this.values, function (value, index) {
|
||||
this.values.forEach((value, index) => {
|
||||
self.$el.append(qweb.render('FieldRadio.button', {
|
||||
checked: value[0] === currentValue,
|
||||
id: self.unique_id + '_' + value[0],
|
||||
|
||||
@@ -324,8 +324,8 @@ export const PublicRoot = publicWidget.RootWidget.extend({
|
||||
* @private
|
||||
*/
|
||||
_onWebsiteFormSubmit: function (ev) {
|
||||
var $buttons = $(ev.currentTarget).find('button[type="submit"], a.a-submit');
|
||||
_.each($buttons, function (btn) {
|
||||
var $buttons = $(ev.currentTarget).find('button[type="submit"], a.a-submit').toArray();
|
||||
$buttons.forEach((btn) => {
|
||||
var $btn = $(btn);
|
||||
$btn.prepend('<i class="fa fa-circle-o-notch fa-spin"></i> ');
|
||||
$btn.prop('disabled', true);
|
||||
|
||||
@@ -197,7 +197,7 @@ var PublicWidget = Widget.extend({
|
||||
var originalEvents = this.events;
|
||||
|
||||
var events = {};
|
||||
_.each(this.events, function (method, event) {
|
||||
Object.entries(this.events || {}).forEach(([event, method]) => {
|
||||
// If the method is a function, use the default Widget system
|
||||
if (typeof method !== 'string') {
|
||||
events[event] = method;
|
||||
|
||||
@@ -14,12 +14,12 @@ import translation from "web.translation";
|
||||
*/
|
||||
var bus = new Bus();
|
||||
|
||||
_.each('click,dblclick,keydown,keypress,keyup'.split(','), function (evtype) {
|
||||
["click","dblclick","keydown","keypress","keyup"].forEach((evtype) => {
|
||||
$('html').on(evtype, function (ev) {
|
||||
bus.trigger(evtype, ev);
|
||||
});
|
||||
});
|
||||
_.each('resize,scroll'.split(','), function (evtype) {
|
||||
["resize", "scroll"].forEach((evtype) => {
|
||||
$(window).on(evtype, function (ev) {
|
||||
bus.trigger(evtype, ev);
|
||||
});
|
||||
|
||||
@@ -370,7 +370,7 @@ var BasicModel = AbstractModel.extend({
|
||||
context: context,
|
||||
})
|
||||
.then(function () {
|
||||
_.each(records, function (record) {
|
||||
records.forEach((record) => {
|
||||
// discard any changes to prevent creating a new record with auto-save
|
||||
self.discardChanges(record.id);
|
||||
var parent = record.parentID && self.localData[record.parentID];
|
||||
@@ -610,7 +610,7 @@ var BasicModel = AbstractModel.extend({
|
||||
this._sortList(element);
|
||||
|
||||
if (!element.orderedResIDs && element._changes) {
|
||||
_.each(element._changes, function (change) {
|
||||
element._changes.forEach((change) => {
|
||||
if (change.operation === 'ADD' && change.isNew) {
|
||||
element.data = _.without(element.data, change.id);
|
||||
if (change.position === 'top') {
|
||||
@@ -842,13 +842,13 @@ var BasicModel = AbstractModel.extend({
|
||||
var self = this;
|
||||
var defs = [];
|
||||
var record_fields = {};
|
||||
_.each(fields, function (field) {
|
||||
fields.forEach((field) => {
|
||||
record_fields[field.name] = _.pick(field, 'type', 'relation', 'domain', 'selection');
|
||||
});
|
||||
fieldInfo = fieldInfo || {};
|
||||
var fieldsInfo = {};
|
||||
fieldsInfo.default = {};
|
||||
_.each(fields, function (field) {
|
||||
fields.forEach((field) => {
|
||||
fieldsInfo.default[field.name] = fieldInfo[field.name] || {};
|
||||
});
|
||||
var record = this._makeDataPoint({
|
||||
@@ -857,7 +857,7 @@ var BasicModel = AbstractModel.extend({
|
||||
fieldsInfo: fieldsInfo,
|
||||
viewType: 'default',
|
||||
});
|
||||
_.each(fields, function (field) {
|
||||
fields.forEach((field) => {
|
||||
var dataPoint;
|
||||
record.data[field.name] = null;
|
||||
if (field.type === 'many2one') {
|
||||
@@ -890,7 +890,7 @@ var BasicModel = AbstractModel.extend({
|
||||
} else if (field.type === 'one2many' || field.type === 'many2many') {
|
||||
var relatedFieldsInfo = {};
|
||||
relatedFieldsInfo.default = {};
|
||||
_.each(field.fields, function (field) {
|
||||
(field.fields || []).forEach((field) => {
|
||||
relatedFieldsInfo.default[field.name] = {};
|
||||
});
|
||||
var dpParams = {
|
||||
@@ -910,7 +910,7 @@ var BasicModel = AbstractModel.extend({
|
||||
if (_.isObject(field.value[0])) {
|
||||
dpParams.res_ids = _.pluck(field.value, 'id');
|
||||
dataPoint = self._makeDataPoint(dpParams);
|
||||
_.each(field.value, function (data) {
|
||||
field.value.forEach((data) => {
|
||||
var recordDP = self._makeDataPoint({
|
||||
data: data,
|
||||
modelName: field.relation,
|
||||
@@ -1061,7 +1061,7 @@ var BasicModel = AbstractModel.extend({
|
||||
if (data.data.length) {
|
||||
var dataType = self.localData[data.data[0]].type;
|
||||
if (dataType === 'record') {
|
||||
_.each(data.data, function (dataPoint) {
|
||||
data.data.forEach((dataPoint) => {
|
||||
var recordData = self.localData[dataPoint].data;
|
||||
var inRecords = _.findWhere(records, {id: recordData.id});
|
||||
if (inRecords) {
|
||||
@@ -1079,7 +1079,7 @@ var BasicModel = AbstractModel.extend({
|
||||
}
|
||||
}
|
||||
data.res_ids = [];
|
||||
_.each(data.data, function (d) {
|
||||
data.data.forEach((d) => {
|
||||
var dataPoint = self.localData[d];
|
||||
if (dataPoint.type === 'record') {
|
||||
data.res_ids.push(dataPoint.res_id);
|
||||
@@ -1144,7 +1144,7 @@ var BasicModel = AbstractModel.extend({
|
||||
|
||||
if (method === 'create') {
|
||||
var fieldNames = record.getFieldNames();
|
||||
_.each(fieldNames, function (name) {
|
||||
fieldNames.forEach((name) => {
|
||||
if (changes[name] === null) {
|
||||
delete changes[name];
|
||||
}
|
||||
@@ -1238,7 +1238,7 @@ var BasicModel = AbstractModel.extend({
|
||||
if (list.type === 'record') {
|
||||
return;
|
||||
} else if (list._changes) {
|
||||
_.each(list._changes, function (change) {
|
||||
list._changes.forEach((change) => {
|
||||
delete change.isNew;
|
||||
});
|
||||
}
|
||||
@@ -1460,7 +1460,7 @@ var BasicModel = AbstractModel.extend({
|
||||
var additionalContexts = options && options.context;
|
||||
var makeDefaultRecords = [];
|
||||
if (additionalContexts){
|
||||
_.each(additionalContexts, function (context) {
|
||||
additionalContexts.forEach((context) => {
|
||||
params.context = self._getContext(list, {additionalContext: context, full: true, sanitize_default_values: true});
|
||||
makeDefaultRecords.push(self._makeDefaultRecord(list.model, params));
|
||||
});
|
||||
@@ -1471,7 +1471,7 @@ var BasicModel = AbstractModel.extend({
|
||||
|
||||
return Promise.all(makeDefaultRecords).then(function (resultIds){
|
||||
var ids = [];
|
||||
_.each(resultIds, function (id){
|
||||
resultIds.forEach((id) => {
|
||||
ids.push(id);
|
||||
|
||||
list._changes.push({operation: 'ADD', id: id, position: position, isNew: true});
|
||||
@@ -1800,7 +1800,7 @@ var BasicModel = AbstractModel.extend({
|
||||
|
||||
// save it in case of a [5] which will remove the _changes
|
||||
var oldChanges = list._changes;
|
||||
_.each(val, function (command) {
|
||||
val.forEach((command) => {
|
||||
var rec, recID;
|
||||
if (command[0] === 0 || command[0] === 1) {
|
||||
// CREATE or UPDATE
|
||||
@@ -1860,7 +1860,7 @@ var BasicModel = AbstractModel.extend({
|
||||
list._changes = [{operation: 'REMOVE_ALL'}];
|
||||
} else if (command[0] === 6) {
|
||||
list._changes = [{operation: 'REMOVE_ALL'}];
|
||||
_.each(command[2], function (resID) {
|
||||
Object.values(command[2] || {}).forEach((resID) => {
|
||||
linkRecord(list, resID);
|
||||
});
|
||||
}
|
||||
@@ -1988,7 +1988,7 @@ var BasicModel = AbstractModel.extend({
|
||||
}
|
||||
|
||||
var list_records = {};
|
||||
_.each(data, function (d) {
|
||||
data.forEach((d) => {
|
||||
rec = self._makeDataPoint({
|
||||
context: record.context,
|
||||
modelName: field.relation,
|
||||
@@ -2016,7 +2016,7 @@ var BasicModel = AbstractModel.extend({
|
||||
args: [_.pluck(data, 'id'), fieldNames],
|
||||
context: Object.assign({}, record.context, field.context, list.getContext()),
|
||||
}).then(function (records) {
|
||||
_.each(records, function (record) {
|
||||
records.forEach((record) => {
|
||||
list_records[record.id].data = record;
|
||||
self._parseServerData(fieldNames, list, record);
|
||||
});
|
||||
@@ -2036,7 +2036,7 @@ var BasicModel = AbstractModel.extend({
|
||||
createOptions.viewType = fieldInfo.mode;
|
||||
|
||||
def = this._addX2ManyDefaultRecord(list, createOptions).then(function (ids) {
|
||||
_.each(ids, function(id){
|
||||
ids.forEach((id) => {
|
||||
if (command.position === 'bottom' && list.orderedResIDs && list.orderedResIDs.length >= list.limit) {
|
||||
list.tempLimitIncrement = (list.tempLimitIncrement || 0) + 1;
|
||||
list.limit += 1;
|
||||
@@ -2121,7 +2121,7 @@ var BasicModel = AbstractModel.extend({
|
||||
return Promise.all([addDef, removedDef]);
|
||||
case 'MULTI':
|
||||
// allows batching multiple operations
|
||||
_.each(command.commands, function (innerCommand){
|
||||
command.commands.forEach((innerCommand) => {
|
||||
defs.push(self._applyX2ManyChange(
|
||||
record,
|
||||
fieldName,
|
||||
@@ -2170,7 +2170,7 @@ var BasicModel = AbstractModel.extend({
|
||||
var to = options.to === 0 ? 0 : (options.to || changes.length);
|
||||
changes = changes.slice(options.from || 0, to);
|
||||
}
|
||||
_.each(changes, function (change) {
|
||||
changes.forEach((change) => {
|
||||
var relRecord;
|
||||
if (change.id) {
|
||||
relRecord = self.localData[change.id];
|
||||
@@ -2234,7 +2234,7 @@ var BasicModel = AbstractModel.extend({
|
||||
// and their subviews
|
||||
function generateSpecs(fieldsInfo, fields, prefix) {
|
||||
prefix = prefix || '';
|
||||
_.each(Object.keys(fieldsInfo), function (name) {
|
||||
Object.keys(fieldsInfo).forEach((name) => {
|
||||
var field = fields[name];
|
||||
var fieldInfo = fieldsInfo[name];
|
||||
var key = prefix + name;
|
||||
@@ -2243,7 +2243,7 @@ var BasicModel = AbstractModel.extend({
|
||||
hasOnchange = true;
|
||||
}
|
||||
if (field.type === 'one2many' || field.type === 'many2many') {
|
||||
_.each(fieldInfo.views, function (view) {
|
||||
Object.values(fieldInfo.views || {}).forEach((view) => {
|
||||
generateSpecs(view.fieldsInfo[view.type], view.fields, key + '.');
|
||||
});
|
||||
}
|
||||
@@ -2492,7 +2492,7 @@ var BasicModel = AbstractModel.extend({
|
||||
var ids = [];
|
||||
list = this._applyX2ManyOperations(list);
|
||||
|
||||
_.each(list.data, function (localId) {
|
||||
list.data.forEach((localId) => {
|
||||
var record = self.localData[localId];
|
||||
var data = record._changes || record.data;
|
||||
var many2oneId = data[fieldName];
|
||||
@@ -2515,7 +2515,7 @@ var BasicModel = AbstractModel.extend({
|
||||
context: list.context,
|
||||
})
|
||||
.then(function (name_gets) {
|
||||
_.each(records, function (record) {
|
||||
records.forEach((record) => {
|
||||
var nameGet = name_gets.find(nameGet => nameGet[0] === record.data.id);
|
||||
record.data.display_name = nameGet[1];
|
||||
});
|
||||
@@ -2619,9 +2619,9 @@ var BasicModel = AbstractModel.extend({
|
||||
args: [ids],
|
||||
context: self.localData[parent].getContext({fieldName: fieldName, withoutRecordData: true}),
|
||||
}).then(function (result) {
|
||||
_.each(result, function (el) {
|
||||
result.forEach((el) => {
|
||||
var parentIDs = datapoints[el[0]];
|
||||
_.each(parentIDs, function (parentID) {
|
||||
parentIDs.forEach((parentID) => {
|
||||
var parent = self.localData[parentID];
|
||||
var referenceDp = self._makeDataPoint({
|
||||
data: {
|
||||
@@ -2649,7 +2649,7 @@ var BasicModel = AbstractModel.extend({
|
||||
var self = this;
|
||||
var defs = [];
|
||||
var fieldNames = options && options.fieldNames || record.getFieldNames();
|
||||
_.each(fieldNames, function (fieldName) {
|
||||
fieldNames.forEach((fieldName) => {
|
||||
var field = record.fields[fieldName];
|
||||
if (field.type === 'reference') {
|
||||
var def = self._fetchReference(record, fieldName).then(function (dataPoint) {
|
||||
@@ -2679,7 +2679,7 @@ var BasicModel = AbstractModel.extend({
|
||||
var toFetch = this._getDataToFetchByModel(list, fieldName);
|
||||
var defs = [];
|
||||
// one name_get by model
|
||||
_.each(toFetch, function (datapoints, model) {
|
||||
Object.entries(toFetch).forEach(([model, datapoints]) => {
|
||||
defs.push(self._fetchReferenceData(datapoints, model, fieldName));
|
||||
});
|
||||
|
||||
@@ -2715,14 +2715,14 @@ var BasicModel = AbstractModel.extend({
|
||||
|
||||
// collect ids by model
|
||||
var toFetch = {};
|
||||
_.each(list.data, function (groupIndex) {
|
||||
list.data.forEach((groupIndex) => {
|
||||
var group = self.localData[groupIndex];
|
||||
self._getDataToFetchByModel(group, fieldName, toFetch);
|
||||
});
|
||||
|
||||
var defs = [];
|
||||
// one name_get by model
|
||||
_.each(toFetch, function (datapoints, model) {
|
||||
Object.entries(toFetch).forEach(([model, datapoints]) => {
|
||||
defs.push(self._fetchReferenceData(datapoints, model, fieldName));
|
||||
});
|
||||
|
||||
@@ -2958,7 +2958,7 @@ var BasicModel = AbstractModel.extend({
|
||||
var foldField = fieldInfo.options.fold_field;
|
||||
var fieldsToRead = foldField ? [foldField] : [];
|
||||
return this._fetchSpecialMany2ones(record, fieldName, fieldInfo, fieldsToRead).then(function (m2os) {
|
||||
_.each(m2os, function (m2o) {
|
||||
Object.values(m2os || {}).forEach((m2o) => {
|
||||
m2o.fold = foldField ? m2o[foldField] : false;
|
||||
});
|
||||
return m2os;
|
||||
@@ -3042,7 +3042,7 @@ var BasicModel = AbstractModel.extend({
|
||||
options = options || {};
|
||||
var fieldNames = options.fieldNames || record.getFieldNames(options);
|
||||
var viewType = options.viewType || record.viewType;
|
||||
_.each(fieldNames, function (fieldName) {
|
||||
fieldNames.forEach((fieldName) => {
|
||||
var field = record.fields[fieldName];
|
||||
if (field.type === 'one2many' || field.type === 'many2many') {
|
||||
var fieldInfo = record.fieldsInfo[viewType][fieldName];
|
||||
@@ -3119,10 +3119,10 @@ var BasicModel = AbstractModel.extend({
|
||||
_fetchX2ManySingleBatch: function (list, fieldName) {
|
||||
var self = this;
|
||||
var toFetch = {};
|
||||
_.each(list.data, function (groupIndex) {
|
||||
list.data.forEach((groupIndex) => {
|
||||
var group = self.localData[groupIndex];
|
||||
var nextDataToFetch = self._getDataToFetch(group, fieldName);
|
||||
_.each(Object.keys(nextDataToFetch), function (id) {
|
||||
Object.keys(nextDataToFetch).forEach((id) => {
|
||||
if (toFetch[id]) {
|
||||
toFetch[id] = toFetch[id].concat(nextDataToFetch[id]);
|
||||
} else {
|
||||
@@ -3304,7 +3304,7 @@ var BasicModel = AbstractModel.extend({
|
||||
var oldResIDs = list.res_ids.slice(0);
|
||||
var relRecordAdded = [];
|
||||
var relRecordUpdated = [];
|
||||
_.each(list._changes, function (change) {
|
||||
Object.values(list._changes || {}).forEach((change) => {
|
||||
if (change.operation === 'ADD' && change.id) {
|
||||
relRecordAdded.push(self.localData[change.id]);
|
||||
} else if (change.operation === 'UPDATE' && !self.isNew(change.id)) {
|
||||
@@ -3325,13 +3325,13 @@ var BasicModel = AbstractModel.extend({
|
||||
// and 2) to guard against concurrent updates (policy: force
|
||||
// a complete override of the actual value of the m2m)
|
||||
commands[fieldName].push(x2ManyCommands.replace_with(realIDs));
|
||||
_.each(relRecordCreated, function (relRecord) {
|
||||
relRecordCreated.forEach((relRecord) => {
|
||||
var changes = self._generateChanges(relRecord, options);
|
||||
commands[fieldName].push(x2ManyCommands.create(relRecord.ref, changes));
|
||||
});
|
||||
// generate update commands for records that have been
|
||||
// updated (it may happen with editable lists)
|
||||
_.each(relRecordUpdated, function (relRecord) {
|
||||
relRecordUpdated.forEach((relRecord) => {
|
||||
var changes = self._generateChanges(relRecord, options);
|
||||
if (!_.isEmpty(changes)) {
|
||||
var command = x2ManyCommands.update(relRecord.res_id, changes);
|
||||
@@ -3533,7 +3533,7 @@ var BasicModel = AbstractModel.extend({
|
||||
return;
|
||||
}
|
||||
|
||||
_.each(record.data[fieldName], function (id) {
|
||||
Object.values(record.data[fieldName] || {}).forEach((id) => {
|
||||
toFetch[id] = toFetch[id] || [];
|
||||
toFetch[id].push(record);
|
||||
});
|
||||
@@ -3571,7 +3571,7 @@ var BasicModel = AbstractModel.extend({
|
||||
_getDataToFetchByModel: function (list, fieldName, toFetchAcc) {
|
||||
var self = this;
|
||||
var toFetch = toFetchAcc || {};
|
||||
_.each(list.data, function (dataPoint) {
|
||||
list.data.forEach((dataPoint) => {
|
||||
var record = self.localData[dataPoint];
|
||||
var value = record.data[fieldName];
|
||||
// if the reference field has already been fetched, the value is a
|
||||
@@ -3828,11 +3828,11 @@ var BasicModel = AbstractModel.extend({
|
||||
*/
|
||||
_getMany2OneFieldNames: function (datapoint) {
|
||||
var many2ones = [];
|
||||
_.each(datapoint.fields, function (field, name) {
|
||||
for (const [name, field] of Object.entries(datapoint.fields)) {
|
||||
if (field.type === 'many2one') {
|
||||
many2ones.push(name);
|
||||
}
|
||||
});
|
||||
}
|
||||
return many2ones;
|
||||
},
|
||||
/**
|
||||
@@ -4043,7 +4043,7 @@ var BasicModel = AbstractModel.extend({
|
||||
var self = this;
|
||||
var isValid = true;
|
||||
var element = this.localData[id];
|
||||
_.each(element._changes, function (command) {
|
||||
Object.values(element._changes || {}).forEach((command) => {
|
||||
if (command.operation === 'DELETE' ||
|
||||
command.operation === 'FORGET' ||
|
||||
(command.operation === 'ADD' && !command.isNew)||
|
||||
@@ -4052,7 +4052,7 @@ var BasicModel = AbstractModel.extend({
|
||||
}
|
||||
var recordData = self.get(command.id, {raw: true}).data;
|
||||
var record = self.localData[command.id];
|
||||
_.each(element.getFieldNames(), function (fieldName) {
|
||||
element.getFieldNames().forEach((fieldName) => {
|
||||
var field = element.fields[fieldName];
|
||||
var fieldInfo = element.fieldsInfo[element.viewType][fieldName];
|
||||
var rawModifiers = fieldInfo.modifiers || {};
|
||||
@@ -4312,7 +4312,7 @@ var BasicModel = AbstractModel.extend({
|
||||
*/
|
||||
_parseServerData: function (fieldNames, element, data) {
|
||||
var self = this;
|
||||
_.each(fieldNames, function (fieldName) {
|
||||
fieldNames.forEach((fieldName) => {
|
||||
var field = element.fields[fieldName];
|
||||
var val = data[fieldName];
|
||||
if (field.type === 'many2one') {
|
||||
@@ -4500,7 +4500,7 @@ var BasicModel = AbstractModel.extend({
|
||||
var viewType = options && options.viewType || record.viewType;
|
||||
var defs = [];
|
||||
|
||||
_.each(record.getFieldNames(options), function (name) {
|
||||
record.getFieldNames(options).forEach((name) => {
|
||||
var field = record.fields[name];
|
||||
var fieldInfo = record.fieldsInfo[viewType][name] || {};
|
||||
var options = fieldInfo.options || {};
|
||||
@@ -4593,7 +4593,7 @@ var BasicModel = AbstractModel.extend({
|
||||
if (!isCommandList) {
|
||||
commands = [[6, false, commands]];
|
||||
}
|
||||
_.each(commands, function (value) {
|
||||
commands.forEach((value) => {
|
||||
// value is a command
|
||||
if (value[0] === 0) {
|
||||
// CREATE
|
||||
@@ -4610,7 +4610,7 @@ var BasicModel = AbstractModel.extend({
|
||||
x2manyList._cache[r.res_id] = r.id;
|
||||
|
||||
// this is necessary so the fields are initialized
|
||||
_.each(r.getFieldNames(), function (fieldName) {
|
||||
r.getFieldNames().forEach((fieldName) => {
|
||||
r.data[fieldName] = null;
|
||||
});
|
||||
|
||||
@@ -4654,7 +4654,7 @@ var BasicModel = AbstractModel.extend({
|
||||
}
|
||||
if (value[0] === 6) {
|
||||
// REPLACE_WITH
|
||||
_.each(value[2], function (res_id) {
|
||||
value[2].forEach((res_id) => {
|
||||
x2manyList._changes.push({operation: 'ADD', resID: res_id});
|
||||
});
|
||||
var def = self._readUngroupedList(x2manyList).then(function () {
|
||||
@@ -4668,7 +4668,7 @@ var BasicModel = AbstractModel.extend({
|
||||
});
|
||||
|
||||
// fetch many2ones display_name
|
||||
_.each(Object.keys(many2ones), function (name) {
|
||||
Object.keys(many2ones).forEach((name) => {
|
||||
defs.push(self._fetchNameGets(x2manyList, name));
|
||||
});
|
||||
|
||||
@@ -4716,7 +4716,7 @@ var BasicModel = AbstractModel.extend({
|
||||
}));
|
||||
}
|
||||
return def.then(function (records) {
|
||||
_.each(resIDs, function (id) {
|
||||
resIDs.forEach((id) => {
|
||||
var dataPoint;
|
||||
var data = _.findWhere(records, {id: id});
|
||||
if (id in list._cache) {
|
||||
@@ -4741,7 +4741,7 @@ var BasicModel = AbstractModel.extend({
|
||||
list._cache[id] = dataPoint.id;
|
||||
}
|
||||
// set the dataPoint id in potential 'ADD' operation adding the current record
|
||||
_.each(list._changes, function (change) {
|
||||
Object.values(list._changes || {}).forEach((change) => {
|
||||
if (change.operation === 'ADD' && !change.id && change.resID === id) {
|
||||
change.id = dataPoint.id;
|
||||
}
|
||||
@@ -4796,14 +4796,14 @@ var BasicModel = AbstractModel.extend({
|
||||
var defs = [];
|
||||
var openGroupCount = 0;
|
||||
|
||||
_.each(groups, function (group) {
|
||||
groups.forEach((group) => {
|
||||
var aggregateValues = {};
|
||||
_.each(group, function (value, key) {
|
||||
for (const [key, value] of Object.entries(group)) {
|
||||
if (_.contains(fields, key) && key !== groupByField &&
|
||||
AGGREGATABLE_TYPES.includes(list.fields[key].type)) {
|
||||
aggregateValues[key] = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
// When a view is grouped, we need to display the name of each group in
|
||||
// the 'title'.
|
||||
var value = group[groupByField];
|
||||
@@ -4871,7 +4871,7 @@ var BasicModel = AbstractModel.extend({
|
||||
// Note that these groups are put after existing groups so
|
||||
// the order is not conserved. A sort *might* be useful.
|
||||
var emptyGroupsIDs = _.difference(_.pluck(previousGroups, 'id'), list.data);
|
||||
_.each(emptyGroupsIDs, function (groupID) {
|
||||
emptyGroupsIDs.forEach((groupID) => {
|
||||
list.data.push(groupID);
|
||||
var emptyGroup = self.localData[groupID];
|
||||
// this attribute hasn't been updated in the previous
|
||||
@@ -4993,7 +4993,7 @@ var BasicModel = AbstractModel.extend({
|
||||
}
|
||||
} else if (element._changes) {
|
||||
delete element.tempLimitIncrement;
|
||||
_.each(element._changes, function (change) {
|
||||
element._changes.forEach((change) => {
|
||||
delete change.isNew;
|
||||
});
|
||||
}
|
||||
@@ -5161,7 +5161,7 @@ var BasicModel = AbstractModel.extend({
|
||||
idsInRange = list.res_ids;
|
||||
}
|
||||
list.data = [];
|
||||
_.each(idsInRange, function (id) {
|
||||
idsInRange.forEach((id) => {
|
||||
if (list._cache[id]) {
|
||||
list.data.push(list._cache[id]);
|
||||
}
|
||||
@@ -5320,10 +5320,10 @@ var BasicModel = AbstractModel.extend({
|
||||
var viewType = view ? view.type : fieldInfo.viewType;
|
||||
var id2Values = new Map(values.map((value) => [value.id, value]))
|
||||
|
||||
_.each(records, function (record) {
|
||||
records.forEach((record) => {
|
||||
var x2mList = self.localData[record.data[fieldName]];
|
||||
x2mList.data = [];
|
||||
_.each(x2mList.res_ids, function (res_id) {
|
||||
x2mList.res_ids.forEach((res_id) => {
|
||||
var dataPoint = self._makeDataPoint({
|
||||
modelName: field.relation,
|
||||
data: id2Values.get(res_id),
|
||||
@@ -5408,7 +5408,7 @@ var BasicModel = AbstractModel.extend({
|
||||
}
|
||||
if (element.type === 'list') {
|
||||
element = this._applyX2ManyOperations(element);
|
||||
_.each(element.data, function (elemId) {
|
||||
element.data.forEach((elemId) => {
|
||||
var elem = self.localData[elemId];
|
||||
self._visitChildren(elem, fn);
|
||||
});
|
||||
|
||||
@@ -41,11 +41,11 @@ var StandaloneFieldManagerMixin = Object.assign({}, FieldManagerMixin, {
|
||||
_confirmChange: function (id, fields, event) {
|
||||
var result = FieldManagerMixin._confirmChange.apply(this, arguments);
|
||||
var record = this.model.get(id);
|
||||
_.each(this.registeredWidgets[id], function (widget, fieldName) {
|
||||
for (const [fieldName, widget] of Object.entries(this.registeredWidgets[id])) {
|
||||
if (_.contains(fields, fieldName)) {
|
||||
widget.reset(record, event);
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
|
||||
@@ -135,9 +135,9 @@ var ColorpickerWidget = Widget.extend({
|
||||
var self = this;
|
||||
|
||||
// Update inputs
|
||||
_.each(this.colorComponents, function (value, color) {
|
||||
for (const [color, value] of Object.entries(this.colorComponents)) {
|
||||
self.$(`.o_${color}_input`).val(value);
|
||||
});
|
||||
}
|
||||
|
||||
// Update preview
|
||||
this.$('.o_color_preview').css('background-color', this.colorComponents.cssColor);
|
||||
|
||||
@@ -222,7 +222,7 @@ var DomainTree = DomainNode.extend({
|
||||
getDomain: function () {
|
||||
var childDomains = [];
|
||||
var nbChildren = 0;
|
||||
_.each(this.children, function (child) {
|
||||
this.children.forEach((child) => {
|
||||
var childDomain = child.getDomain();
|
||||
if (childDomain.length) {
|
||||
nbChildren++;
|
||||
@@ -276,10 +276,12 @@ var DomainTree = DomainNode.extend({
|
||||
this.children.push(node);
|
||||
return;
|
||||
}
|
||||
_.each(node.children, (function (child) {
|
||||
child.setParent(this);
|
||||
this.children.push(child);
|
||||
}).bind(this));
|
||||
node.children.forEach(
|
||||
((child) => {
|
||||
child.setParent(this);
|
||||
this.children.push(child);
|
||||
}).bind(this)
|
||||
);
|
||||
node.destroy();
|
||||
},
|
||||
/**
|
||||
@@ -380,7 +382,7 @@ var DomainTree = DomainNode.extend({
|
||||
return Promise.all(_.map(children, (function (child) {
|
||||
return child.appendTo($div);
|
||||
}).bind(this))).then((function () {
|
||||
_.each(children, function (child) {
|
||||
children.forEach((child) => {
|
||||
child.$el.appendTo($to); // Forced to do it this way so that the
|
||||
// children are not misordered
|
||||
});
|
||||
@@ -570,10 +572,14 @@ var DomainSelector = DomainTree.extend({
|
||||
if (_redrawId !== this._redrawId) {
|
||||
return;
|
||||
}
|
||||
_.each(oldChildren, function (child) { child.destroy(); });
|
||||
oldChildren.forEach((child) => { child.destroy(); });
|
||||
this.renderElement();
|
||||
this._postRender();
|
||||
_.each(this.children, (function (child) { child.$el.appendTo(this.$childrenContainer); }).bind(this));
|
||||
this.children.forEach(
|
||||
((child) => {
|
||||
child.$el.appendTo(this.$childrenContainer);
|
||||
}).bind(this)
|
||||
);
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ const domParser = new DOMParser();
|
||||
|
||||
function traverse(tree, f) {
|
||||
if (f(tree)) {
|
||||
_.each(tree.children, function (c) {
|
||||
Object.values(tree.children || {}).forEach((c) => {
|
||||
traverse(c, f);
|
||||
});
|
||||
}
|
||||
@@ -66,7 +66,9 @@ export function processArch(arch, viewType, resModel, models) {
|
||||
const viewFieldsInfo = models[resModel][fieldName];
|
||||
const nodeString = node.getAttribute("string");
|
||||
if (nodeString === null && viewFieldsInfo === undefined) {
|
||||
throw new Error(`Missing field string information for the field '${fieldName}' from the '${resModel}' model`);
|
||||
throw new Error(
|
||||
`Missing field string information for the field '${fieldName}' from the '${resModel}' model`
|
||||
);
|
||||
}
|
||||
viewFields[fieldName] = {
|
||||
...viewFieldsInfo,
|
||||
|
||||
@@ -1218,9 +1218,9 @@ export class RelationalModel extends Model {
|
||||
// avoid losing the initial fields (display_name)
|
||||
const fieldViews = fieldInfo.views || fieldInfo.fieldsInfo || {};
|
||||
const defaultFieldInfo = legRec.data[name].fieldsInfo.default;
|
||||
_.each(fieldViews, function (fieldView) {
|
||||
Object.values(fieldViews).forEach((fieldView) => {
|
||||
_.defaults(fieldView.fields, defaultFieldInfo);
|
||||
_.each(fieldView.fieldsInfo, function (x2mFieldInfo) {
|
||||
Object.values(fieldView.fieldsInfo).forEach((x2mFieldInfo) => {
|
||||
_.defaults(x2mFieldInfo, defaultFieldInfo);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -357,8 +357,8 @@ export class MockServer {
|
||||
defaultValues[attr] = !!field[attr];
|
||||
});
|
||||
// LPE: what is this ?
|
||||
/* _.each(field.states || {}, function (modifs, state) {
|
||||
_.each(modifs, function (modif) {
|
||||
/* for (const [state, modifs] of Object.entries(field.states || {})) {
|
||||
modifs.forEach((modif) => {
|
||||
if (defaultValues[modif[0]] !== modif[1]) {
|
||||
stateExceptions[modif[0]].append(state);
|
||||
}
|
||||
|
||||
@@ -334,24 +334,24 @@ var MockServer = Class.extend({
|
||||
}
|
||||
var defaultValues = {};
|
||||
var stateExceptions = {};
|
||||
_.each(modifiersNames, function (attr) {
|
||||
modifiersNames.forEach((attr) => {
|
||||
stateExceptions[attr] = [];
|
||||
defaultValues[attr] = !!field[attr];
|
||||
});
|
||||
_.each(field.states || {}, function (modifs, state) {
|
||||
_.each(modifs, function (modif) {
|
||||
for (const [state, modifs] of Object.entries(field.states || {})) {
|
||||
modifs.forEach((modif) => {
|
||||
if (defaultValues[modif[0]] !== modif[1]) {
|
||||
stateExceptions[modif[0]].append(state);
|
||||
}
|
||||
});
|
||||
});
|
||||
_.each(defaultValues, function (defaultValue, attr) {
|
||||
}
|
||||
for (const [attr, defaultValue] of Object.entries(defaultValues)) {
|
||||
if (stateExceptions[attr].length) {
|
||||
modifiers[attr] = [("state", defaultValue ? "not in" : "in", stateExceptions[attr])];
|
||||
} else {
|
||||
modifiers[attr] = defaultValue;
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (isGroupby && !node._isProcessed) {
|
||||
var groupbyName = node.getAttribute('name');
|
||||
fieldNodes[groupbyName] = node;
|
||||
@@ -374,7 +374,7 @@ var MockServer = Class.extend({
|
||||
}
|
||||
|
||||
const inListHeader = inTreeView && node.closest('header');
|
||||
_.each(modifiersNames, function (a) {
|
||||
modifiersNames.forEach((a) => {
|
||||
var mod = node.getAttribute(a);
|
||||
if (mod) {
|
||||
var pyevalContext = window.py.dict.fromJSON(context || {});
|
||||
@@ -387,7 +387,7 @@ var MockServer = Class.extend({
|
||||
}
|
||||
});
|
||||
|
||||
_.each(modifiersNames, function (a) {
|
||||
modifiersNames.forEach((a) => {
|
||||
if (a in modifiers && (!!modifiers[a] === false || (Array.isArray(modifiers[a]) && !modifiers[a].length))) {
|
||||
delete modifiers[a];
|
||||
}
|
||||
@@ -405,7 +405,7 @@ var MockServer = Class.extend({
|
||||
});
|
||||
|
||||
let relModel, relFields;
|
||||
_.each(fieldNodes, function (node, name) {
|
||||
for (const [name, node] of Object.entries(fieldNodes)) {
|
||||
var field = fields[name];
|
||||
if (field.type === "many2one" || field.type === "many2many") {
|
||||
var canCreate = node.getAttribute('can_create');
|
||||
@@ -416,7 +416,7 @@ var MockServer = Class.extend({
|
||||
if (field.type === "one2many" || field.type === "many2many") {
|
||||
relModel = field.relation;
|
||||
relatedModels.add(relModel);
|
||||
_.each(node.childNodes, function (childNode) {
|
||||
node.childNodes.forEach((childNode) => {
|
||||
if (childNode.tagName) { // skip text nodes
|
||||
relFields = $.extend(true, {}, self.data[relModel].fields);
|
||||
// this is hackhish, but _getView modifies the subview document in place,
|
||||
@@ -432,8 +432,8 @@ var MockServer = Class.extend({
|
||||
if (name in onchanges) {
|
||||
node.setAttribute('on_change', "1");
|
||||
}
|
||||
});
|
||||
_.each(groupbyNodes, function (node, name) {
|
||||
}
|
||||
for (const [name, node] of Object.entries(groupbyNodes)) {
|
||||
var field = fields[name];
|
||||
if (field.type !== 'many2one') {
|
||||
throw new Error('groupby can only target many2one');
|
||||
@@ -446,7 +446,7 @@ var MockServer = Class.extend({
|
||||
// postprocess simulation
|
||||
const { models } = self._getView(node, relModel, relFields, context);
|
||||
[...models].forEach((modelName) => relatedModels.add(modelName));
|
||||
});
|
||||
}
|
||||
|
||||
var xmlSerializer = new XMLSerializer();
|
||||
var processedArch = xmlSerializer.serializeToString(doc);
|
||||
@@ -480,7 +480,7 @@ var MockServer = Class.extend({
|
||||
if (active_test && 'active' in this.data[model].fields) {
|
||||
// add ['active', '=', true] to the domain if 'active' is not yet present in domain
|
||||
var activeInDomain = false;
|
||||
_.each(domain, function (subdomain) {
|
||||
domain.forEach((subdomain) => {
|
||||
activeInDomain = activeInDomain || subdomain[0] === 'active';
|
||||
});
|
||||
if (!activeInDomain) {
|
||||
@@ -497,7 +497,7 @@ var MockServer = Class.extend({
|
||||
var childIDs = [criterion[2]];
|
||||
while (childIDs.length > oldLength) {
|
||||
oldLength = childIDs.length;
|
||||
_.each(records, function (r) {
|
||||
records.forEach((r) => {
|
||||
if (childIDs.indexOf(r.parent_id) >= 0) {
|
||||
childIDs.push(r.id);
|
||||
}
|
||||
@@ -1205,7 +1205,7 @@ var MockServer = Class.extend({
|
||||
_mockGetViews: function (model, kwargs) {
|
||||
var self = this;
|
||||
var views = {};
|
||||
_.each(kwargs.views, function (view_descr) {
|
||||
kwargs.views.forEach((view_descr) => {
|
||||
var viewID = view_descr[0] || false;
|
||||
var viewType = view_descr[1];
|
||||
if (!viewID) {
|
||||
@@ -1443,7 +1443,7 @@ var MockServer = Class.extend({
|
||||
var self = this;
|
||||
var fields = this.data[model].fields;
|
||||
var aggregatedFields = [];
|
||||
_.each(kwargs.fields, function (field) {
|
||||
kwargs.fields.forEach((field) => {
|
||||
var split = field.split(":");
|
||||
var fieldName = split[0];
|
||||
if (kwargs.groupby.indexOf(fieldName) > 0) {
|
||||
@@ -1700,7 +1700,7 @@ var MockServer = Class.extend({
|
||||
var records = this._getRecords(model, domain || []);
|
||||
|
||||
var data = {};
|
||||
_.each(records, function (record) {
|
||||
records.forEach((record) => {
|
||||
var groupByValue = record[groupBy]; // always technical value here
|
||||
|
||||
// special case for bool values: rpc call response with capitalized strings
|
||||
@@ -1714,7 +1714,7 @@ var MockServer = Class.extend({
|
||||
|
||||
if (!(groupByValue in data)) {
|
||||
data[groupByValue] = {};
|
||||
_.each(progress_bar.colors, function (val, key) {
|
||||
Object.keys(progress_bar.colors).forEach((key) => {
|
||||
data[groupByValue][key] = 0;
|
||||
});
|
||||
}
|
||||
@@ -1836,7 +1836,7 @@ var MockServer = Class.extend({
|
||||
records = records.slice(offset, args.limit ? (offset + args.limit) : nbRecords);
|
||||
var processedRecords = _.map(records, function (r) {
|
||||
var result = {};
|
||||
_.each(_.uniq(fields.concat(['id'])), function (fieldName) {
|
||||
_.uniq(fields.concat(['id'])).forEach((fieldName) => {
|
||||
var field = self.data[args.model].fields[fieldName];
|
||||
if (field.type === 'many2one') {
|
||||
var related_record = _.findWhere(self.data[field.relation].records, {
|
||||
@@ -1872,12 +1872,12 @@ var MockServer = Class.extend({
|
||||
this.data[model].records = this.data[model].records.filter(record => !_.contains(ids, record.id));
|
||||
|
||||
// update value of relationnal fields pointing to the deleted records
|
||||
_.each(this.data, function (d) {
|
||||
Object.values(this.data).forEach((d) => {
|
||||
var relatedFields = _.pick(d.fields, function (field) {
|
||||
return field.relation === model;
|
||||
});
|
||||
_.each(Object.keys(relatedFields), function (relatedField) {
|
||||
_.each(d.records, function (record) {
|
||||
Object.keys(relatedFields).forEach((relatedField) => {
|
||||
d.records.forEach((record) => {
|
||||
if (Array.isArray(record[relatedField])) {
|
||||
record[relatedField] = _.difference(record[relatedField], ids);
|
||||
} else if (ids.includes(record[relatedField])) {
|
||||
@@ -1943,7 +1943,7 @@ var MockServer = Class.extend({
|
||||
* @returns {boolean} currently, always return 'true'
|
||||
*/
|
||||
_mockWrite: function (model, args) {
|
||||
_.each(args[0], id => {
|
||||
args[0].forEach((id) => {
|
||||
const originalRecord = this._mockSearchRead(model, [[['id', '=', id]]], {})[0];
|
||||
this._writeRecord(model, args[1], id);
|
||||
const updatedRecord = this.data[model].records.find(record => record.id === id);
|
||||
@@ -2115,7 +2115,9 @@ var MockServer = Class.extend({
|
||||
_traverse: function (tree, f) {
|
||||
var self = this;
|
||||
if (f(tree)) {
|
||||
_.each(tree.childNodes, function (c) { self._traverse(c, f); });
|
||||
Object.values(tree.childNodes || {}).forEach((c) => {
|
||||
self._traverse(c, f);
|
||||
});
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -632,7 +632,7 @@ function patch(target, props) {
|
||||
ownPatchedProps: [],
|
||||
};
|
||||
if (target.prototype) {
|
||||
_.each(props, function (value, key) {
|
||||
Object.keys(props).forEach((key) => {
|
||||
if (target.prototype.hasOwnProperty(key)) {
|
||||
patches[patchID].ownPatchedProps.push({
|
||||
key: key,
|
||||
@@ -644,7 +644,7 @@ function patch(target, props) {
|
||||
});
|
||||
target.include(props);
|
||||
} else {
|
||||
_.each(props, function (value, key) {
|
||||
for (const [key, value] of Object.entries(props)) {
|
||||
if (key in target) {
|
||||
var oldValue = target[key];
|
||||
patches[patchID].ownPatchedProps.push({
|
||||
@@ -670,7 +670,7 @@ function patch(target, props) {
|
||||
patches[patchID].otherPatchedProps.push(key);
|
||||
target[key] = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -683,17 +683,17 @@ function unpatch(target) {
|
||||
var patchID = target.__patchID;
|
||||
var patch = patches[patchID];
|
||||
if (target.prototype) {
|
||||
_.each(patch.ownPatchedProps, function (p) {
|
||||
patch.ownPatchedProps.forEach((p) => {
|
||||
target.prototype[p.key] = p.initialValue;
|
||||
});
|
||||
_.each(patch.otherPatchedProps, function (key) {
|
||||
patch.otherPatchedProps.forEach((key) => {
|
||||
delete target.prototype[key];
|
||||
});
|
||||
} else {
|
||||
_.each(patch.ownPatchedProps, function (p) {
|
||||
patch.ownPatchedProps.forEach((p) => {
|
||||
target[p.key] = p.initialValue;
|
||||
});
|
||||
_.each(patch.otherPatchedProps, function (key) {
|
||||
patch.otherPatchedProps.forEach((key) => {
|
||||
delete target[key];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -524,11 +524,11 @@ var ViewEditor = Widget.extend({
|
||||
// Initialize a 0 level for each view and assign them an array containing their children.
|
||||
var self = this;
|
||||
var roots = [];
|
||||
_.each(this.views, function (view) {
|
||||
Object.values(this.views).forEach((view) => {
|
||||
view.level = 0;
|
||||
view.children = [];
|
||||
});
|
||||
_.each(this.views, function (view) {
|
||||
Object.values(this.views).forEach((view) => {
|
||||
var parentId = view.inherit_id[0];
|
||||
var parent = parentId && self.views[parentId];
|
||||
if (parent) {
|
||||
@@ -544,11 +544,11 @@ var ViewEditor = Widget.extend({
|
||||
function visit(view, level) {
|
||||
view.level = level;
|
||||
self.sortedViews.push(view);
|
||||
_.each(view.children, function (child) {
|
||||
view.children.forEach((child) => {
|
||||
visit(child, level + 1);
|
||||
});
|
||||
}
|
||||
_.each(roots, function (root) {
|
||||
roots.forEach((root) => {
|
||||
visit(root, 0);
|
||||
});
|
||||
}
|
||||
@@ -563,8 +563,10 @@ var ViewEditor = Widget.extend({
|
||||
|
||||
// Store the URL ungrouped by bundle and use the URL as key (resource ID)
|
||||
var resources = type === 'scss' ? this.scss : this.js;
|
||||
_.each(data, function (bundleInfos) {
|
||||
_.each(bundleInfos[1], function (info) { info.bundle = bundleInfos[0]; });
|
||||
data.forEach((bundleInfos) => {
|
||||
bundleInfos[1].forEach((info) => {
|
||||
info.bundle = bundleInfos[0];
|
||||
});
|
||||
Object.assign(resources, _.indexBy(bundleInfos[1], 'url'));
|
||||
});
|
||||
}
|
||||
@@ -629,41 +631,45 @@ var ViewEditor = Widget.extend({
|
||||
var self = this;
|
||||
var toSave = {};
|
||||
var errorFound = false;
|
||||
_.each(this.editingSessions, (function (editingSessions, type) {
|
||||
if (errorFound) return;
|
||||
Object.entries(this.editingSessions || {}).forEach(
|
||||
(([type, editingSessions]) => {
|
||||
if (errorFound) return;
|
||||
|
||||
var dirtySessions = _.pick(editingSessions, function (session) {
|
||||
return session.getUndoManager().hasUndo();
|
||||
});
|
||||
toSave[type] = _.map(dirtySessions, function (session, resID) {
|
||||
return {
|
||||
id: parseInt(resID, 10) || resID,
|
||||
text: session.getValue(),
|
||||
};
|
||||
});
|
||||
var dirtySessions = _.pick(editingSessions, function (session) {
|
||||
return session.getUndoManager().hasUndo();
|
||||
});
|
||||
toSave[type] = _.map(dirtySessions, function (session, resID) {
|
||||
return {
|
||||
id: parseInt(resID, 10) || resID,
|
||||
text: session.getValue(),
|
||||
};
|
||||
});
|
||||
|
||||
this._showErrorLine();
|
||||
for (var i = 0 ; i < toSave[type].length && !errorFound ; i++) {
|
||||
var check = (type === 'xml' ? checkXML : checkSCSS)(toSave[type][i].text);
|
||||
if (!check.isValid) {
|
||||
this._showErrorLine(check.error.line, check.error.message, toSave[type][i].id, type);
|
||||
errorFound = toSave[type][i];
|
||||
this._showErrorLine();
|
||||
for (var i = 0 ; i < toSave[type].length && !errorFound ; i++) {
|
||||
var check = (type === 'xml' ? checkXML : checkSCSS)(toSave[type][i].text);
|
||||
if (!check.isValid) {
|
||||
this._showErrorLine(check.error.line, check.error.message, toSave[type][i].id, type);
|
||||
errorFound = toSave[type][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}).bind(this));
|
||||
}).bind(this)
|
||||
);
|
||||
if (errorFound) return Promise.reject(errorFound);
|
||||
|
||||
var defs = [];
|
||||
var mutex = new concurrency.Mutex();
|
||||
_.each(toSave, (function (_toSave, type) {
|
||||
// Child views first as COW on a parent would delete them
|
||||
_toSave = _.sortBy(_toSave, 'id').reverse();
|
||||
_.each(_toSave, function (session) {
|
||||
defs.push(mutex.exec(function () {
|
||||
return (type === 'xml' ? self._saveView(session) : self._saveSCSSorJS(session));
|
||||
}));
|
||||
});
|
||||
}).bind(this));
|
||||
Object.entries(toSave || {}).forEach(
|
||||
(([type, _toSave]) => {
|
||||
// Child views first as COW on a parent would delete them
|
||||
_toSave = _.sortBy(_toSave, 'id').reverse();
|
||||
_toSave.forEach((session) => {
|
||||
defs.push(mutex.exec(function () {
|
||||
return (type === 'xml' ? self._saveView(session) : self._saveSCSSorJS(session));
|
||||
}));
|
||||
});
|
||||
}).bind(this)
|
||||
);
|
||||
|
||||
var self = this;
|
||||
return Promise.all(defs).guardedCatch(function (results) {
|
||||
@@ -811,7 +817,7 @@ var ViewEditor = Widget.extend({
|
||||
_switchType: function (type) {
|
||||
this.currentType = type;
|
||||
this.$typeSwitcherBtn.html(this.$typeSwitcherChoices.filter('[data-type=' + type + ']').html());
|
||||
_.each(this.$lists, function ($list, _type) { $list.toggleClass('d-none', type !== _type); });
|
||||
Object.entries(this.$lists).forEach(([_type, $list]) => { $list.toggleClass('d-none', type !== _type); });
|
||||
this.$lists[type].change();
|
||||
|
||||
this.$includeBundlesArea.toggleClass('d-none', this.currentType !== 'xml' || !config.isDebug());
|
||||
@@ -851,7 +857,7 @@ var ViewEditor = Widget.extend({
|
||||
|
||||
var self = this;
|
||||
this.$lists.xml.empty();
|
||||
_.each(this.sortedViews, function (view) {
|
||||
this.sortedViews.forEach((view) => {
|
||||
self.$lists.xml.append($('<option/>', {
|
||||
value: view.id,
|
||||
text: view.name,
|
||||
@@ -887,11 +893,11 @@ var ViewEditor = Widget.extend({
|
||||
this.$lists.js.data('select2').dropdown.addClass('o_ace_select2_dropdown');
|
||||
|
||||
function _populateList(sortedData, $list, lettersToRemove) {
|
||||
_.each(sortedData, function (bundleInfos) {
|
||||
sortedData.forEach((bundleInfos) => {
|
||||
var $optgroup = $('<optgroup/>', {
|
||||
label: bundleInfos[0],
|
||||
}).appendTo($list);
|
||||
_.each(bundleInfos[1], function (dataInfo) {
|
||||
bundleInfos[1].forEach((dataInfo) => {
|
||||
var name = dataInfo.url.substring(dataInfo.url.lastIndexOf('/') + 1, dataInfo.url.length - lettersToRemove);
|
||||
$optgroup.append($('<option/>', {
|
||||
value: dataInfo.url,
|
||||
|
||||
@@ -1539,7 +1539,7 @@ var SnippetEditor = Widget.extend({
|
||||
// propagated to parent editor
|
||||
if (ev.data.optionNames) {
|
||||
ev.stopPropagation();
|
||||
_.each(ev.data.optionNames, function (name) {
|
||||
ev.data.optionNames.forEach((name) => {
|
||||
notifyForEachMatchedOption(name);
|
||||
});
|
||||
}
|
||||
@@ -3037,7 +3037,7 @@ var SnippetsMenu = Widget.extend({
|
||||
: $els => $els;
|
||||
|
||||
var check = false;
|
||||
_.each(self.templateOptions, function (option, k) {
|
||||
self.templateOptions.forEach((option, k) => {
|
||||
if (check || !($snippetBody.is(option.base_selector) && !$snippetBody.is(option.base_exclude))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4444,13 +4444,13 @@ registry.sizing = SnippetOptionWidget.extend({
|
||||
let current = 0;
|
||||
const cssProperty = resize[2];
|
||||
const cssPropertyValue = parseInt(self.$target.css(cssProperty));
|
||||
_.each(resize[0], function (val, key) {
|
||||
for (const [key, val] of Object.entries(resize[0])) {
|
||||
if (self.$target.hasClass(val)) {
|
||||
current = key;
|
||||
} else if (resize[1][key] === cssPropertyValue) {
|
||||
current = key;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
props.resize = resize;
|
||||
props.current = current;
|
||||
@@ -4551,9 +4551,9 @@ registry.sizing = SnippetOptionWidget.extend({
|
||||
$body.on('mouseup', bodyMouseUp);
|
||||
});
|
||||
|
||||
_.each(resizeValues, (value, key) => {
|
||||
for (const [key, value] of Object.entries(resizeValues)) {
|
||||
this.$handles.filter('.' + key).toggleClass('readonly', !value);
|
||||
});
|
||||
}
|
||||
if (this.$target[0].classList.contains('o_grid_item')) {
|
||||
this.$handles.filter('.o_grid_handle').toggleClass('readonly', false);
|
||||
}
|
||||
@@ -4661,7 +4661,7 @@ registry.sizing = SnippetOptionWidget.extend({
|
||||
// Adapt the resize handles according to the classes and dimensions
|
||||
var resizeValues = this._getSize();
|
||||
var $handles = this.$overlay.find('.o_handle');
|
||||
_.each(resizeValues, function (resizeValue, direction) {
|
||||
for (const [direction, resizeValue] of Object.entries(resizeValues)) {
|
||||
var classes = resizeValue[0];
|
||||
var values = resizeValue[1];
|
||||
var cssProperty = resizeValue[2];
|
||||
@@ -4670,7 +4670,7 @@ registry.sizing = SnippetOptionWidget.extend({
|
||||
|
||||
var current = 0;
|
||||
var cssPropertyValue = parseInt(self.$target.css(cssProperty));
|
||||
_.each(classes, function (className, key) {
|
||||
classes.forEach((className, key) => {
|
||||
if (self.$target.hasClass(className)) {
|
||||
current = key;
|
||||
} else if (values[key] === cssPropertyValue) {
|
||||
@@ -4680,7 +4680,7 @@ registry.sizing = SnippetOptionWidget.extend({
|
||||
|
||||
$handle.toggleClass('o_handle_start', current === 0);
|
||||
$handle.toggleClass('o_handle_end', current === classes.length - 1);
|
||||
});
|
||||
}
|
||||
|
||||
// Adapt the handles to fit the left, top and bottom sizes
|
||||
var ml = this.$target.css('margin-left');
|
||||
@@ -4691,7 +4691,7 @@ registry.sizing = SnippetOptionWidget.extend({
|
||||
this.$overlay.find('.o_handle.e').css({
|
||||
width: 0,
|
||||
});
|
||||
_.each(this.$overlay.find(".o_handle.n, .o_handle.s"), function (handle) {
|
||||
this.$overlay.find(".o_handle.n, .o_handle.s").toArray().forEach((handle) => {
|
||||
var $handle = $(handle);
|
||||
var direction = $handle.hasClass('n') ? 'top' : 'bottom';
|
||||
$handle.height(self.$target.css('padding-' + direction));
|
||||
@@ -5288,7 +5288,7 @@ registry.layout_column = SnippetOptionWidget.extend({
|
||||
var colSize = Math.floor(12 / colsLength) || 1;
|
||||
var colOffset = Math.floor((12 - colSize * colsLength) / 2);
|
||||
var colClass = 'col-lg-' + colSize;
|
||||
_.each($columns, function (column) {
|
||||
$columns.toArray().forEach((column) => {
|
||||
var $column = $(column);
|
||||
$column.attr('class', $column.attr('class').replace(/\b(col|offset)-lg(-\d+)?\b/g, ''));
|
||||
$column.addClass(colClass);
|
||||
|
||||
@@ -88,7 +88,7 @@ export default {
|
||||
*/
|
||||
computeFonts: _.once(function () {
|
||||
var self = this;
|
||||
_.each(this.fontIcons, function (data) {
|
||||
this.fontIcons.forEach((data) => {
|
||||
data.cssData = self.getCssSelectors(data.parser);
|
||||
data.alias = _.flatten(_.map(data.cssData, _.property('names')));
|
||||
});
|
||||
|
||||
@@ -121,11 +121,11 @@ const ColorPaletteWidget = Widget.extend({
|
||||
colorpickerEl.querySelectorAll('button').forEach(el => el.classList.add('o_we_color_btn'));
|
||||
|
||||
// Populate tabs based on the tabs configuration indicated in this.tabs
|
||||
_.each(this.tabs, (tab, index) => {
|
||||
this.tabs.forEach((tab, index) => {
|
||||
// Append pickers to section
|
||||
const sectionEl = this.el.querySelector(`.o_colorpicker_sections[data-color-tab="${tab.id}"]`);
|
||||
let sectionIsEmpty = true;
|
||||
_.each(tab.pickers, pickerId => {
|
||||
tab.pickers.forEach((pickerId) => {
|
||||
let pickerEl;
|
||||
switch (pickerId) {
|
||||
case 'common_grays':
|
||||
@@ -215,7 +215,7 @@ const ColorPaletteWidget = Widget.extend({
|
||||
|
||||
// Remove excluded palettes (note: only hide them to still be able
|
||||
// to remove their related colors on the DOM target)
|
||||
_.each(this.options.excluded, exc => {
|
||||
this.options.excluded.forEach((exc) => {
|
||||
this.$('[data-name="' + exc + '"]').addClass('d-none');
|
||||
});
|
||||
if (this.options.excludeSectionOf) {
|
||||
@@ -367,7 +367,7 @@ const ColorPaletteWidget = Widget.extend({
|
||||
this._addCustomColor(existingColors, color);
|
||||
}
|
||||
});
|
||||
_.each(this.options.$editable.find('[style*="color"]'), el => {
|
||||
this.options.$editable.find('[style*="color"]').toArray().forEach((el) => {
|
||||
for (const colorProp of ['color', 'backgroundColor']) {
|
||||
this._addCustomColor(existingColors, el.style[colorProp]);
|
||||
}
|
||||
|
||||
@@ -357,7 +357,7 @@ var keyboardMap = {
|
||||
"91": "OS_KEY", // 'left command': Windows Key (Windows) or Command Key (Mac)
|
||||
"93": "CONTEXT_MENU", // 'right command'
|
||||
};
|
||||
_.each(range(40, 127), function (keyCode) {
|
||||
range(40, 127).forEach((keyCode) => {
|
||||
if (!keyboardMap[keyCode]) {
|
||||
keyboardMap[keyCode] = String.fromCharCode(keyCode);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ export class AttributeTranslateDialog extends Component {
|
||||
useEffect(() => {
|
||||
this.translation = $(this.props.node).data('translation');
|
||||
const $group = $('<div/>', {class: 'mb-3'}).appendTo(this.formEl.el);
|
||||
_.each(this.translation, function (node, attr) {
|
||||
for (const [attr, node] of Object.entries(this.translation)) {
|
||||
const $node = $(node);
|
||||
const $label = $('<label class="col-form-label"></label>').text(attr);
|
||||
const $input = $('<input class="form-control"/>').val($node.html());
|
||||
@@ -38,7 +38,7 @@ export class AttributeTranslateDialog extends Component {
|
||||
$node.trigger('change');
|
||||
});
|
||||
$group.append($label).append($input);
|
||||
});
|
||||
}
|
||||
}, () => [this.props.node]);
|
||||
}
|
||||
}
|
||||
@@ -132,7 +132,7 @@ export class WebsiteTranslator extends WebsiteEditorComponent {
|
||||
const $editable = this.getEditableArea();
|
||||
const translationRegex = /<span [^>]*data-oe-translation-initial-sha="([^"]+)"[^>]*>(.*)<\/span>/;
|
||||
let $edited = $();
|
||||
_.each(attrs, function (attr) {
|
||||
attrs.forEach((attr) => {
|
||||
const attrEdit = $editable.filter('[' + attr + '*="data-oe-translation-initial-sha="]').filter(':empty, input, select, textarea, img');
|
||||
attrEdit.each(function () {
|
||||
var $node = $(this);
|
||||
@@ -269,7 +269,7 @@ export class WebsiteTranslator extends WebsiteEditorComponent {
|
||||
this.$translations.each(function () {
|
||||
var $node = $(this);
|
||||
var translation = $node.data('translation');
|
||||
_.each(translation, function (node, attr) {
|
||||
Object.values(translation).forEach((node) => {
|
||||
var trans = self.getTranslationObject(node);
|
||||
trans.value = (trans.value ? trans.value : $node.html()).replace(/[ \t\n\r]+/, ' ');
|
||||
$node.attr('data-oe-translation-state', (trans.state || 'to_translate'));
|
||||
|
||||
@@ -109,7 +109,7 @@ var Dashboard = AbstractAction.extend({
|
||||
|
||||
render_dashboards: function() {
|
||||
var self = this;
|
||||
_.each(this.dashboards_templates, function(template) {
|
||||
this.dashboards_templates.forEach((template) => {
|
||||
self.$('.o_website_dashboard').append(QWeb.render(template, {widget: self}));
|
||||
});
|
||||
},
|
||||
@@ -205,7 +205,7 @@ var Dashboard = AbstractAction.extend({
|
||||
render_graphs: function() {
|
||||
var self = this;
|
||||
if (this._isInDom) {
|
||||
_.each(this.graphs, function(e) {
|
||||
this.graphs.forEach((e) => {
|
||||
var renderGraph = self.groups[e.group] &&
|
||||
self.dashboards_data[e.name].summary.order_count;
|
||||
if (!self.chartIds[e.name]) {
|
||||
|
||||
@@ -165,10 +165,10 @@ var AnimationEffect = Class.extend(mixins.ParentedMixin, {
|
||||
}
|
||||
|
||||
function _processEvents(events, namespace) {
|
||||
events = events.split(' ');
|
||||
return _.each(events, function (e, index) {
|
||||
events[index] += ('.' + namespace);
|
||||
}).join(' ');
|
||||
return events
|
||||
.split(" ")
|
||||
.map((e) => (e += "." + namespace))
|
||||
.join(" ");
|
||||
}
|
||||
},
|
||||
/**
|
||||
@@ -375,7 +375,7 @@ var Animation = publicWidget.Widget.extend({
|
||||
*/
|
||||
start: function () {
|
||||
this._prepareEffects();
|
||||
_.each(this._animationEffects, function (effect) {
|
||||
this._animationEffects.forEach((effect) => {
|
||||
effect.start();
|
||||
});
|
||||
return this._super.apply(this, arguments);
|
||||
@@ -397,7 +397,7 @@ var Animation = publicWidget.Widget.extend({
|
||||
this._animationEffects = [];
|
||||
|
||||
var self = this;
|
||||
_.each(this.effects, function (desc) {
|
||||
this.effects.forEach((desc) => {
|
||||
self._addEffect(self[desc.update], desc.startEvents, _findTarget(desc.startTarget), {
|
||||
getStateCallback: desc.getState && self[desc.getState],
|
||||
endEvents: desc.endEvents || undefined,
|
||||
@@ -462,9 +462,11 @@ registry.slider = publicWidget.Widget.extend({
|
||||
this.$('img').off('.slider');
|
||||
this.$el.carousel('pause');
|
||||
this.$el.removeData('bs.carousel');
|
||||
_.each(this.$('.carousel-item'), function (el) {
|
||||
$(el).css('min-height', '');
|
||||
});
|
||||
this.$(".carousel-item")
|
||||
.toArray()
|
||||
.forEach((el) => {
|
||||
$(el).css("min-height", "");
|
||||
});
|
||||
$(window).off('.slider');
|
||||
},
|
||||
|
||||
@@ -479,7 +481,7 @@ registry.slider = publicWidget.Widget.extend({
|
||||
var maxHeight = 0;
|
||||
var $items = this.$('.carousel-item');
|
||||
$items.css('min-height', '');
|
||||
_.each($items, el => {
|
||||
$items.toArray().forEach((el) => {
|
||||
var $item = $(el);
|
||||
var isActive = $item.hasClass('active');
|
||||
this.options.wysiwyg && this.options.wysiwyg.odooEditor.observerUnactive('_computeHeights');
|
||||
@@ -1265,7 +1267,7 @@ registry.WebsiteAnimate = publicWidget.Widget.extend({
|
||||
|
||||
// By default, elements are hidden by the css of o_animate.
|
||||
// Render elements and trigger the animation then pause it in state 0.
|
||||
_.each(this.$animatedElements, el => {
|
||||
this.$animatedElements.toArray().forEach((el) => {
|
||||
if (el.closest('.dropdown')) {
|
||||
el.classList.add('o_animate_in_dropdown');
|
||||
return;
|
||||
@@ -1389,7 +1391,7 @@ registry.WebsiteAnimate = publicWidget.Widget.extend({
|
||||
* @param {Element} el
|
||||
*/
|
||||
_scrollWebsiteAnimate(el) {
|
||||
_.each(this.$('.o_animate:not(.o_animate_in_dropdown)'), el => {
|
||||
this.$('.o_animate:not(.o_animate_in_dropdown)').toArray().forEach((el) => {
|
||||
const $el = $(el);
|
||||
const elHeight = el.offsetHeight;
|
||||
const animateOnScroll = el.classList.contains('o_animate_on_scroll');
|
||||
|
||||
@@ -305,7 +305,7 @@ const FontFamilyPickerUserValueWidget = SelectUserValueWidget.extend({
|
||||
|
||||
// Adapt font variable indexes to the removal
|
||||
const style = window.getComputedStyle(this.$target[0].ownerDocument.documentElement);
|
||||
_.each(FontFamilyPickerUserValueWidget.prototype.fontVariables, variable => {
|
||||
FontFamilyPickerUserValueWidget.prototype.fontVariables.forEach((variable) => {
|
||||
const value = weUtils.getCSSVariableValue(variable, style);
|
||||
if (value.substring(1, value.length - 1) === googleFontName) {
|
||||
// If an element is using the google font being removed, reset
|
||||
@@ -1755,7 +1755,7 @@ options.registry.Carousel = options.Class.extend({
|
||||
const id = 'myCarousel' + Date.now();
|
||||
this.$target.attr('id', id);
|
||||
this.$target.find('[data-bs-target]').attr('data-bs-target', '#' + id);
|
||||
_.each(this.$target.find('[data-bs-slide], [data-bs-slide-to]'), function (el) {
|
||||
this.$target.find('[data-bs-slide], [data-bs-slide-to]').toArray().forEach((el) => {
|
||||
var $el = $(el);
|
||||
if ($el.attr('data-bs-target')) {
|
||||
$el.attr('data-bs-target', '#' + id);
|
||||
|
||||
@@ -103,9 +103,9 @@ options.registry.facebookPage = options.Class.extend({
|
||||
} else {
|
||||
this.fbData.height = 150;
|
||||
}
|
||||
_.each(this.fbData, (value, key) => {
|
||||
for (const [key, value] of Object.entries(this.fbData)) {
|
||||
this.$target[0].dataset[key] = value;
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -163,7 +163,7 @@ options.registry.gallery = options.Class.extend({
|
||||
var colClass = 'col-lg-' + (12 / columns);
|
||||
var $container = this._replaceContent($row);
|
||||
|
||||
_.each(imgs, function (img, index) {
|
||||
imgs.forEach((img, index) => {
|
||||
var $img = $(img);
|
||||
var $col = $('<div/>', {class: colClass});
|
||||
$col.append($img).appendTo($row);
|
||||
@@ -199,7 +199,7 @@ options.registry.gallery = options.Class.extend({
|
||||
while (imgs.length) {
|
||||
var min = Infinity;
|
||||
var $lowest;
|
||||
_.each(cols, function (col) {
|
||||
cols.forEach((col) => {
|
||||
var $col = $(col);
|
||||
var height = $col.is(':empty') ? 0 : $col.find('img').last().offset().top + $col.find('img').last().height() - self.$target.offset().top;
|
||||
if (height < min) {
|
||||
@@ -244,7 +244,7 @@ options.registry.gallery = options.Class.extend({
|
||||
|
||||
this._replaceContent($row);
|
||||
|
||||
_.each(imgs, function (img) {
|
||||
imgs.forEach((img) => {
|
||||
var wrapClass = 'col-lg-3';
|
||||
if (img.width >= img.height * 2 || img.width > 600) {
|
||||
wrapClass = 'col-lg-6';
|
||||
@@ -296,7 +296,7 @@ options.registry.gallery = options.Class.extend({
|
||||
},
|
||||
$slideshow = $(qweb.render('website.gallery.slideshow', params));
|
||||
this._replaceContent($slideshow);
|
||||
_.each(this.$('img'), function (img, index) {
|
||||
this.$("img").toArray().forEach((img, index) => {
|
||||
$(img).attr({contenteditable: true, 'data-index': index});
|
||||
});
|
||||
this.$target.css('height', Math.round(window.innerHeight * 0.7));
|
||||
@@ -339,7 +339,7 @@ options.registry.gallery = options.Class.extend({
|
||||
break;
|
||||
}
|
||||
position = imgs.indexOf(data.$image[0]);
|
||||
_.each(imgs, function (img, index) {
|
||||
imgs.forEach((img, index) => {
|
||||
// Note: there might be more efficient ways to do that but it is
|
||||
// more simple this way and allows compatibility with 10.0 where
|
||||
// indexes were not the same as positions.
|
||||
@@ -377,7 +377,7 @@ options.registry.gallery = options.Class.extend({
|
||||
_adaptNavigationIDs: function () {
|
||||
var uuid = new Date().getTime();
|
||||
this.$target.find('.carousel').attr('id', 'slideshow_' + uuid);
|
||||
_.each(this.$target.find('[data-bs-slide], [data-bs-slide-to]'), function (el) {
|
||||
this.$target.find('[data-bs-slide], [data-bs-slide-to]').toArray().forEach((el) => {
|
||||
var $el = $(el);
|
||||
if ($el.attr('data-bs-target')) {
|
||||
$el.attr('data-bs-target', '#slideshow_' + uuid);
|
||||
|
||||
@@ -21,7 +21,7 @@ options.registry.ProductCatalog = options.Class.extend({
|
||||
const $name = $dishes.find('.s_product_catalog_dish_name');
|
||||
$name.toggleClass('s_product_catalog_dish_dot_leaders', !widgetValue);
|
||||
if (widgetValue) {
|
||||
_.each($dishes, el => {
|
||||
$dishes.toArray().forEach((el) => {
|
||||
const $description = $(el).find('.s_product_catalog_dish_description');
|
||||
if ($description.length) {
|
||||
$description.removeClass('d-none');
|
||||
@@ -35,7 +35,7 @@ options.registry.ProductCatalog = options.Class.extend({
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_.each($dishes, el => {
|
||||
$dishes.toArray().forEach((el) => {
|
||||
const $description = $(el).find('.s_product_catalog_dish_description');
|
||||
if ($description.hasClass('o_default_snippet_text') || $description.find('.o_default_snippet_text').length) {
|
||||
$description.remove();
|
||||
|
||||
@@ -61,7 +61,7 @@ const TableOfContent = publicWidget.Widget.extend({
|
||||
}
|
||||
let position = 0;
|
||||
const $fixedElements = $('.o_top_fixed_element');
|
||||
_.each($fixedElements, el => position += $(el).outerHeight());
|
||||
$fixedElements.toArray().forEach((el) => position += $(el).outerHeight());
|
||||
const isHorizontalNavbar = this.$el.hasClass('s_table_of_content_horizontal_navbar');
|
||||
this.$el.css('top', isHorizontalNavbar ? position : '');
|
||||
this.$el.find('.s_table_of_content_navbar').css('top', isHorizontalNavbar ? '' : position + 20);
|
||||
|
||||
@@ -97,7 +97,7 @@ options.registry.TableOfContent = options.Class.extend({
|
||||
this._disposeScrollSpy();
|
||||
const $nav = this.$target.find('.s_table_of_content_navbar');
|
||||
$nav.empty();
|
||||
_.each(headingsEls, el => {
|
||||
headingsEls.forEach((el) => {
|
||||
const $el = $(el);
|
||||
const id = 'table_of_content_heading_' + _.now() + '_' + _.uniqueId();
|
||||
$('<a>').attr('href', "#" + id)
|
||||
|
||||
@@ -285,7 +285,7 @@ import { sprintf } from "@web/core/utils/strings";
|
||||
// Serialize form inputs into a single object
|
||||
// Aggregate multiple values into arrays
|
||||
var form_values = {};
|
||||
_.each(this.form_fields, function (input) {
|
||||
this.form_fields.forEach((input) => {
|
||||
if (input.name in form_values) {
|
||||
// If a value already exists for this field,
|
||||
// we are facing a x2many field, so we store
|
||||
|
||||
@@ -818,11 +818,13 @@ options.registry.WebsiteFieldEditor = FieldEditor.extend({
|
||||
authorizedFieldsCache[model] = getFields;
|
||||
}
|
||||
|
||||
this.existingFields = await getFields.then(fields => {
|
||||
this.fields = _.each(fields, function (field, fieldName) {
|
||||
this.existingFields = await getFields.then((fields) => {
|
||||
this.fields = {};
|
||||
for (const [fieldName, field] of Object.entries(fields)) {
|
||||
field.name = fieldName;
|
||||
field.domain = field.domain || [];
|
||||
});
|
||||
this.fields[fieldName] = field;
|
||||
}
|
||||
// Create the buttons for the type we-select
|
||||
return Object.keys(fields).map(key => {
|
||||
const field = fields[key];
|
||||
|
||||
@@ -64,7 +64,7 @@ publicWidget.registry.websiteEventTrackProposalFormTags = publicWidget.Widget.ex
|
||||
fill_data: function (query, data) {
|
||||
var that = this,
|
||||
tags = {results: []};
|
||||
_.each(data, function (obj) {
|
||||
data.forEach((obj) => {
|
||||
// select tags matching either category or tag name
|
||||
if (that.matcher(query.term, obj[nameKey]) || that.matcher(query.term, obj.category_id[1])) {
|
||||
if (obj.category_id[1]) {
|
||||
|
||||
@@ -93,7 +93,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
},
|
||||
results: function (data) {
|
||||
var ret = [];
|
||||
_.each(data, function (x) {
|
||||
data.forEach((x) => {
|
||||
ret.push({
|
||||
id: x.id,
|
||||
text: x.name,
|
||||
@@ -107,7 +107,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
// Take default tags from the input value
|
||||
initSelection: function (element, callback) {
|
||||
var data = [];
|
||||
_.each(element.data('init-value'), function (x) {
|
||||
element.data("init-value").forEach((x) => {
|
||||
data.push({id: x.id, text: x.name, isNew: false});
|
||||
});
|
||||
element.val('');
|
||||
@@ -115,7 +115,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
},
|
||||
});
|
||||
|
||||
_.each($('textarea.o_wysiwyg_loader'), function (textarea) {
|
||||
$('textarea.o_wysiwyg_loader').toArray().forEach((textarea) => {
|
||||
var $textarea = $(textarea);
|
||||
var editorKarma = $textarea.data('karma') || 0; // default value for backward compatibility
|
||||
var $form = $textarea.closest('form');
|
||||
@@ -146,7 +146,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
});
|
||||
});
|
||||
|
||||
_.each(this.$('.o_wforum_bio_popover'), authorBox => {
|
||||
this.$('.o_wforum_bio_popover').toArray().forEach((authorBox) => {
|
||||
$(authorBox).popover({
|
||||
trigger: 'hover',
|
||||
offset: '10',
|
||||
@@ -216,7 +216,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
ev.preventDefault();
|
||||
setTimeout(function() {
|
||||
var $buttons = $(ev.currentTarget).find('button[type="submit"], a.a-submit');
|
||||
_.each($buttons, function (btn) {
|
||||
$buttons.toArray().forEach((btn) => {
|
||||
let $btn = $(btn);
|
||||
$btn.find('i').remove();
|
||||
$btn.prop('disabled', false);
|
||||
@@ -443,7 +443,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
type: "warning",
|
||||
});
|
||||
} else {
|
||||
_.each(this.$('.forum_answer'), answer => {
|
||||
this.$('.forum_answer').toArray().forEach((answer) => {
|
||||
var $answer = $(answer);
|
||||
var isCorrect = $answer.is(target) ? data : false;
|
||||
var $toggler = $answer.find('.o_wforum_validate_toggler');
|
||||
@@ -600,7 +600,7 @@ publicWidget.registry.websiteForumSpam = publicWidget.Widget.extend({
|
||||
],
|
||||
kwargs: {}
|
||||
}).then(function (o) {
|
||||
_.each(o, function (r) {
|
||||
Object.values(o).forEach((r) => {
|
||||
r.content = $('<p>' + $(r.content).html() + '</p>').text().substring(0, 250);
|
||||
});
|
||||
self.$('div.post_spam').html(qweb.render('website_forum.spam_search_name', {
|
||||
|
||||
@@ -301,7 +301,7 @@ var RecentLinks = publicWidget.Widget.extend({
|
||||
limit: 20,
|
||||
},
|
||||
}).then(function (result) {
|
||||
_.each(result.reverse(), function (link) {
|
||||
result.reverse().forEach((link) => {
|
||||
self._addLink(link);
|
||||
});
|
||||
self._updateNotification();
|
||||
|
||||
@@ -74,7 +74,7 @@ publicWidget.registry.DonationSnippet = publicWidget.Widget.extend({
|
||||
this.currency = result;
|
||||
this.$('.s_donation_currency').remove();
|
||||
const $prefilledButtons = this.$('.s_donation_btn, .s_range_bubble');
|
||||
_.each($prefilledButtons, button => {
|
||||
$prefilledButtons.toArray().forEach((button) => {
|
||||
const before = result.position === "before";
|
||||
const $currencySymbol = document.createElement('span');
|
||||
$currencySymbol.innerText = result.symbol;
|
||||
|
||||
@@ -97,7 +97,7 @@ options.registry.Donation = options.Class.extend({
|
||||
const valueList = JSON.parse(value);
|
||||
const donationAmounts = [];
|
||||
delete this.$target[0].dataset.donationAmounts;
|
||||
_.each(valueList, value => {
|
||||
valueList.forEach((value) => {
|
||||
donationAmounts.push(value.display_name);
|
||||
});
|
||||
this.$target[0].dataset.donationAmounts = JSON.stringify(donationAmounts);
|
||||
@@ -233,7 +233,7 @@ options.registry.Donation = options.Class.extend({
|
||||
if (this.$target[0].dataset.descriptions) {
|
||||
const $descriptions = this.$target.find('#s_donation_description_inputs > input');
|
||||
const $tableEl = this.$el.find('we-list table');
|
||||
_.each($tableEl.find('tr'), (trEl, i) => {
|
||||
$tableEl.find("tr").toArray().forEach((trEl, i) => {
|
||||
const $inputAmount = $(trEl).find('td').first();
|
||||
$inputAmount.addClass('w-25');
|
||||
const tdEl = document.createElement('td');
|
||||
@@ -256,7 +256,7 @@ options.registry.Donation = options.Class.extend({
|
||||
const descriptionInputs = this.$target.find('#s_donation_description_inputs');
|
||||
descriptionInputs.empty();
|
||||
const descriptions = this.$el.find('we-list input[type=text]');
|
||||
_.each(descriptions, description => {
|
||||
descriptions.toArray().forEach((description) => {
|
||||
const inputEl = document.createElement('input');
|
||||
inputEl.type = 'hidden';
|
||||
inputEl.classList.add('o_translatable_input_hidden', 'd-block', 'mb-1', 'w-100');
|
||||
|
||||
@@ -760,9 +760,12 @@ options.registry.WebsiteSaleProductPage = options.Class.extend({
|
||||
'input.js_variant_change:checked',
|
||||
'select.js_variant_change'
|
||||
];
|
||||
_.each($container.find(variantsValuesSelectors.join(', ')), function (el) {
|
||||
values.push(+$(el).val());
|
||||
});
|
||||
$container
|
||||
.find(variantsValuesSelectors.join(", "))
|
||||
.toArray()
|
||||
.forEach((el) => {
|
||||
values.push(+$(el).val());
|
||||
});
|
||||
|
||||
return values;
|
||||
},
|
||||
|
||||
@@ -69,7 +69,9 @@ publicWidget.registry.WebsiteSale = publicWidget.Widget.extend(VariantMixin, car
|
||||
|
||||
this._applyHashFromSearch();
|
||||
|
||||
_.each(this.$('div.js_product'), function (product) {
|
||||
this.$("div.js_product")
|
||||
.toArray()
|
||||
.forEach((product) => {
|
||||
$('input.js_product_change', product).first().trigger('change');
|
||||
});
|
||||
|
||||
@@ -159,7 +161,7 @@ publicWidget.registry.WebsiteSale = publicWidget.Widget.extend(VariantMixin, car
|
||||
if (params['attr']) {
|
||||
var attributeIds = params['attr'].split(',');
|
||||
var $inputs = this.$('input.js_variant_change, select.js_variant_change option');
|
||||
_.each(attributeIds, function (id) {
|
||||
attributeIds.forEach((id) => {
|
||||
var $toSelect = $inputs.filter('[data-value_id="' + id + '"]');
|
||||
if ($toSelect.is('input[type="radio"]')) {
|
||||
$toSelect.prop('checked', true);
|
||||
@@ -191,17 +193,15 @@ publicWidget.registry.WebsiteSale = publicWidget.Widget.extend(VariantMixin, car
|
||||
* @param {Array} valueSelectors Selectors
|
||||
*/
|
||||
_changeAttribute: function (valueSelectors) {
|
||||
_.each(valueSelectors, function (selector) {
|
||||
$(selector).removeClass("active")
|
||||
.filter(':has(input:checked)')
|
||||
.addClass("active");
|
||||
valueSelectors.forEach((selector) => {
|
||||
$(selector).removeClass("active").filter(":has(input:checked)").addClass("active");
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_changeCartQuantity: function ($input, value, $dom_optional, line_id, productIDs) {
|
||||
_.each($dom_optional, function (elem) {
|
||||
$($dom_optional).toArray().forEach((elem) => {
|
||||
$(elem).find('.js_quantity').text(value);
|
||||
productIDs.push($(elem).find('span[data-product-id]').data('product-id'));
|
||||
});
|
||||
@@ -259,7 +259,7 @@ publicWidget.registry.WebsiteSale = publicWidget.Widget.extend(VariantMixin, car
|
||||
if (selectStates.data('init')===0 || selectStates.find('option').length===1) {
|
||||
if (data.states.length || data.state_required) {
|
||||
selectStates.html('');
|
||||
_.each(data.states, function (x) {
|
||||
data.states.forEach((x) => {
|
||||
var opt = $('<option>').text(x[1])
|
||||
.attr('value', x[0])
|
||||
.attr('data-code', x[2]);
|
||||
@@ -282,7 +282,7 @@ publicWidget.registry.WebsiteSale = publicWidget.Widget.extend(VariantMixin, car
|
||||
$(".div_zip").after($(".div_city"));
|
||||
}
|
||||
var all_fields = ["street", "zip", "city", "country_name"]; // "state_code"];
|
||||
_.each(all_fields, function (field) {
|
||||
all_fields.forEach((field) => {
|
||||
$(".checkout_autoformat .div_" + field.split('_')[0]).toggle($.inArray(field, data.fields)>=0);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ publicWidget.registry.websiteSaleDelivery = publicWidget.Widget.extend({
|
||||
}
|
||||
|
||||
await this._getCurrentLocation();
|
||||
await _.each(carriers, async carrierInput => {
|
||||
await carriers.forEach(async (carrierInput) => {
|
||||
this._showLoading((carrierInput));
|
||||
await this._handleCarrierUpdateResult(carrierInput)
|
||||
});
|
||||
|
||||
@@ -145,7 +145,7 @@ var ProductComparison = publicWidget.Widget.extend(VariantMixin, {
|
||||
}).then(function (data) {
|
||||
self.comparelist_product_ids = JSON.parse(data.cookies);
|
||||
delete data.cookies;
|
||||
_.each(data, function (product) {
|
||||
Object.values(data).forEach((product) => {
|
||||
self.product_data[product.product.id] = product;
|
||||
});
|
||||
if (product_ids.length > Object.keys(data).length) {
|
||||
@@ -191,7 +191,7 @@ var ProductComparison = publicWidget.Widget.extend(VariantMixin, {
|
||||
_updateContent: function (force) {
|
||||
var self = this;
|
||||
this.$('.o_comparelist_products .o_product_row').remove();
|
||||
_.each(this.comparelist_product_ids, function (res) {
|
||||
this.comparelist_product_ids.forEach((res) => {
|
||||
if (self.product_data.hasOwnProperty(res)) {
|
||||
// It is possible that we do not have the required product_data for all IDs in
|
||||
// comparelist_product_ids
|
||||
|
||||
@@ -13,7 +13,7 @@ publicWidget.registry.websiteSlides = publicWidget.Widget.extend({
|
||||
start: function (parent) {
|
||||
var defs = [this._super.apply(this, arguments)];
|
||||
|
||||
_.each($("timeago.timeago"), function (el) {
|
||||
$("timeago.timeago").toArray().forEach((el) => {
|
||||
var datetime = $(el).attr('datetime');
|
||||
var datetimeObj = time.str_to_datetime(datetime);
|
||||
// if presentation 7 days, 24 hours, 60 min, 60 second, 1000 millis old(one week)
|
||||
|
||||
@@ -130,7 +130,7 @@ var TagCourseDialog = Dialog.extend({
|
||||
fill_data: function (query, data) {
|
||||
var that = this,
|
||||
tags = {results: []};
|
||||
_.each(data, function (obj) {
|
||||
Object.values(data).forEach((obj) => {
|
||||
if (that.matcher(query.term, obj[nameKey])) {
|
||||
tags.results.push({id: obj.id, text: obj[nameKey]});
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ var SlideUploadDialog = Dialog.extend({
|
||||
var self = this;
|
||||
// tags
|
||||
var tagValues = [];
|
||||
_.each(this.$('#tag_ids').select2('data'), function (val) {
|
||||
this.$('#tag_ids').select2('data').forEach((val) => {
|
||||
if (val.create) {
|
||||
tagValues.push([0, 0, {'name': val.text}]);
|
||||
} else {
|
||||
@@ -312,7 +312,7 @@ var SlideUploadDialog = Dialog.extend({
|
||||
fill_data: function (query, data) {
|
||||
var self = this,
|
||||
tags = {results: []};
|
||||
_.each(data, function (obj) {
|
||||
data.forEach((obj) => {
|
||||
if (self.matcher(query.term, obj[nameKey])) {
|
||||
tags.results.push({id: obj.id, text: obj[nameKey]});
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ publicWidget.registry.twitter = publicWidget.Widget.extend({
|
||||
var tweetSlices = [tweets.slice(0, f).join(' '), tweets.slice(f, f * 2).join(' '), tweets.slice(f * 2, tweets.length).join(' ')];
|
||||
|
||||
self.$scroller = $(qweb.render('website.Twitter.Scroller')).appendTo($timeline);
|
||||
_.each(self.$scroller.find('div[id^="scroller"]'), function (element, index) {
|
||||
self.$scroller.find('div[id^="scroller"]').toArray().forEach((element, index) => {
|
||||
var $scrollWrapper = $('<div/>', {class: 'scrollWrapper'});
|
||||
var $scrollableArea = $('<div/>', {class: 'scrollableArea'});
|
||||
$scrollWrapper.append($scrollableArea)
|
||||
@@ -85,7 +85,7 @@ publicWidget.registry.twitter = publicWidget.Widget.extend({
|
||||
$scrollableArea.append(tweetSlices[index]);
|
||||
$(element).append($scrollWrapper);
|
||||
var totalWidth = 0;
|
||||
_.each($scrollableArea.children(), function (area) {
|
||||
$scrollableArea.children().forEach((area) => {
|
||||
totalWidth += $(area).outerWidth(true);
|
||||
});
|
||||
$scrollableArea.width(totalWidth);
|
||||
@@ -115,7 +115,7 @@ publicWidget.registry.twitter = publicWidget.Widget.extend({
|
||||
if (!this.$scroller) {
|
||||
return;
|
||||
}
|
||||
_.each(this.$scroller.find('.scrollWrapper'), function (el) {
|
||||
this.$scroller.find('.scrollWrapper').toArray().forEach((el) => {
|
||||
var $wrapper = $(el);
|
||||
$wrapper.data('getNextElementWidth', true);
|
||||
$wrapper.data('autoScrollingInterval', setInterval(function () {
|
||||
@@ -140,7 +140,7 @@ publicWidget.registry.twitter = publicWidget.Widget.extend({
|
||||
if (!this.$scroller) {
|
||||
return;
|
||||
}
|
||||
_.each(this.$scroller.find('.scrollWrapper'), function (el) {
|
||||
this.$scroller.find('.scrollWrapper').toArray().forEach((el) => {
|
||||
var $wrapper = $(el);
|
||||
clearInterval($wrapper.data('autoScrollingInterval'));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user