mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
2840794fa2
closes #130
302 lines
8.0 KiB
JavaScript
302 lines
8.0 KiB
JavaScript
import {
|
|
buildData,
|
|
startMeasure,
|
|
stopMeasure,
|
|
formatNumber
|
|
} from "../shared/utils.js";
|
|
|
|
odoo.define("app", function(require) {
|
|
const Widget = require("web.Widget");
|
|
var core = require("web.core");
|
|
var dom = require("web.dom");
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Likes Counter Widget
|
|
//----------------------------------------------------------------------------
|
|
var Counter = Widget.extend({
|
|
template: "counter",
|
|
events: {
|
|
"click .o_increment": "_onIncrement"
|
|
},
|
|
init: function(parent) {
|
|
this._super(parent);
|
|
this.value = 0;
|
|
},
|
|
start: function() {
|
|
this.updateCounter();
|
|
},
|
|
on_attach_callback: function() {},
|
|
on_detach_callback: function() {},
|
|
updateCounter: function() {
|
|
this.$(".o_increment").html("Value: " + this.value);
|
|
},
|
|
_onIncrement: function(ev) {
|
|
ev.stopPropagation();
|
|
this.value += 1;
|
|
this.updateCounter();
|
|
}
|
|
});
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Message Widget
|
|
//----------------------------------------------------------------------------
|
|
var Message = Widget.extend({
|
|
template: "message",
|
|
events: {
|
|
"click .remove": "_onRemove"
|
|
},
|
|
|
|
init: function(parent, message) {
|
|
this._super(parent);
|
|
this.author = message.author;
|
|
this.msg = message.msg;
|
|
this.id = message.id;
|
|
},
|
|
willStart: function() {
|
|
this.counter = new Counter(this);
|
|
return this.counter.appendTo($("<div>"));
|
|
},
|
|
|
|
start: function() {
|
|
this.$msg = this.$(".msg");
|
|
dom.append(this.$el, this.counter.$el, {
|
|
in_DOM: this.isInDom,
|
|
callbacks: [{ widget: this.counter }]
|
|
});
|
|
},
|
|
on_attach_callback: function() {
|
|
this.isInDom = true;
|
|
if (this.counter) {
|
|
this.counter.on_attach_callback();
|
|
}
|
|
},
|
|
on_detach_callback: function() {
|
|
this.isInDom = true;
|
|
if (this.counter) {
|
|
this.counter.on_detach_callback();
|
|
}
|
|
},
|
|
|
|
_onRemove: function() {
|
|
this.trigger_up("remove_message", { id: this.id });
|
|
},
|
|
|
|
update: function() {
|
|
this.msg += "!!!";
|
|
this.$msg.text(this.msg);
|
|
}
|
|
});
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Root Widget
|
|
//----------------------------------------------------------------------------
|
|
var App = Widget.extend({
|
|
template: "root",
|
|
events: {
|
|
"click .o_btn_msg.100": function() {
|
|
this.addMessages(100);
|
|
},
|
|
"click .o_btn_msg.1000": function() {
|
|
this.addMessages(1000);
|
|
},
|
|
"click .o_btn_msg.10000": function() {
|
|
this.addMessages(10000);
|
|
},
|
|
"click .o_btn_msg.30000": function() {
|
|
this.addMessages(30000);
|
|
},
|
|
"click .updateSomeMessages": function() {
|
|
this.updateSomeMessages();
|
|
},
|
|
"click .clear": function() {
|
|
this.clear();
|
|
},
|
|
"click .o_multiple": function() {
|
|
this.multipleFlag = !this.multipleFlag;
|
|
},
|
|
"click .o_clear": function() {
|
|
this.clearFlag = !this.clearFlag;
|
|
},
|
|
"click .clear-log": function() {
|
|
this.$log[0].innerHTML = "";
|
|
}
|
|
},
|
|
custom_events: {
|
|
remove_message: "_onRemoveMessage"
|
|
},
|
|
|
|
init: function(parent) {
|
|
this._super(parent);
|
|
this.widgets = {};
|
|
this.isInDom = false;
|
|
this.messageCount = 0;
|
|
this.multipleFlag = false;
|
|
this.clearFlag = false;
|
|
},
|
|
|
|
start: function() {
|
|
this.$content = this.$(".content");
|
|
this.$msgCount = this.$(".message_count");
|
|
this.$log = this.$(".log-content");
|
|
this.log("Benchmarking odoo widgets, 12.0");
|
|
},
|
|
on_attach_callback: function() {
|
|
this.isInDom = true;
|
|
for (let widget of Object.values(this.widgets)) {
|
|
if (widget.on_attach_callback) {
|
|
widget.on_attach_callback();
|
|
}
|
|
}
|
|
},
|
|
on_detach_callback: function() {
|
|
this.isInDom = true;
|
|
for (let widget of Object.values(this.widgets)) {
|
|
if (widget.on_detach_callback) {
|
|
widget.on_detach_callback();
|
|
}
|
|
}
|
|
},
|
|
|
|
updateMessageCount() {
|
|
this.$msgCount.text("Number of msg: " + this.messageCount);
|
|
},
|
|
|
|
addMessages: function(n) {
|
|
const self = this;
|
|
this.benchmark("add " + n, () => {
|
|
const defs = [];
|
|
const messages = buildData(n);
|
|
for (let message of messages) {
|
|
const widget = new Message(this, message);
|
|
this.widgets[message.id] = widget;
|
|
defs.push(widget.appendTo("<div>"));
|
|
}
|
|
return $.when
|
|
.apply($, defs)
|
|
.then(function() {
|
|
for (let message of messages) {
|
|
let widget = self.widgets[message.id];
|
|
dom.append(self.$content, widget.$el, {
|
|
in_DOM: this.isInDom,
|
|
callbacks: [{ widget: widget }]
|
|
});
|
|
}
|
|
})
|
|
.then(function() {
|
|
self.messageCount += n;
|
|
self.updateMessageCount();
|
|
});
|
|
});
|
|
},
|
|
clear: function() {
|
|
startMeasure("clear");
|
|
this._clear();
|
|
stopMeasure(info => {
|
|
this.log(info.msg);
|
|
});
|
|
},
|
|
|
|
_clear: function() {
|
|
this.$content.empty();
|
|
for (let key in this.widgets) {
|
|
this.widgets[key].destroy();
|
|
delete this.widgets[key];
|
|
}
|
|
this.messageCount = 0;
|
|
this.updateMessageCount();
|
|
},
|
|
updateSomeMessages: function() {
|
|
this.benchmark("update every 10th", () => {
|
|
const widgets = Object.values(this.widgets);
|
|
for (let i = 0; i < widgets.length; i += 10) {
|
|
widgets[i].update();
|
|
}
|
|
});
|
|
},
|
|
_onRemoveMessage: function(ev) {
|
|
startMeasure("remove message");
|
|
ev.target.destroy();
|
|
delete this.widgets[ev.data.id];
|
|
this.messageCount--;
|
|
this.updateMessageCount();
|
|
stopMeasure();
|
|
},
|
|
|
|
benchmark: function(message, fn, callback) {
|
|
if (this.multipleFlag) {
|
|
const N = 20;
|
|
let n = N;
|
|
let total = 0;
|
|
let cb = info => {
|
|
let finalize = () => {
|
|
n--;
|
|
total += info.delta;
|
|
if (n === 0) {
|
|
const avg = total / N;
|
|
this.log(`Average: ${formatNumber(avg)}ms`, true);
|
|
if (callback) {
|
|
callback();
|
|
}
|
|
} else {
|
|
this._benchmark(message, fn, cb);
|
|
}
|
|
};
|
|
|
|
if (this.clearFlag) {
|
|
this._benchmark("clear", this._clear.bind(this), finalize, false);
|
|
} else {
|
|
finalize();
|
|
}
|
|
};
|
|
this._benchmark(message, fn, cb);
|
|
} else {
|
|
this._benchmark(message, fn, callback);
|
|
}
|
|
},
|
|
|
|
_benchmark: function(message, fn, cb, log = true) {
|
|
setTimeout(() => {
|
|
startMeasure(message);
|
|
const benchmark = fn();
|
|
(benchmark && benchmark.then ? benchmark : $.when()).then(() => {
|
|
stopMeasure(info => {
|
|
if (log) {
|
|
this.log(info.msg);
|
|
}
|
|
if (cb) {
|
|
cb(info);
|
|
}
|
|
});
|
|
}, 10);
|
|
});
|
|
},
|
|
|
|
log: function(str, isBold) {
|
|
const div = document.createElement("div");
|
|
if (isBold) {
|
|
div.classList.add("bold");
|
|
}
|
|
div.textContent = `> ${str}`;
|
|
this.$log[0].appendChild(div);
|
|
this.$log[0].scrollTop = this.$log[0].scrollHeight;
|
|
}
|
|
});
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Application initialization
|
|
//------------------------------------------------------------------------------
|
|
async function start() {
|
|
// prepare QWeb
|
|
const templates = await fetch("templates.xml");
|
|
let strTemplates = await templates.text();
|
|
strTemplates = strTemplates.replace(/<!--[\s\S]*?-->/g, "");
|
|
core.qweb.add_template(strTemplates);
|
|
|
|
// prepare app
|
|
const app = new App();
|
|
await app.appendTo(document.body);
|
|
}
|
|
|
|
start();
|
|
});
|