forked from Techsystech/web
[IMP] web_pwa_oca: Add support for require system
Service workers need to load "Odoo Bootstrap" to be able to use "require". The problem is that "Odoo Bootstrap" does operations on the DOM (by using jQuery) and to avoid errors a minimal compatibility layer "jquery-sw-compat.js" has been created to allow using "require" in the service worker. Moved Service Worker (js) code from the xml to python.12.0
parent
54b074a50e
commit
dfe4e8ae6c
|
@ -21,7 +21,6 @@
|
|||
],
|
||||
"data": [
|
||||
"templates/assets.xml",
|
||||
"templates/service_worker.xml",
|
||||
"views/res_config_settings_views.xml",
|
||||
],
|
||||
'images': ['static/description/pwa.png'],
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# Copyright 2020 Lorenzo Battistini @ TAKOBI
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
|
||||
from . import main
|
||||
from . import service_worker
|
||||
|
|
|
@ -12,7 +12,9 @@ class PWA(Controller):
|
|||
"""Scripts to be imported in the service worker (Order is important)"""
|
||||
return [
|
||||
"/web/static/lib/underscore/underscore.js",
|
||||
"/web_pwa_oca/static/src/js/worker/libs/class.js",
|
||||
"/web_pwa_oca/static/src/js/worker/jquery-sw-compat.js",
|
||||
"/web/static/src/js/boot.js",
|
||||
"/web/static/src/js/core/class.js",
|
||||
"/web_pwa_oca/static/src/js/worker/pwa.js",
|
||||
]
|
||||
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
# Copyright 2021 Tecnativa - Alexandre D. Díaz
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
|
||||
from odoo.http import request, route
|
||||
from .main import PWA
|
||||
|
||||
|
||||
class ServiceWorker(PWA):
|
||||
|
||||
JS_PWA_CORE_EVENT_INSTALL = """
|
||||
self.addEventListener('install', evt => {{
|
||||
console.log('[ServiceWorker] Installing...');
|
||||
{}
|
||||
}});
|
||||
"""
|
||||
|
||||
JS_PWA_CORE_EVENT_FETCH = """
|
||||
self.addEventListener('fetch', evt => {{
|
||||
{}
|
||||
}});
|
||||
"""
|
||||
|
||||
JS_PWA_CORE_EVENT_ACTIVATE = """
|
||||
self.addEventListener('activate', evt => {{
|
||||
{}
|
||||
}});
|
||||
"""
|
||||
|
||||
JS_PWA_MAIN = """
|
||||
self.importScripts(...{pwa_scripts});
|
||||
|
||||
odoo.define("web_pwa_oca.ServiceWorker", function (require) {{
|
||||
"use strict";
|
||||
|
||||
{pwa_requires}
|
||||
|
||||
{pwa_init}
|
||||
{pwa_core_event_install}
|
||||
{pwa_core_event_activate}
|
||||
{pwa_core_event_fetch}
|
||||
}});
|
||||
"""
|
||||
|
||||
def _get_js_pwa_requires(self):
|
||||
return """
|
||||
const PWA = require('web_pwa_oca.PWA');
|
||||
"""
|
||||
|
||||
def _get_js_pwa_init(self):
|
||||
return """
|
||||
const oca_pwa = new PWA({});
|
||||
""".format(self._get_pwa_params())
|
||||
|
||||
def _get_js_pwa_core_event_install_impl(self):
|
||||
return """
|
||||
evt.waitUntil(oca_pwa.installWorker());
|
||||
self.skipWaiting();
|
||||
"""
|
||||
|
||||
def _get_js_pwa_core_event_activate_impl(self):
|
||||
return """
|
||||
console.log('[ServiceWorker] Activating...');
|
||||
evt.waitUntil(oca_pwa.activateWorker());
|
||||
self.clients.claim();
|
||||
"""
|
||||
|
||||
def _get_js_pwa_core_event_fetch_impl(self):
|
||||
return ""
|
||||
|
||||
@route("/service-worker.js", type="http", auth="public")
|
||||
def render_service_worker(self):
|
||||
"""Route to register the service worker in the 'main' scope ('/')"""
|
||||
|
||||
sw_code = self.JS_PWA_MAIN.format(**{
|
||||
'pwa_scripts': self._get_pwa_scripts(),
|
||||
'pwa_requires': self._get_js_pwa_requires(),
|
||||
'pwa_init': self._get_js_pwa_init(),
|
||||
'pwa_core_event_install': self.JS_PWA_CORE_EVENT_INSTALL.format(
|
||||
self._get_js_pwa_core_event_install_impl()),
|
||||
'pwa_core_event_activate': self.JS_PWA_CORE_EVENT_ACTIVATE.format(
|
||||
self._get_js_pwa_core_event_activate_impl()),
|
||||
'pwa_core_event_fetch': self.JS_PWA_CORE_EVENT_FETCH.format(
|
||||
self._get_js_pwa_core_event_fetch_impl()),
|
||||
})
|
||||
return request.make_response(
|
||||
sw_code,
|
||||
[('Content-Type', "text/javascript;charset=utf-8"),
|
||||
('Content-Length', len(sw_code))])
|
|
@ -6,15 +6,16 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 12.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2021-02-17 10:45+0000\n"
|
||||
"POT-Creation-Date: 2021-03-11 16:50+0000\n"
|
||||
"PO-Revision-Date: 2021-03-11 19:03+0100\n"
|
||||
"Last-Translator: claudiagn <claudia.gargallo@qubiq.es>\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 4.3.2\n"
|
||||
"X-Generator: Poedit 2.4.1\n"
|
||||
|
||||
#. module: web_pwa_oca
|
||||
#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_background_color
|
||||
|
@ -123,266 +124,3 @@ msgstr "[ServiceWorker] Registrada:"
|
|||
#, python-format
|
||||
msgid "[ServiceWorker] Registration failed: "
|
||||
msgstr "[ServiceWorker] Error en el registro: "
|
||||
|
||||
#. module: web_pwa_oca
|
||||
#: model_terms:ir.ui.view,arch_db:web_pwa_oca.pwa_core_events
|
||||
msgid ""
|
||||
"console.log('[ServiceWorker] Activating...');\n"
|
||||
" evt.waitUntil(oca_pwa.activateWorker());\n"
|
||||
" self.clients.claim();"
|
||||
msgstr ""
|
||||
"console.log('[ServiceWorker] Activating...');\n"
|
||||
" evt.waitUntil(oca_pwa.activateWorker());\n"
|
||||
" self.clients.claim();"
|
||||
|
||||
#. module: web_pwa_oca
|
||||
#: model_terms:ir.ui.view,arch_db:web_pwa_oca.pwa_init
|
||||
msgid "const oca_pwa = new PWA("
|
||||
msgstr "const oca_pwa = nuevo PWA("
|
||||
|
||||
#. module: web_pwa_oca
|
||||
#: model_terms:ir.ui.view,arch_db:web_pwa_oca.pwa_core_events
|
||||
msgid ""
|
||||
"evt.waitUntil(oca_pwa.installWorker());\n"
|
||||
" self.skipWaiting();"
|
||||
msgstr ""
|
||||
"evt.waitUntil(oca_pwa.installWorker());\n"
|
||||
" self.skipWaiting();"
|
||||
|
||||
#. module: web_pwa_oca
|
||||
#: model_terms:ir.ui.view,arch_db:web_pwa_oca.pwa_core_events
|
||||
msgid "self.addEventListener('activate', evt => {"
|
||||
msgstr "self.addEventListener('activate', evt => {"
|
||||
|
||||
#. module: web_pwa_oca
|
||||
#: model_terms:ir.ui.view,arch_db:web_pwa_oca.pwa_core_events
|
||||
msgid "self.addEventListener('fetch', evt => {"
|
||||
msgstr "self.addEventListener('fetch', evt => {"
|
||||
|
||||
#. module: web_pwa_oca
|
||||
#: model_terms:ir.ui.view,arch_db:web_pwa_oca.pwa_core_events
|
||||
msgid ""
|
||||
"self.addEventListener('install', evt => {\n"
|
||||
" console.log('[ServiceWorker] Installing...');"
|
||||
msgstr ""
|
||||
"self.addEventListener('install', evt => {\n"
|
||||
" console.log('[ServiceWorker] Installing...');"
|
||||
|
||||
#. module: web_pwa_oca
|
||||
#: model_terms:ir.ui.view,arch_db:web_pwa_oca.service_worker
|
||||
msgid "self.importScripts(..."
|
||||
msgstr "self.importScripts(..."
|
||||
|
||||
#~ msgid "Install PWA"
|
||||
#~ msgstr "Instalar PWA"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\",\n"
|
||||
#~ " \"sizes\": \"128x128\",\n"
|
||||
#~ " \"type\": \"image/png\"\n"
|
||||
#~ " }, {\n"
|
||||
#~ " \"src\": \""
|
||||
#~ msgstr ""
|
||||
#~ "\",\n"
|
||||
#~ " \"sizes\": \"128x128\",\n"
|
||||
#~ " \"type\": \"image/png\"\n"
|
||||
#~ " }, {\n"
|
||||
#~ " \"src\": \""
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\",\n"
|
||||
#~ " \"sizes\": \"144x144\",\n"
|
||||
#~ " \"type\": \"image/png\"\n"
|
||||
#~ " }, {\n"
|
||||
#~ " \"src\": \""
|
||||
#~ msgstr ""
|
||||
#~ "\",\n"
|
||||
#~ " \"sizes\": \"144x144\",\n"
|
||||
#~ " \"type\": \"image/png\"\n"
|
||||
#~ " }, {\n"
|
||||
#~ " \"src\": \""
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\",\n"
|
||||
#~ " \"sizes\": \"152x152\",\n"
|
||||
#~ " \"type\": \"image/png\"\n"
|
||||
#~ " }, {\n"
|
||||
#~ " \"src\": \""
|
||||
#~ msgstr ""
|
||||
#~ "\",\n"
|
||||
#~ " \"sizes\": \"152x152\",\n"
|
||||
#~ " \"type\": \"image/png\"\n"
|
||||
#~ " }, {\n"
|
||||
#~ " \"src\": \""
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\",\n"
|
||||
#~ " \"sizes\": \"192x192\",\n"
|
||||
#~ " \"type\": \"image/png\"\n"
|
||||
#~ " }, {\n"
|
||||
#~ " \"src\": \""
|
||||
#~ msgstr ""
|
||||
#~ "\",\n"
|
||||
#~ " \"sizes\": \"192x192\",\n"
|
||||
#~ " \"type\": \"image/png\"\n"
|
||||
#~ " }, {\n"
|
||||
#~ " \"src\": \""
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\",\n"
|
||||
#~ " \"sizes\": \"256x256\",\n"
|
||||
#~ " \"type\": \"image/png\"\n"
|
||||
#~ " }, {\n"
|
||||
#~ " \"src\": \""
|
||||
#~ msgstr ""
|
||||
#~ "\",\n"
|
||||
#~ " \"sizes\": \"256x256\",\n"
|
||||
#~ " \"type\": \"image/png\"\n"
|
||||
#~ " }, {\n"
|
||||
#~ " \"src\": \""
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\",\n"
|
||||
#~ " \"sizes\": \"512x512\",\n"
|
||||
#~ " \"type\": \"image/png\"\n"
|
||||
#~ " }],\n"
|
||||
#~ " \"start_url\": \"/web\",\n"
|
||||
#~ " \"display\": \"standalone\",\n"
|
||||
#~ " \"background_color\": \""
|
||||
#~ msgstr ""
|
||||
#~ "\",\n"
|
||||
#~ " \"sizes\": \"512x512\",\n"
|
||||
#~ " \"type\": \"image/png\"\n"
|
||||
#~ " }],\n"
|
||||
#~ " \"start_url\": \"/web\",\n"
|
||||
#~ " \"display\": \"standalone\",\n"
|
||||
#~ " \"background_color\": \""
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\",\n"
|
||||
#~ " \"icons\": [{\n"
|
||||
#~ " \"src\": \""
|
||||
#~ msgstr ""
|
||||
#~ "\",\n"
|
||||
#~ " \"icons\": [{\n"
|
||||
#~ " \"src\": \""
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\",\n"
|
||||
#~ " \"short_name\": \""
|
||||
#~ msgstr ""
|
||||
#~ "\",\n"
|
||||
#~ " \"short_name\": \""
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\",\n"
|
||||
#~ " \"theme_color\": \""
|
||||
#~ msgstr ""
|
||||
#~ "\",\n"
|
||||
#~ " \"theme_color\": \""
|
||||
|
||||
#~ msgid ""
|
||||
#~ "';\n"
|
||||
#~ "const FILES_TO_CACHE = ["
|
||||
#~ msgstr ""
|
||||
#~ "';\n"
|
||||
#~ "const FILES_TO_CACHE = ["
|
||||
|
||||
#~ msgid ""
|
||||
#~ "'use strict';\n"
|
||||
#~ "const CACHE_NAME = '"
|
||||
#~ msgstr ""
|
||||
#~ "'use strict';\n"
|
||||
#~ "const CACHE_NAME = '"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "];\n"
|
||||
#~ "self.addEventListener('install', function (evt) {\n"
|
||||
#~ " console.log('[ServiceWorker] Install');\n"
|
||||
#~ " evt.waitUntil(\n"
|
||||
#~ " caches.open(CACHE_NAME).then(function (cache) {\n"
|
||||
#~ " console.log('[ServiceWorker] Pre-caching offline page');\n"
|
||||
#~ " return cache.addAll(FILES_TO_CACHE);\n"
|
||||
#~ " })\n"
|
||||
#~ " );\n"
|
||||
#~ " self.skipWaiting();\n"
|
||||
#~ "});\n"
|
||||
#~ "self.addEventListener('activate', function(evt) {\n"
|
||||
#~ " console.log('[ServiceWorker] Activate');\n"
|
||||
#~ " evt.waitUntil(\n"
|
||||
#~ " caches.keys().then(function(keyList) {\n"
|
||||
#~ " return Promise.all(keyList.map(function(key) {\n"
|
||||
#~ " if (key !== CACHE_NAME) {\n"
|
||||
#~ " console.log('[ServiceWorker] Removing old cache', "
|
||||
#~ "key);\n"
|
||||
#~ " return caches.delete(key);\n"
|
||||
#~ " }\n"
|
||||
#~ " }));\n"
|
||||
#~ " })\n"
|
||||
#~ " );\n"
|
||||
#~ " self.clients.claim();\n"
|
||||
#~ "});\n"
|
||||
#~ "self.addEventListener('fetch', function(evt) {\n"
|
||||
#~ " if (evt.request.cache === 'only-if-cached' && evt.request.mode !"
|
||||
#~ "== 'same-origin') {\n"
|
||||
#~ " return;\n"
|
||||
#~ " }\n"
|
||||
#~ " console.log('[ServiceWorker] Fetch', evt.request.url);\n"
|
||||
#~ " evt.respondWith(\n"
|
||||
#~ " caches.open(CACHE_NAME).then(function(cache) {\n"
|
||||
#~ " return cache.match(evt.request)\n"
|
||||
#~ " .then(function(response) {\n"
|
||||
#~ " return response || fetch(evt.request);\n"
|
||||
#~ " });\n"
|
||||
#~ " })\n"
|
||||
#~ " );\n"
|
||||
#~ "});"
|
||||
#~ msgstr ""
|
||||
#~ "];\n"
|
||||
#~ "self.addEventListener('install', function (evt) {\n"
|
||||
#~ " console.log('[ServiceWorker] Install');\n"
|
||||
#~ " evt.waitUntil(\n"
|
||||
#~ " caches.open(CACHE_NAME).then(function (cache) {\n"
|
||||
#~ " console.log('[ServiceWorker] Pre-caching offline page');\n"
|
||||
#~ " return cache.addAll(FILES_TO_CACHE);\n"
|
||||
#~ " })\n"
|
||||
#~ " );\n"
|
||||
#~ " self.skipWaiting();\n"
|
||||
#~ "});\n"
|
||||
#~ "self.addEventListener('activate', function(evt) {\n"
|
||||
#~ " console.log('[ServiceWorker] Activate');\n"
|
||||
#~ " evt.waitUntil(\n"
|
||||
#~ " caches.keys().then(function(keyList) {\n"
|
||||
#~ " return Promise.all(keyList.map(function(key) {\n"
|
||||
#~ " if (key !== CACHE_NAME) {\n"
|
||||
#~ " console.log('[ServiceWorker] Removing old cache', "
|
||||
#~ "key);\n"
|
||||
#~ " return caches.delete(key);\n"
|
||||
#~ " }\n"
|
||||
#~ " }));\n"
|
||||
#~ " })\n"
|
||||
#~ " );\n"
|
||||
#~ " self.clients.claim();\n"
|
||||
#~ "});\n"
|
||||
#~ "self.addEventListener('fetch', function(evt) {\n"
|
||||
#~ " if (evt.request.cache === 'only-if-cached' && evt.request.mode !"
|
||||
#~ "== 'same-origin') {\n"
|
||||
#~ " return;\n"
|
||||
#~ " }\n"
|
||||
#~ " console.log('[ServiceWorker] Fetch', evt.request.url);\n"
|
||||
#~ " evt.respondWith(\n"
|
||||
#~ " caches.open(CACHE_NAME).then(function(cache) {\n"
|
||||
#~ " return cache.match(evt.request)\n"
|
||||
#~ " .then(function(response) {\n"
|
||||
#~ " return response || fetch(evt.request);\n"
|
||||
#~ " });\n"
|
||||
#~ " })\n"
|
||||
#~ " );\n"
|
||||
#~ "});"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "{\n"
|
||||
#~ " \"name\": \""
|
||||
#~ msgstr ""
|
||||
#~ "{\n"
|
||||
#~ " \"name\": \""
|
||||
|
|
|
@ -6,6 +6,8 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 12.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-11 16:50+0000\n"
|
||||
"PO-Revision-Date: 2021-03-11 16:50+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -117,42 +119,3 @@ msgstr ""
|
|||
msgid "[ServiceWorker] Registration failed: "
|
||||
msgstr ""
|
||||
|
||||
#. module: web_pwa_oca
|
||||
#: model_terms:ir.ui.view,arch_db:web_pwa_oca.pwa_core_events
|
||||
msgid "console.log('[ServiceWorker] Activating...');\n"
|
||||
" evt.waitUntil(oca_pwa.activateWorker());\n"
|
||||
" self.clients.claim();"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_pwa_oca
|
||||
#: model_terms:ir.ui.view,arch_db:web_pwa_oca.pwa_init
|
||||
msgid "const oca_pwa = new PWA("
|
||||
msgstr ""
|
||||
|
||||
#. module: web_pwa_oca
|
||||
#: model_terms:ir.ui.view,arch_db:web_pwa_oca.pwa_core_events
|
||||
msgid "evt.waitUntil(oca_pwa.installWorker());\n"
|
||||
" self.skipWaiting();"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_pwa_oca
|
||||
#: model_terms:ir.ui.view,arch_db:web_pwa_oca.pwa_core_events
|
||||
msgid "self.addEventListener('activate', evt => {"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_pwa_oca
|
||||
#: model_terms:ir.ui.view,arch_db:web_pwa_oca.pwa_core_events
|
||||
msgid "self.addEventListener('fetch', evt => {"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_pwa_oca
|
||||
#: model_terms:ir.ui.view,arch_db:web_pwa_oca.pwa_core_events
|
||||
msgid "self.addEventListener('install', evt => {\n"
|
||||
" console.log('[ServiceWorker] Installing...');"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_pwa_oca
|
||||
#: model_terms:ir.ui.view,arch_db:web_pwa_oca.service_worker
|
||||
msgid "self.importScripts(..."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -31,6 +31,5 @@
|
|||
|
||||
* Fix issue when trying to run in localhost with several databases. The browser
|
||||
doesn't send the cookie and web manifest returns 404.
|
||||
* Evaluate to support 'require' system.
|
||||
* Firefox can't detect 'standalone' mode. See https://bugzilla.mozilla.org/show_bug.cgi?id=1285858
|
||||
* Firefox disable service worker in private mode. See https://bugzilla.mozilla.org/show_bug.cgi?id=1601916
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/* Copyright 2020 Tecnativa - Alexandre D. Díaz
|
||||
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
|
||||
|
||||
// Compatibility layer to load some Odoo modules
|
||||
// This is a very simple implementation!!!
|
||||
|
||||
function JQuery (selector, context) {
|
||||
return new JQuery.prototype.init(selector, context);
|
||||
};
|
||||
|
||||
JQuery.prototype = {
|
||||
|
||||
init: function (selector, context) {
|
||||
if (typeof selector === "function") {
|
||||
selector();
|
||||
}
|
||||
},
|
||||
|
||||
// This is a hack, not a complete implementation!
|
||||
// only expected to be used by boot.js
|
||||
deparam: function (data) {
|
||||
const params = data.split(',');
|
||||
const res = [];
|
||||
for (let param of params) {
|
||||
res.push(param.split('='));
|
||||
}
|
||||
return _.object(res);
|
||||
},
|
||||
|
||||
param: {
|
||||
querystring: function () {
|
||||
return "debug=1";
|
||||
}
|
||||
},
|
||||
|
||||
when: function (tasks) {
|
||||
if (!(tasks instanceof Array)) {
|
||||
tasks = [tasks];
|
||||
}
|
||||
return Promise.all(tasks).then((results) => {
|
||||
return results.length === 1 ? results[0] : results;
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
class Deferred {
|
||||
constructor() {
|
||||
this.promise = new Promise((resolve, reject)=> {
|
||||
this.reject = reject;
|
||||
this.resolve = resolve;
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
JQuery.prototype.Deferred = () => new Deferred();
|
||||
|
||||
self.$ = JQuery;
|
||||
self.$.deparam = JQuery.prototype.deparam;
|
||||
self.$.param = JQuery.prototype.param;
|
||||
self.$.Deferred = JQuery.prototype.Deferred;
|
||||
self.$.when = JQuery.prototype.when;
|
||||
self.window = self;
|
|
@ -1,150 +0,0 @@
|
|||
/**
|
||||
* Improved John Resig's inheritance, based on:
|
||||
*
|
||||
* Simple JavaScript Inheritance
|
||||
* By John Resig http://ejohn.org/
|
||||
* MIT Licensed.
|
||||
*
|
||||
* Adds "include()"
|
||||
*
|
||||
* Defines The Class object. That object can be used to define and inherit classes using
|
||||
* the extend() method.
|
||||
*
|
||||
* Example::
|
||||
*
|
||||
* var Person = Class.extend({
|
||||
* init: function(isDancing){
|
||||
* this.dancing = isDancing;
|
||||
* },
|
||||
* dance: function(){
|
||||
* return this.dancing;
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* The init() method act as a constructor. This class can be instanced this way::
|
||||
*
|
||||
* var person = new Person(true);
|
||||
* person.dance();
|
||||
*
|
||||
* The Person class can also be extended again:
|
||||
*
|
||||
* var Ninja = Person.extend({
|
||||
* init: function(){
|
||||
* this._super( false );
|
||||
* },
|
||||
* dance: function(){
|
||||
* // Call the inherited version of dance()
|
||||
* return this._super();
|
||||
* },
|
||||
* swingSword: function(){
|
||||
* return true;
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* When extending a class, each re-defined method can use this._super() to call the previous
|
||||
* implementation of that method.
|
||||
*
|
||||
* @class Class
|
||||
*/
|
||||
function OdooClass(){}
|
||||
|
||||
var initializing = false;
|
||||
var fnTest = /xyz/.test(function(){xyz();}) ? /\b_super\b/ : /.*/;
|
||||
|
||||
/**
|
||||
* Subclass an existing class
|
||||
*
|
||||
* @param {Object} prop class-level properties (class attributes and instance methods) to set on the new class
|
||||
*/
|
||||
OdooClass.extend = function() {
|
||||
var _super = this.prototype;
|
||||
// Support mixins arguments
|
||||
var args = _.toArray(arguments);
|
||||
args.unshift({});
|
||||
var prop = _.extend.apply(_,args);
|
||||
|
||||
// Instantiate a web class (but only create the instance,
|
||||
// don't run the init constructor)
|
||||
initializing = true;
|
||||
var This = this;
|
||||
var prototype = new This();
|
||||
initializing = false;
|
||||
|
||||
// Copy the properties over onto the new prototype
|
||||
_.each(prop, function(val, name) {
|
||||
// Check if we're overwriting an existing function
|
||||
prototype[name] = typeof prop[name] == "function" &&
|
||||
fnTest.test(prop[name]) ?
|
||||
(function(name, fn) {
|
||||
return function() {
|
||||
var tmp = this._super;
|
||||
|
||||
// Add a new ._super() method that is the same
|
||||
// method but on the super-class
|
||||
this._super = _super[name];
|
||||
|
||||
// The method only need to be bound temporarily, so
|
||||
// we remove it when we're done executing
|
||||
var ret = fn.apply(this, arguments);
|
||||
this._super = tmp;
|
||||
|
||||
return ret;
|
||||
};
|
||||
})(name, prop[name]) :
|
||||
prop[name];
|
||||
});
|
||||
|
||||
// The dummy class constructor
|
||||
function Class() {
|
||||
if(this.constructor !== OdooClass){
|
||||
throw new Error("You can only instanciate objects with the 'new' operator");
|
||||
}
|
||||
// All construction is actually done in the init method
|
||||
this._super = null;
|
||||
if (!initializing && this.init) {
|
||||
var ret = this.init.apply(this, arguments);
|
||||
if (ret) { return ret; }
|
||||
}
|
||||
return this;
|
||||
}
|
||||
Class.include = function (properties) {
|
||||
_.each(properties, function(val, name) {
|
||||
if (typeof properties[name] !== 'function'
|
||||
|| !fnTest.test(properties[name])) {
|
||||
prototype[name] = properties[name];
|
||||
} else if (typeof prototype[name] === 'function'
|
||||
&& prototype.hasOwnProperty(name)) {
|
||||
prototype[name] = (function (name, fn, previous) {
|
||||
return function () {
|
||||
var tmp = this._super;
|
||||
this._super = previous;
|
||||
var ret = fn.apply(this, arguments);
|
||||
this._super = tmp;
|
||||
return ret;
|
||||
};
|
||||
})(name, properties[name], prototype[name]);
|
||||
} else if (typeof _super[name] === 'function') {
|
||||
prototype[name] = (function (name, fn) {
|
||||
return function () {
|
||||
var tmp = this._super;
|
||||
this._super = _super[name];
|
||||
var ret = fn.apply(this, arguments);
|
||||
this._super = tmp;
|
||||
return ret;
|
||||
};
|
||||
})(name, properties[name]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Populate our constructed prototype object
|
||||
Class.prototype = prototype;
|
||||
|
||||
// Enforce the constructor to be what we expect
|
||||
Class.constructor = Class;
|
||||
|
||||
// And make this class extendable
|
||||
Class.extend = this.extend;
|
||||
|
||||
return Class;
|
||||
};
|
|
@ -1,7 +1,3 @@
|
|||
"use strict";
|
||||
/* eslint strict: ["error", "global"] */
|
||||
/* eslint-disable no-undef, no-empty-function, no-implicit-globals,
|
||||
no-unused-vars */
|
||||
/* Copyright 2020 Tecnativa - Alexandre D. Díaz
|
||||
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
|
||||
|
||||
|
@ -11,25 +7,36 @@ no-unused-vars */
|
|||
* When the service worker is called to be installed from the "pwa_manager"
|
||||
* this class is instantiated.
|
||||
*/
|
||||
var PWA = OdooClass.extend({
|
||||
|
||||
// eslint-disable-next-line
|
||||
init: function (params) {
|
||||
// To be overridden
|
||||
},
|
||||
|
||||
/**
|
||||
* @returns {Promise}
|
||||
*/
|
||||
installWorker: function () {
|
||||
return Promise.resolve();
|
||||
},
|
||||
odoo.define("web_pwa_oca.PWA", function (require) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @returns {Promise}
|
||||
*/
|
||||
activateWorker: function () {
|
||||
return Promise.resolve();
|
||||
},
|
||||
const OdooClass = require("web.Class");
|
||||
|
||||
const PWA = OdooClass.extend({
|
||||
|
||||
// eslint-disable-next-line
|
||||
init: function (params) {
|
||||
// To be overridden
|
||||
},
|
||||
|
||||
/**
|
||||
* @returns {Promise}
|
||||
*/
|
||||
installWorker: function () {
|
||||
// To be overridden
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
/**
|
||||
* @returns {Promise}
|
||||
*/
|
||||
activateWorker: function () {
|
||||
// To be overridden
|
||||
return Promise.resolve();
|
||||
},
|
||||
});
|
||||
|
||||
return PWA;
|
||||
});
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template id="pwa_init" name="PWA Initialization">
|
||||
const oca_pwa = new PWA(<t t-esc="str(pwa_params)"/>);
|
||||
</template>
|
||||
<template id="pwa_core_events" name="PWA Core Events">
|
||||
<t t-set="evt_install">
|
||||
evt.waitUntil(oca_pwa.installWorker());
|
||||
self.skipWaiting();
|
||||
</t>
|
||||
self.addEventListener('install', evt => {
|
||||
console.log('[ServiceWorker] Installing...');
|
||||
<t t-raw="evt_install" />
|
||||
});
|
||||
|
||||
<!-- This is necessary to get PWA installable.
|
||||
Other modules can add logic using 'evt_fetch' -->
|
||||
<t t-set="evt_fetch" />
|
||||
self.addEventListener('fetch', evt => {
|
||||
<t t-raw="evt_fetch" />
|
||||
});
|
||||
|
||||
<t t-set="evt_activate">
|
||||
console.log('[ServiceWorker] Activating...');
|
||||
evt.waitUntil(oca_pwa.activateWorker());
|
||||
self.clients.claim();
|
||||
</t>
|
||||
self.addEventListener('activate', evt => {
|
||||
<t t-raw="evt_activate" />
|
||||
});
|
||||
</template>
|
||||
<template id="service_worker" name="PWA Service Worker">
|
||||
self.importScripts(...<t t-esc="str(pwa_scripts)" />);
|
||||
<t t-call="web_pwa_oca.pwa_init" />
|
||||
<t t-call="web_pwa_oca.pwa_core_events" />
|
||||
</template>
|
||||
|
||||
</odoo>
|
Loading…
Reference in New Issue