summaryrefslogtreecommitdiff
path: root/addons/web/doc/module
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/web/doc/module
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/web/doc/module')
-rw-r--r--addons/web/doc/module/017
-rw-r--r--addons/web/doc/module/1013
-rw-r--r--addons/web/doc/module/1111
-rw-r--r--addons/web/doc/module/1228
-rw-r--r--addons/web/doc/module/1417
-rw-r--r--addons/web/doc/module/1519
-rw-r--r--addons/web/doc/module/1625
-rw-r--r--addons/web/doc/module/1752
-rw-r--r--addons/web/doc/module/1819
-rw-r--r--addons/web/doc/module/1952
-rw-r--r--addons/web/doc/module/212
-rw-r--r--addons/web/doc/module/2064
-rw-r--r--addons/web/doc/module/2127
-rw-r--r--addons/web/doc/module/226
-rw-r--r--addons/web/doc/module/2314
-rw-r--r--addons/web/doc/module/2410
-rw-r--r--addons/web/doc/module/2555
-rw-r--r--addons/web/doc/module/2638
-rw-r--r--addons/web/doc/module/2728
-rw-r--r--addons/web/doc/module/2813
-rw-r--r--addons/web/doc/module/2937
-rw-r--r--addons/web/doc/module/39
-rw-r--r--addons/web/doc/module/411
-rw-r--r--addons/web/doc/module/511
-rw-r--r--addons/web/doc/module/629
-rw-r--r--addons/web/doc/module/814
-rw-r--r--addons/web/doc/module/921
-rw-r--r--addons/web/doc/module/series27
-rw-r--r--addons/web/doc/module/testing_0.pngbin0 -> 23285 bytes
-rw-r--r--addons/web/doc/module/testing_1.pngbin0 -> 36183 bytes
30 files changed, 679 insertions, 0 deletions
diff --git a/addons/web/doc/module/0 b/addons/web/doc/module/0
new file mode 100644
index 00000000..17b70a86
--- /dev/null
+++ b/addons/web/doc/module/0
@@ -0,0 +1,17 @@
+# HG changeset patch
+# Parent 0000000000000000000000000000000000000000
+
+diff --git a/__init__.py b/__init__.py
+new file mode 100644
+diff --git a/__manifest__.py b/__manifest__.py
+new file mode 100644
+--- /dev/null
++++ b/__manifest__.py
+@@ -0,0 +1,7 @@
++# __manifest__.py
++{
++ 'name': "Web Example",
++ 'description': "Basic example of a (future) web module",
++ 'category': 'Hidden',
++ 'depends': ['base'],
++}
diff --git a/addons/web/doc/module/10 b/addons/web/doc/module/10
new file mode 100644
index 00000000..dc3b670c
--- /dev/null
+++ b/addons/web/doc/module/10
@@ -0,0 +1,13 @@
+# HG changeset patch
+# Parent 72d9d59a93fcee06ba28cf0b98a1075331dcc8f4
+diff --git a/static/src/css/web_example.css b/static/src/css/web_example.css
+new file mode 100644
+--- /dev/null
++++ b/static/src/css/web_example.css
+@@ -0,0 +1,6 @@
++.openerp .oe_web_example {
++ color: white;
++ background-color: black;
++ height: 100%;
++ font-size: 400%;
++}
diff --git a/addons/web/doc/module/11 b/addons/web/doc/module/11
new file mode 100644
index 00000000..889ee98e
--- /dev/null
+++ b/addons/web/doc/module/11
@@ -0,0 +1,11 @@
+# HG changeset patch
+# Parent 3ed382d9a8fe64fbb8e2bf4045e3fcd5c74c92bc
+diff --git a/__manifest__.py b/__manifest__.py
+--- a/__manifest__.py
++++ b/__manifest__.py
+@@ -6,4 +6,5 @@
+ 'depends': ['web'],
+ 'data': ['web_example.xml'],
+ 'js': ['static/src/js/first_module.js'],
++ 'css': ['static/src/css/web_example.css'],
+ }
diff --git a/addons/web/doc/module/12 b/addons/web/doc/module/12
new file mode 100644
index 00000000..85c931c3
--- /dev/null
+++ b/addons/web/doc/module/12
@@ -0,0 +1,28 @@
+# HG changeset patch
+# Parent 43f21611dacb7c2b2f3810baeeef359ad7c329f0
+
+diff --git a/__manifest__.py b/__manifest__.py
+--- a/__manifest__.py
++++ b/__manifest__.py
+@@ -7,4 +7,5 @@
+ 'data': ['web_example.xml'],
+ 'js': ['static/src/js/first_module.js'],
+ 'css': ['static/src/css/web_example.css'],
++ 'qweb': ['static/src/xml/web_example.xml'],
+ }
+diff --git a/static/src/xml/web_example.xml b/static/src/xml/web_example.xml
+new file mode 100644
+--- /dev/null
++++ b/static/src/xml/web_example.xml
+@@ -0,0 +1,11 @@
++<templates>
++<div t-name="web_example.action" class="oe_web_example oe_web_example_stopped">
++ <h4 class="oe_web_example_timer">00:00:00</h4>
++ <p class="oe_web_example_start">
++ <button type="button">Start</button>
++ </p>
++ <p class="oe_web_example_stop">
++ <button type="button">Stop</button>
++ </p>
++</div>
++</templates>
diff --git a/addons/web/doc/module/14 b/addons/web/doc/module/14
new file mode 100644
index 00000000..a908cbc6
--- /dev/null
+++ b/addons/web/doc/module/14
@@ -0,0 +1,17 @@
+# HG changeset patch
+# Parent ae3b427c96b532794a65357b3f075129cc991276
+diff --git a/static/src/js/first_module.js b/static/src/js/first_module.js
+--- a/static/src/js/first_module.js
++++ b/static/src/js/first_module.js
+@@ -2,10 +2,6 @@
+ openerp.web_example = function (instance) {
+ instance.web.client_actions.add('example.action', 'instance.web_example.Action');
+ instance.web_example.Action = instance.web.Widget.extend({
+- className: 'oe_web_example',
+- start: function () {
+- this.$el.text("Hello, world!");
+- return this._super();
+- }
++ template: 'web_example.action'
+ });
+ };
diff --git a/addons/web/doc/module/15 b/addons/web/doc/module/15
new file mode 100644
index 00000000..d82abee3
--- /dev/null
+++ b/addons/web/doc/module/15
@@ -0,0 +1,19 @@
+# HG changeset patch
+# Parent e2d2e1a4cc2d2496aebeb05d94768384427c9e8b
+diff --git a/static/src/css/web_example.css b/static/src/css/web_example.css
+--- a/static/src/css/web_example.css
++++ b/static/src/css/web_example.css
+@@ -2,5 +2,12 @@
+ color: white;
+ background-color: black;
+ height: 100%;
+- font-size: 400%;
+ }
++.openerp .oe_web_example h4 {
++ margin: 0;
++ font-size: 200%;
++}
++.openerp .oe_web_example.oe_web_example_started .oe_web_example_start button,
++.openerp .oe_web_example.oe_web_example_stopped .oe_web_example_stop button {
++ display: none
++}
diff --git a/addons/web/doc/module/16 b/addons/web/doc/module/16
new file mode 100644
index 00000000..816c23aa
--- /dev/null
+++ b/addons/web/doc/module/16
@@ -0,0 +1,25 @@
+# HG changeset patch
+# Parent 2645d7a09dcba7f6d6074a33252c16c03c56fdf3
+diff --git a/static/src/js/first_module.js b/static/src/js/first_module.js
+--- a/static/src/js/first_module.js
++++ b/static/src/js/first_module.js
+@@ -2,6 +2,18 @@
+ openerp.web_example = function (instance) {
+ instance.web.client_actions.add('example.action', 'instance.web_example.Action');
+ instance.web_example.Action = instance.web.Widget.extend({
+- template: 'web_example.action'
++ template: 'web_example.action',
++ events: {
++ 'click .oe_web_example_start button': 'watch_start',
++ 'click .oe_web_example_stop button': 'watch_stop'
++ },
++ watch_start: function () {
++ this.$el.addClass('oe_web_example_started')
++ .removeClass('oe_web_example_stopped');
++ },
++ watch_stop: function () {
++ this.$el.removeClass('oe_web_example_started')
++ .addClass('oe_web_example_stopped');
++ },
+ });
+ };
diff --git a/addons/web/doc/module/17 b/addons/web/doc/module/17
new file mode 100644
index 00000000..d6d6ecc7
--- /dev/null
+++ b/addons/web/doc/module/17
@@ -0,0 +1,52 @@
+# HG changeset patch
+# Parent 2921a545adc3406d3139be7951f3225e94493466
+diff --git a/static/src/js/first_module.js b/static/src/js/first_module.js
+--- a/static/src/js/first_module.js
++++ b/static/src/js/first_module.js
+@@ -7,13 +7,46 @@ openerp.web_example = function (instance
+ 'click .oe_web_example_start button': 'watch_start',
+ 'click .oe_web_example_stop button': 'watch_stop'
+ },
++ init: function () {
++ this._super.apply(this, arguments);
++ this._start = null;
++ this._watch = null;
++ },
++ update_counter: function () {
++ var h, m, s;
++ // Subtracting javascript dates returns the difference in milliseconds
++ var diff = new Date() - this._start;
++ s = diff / 1000;
++ m = Math.floor(s / 60);
++ s -= 60*m;
++ h = Math.floor(m / 60);
++ m -= 60*h;
++ this.$('.oe_web_example_timer').text(
++ _.str.sprintf("%02d:%02d:%02d", h, m, s));
++ },
+ watch_start: function () {
+ this.$el.addClass('oe_web_example_started')
+ .removeClass('oe_web_example_stopped');
++ this._start = new Date();
++ // Update the UI to the current time
++ this.update_counter();
++ // Update the counter at 30 FPS (33ms/frame)
++ this._watch = setInterval(
++ this.proxy('update_counter'),
++ 33);
+ },
+ watch_stop: function () {
++ clearInterval(this._watch);
++ this.update_counter();
++ this._start = this._watch = null;
+ this.$el.removeClass('oe_web_example_started')
+ .addClass('oe_web_example_stopped');
+ },
++ destroy: function () {
++ if (this._watch) {
++ clearInterval(this._watch);
++ }
++ this._super();
++ }
+ });
+ };
diff --git a/addons/web/doc/module/18 b/addons/web/doc/module/18
new file mode 100644
index 00000000..6781c985
--- /dev/null
+++ b/addons/web/doc/module/18
@@ -0,0 +1,19 @@
+# HG changeset patch
+# Parent e0cc13c2b2ec4d6f6bfdb033b189a32e44106f2e
+diff --git a/__init__.py b/__init__.py
+--- a/__init__.py
++++ b/__init__.py
+@@ -0,0 +1,13 @@
++# __init__.py
++from openerp.osv import orm, fields
++
++
++class Times(orm.Model):
++ _name = 'web_example.stopwatch'
++
++ _columns = {
++ 'time': fields.integer("Time", required=True,
++ help="Measured time in milliseconds"),
++ 'user_id': fields.many2one('res.users', "User", required=True,
++ help="User who registered the measurement")
++ }
diff --git a/addons/web/doc/module/19 b/addons/web/doc/module/19
new file mode 100644
index 00000000..d95a89a3
--- /dev/null
+++ b/addons/web/doc/module/19
@@ -0,0 +1,52 @@
+# HG changeset patch
+# Parent 05797cc75b49634e640f44b24347f2905b464022
+diff --git a/static/src/js/first_module.js b/static/src/js/first_module.js
+--- a/static/src/js/first_module.js
++++ b/static/src/js/first_module.js
+@@ -12,11 +12,13 @@ openerp.web_example = function (instance
+ this._start = null;
+ this._watch = null;
+ },
+- update_counter: function () {
++ current: function () {
++ // Subtracting javascript dates returns the difference in milliseconds
++ return new Date() - this._start;
++ },
++ update_counter: function (time) {
+ var h, m, s;
+- // Subtracting javascript dates returns the difference in milliseconds
+- var diff = new Date() - this._start;
+- s = diff / 1000;
++ s = time / 1000;
+ m = Math.floor(s / 60);
+ s -= 60*m;
+ h = Math.floor(m / 60);
+@@ -29,18 +31,24 @@ openerp.web_example = function (instance
+ .removeClass('oe_web_example_stopped');
+ this._start = new Date();
+ // Update the UI to the current time
+- this.update_counter();
++ this.update_counter(this.current());
+ // Update the counter at 30 FPS (33ms/frame)
+- this._watch = setInterval(
+- this.proxy('update_counter'),
++ this._watch = setInterval(function () {
++ this.update_counter(this.current());
++ }.bind(this),
+ 33);
+ },
+ watch_stop: function () {
+ clearInterval(this._watch);
+- this.update_counter();
++ var time = this.current();
++ this.update_counter(time);
+ this._start = this._watch = null;
+ this.$el.removeClass('oe_web_example_started')
+ .addClass('oe_web_example_stopped');
++ new instance.web.Model('web_example.stopwatch').call('create', [{
++ user_id: instance.session.uid,
++ time: time,
++ }]);
+ },
+ destroy: function () {
+ if (this._watch) {
diff --git a/addons/web/doc/module/2 b/addons/web/doc/module/2
new file mode 100644
index 00000000..7d8e9f05
--- /dev/null
+++ b/addons/web/doc/module/2
@@ -0,0 +1,12 @@
+# HG changeset patch
+# Parent 8a986919a3e22cd7cca51210820c09d4545dc60d
+diff --git a/__manifest__.py b/__manifest__.py
+--- a/__manifest__.py
++++ b/__manifest__.py
+@@ -3,5 +3,5 @@
+ 'name': "Web Example",
+ 'description': "Basic example of a (future) web module",
+ 'category': 'Hidden',
+- 'depends': ['base'],
++ 'depends': ['web'],
+ }
diff --git a/addons/web/doc/module/20 b/addons/web/doc/module/20
new file mode 100644
index 00000000..042ff280
--- /dev/null
+++ b/addons/web/doc/module/20
@@ -0,0 +1,64 @@
+Index: web_example/static/src/js/first_module.js
+===================================================================
+--- web_example.orig/static/src/js/first_module.js
++++ web_example/static/src/js/first_module.js
+@@ -11,20 +11,36 @@ openerp.web_example = function (instance
+ this._super.apply(this, arguments);
+ this._start = null;
+ this._watch = null;
++ this.model = new instance.web.Model('web_example.stopwatch');
++ },
++ start: function () {
++ var display = this.display_record.bind(this);
++ return this.model.query()
++ .filter([['user_id', '=', instance.session.uid]])
++ .all().done(function (records) {
++ _(records).each(display);
++ });
+ },
+ current: function () {
+ // Subtracting javascript dates returns the difference in milliseconds
+ return new Date() - this._start;
+ },
+- update_counter: function (time) {
++ display_record: function (record) {
++ $('<li>')
++ .text(this.format_time(record.time))
++ .appendTo(this.$('.oe_web_example_saved'));
++ },
++ format_time: function (time) {
+ var h, m, s;
+ s = time / 1000;
+ m = Math.floor(s / 60);
+ s -= 60*m;
+ h = Math.floor(m / 60);
+ m -= 60*h;
+- this.$('.oe_web_example_timer').text(
+- _.str.sprintf("%02d:%02d:%02d", h, m, s));
++ return _.str.sprintf("%02d:%02d:%02d", h, m, s);
++ },
++ update_counter: function (time) {
++ this.$('.oe_web_example_timer').text(this.format_time(time));
+ },
+ watch_start: function () {
+ this.$el.addClass('oe_web_example_started')
+@@ -45,7 +61,7 @@ openerp.web_example = function (instance
+ this._start = this._watch = null;
+ this.$el.removeClass('oe_web_example_started')
+ .addClass('oe_web_example_stopped');
+- new instance.web.Model('web_example.stopwatch').call('create', [{
++ this.model.call('create', [{
+ user_id: instance.session.uid,
+ time: time,
+ }]);
+Index: web_example/static/src/xml/web_example.xml
+===================================================================
+--- web_example.orig/static/src/xml/web_example.xml
++++ web_example/static/src/xml/web_example.xml
+@@ -7,5 +7,6 @@
+ <p class="oe_web_example_stop">
+ <button type="button">Stop</button>
+ </p>
++ <ol class="oe_web_example_saved"></ol>
+ </div>
+ </templates>
diff --git a/addons/web/doc/module/21 b/addons/web/doc/module/21
new file mode 100644
index 00000000..0acfac90
--- /dev/null
+++ b/addons/web/doc/module/21
@@ -0,0 +1,27 @@
+Index: web_example/static/src/js/first_module.js
+===================================================================
+--- web_example.orig/static/src/js/first_module.js
++++ web_example/static/src/js/first_module.js
+@@ -55,16 +55,20 @@ openerp.web_example = function (instance
+ 33);
+ },
+ watch_stop: function () {
++ var self = this;
+ clearInterval(this._watch);
+ var time = this.current();
+ this.update_counter(time);
+ this._start = this._watch = null;
+ this.$el.removeClass('oe_web_example_started')
+ .addClass('oe_web_example_stopped');
+- this.model.call('create', [{
++ var record = {
+ user_id: instance.session.uid,
+ time: time,
+- }]);
++ };
++ this.model.call('create', [record]).done(function () {
++ self.display_record(record);
++ });
+ },
+ destroy: function () {
+ if (this._watch) {
diff --git a/addons/web/doc/module/22 b/addons/web/doc/module/22
new file mode 100644
index 00000000..5df76b30
--- /dev/null
+++ b/addons/web/doc/module/22
@@ -0,0 +1,6 @@
+Index: web_example/static/src/tests/timer.js
+===================================================================
+--- /dev/null
++++ web_example/static/src/tests/timer.js
+@@ -0,0 +1 @@
++
diff --git a/addons/web/doc/module/23 b/addons/web/doc/module/23
new file mode 100644
index 00000000..d08a026a
--- /dev/null
+++ b/addons/web/doc/module/23
@@ -0,0 +1,14 @@
+Index: web_example/static/src/tests/timer.js
+===================================================================
+--- web_example.orig/static/src/tests/timer.js
++++ web_example/static/src/tests/timer.js
+@@ -1 +1,8 @@
+-
++openerp.testing.section('timer', function (test) {
++ test('successful test', function () {
++ ok(true, "should work");
++ });
++ test('unsuccessful test', function () {
++ ok(false, "shoud fail");
++ });
++});
diff --git a/addons/web/doc/module/24 b/addons/web/doc/module/24
new file mode 100644
index 00000000..0972e856
--- /dev/null
+++ b/addons/web/doc/module/24
@@ -0,0 +1,10 @@
+Index: web_example/__manifest__.py
+===================================================================
+--- web_example.orig/__manifest__.py
++++ web_example/__manifest__.py
+@@ -8,4 +8,5 @@
+ 'js': ['static/src/js/first_module.js'],
+ 'css': ['static/src/css/web_example.css'],
+ 'qweb': ['static/src/xml/web_example.xml'],
++ 'test': ['static/src/tests/timer.js'],
+ }
diff --git a/addons/web/doc/module/25 b/addons/web/doc/module/25
new file mode 100644
index 00000000..1d63dc7f
--- /dev/null
+++ b/addons/web/doc/module/25
@@ -0,0 +1,55 @@
+Index: web_example/static/src/tests/timer.js
+===================================================================
+--- web_example.orig/static/src/tests/timer.js
++++ web_example/static/src/tests/timer.js
+@@ -1,8 +1,45 @@
+ openerp.testing.section('timer', function (test) {
+- test('successful test', function () {
+- ok(true, "should work");
+- });
+- test('unsuccessful test', function () {
+- ok(false, "shoud fail");
++ test('format_time', function (instance) {
++ var w = new instance.web_example.Action();
++
++ strictEqual(
++ w.format_time(0),
++ '00:00:00');
++ strictEqual(
++ w.format_time(543),
++ '00:00:00',
++ "should round sub-second times down to zero");
++ strictEqual(
++ w.format_time(5340),
++ '00:00:05',
++ "should floor sub-second extents to the previous second");
++ strictEqual(
++ w.format_time(60000),
++ '00:01:00');
++ strictEqual(
++ w.format_time(3600000),
++ '01:00:00');
++ strictEqual(
++ w.format_time(86400000),
++ '24:00:00');
++ strictEqual(
++ w.format_time(604800000),
++ '168:00:00');
++
++ strictEqual(
++ w.format_time(22733958),
++ '06:18:53');
++ strictEqual(
++ w.format_time(41676639),
++ '11:34:36');
++ strictEqual(
++ w.format_time(57802094),
++ '16:03:22');
++ strictEqual(
++ w.format_time(73451828),
++ '20:24:11');
++ strictEqual(
++ w.format_time(84092336),
++ '23:21:32');
+ });
+ });
diff --git a/addons/web/doc/module/26 b/addons/web/doc/module/26
new file mode 100644
index 00000000..ec0b345a
--- /dev/null
+++ b/addons/web/doc/module/26
@@ -0,0 +1,38 @@
+Index: web_example/static/src/tests/timer.js
+===================================================================
+--- web_example.orig/static/src/tests/timer.js
++++ web_example/static/src/tests/timer.js
+@@ -42,4 +42,33 @@ openerp.testing.section('timer', functio
+ w.format_time(84092336),
+ '23:21:32');
+ });
++ test('update_counter', function (instance, $fixture) {
++ var w = new instance.web_example.Action();
++ // $fixture is a DOM tree whose content gets cleaned up before
++ // each test, so we can add whatever we need to it
++ $fixture.append('<div class="oe_web_example_timer">');
++ // Then set it on the widget
++ w.setElement($fixture);
++
++ // Update the counter with a known value
++ w.update_counter(22733958);
++ // And check the DOM matches
++ strictEqual($fixture.text(), '06:18:53');
++
++ w.update_counter(73451828)
++ strictEqual($fixture.text(), '20:24:11');
++ });
++ test('display_record', function (instance, $fixture) {
++ var w = new instance.web_example.Action();
++ $fixture.append('<ol class="oe_web_example_saved">')
++ w.setElement($fixture);
++
++ w.display_record({time: 41676639});
++ w.display_record({time: 84092336});
++
++ var $lis = $fixture.find('li');
++ strictEqual($lis.length, 2, "should have printed 2 records");
++ strictEqual($lis[0].textContent, '11:34:36');
++ strictEqual($lis[1].textContent, '23:21:32');
++ });
+ });
diff --git a/addons/web/doc/module/27 b/addons/web/doc/module/27
new file mode 100644
index 00000000..2061b700
--- /dev/null
+++ b/addons/web/doc/module/27
@@ -0,0 +1,28 @@
+Index: web_example/static/src/tests/timer.js
+===================================================================
+--- web_example.orig/static/src/tests/timer.js
++++ web_example/static/src/tests/timer.js
+@@ -71,4 +71,23 @@ openerp.testing.section('timer', functio
+ strictEqual($lis[0].textContent, '11:34:36');
+ strictEqual($lis[1].textContent, '23:21:32');
+ });
++ test('start', {templates: true, rpc: 'mock', asserts: 3}, function (instance, $fixture, mock) {
++ // Rather odd-looking shortcut for search+read in a single RPC call
++ mock('/web/dataset/search_read', function () {
++ // ignore parameters, just return a pair of records.
++ return {records: [
++ {time: 22733958},
++ {time: 84092336}
++ ]};
++ });
++
++ var w = new instance.web_example.Action();
++ return w.appendTo($fixture)
++ .then(function () {
++ var $lis = $fixture.find('li');
++ strictEqual($lis.length, 2);
++ strictEqual($lis[0].textContent, '06:18:53');
++ strictEqual($lis[1].textContent, '23:21:32');
++ });
++ });
+ });
diff --git a/addons/web/doc/module/28 b/addons/web/doc/module/28
new file mode 100644
index 00000000..800e7a6f
--- /dev/null
+++ b/addons/web/doc/module/28
@@ -0,0 +1,13 @@
+Index: web_example/static/src/js/first_module.js
+===================================================================
+--- web_example.orig/static/src/js/first_module.js
++++ web_example/static/src/js/first_module.js
+@@ -66,7 +66,7 @@ openerp.web_example = function (instance
+ user_id: instance.session.uid,
+ time: time,
+ };
+- this.model.call('create', [record]).done(function () {
++ return this.model.call('create', [record]).done(function () {
+ self.display_record(record);
+ });
+ },
diff --git a/addons/web/doc/module/29 b/addons/web/doc/module/29
new file mode 100644
index 00000000..509d4b78
--- /dev/null
+++ b/addons/web/doc/module/29
@@ -0,0 +1,37 @@
+Index: web_example/static/src/tests/timer.js
+===================================================================
+--- web_example.orig/static/src/tests/timer.js
++++ web_example/static/src/tests/timer.js
+@@ -90,4 +90,32 @@ openerp.testing.section('timer', functio
+ strictEqual($lis[1].textContent, '23:21:32');
+ });
+ });
++ test('watch_stop', {templates: true, rpc: 'mock', asserts: 3}, function (instance, $fix, mock) {
++ var created = false;
++ mock('web_example.stopwatch:create', function (args, kwargs) {
++ created = true;
++ // return a fake id (unused)
++ return 42;
++ });
++ mock('/web/dataset/search_read', function () {
++ return {records: []};
++ });
++
++ var w = new instance.web_example.Action();
++ return w.appendTo($fix)
++ .then(function () {
++ // Virtual start point 5s before 'now'
++ w._start = new Date() - 5000;
++ return w.watch_stop();
++ })
++ .done(function () {
++ ok(created, "should have called create()");
++ strictEqual($fix.find('.oe_web_example_timer').text(),
++ '00:00:05',
++ "should have updated the timer");
++ strictEqual($fix.find('li')[0].textContent,
++ '00:00:05',
++ "should have added the new time to the list");
++ });
++ });
+ });
diff --git a/addons/web/doc/module/3 b/addons/web/doc/module/3
new file mode 100644
index 00000000..c09925f9
--- /dev/null
+++ b/addons/web/doc/module/3
@@ -0,0 +1,9 @@
+# HG changeset patch
+# Parent dcf661a5eef8f82503831bdb8e6c9d2f9beb285e
+diff --git a/static/src/js/first_module.js b/static/src/js/first_module.js
+new file mode 100644
+--- /dev/null
++++ b/static/src/js/first_module.js
+@@ -0,0 +1,2 @@
++// static/src/js/first_module.js
++console.log("Debug statement: file loaded");
diff --git a/addons/web/doc/module/4 b/addons/web/doc/module/4
new file mode 100644
index 00000000..99c073d6
--- /dev/null
+++ b/addons/web/doc/module/4
@@ -0,0 +1,11 @@
+# HG changeset patch
+# Parent 139dae60de67efa0017f5032f71ab774685c5507
+diff --git a/__manifest__.py b/__manifest__.py
+--- a/__manifest__.py
++++ b/__manifest__.py
+@@ -4,4 +4,5 @@
+ 'description': "Basic example of a (future) web module",
+ 'category': 'Hidden',
+ 'depends': ['web'],
++ 'js': ['static/src/js/first_module.js'],
+ }
diff --git a/addons/web/doc/module/5 b/addons/web/doc/module/5
new file mode 100644
index 00000000..49acad9c
--- /dev/null
+++ b/addons/web/doc/module/5
@@ -0,0 +1,11 @@
+# HG changeset patch
+# Parent c8ae7646cce3f271698c844eb2d67f9a8719650d
+diff --git a/static/src/js/first_module.js b/static/src/js/first_module.js
+--- a/static/src/js/first_module.js
++++ b/static/src/js/first_module.js
+@@ -1,2 +1,4 @@
+ // static/src/js/first_module.js
+-console.log("Debug statement: file loaded");
++openerp.web_example = function (instance) {
++ console.log("Module loaded");
++};
diff --git a/addons/web/doc/module/6 b/addons/web/doc/module/6
new file mode 100644
index 00000000..3a1232fa
--- /dev/null
+++ b/addons/web/doc/module/6
@@ -0,0 +1,29 @@
+# HG changeset patch
+# Parent 0026cb80097a724db8d36371bc00da993a51a06f
+
+diff --git a/__manifest__.py b/__manifest__.py
+--- a/__manifest__.py
++++ b/__manifest__.py
+@@ -4,5 +4,6 @@
+ 'description': "Basic example of a (future) web module",
+ 'category': 'Hidden',
+ 'depends': ['web'],
++ 'data': ['web_example.xml'],
+ 'js': ['static/src/js/first_module.js'],
+ }
+diff --git a/web_example.xml b/web_example.xml
+new file mode 100644
+--- /dev/null
++++ b/web_example.xml
+@@ -0,0 +1,11 @@
++<!-- web_example/web_example.xml -->
++<openerp>
++ <data>
++ <record model="ir.actions.client" id="action_client_example">
++ <field name="name">Example Client Action</field>
++ <field name="tag">example.action</field>
++ </record>
++ <menuitem action="action_client_example"
++ id="menu_client_example"/>
++ </data>
++</openerp>
diff --git a/addons/web/doc/module/8 b/addons/web/doc/module/8
new file mode 100644
index 00000000..83e6c371
--- /dev/null
+++ b/addons/web/doc/module/8
@@ -0,0 +1,14 @@
+# HG changeset patch
+# Parent d987c9edd884de1de30f2ceb70d2e554474b8dd1
+diff --git a/static/src/js/first_module.js b/static/src/js/first_module.js
+--- a/static/src/js/first_module.js
++++ b/static/src/js/first_module.js
+@@ -1,4 +1,7 @@
+ // static/src/js/first_module.js
+ openerp.web_example = function (instance) {
+- console.log("Module loaded");
++ instance.web.client_actions.add('example.action', 'instance.web_example.action');
++ instance.web_example.action = function (parent, action) {
++ console.log("Executed the action", action);
++ };
+ };
diff --git a/addons/web/doc/module/9 b/addons/web/doc/module/9
new file mode 100644
index 00000000..9113f914
--- /dev/null
+++ b/addons/web/doc/module/9
@@ -0,0 +1,21 @@
+# HG changeset patch
+# Parent 6a1a7240ea0e63182f60abb1eb5c631089d56dbe
+diff --git a/static/src/js/first_module.js b/static/src/js/first_module.js
+--- a/static/src/js/first_module.js
++++ b/static/src/js/first_module.js
+@@ -1,7 +1,11 @@
+ // static/src/js/first_module.js
+ openerp.web_example = function (instance) {
+- instance.web.client_actions.add('example.action', 'instance.web_example.action');
+- instance.web_example.action = function (parent, action) {
+- console.log("Executed the action", action);
+- };
++ instance.web.client_actions.add('example.action', 'instance.web_example.Action');
++ instance.web_example.Action = instance.web.Widget.extend({
++ className: 'oe_web_example',
++ start: function () {
++ this.$el.text("Hello, world!");
++ return this._super();
++ }
++ });
+ };
diff --git a/addons/web/doc/module/series b/addons/web/doc/module/series
new file mode 100644
index 00000000..ff1a909a
--- /dev/null
+++ b/addons/web/doc/module/series
@@ -0,0 +1,27 @@
+0
+2
+3
+4
+5
+6
+8
+9
+10
+11
+12
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
diff --git a/addons/web/doc/module/testing_0.png b/addons/web/doc/module/testing_0.png
new file mode 100644
index 00000000..62711799
--- /dev/null
+++ b/addons/web/doc/module/testing_0.png
Binary files differ
diff --git a/addons/web/doc/module/testing_1.png b/addons/web/doc/module/testing_1.png
new file mode 100644
index 00000000..40cf3249
--- /dev/null
+++ b/addons/web/doc/module/testing_1.png
Binary files differ