diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_appcache.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_appcache.xml deleted file mode 100644 index 0ca6f86db83f00ac839602191d0e62812976d6f0..0000000000000000000000000000000000000000 --- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_appcache.xml +++ /dev/null @@ -1,414 +0,0 @@ - - - - - - - - - - _Access_contents_information_Permission - - - Anonymous - Assignee - Assignor - Associate - Auditor - Manager - - - - - _Add_portal_content_Permission - - - Assignee - Assignor - Manager - - - - - _Change_local_roles_Permission - - - Assignor - Manager - - - - - _Modify_portal_content_Permission - - - Assignee - Assignor - Manager - - - - - _View_Permission - - - Anonymous - Assignee - Assignor - Associate - Auditor - Manager - - - - - categories - - - - - - content_md5 - - - - - - default_reference - gadget_erp5.appcache - - - description - - - - - - id - rjs_gadget_erp5_appcache - - - language - en - - - portal_type - Web Manifest - - - short_title - - - - - - text_content - CACHE MANIFEST\n -# generated on Wed, 21 Nov 2018 10:00:00 GMT+0100\n -# XXX + fonts\n -# images/ajax-loader.gif\n -CACHE:\n -favicon.ico\n -font-awesome/font-awesome-webfont.eot\n -font-awesome/font-awesome-webfont.woff\n -font-awesome/font-awesome-webfont.woff2\n -font-awesome/font-awesome-webfont.ttf\n -font-awesome/font-awesome-webfont.svg\n -gadget_erp5_worklist_empty.svg?format=svg\n -erp5_launcher_nojqm.js\n -gadget_erp5_nojqm.css\n -gadget_erp5_configure_editor.html\n -gadget_erp5_configure_editor.js\n -gadget_erp5_editor_panel.html\n -gadget_erp5_editor_panel.js\n -gadget_erp5_field_checkbox.html\n -gadget_erp5_field_checkbox.js\n -gadget_erp5_field_datetime.html\n -gadget_erp5_field_datetime.js\n -gadget_erp5_field_editor.html\n -gadget_erp5_field_editor.js\n -gadget_erp5_field_email.html\n -gadget_erp5_field_email.js\n -gadget_erp5_field_file.html\n -gadget_erp5_field_file.js\n -gadget_erp5_field_float.html\n -gadget_erp5_field_float.js\n -gadget_erp5_field_formbox.html\n -gadget_erp5_field_formbox.js\n -gadget_erp5_field_gadget.html\n -gadget_erp5_field_gadget.js\n -gadget_erp5_field_image.html\n -gadget_erp5_field_image.js\n -gadget_erp5_field_integer.html\n -gadget_erp5_field_integer.js\n -gadget_erp5_field_list.html\n -gadget_erp5_field_list.js\n -gadget_erp5_field_lines.html\n -gadget_erp5_field_lines.js\n -gadget_erp5_field_listbox.html\n -gadget_erp5_field_listbox.js\n -gadget_erp5_field_matrixbox.html\n -gadget_erp5_field_matrixbox.js\n -gadget_erp5_field_multicheckbox.html\n -gadget_erp5_field_multicheckbox.js\n -gadget_erp5_field_multilist.html\n -gadget_erp5_field_multilist.js\n -gadget_erp5_field_multirelationstring.html\n -gadget_erp5_field_multirelationstring.js\n -gadget_erp5_field_radio.html\n -gadget_erp5_field_radio.js\n -gadget_erp5_field_readonly.html\n -gadget_erp5_field_readonly.js\n -gadget_erp5_field_relationstring.html\n -gadget_erp5_field_relationstring.js\n -gadget_erp5_field_string.html\n -gadget_erp5_field_string.js\n -gadget_erp5_field_password.html\n -gadget_erp5_field_password.js\n -gadget_erp5_field_textarea.html\n -gadget_erp5_field_textarea.js\n -gadget_erp5_form.html\n -gadget_erp5_form.js\n -gadget_erp5_header.html\n -gadget_erp5_header.js\n -gadget_erp5_jio.html\n -gadget_erp5_jio.js\n -gadget_erp5_label_field.html\n -gadget_erp5_label_field.js\n -gadget_erp5_notification.html\n -gadget_erp5_notification.js\n -gadget_erp5_page_action.html\n -gadget_erp5_page_action.js\n -gadget_erp5_page_export.html\n -gadget_erp5_page_export.js\n -gadget_erp5_page_form.html\n -gadget_erp5_page_form.js\n -gadget_erp5_page_front.html\n -gadget_erp5_page_front.js\n -gadget_erp5_page_history.html\n -gadget_erp5_page_history.js\n -gadget_erp5_page_jump.html\n -gadget_erp5_page_jump.js\n -gadget_erp5_page_language.html\n -gadget_erp5_page_language.js\n -gadget_erp5_page_logout.html\n -gadget_erp5_page_logout.js\n -gadget_erp5_page_preference.html\n -gadget_erp5_page_preference.js\n -gadget_erp5_page_relation_search.html\n -gadget_erp5_page_relation_search.js\n -gadget_erp5_page_search.html\n -gadget_erp5_page_search.js\n -gadget_erp5_page_tab.html\n -gadget_erp5_page_tab.js\n -gadget_erp5_page_worklist.html\n -gadget_erp5_page_worklist.js\n -gadget_erp5_panel.html\n -gadget_erp5_panel.js\n -gadget_erp5_panel.png?format=png\n -gadget_erp5_pt_embedded_form_render.html\n -gadget_erp5_pt_embedded_form_render.js\n -gadget_erp5_pt_form_dialog.html\n -gadget_erp5_pt_form_dialog.js\n -gadget_erp5_pt_form_list.html\n -gadget_erp5_pt_form_list.js\n -gadget_erp5_pt_form_view.html\n -gadget_erp5_pt_form_view.js\n -gadget_erp5_pt_form_view_editable.html\n -gadget_erp5_pt_form_view_editable.js\n -gadget_erp5_pt_report_view.html\n -gadget_erp5_pt_report_view.js\n -gadget_erp5_router.html\n -gadget_erp5_router.js\n -gadget_erp5_relation_input.html\n -gadget_erp5_relation_input.js\n -gadget_erp5_search_editor.html\n -gadget_erp5_search_editor.js\n -gadget_erp5_searchfield.html\n -gadget_erp5_searchfield.js\n -gadget_erp5_sort_editor.html\n -gadget_erp5_sort_editor.js\n -gadget_global.js\n -gadget_html5_element.html\n -gadget_html5_element.js\n -gadget_html5_input.html\n -gadget_html5_input.js\n -gadget_html5_textarea.html\n -gadget_html5_textarea.js\n -gadget_html5_select.html\n -gadget_html5_select.js\n -gadget_erp5_global.js\n -gadget_jio.html\n -gadget_jio.js\n -gadget_translation.html\n -gadget_translation.js\n -gadget_translation_data.js\n -gadget_editor.html\n -gadget_editor.js\n -gadget_button_maximize.html\n -gadget_button_maximize.js\n -handlebars.js\n -jiodev.js\n -renderjs.js\n -rsvp.js\n -NETWORK:\n -* - - - title - RenderJS Gadget ERP5 AppCache - - - version - 001 - - - workflow_history - - AAAAAAAAAAI= - - - - - - - - - - - - - data - - - - document_publication_workflow - - AAAAAAAAAAM= - - - - edit_workflow - - AAAAAAAAAAQ= - - - - - - - - - - - - - - - - - - - action - publish_alive - - - actor - zope - - - comment - - - - error_message - - - - time - - - - - - - - - - - 1465381395.69 - UTC - - - - - - - validation_state - published_alive - - - - - - - - - - - - - - - - - action - edit - - - actor - zope - - - comment - - - - - - error_message - - - - serial - 971.39427.41235.63641 - - - state - current - - - time - - - - - - - - - - - 1542819250.56 - UTC - - - - - - - - - - - diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_launcher_js.js b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_launcher_js.js index 88a42dbdcccc738ec30bd8600dc329a9be5f0633..55293e15f525218b1ed47384d826ebc79c2ce992 100644 --- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_launcher_js.js +++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_launcher_js.js @@ -1,8 +1,10 @@ /*globals window, document, RSVP, rJS, - URI, location, XMLHttpRequest, console, navigator, Event*/ + URI, location, XMLHttpRequest, console, navigator, Event, + URL*/ /*jslint indent: 2, maxlen: 80*/ (function (window, document, RSVP, rJS, - XMLHttpRequest, location, console, navigator, Event) { + XMLHttpRequest, location, console, navigator, Event, + URL) { "use strict"; var MAIN_SCOPE = "m", @@ -823,7 +825,34 @@ .onEvent('submit', function submit() { return displayError(this, new Error("Unexpected form submit")); + }) + + ///////////////////////////////////////////////////////////////// + // For Firefox, Wallpaper URL must be absolute one. + ///////////////////////////////////////////////////////////////// + .declareService(function () { + var index, styleSheet, wallpaper_url, wallpaper_absolute_url; + if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) { + for (index = 0; index < document.styleSheets.length; index += 1) { + styleSheet = document.styleSheets[index]; + if (styleSheet.href.startsWith('data:text/css;')) { + wallpaper_url = styleSheet.cssRules[0].style + .backgroundImage.slice(4, -1).replace(/["']/g, ''); + wallpaper_absolute_url = new URL( + wallpaper_url, + window.location.toString() + ); + styleSheet.cssRules[0].style.backgroundImage = + 'url("' + wallpaper_absolute_url.href + '")'; + break; + } + } + index = null; + styleSheet = null; + wallpaper_url = null; + wallpaper_absolute_url = null; + } }); }(window, document, RSVP, rJS, - XMLHttpRequest, location, console, navigator, Event)); \ No newline at end of file + XMLHttpRequest, location, console, navigator, Event, URL)); \ No newline at end of file diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_launcher_js.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_launcher_js.xml index 5159212f3cf5e0914e66dafa75f9ddf71904e342..6196777ed1ed5d88ff8a1cb53829b5fa20531432 100644 --- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_launcher_js.xml +++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_launcher_js.xml @@ -228,7 +228,7 @@ serial - 975.29292.10042.3754 + 978.15454.53878.14950 state @@ -246,7 +246,7 @@ - 1556870187.8 + 1567693410.93 UTC diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_serviceworker.js b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_serviceworker.js index 18cc8104de0d8dbc75d00f15ae733c9c7a5707c6..88e58e87c29adeaa6eecbfc98464ce92d95df193 100644 --- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_serviceworker.js +++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_serviceworker.js @@ -1,33 +1,43 @@ /*jslint indent: 2*/ -/*global self, caches, fetch*/ -(function (self, caches, fetch) { +/*global self, caches, fetch, Promise, URL, location, Response*/ +(function (self, caches, fetch, Promise, URL, location, Response) { "use strict"; - var CACHE_NAME = 'Thu, 12 July 2016 12:00:00 GMT', + var prefix = location.toString() + '_', + // CLIENT_CACHE_MAPPING_NAME must not start with `prefix` + // else it may be used as a normal content cache. + CLIENT_CACHE_MAPPING_NAME = '__erp5js_' + location.toString(), + CACHE_NAME = prefix + '_0001', + CACHE_MAP = {}, // Files required to make this app work offline REQUIRED_FILES = [ - './', - 'https://netdna.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css', - 'https://netdna.bootstrapcdn.com/font-awesome/4.2.0/fonts/fontawesome-webfont.eot?v=4.2.0', - 'https://netdna.bootstrapcdn.com/font-awesome/4.2.0/fonts/fontawesome-webfont.eot?#iefix&v=4.2.0', - 'https://netdna.bootstrapcdn.com/font-awesome/4.2.0/fonts/fontawesome-webfont.woff?v=4.2.0', - 'https://netdna.bootstrapcdn.com/font-awesome/4.2.0/fonts/fontawesome-webfont.ttf?v=4.2.0', - 'https://netdna.bootstrapcdn.com/font-awesome/4.2.0/fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular', - 'URI.js', - 'erp5_launcher.js', - 'gadget_erp5.css', + 'favicon.ico', + 'font-awesome/font-awesome-webfont.eot', + 'font-awesome/font-awesome-webfont.woff', + 'font-awesome/font-awesome-webfont.woff2', + 'font-awesome/font-awesome-webfont.ttf', + 'font-awesome/font-awesome-webfont.svg', + 'gadget_erp5_worklist_empty.svg?format=svg', + 'erp5_launcher_nojqm.js', + 'gadget_erp5_nojqm.css', + 'gadget_erp5_configure_editor.html', + 'gadget_erp5_configure_editor.js', 'gadget_erp5_editor_panel.html', 'gadget_erp5_editor_panel.js', 'gadget_erp5_field_checkbox.html', 'gadget_erp5_field_checkbox.js', 'gadget_erp5_field_datetime.html', 'gadget_erp5_field_datetime.js', + 'gadget_erp5_field_editor.html', + 'gadget_erp5_field_editor.js', 'gadget_erp5_field_email.html', 'gadget_erp5_field_email.js', 'gadget_erp5_field_file.html', 'gadget_erp5_field_file.js', 'gadget_erp5_field_float.html', 'gadget_erp5_field_float.js', + 'gadget_erp5_field_formbox.html', + 'gadget_erp5_field_formbox.js', 'gadget_erp5_field_gadget.html', 'gadget_erp5_field_gadget.js', 'gadget_erp5_field_image.html', @@ -36,8 +46,12 @@ 'gadget_erp5_field_integer.js', 'gadget_erp5_field_list.html', 'gadget_erp5_field_list.js', + 'gadget_erp5_field_lines.html', + 'gadget_erp5_field_lines.js', 'gadget_erp5_field_listbox.html', 'gadget_erp5_field_listbox.js', + 'gadget_erp5_field_matrixbox.html', + 'gadget_erp5_field_matrixbox.js', 'gadget_erp5_field_multicheckbox.html', 'gadget_erp5_field_multicheckbox.js', 'gadget_erp5_field_multilist.html', @@ -62,8 +76,14 @@ 'gadget_erp5_header.js', 'gadget_erp5_jio.html', 'gadget_erp5_jio.js', + 'gadget_erp5_label_field.html', + 'gadget_erp5_label_field.js', + 'gadget_erp5_notification.html', + 'gadget_erp5_notification.js', 'gadget_erp5_page_action.html', 'gadget_erp5_page_action.js', + 'gadget_erp5_page_export.html', + 'gadget_erp5_page_export.js', 'gadget_erp5_page_form.html', 'gadget_erp5_page_form.js', 'gadget_erp5_page_front.html', @@ -72,6 +92,8 @@ 'gadget_erp5_page_history.js', 'gadget_erp5_page_jump.html', 'gadget_erp5_page_jump.js', + 'gadget_erp5_page_language.html', + 'gadget_erp5_page_language.js', 'gadget_erp5_page_logout.html', 'gadget_erp5_page_logout.js', 'gadget_erp5_page_preference.html', @@ -86,6 +108,9 @@ 'gadget_erp5_page_worklist.js', 'gadget_erp5_panel.html', 'gadget_erp5_panel.js', + 'gadget_erp5_panel.png?format=png', + 'gadget_erp5_pt_embedded_form_render.html', + 'gadget_erp5_pt_embedded_form_render.js', 'gadget_erp5_pt_form_dialog.html', 'gadget_erp5_pt_form_dialog.js', 'gadget_erp5_pt_form_list.html', @@ -107,45 +132,208 @@ 'gadget_erp5_sort_editor.html', 'gadget_erp5_sort_editor.js', 'gadget_global.js', + 'gadget_html5_element.html', + 'gadget_html5_element.js', + 'gadget_html5_input.html', + 'gadget_html5_input.js', + 'gadget_html5_textarea.html', + 'gadget_html5_textarea.js', + 'gadget_html5_select.html', + 'gadget_html5_select.js', 'gadget_erp5_global.js', 'gadget_jio.html', 'gadget_jio.js', 'gadget_translation.html', 'gadget_translation.js', 'gadget_translation_data.js', + 'gadget_editor.html', + 'gadget_editor.js', + 'gadget_button_maximize.html', + 'gadget_button_maximize.js', 'handlebars.js', - 'i18next.js', 'jiodev.js', 'renderjs.js', - 'rsvp.js' - ]; + 'rsvp.js', + './' + ], + required_url_list = [], + i, + len = REQUIRED_FILES.length; + for (i = 0; i < len; i += 1) { + required_url_list.push( + new URL(REQUIRED_FILES[i], location.toString()).toString() + ); + } self.addEventListener('install', function (event) { // Perform install step: loading each required file into cache event.waitUntil( - caches.open(CACHE_NAME) - .then(function (cache) { - // Add all offline dependencies to the cache - return cache.addAll(REQUIRED_FILES); - }) - .then(function () { - // At this point everything has been cached - return self.skipWaiting(); + // We create cache only if it does not exist. That is because + // we do not want to override an existing cache by mistake. + // Code consistency is very important. We must not mix different + // versions of code. + // (For example, developer change service worker code and forget + // to increase the cache version.) + caches.has(CACHE_NAME) + .then(function (result) { + if (!result) { + caches.open(CACHE_NAME) + .then(function (cache) { + // Add all offline dependencies to the cache + return Promise.all( + REQUIRED_FILES + .map(function (url) { + /* Return a promise that's fulfilled + when each url is cached. + */ + // Use cache.add because safari does not support cache.addAll. + console.log("Install " + CACHE_NAME + " = " + url); + return cache.add(url); + }) + ); + }) + .then(function () { + return caches.keys(); + }) + .then(function (keys) { + keys = keys.filter(function (key) {return key.startsWith(prefix); }); + if (keys.length === 1) { + // When user accesses ERP5JS web site first time, service worker is + // installed but it is not activated yet, service worker is activated + // when the page is refreshed or when a new tab opens the site again. + // If user does not refresh the page and continue to use the site, + // user can't use cache, so everything becomes slow. We must avoid this + // situation. + // So, we want to activate the new service worker immediately if it was + // the first one. (We must not activate the new service worker by + // skipWaiting if there is already an active service worker because it + // causes code inconsistency by loading code from a different version of + // cache. + // If there is only one cache, it means that this is the first service worker, + // thus we can do skipWaiting. And self.registration is unreliable on + // Firefox, we can't use self.registration.active + return self.skipWaiting(); + } + }) + .catch(function (error) { + // Since we do not allow to override existing cache, if cache installation + // failed, we need to delete the cache completely. + caches.delete(CACHE_NAME); + // Explicitly unregister service worker else it may not be done. + self.registration.unregister(); + throw error; + }); + } }) ); }); self.addEventListener('fetch', function (event) { - event.respondWith( - caches.match(event.request) + /* When a new service worker is installed, it adds a new Cache + to Cache Storage. When a new client started using this + service worker, the new client uses the latest Cache at + that time by comparing with Cache keys. And once the client + is associated with a Cache key, it keeps using the same Cache + key, it must not use different Caches. Since service worker + is stateless, to maintain the mapping of client and Cache key, + we use Cache Storage as a persistent data store. The key of + this special Cache is CLIENT_CACHE_MAPPING_NAME. + */ + var url = new URL(event.request.url), + client_id = event.clientId.toString(), + // CACHE_MAP is a temprary data store. + // This should be kept until service worker stops. + cache_key, + erp5js_cache; + url.hash = ''; + if (client_id) { + // client_id is null when it is the first request, in other words + // if request is navigate mode. Since major web browsers already + // implement client_id, if client_is is null, let's use the latest cache + // and don't get cache_key from CACHE_MAP and erp5js_cache. + cache_key = CACHE_MAP[client_id]; + } + console.log("Client Id = " + client_id); + + if (cache_key) { + console.log("cache_key from CACHE_MAP " + cache_key); + } + + if ((event.request.method !== 'GET') || + (required_url_list.indexOf(url.toString()) === -1)) { + // Try not to use the untrustable fetch function + // It can only be skip synchronously + return; + } + return event.respondWith( + Promise.resolve() + .then(function () { + if (!cache_key) { + // CLIENT_CACHE_MAPPING_NAME stores cache_key of each client. + return caches.open(CLIENT_CACHE_MAPPING_NAME) + .then(function (cache) { + // Service worker forget everything when it stops. So, when it started + // again, CACHE_MAP is empty, get the associated cache_key from the + // special Cache named CLIENT_CACHE_MAPPING_NAME. + erp5js_cache = cache; + return erp5js_cache.match(client_id) + .then(function (response) { + if (response) { + // We use Cache Storage as a persistent database. + cache_key = response.statusText; + CACHE_MAP[client_id] = cache_key; + console.log("cache_key from Cache Storage " + cache_key); + } + }); + }); + } + }) + .then(function () { + if (!cache_key) { + // If associated cache_key is not found, it means this client is a new one. + // Let's find the latest Cache. + return caches.keys() + .then(function (keys) { + keys = keys.filter(function (key) {return key.startsWith(prefix); }); + console.log("KEYS = " + keys); + if (keys.length) { + cache_key = keys.sort().reverse()[0]; + if (client_id) { + CACHE_MAP[client_id] = cache_key; + } + } else { + cache_key = CACHE_NAME; + if (client_id) { + CACHE_MAP[client_id] = CACHE_NAME; + } + } + // Save the associated cache_key in a persistent database because service + // worker forget everything when it stops. + if (client_id) { + erp5js_cache.put(client_id, new Response(null, {"statusText": cache_key})); + } + }); + } + }) + .then(function () { + // Finally we have the associated cache_key. Let's find a cached response. + return caches.open(cache_key); + }) + .then(function (cache) { + // Don't give request object itself. Firefox's Cache Storage + // does not work properly when VARY contains Accept-Language. + // Give URL string instead, then cache.match works on both Firefox and Chrome. + console.log("MATCH " + cache_key + " " + url); + return cache.match(event.request.url); + }) .then(function (response) { // Cache hit - return the response from the cached version if (response) { return response; } - // Not in cache - return the result from the live server // `fetch` is essentially a "fallback" + console.log("MISS " + cache_key + " " + url); return fetch(event.request); }) ); @@ -162,14 +350,16 @@ */ .keys() .then(function (keys) { + keys = keys + .filter(function (key) { + // Filter by keys that don't start with the latest version prefix. + return key.startsWith(prefix); + }) + .sort(); + keys = keys.slice(0, keys.findIndex(function (element) {return element === CACHE_NAME; })); // We return a promise that settles when all outdated caches are deleted. return Promise.all( keys - .filter(function (key) { - // Filter by keys that don't start with the latest version prefix. - // return !key.startsWith(version); - return key !== CACHE_NAME; - }) .map(function (key) { /* Return a promise that's fulfilled when each outdated cache is deleted. @@ -179,11 +369,12 @@ ); }) .then(function () { - self.clients.claim(); + // If new service worker becomes active, it means that all clients + // (tabs, windows, etc) were already closed. Thus we can remove the + // client cache mapping. + caches.delete(CLIENT_CACHE_MAPPING_NAME); }) ); }); - - -}(self, caches, fetch)); +}(self, caches, fetch, Promise, URL, location, Response)); \ No newline at end of file diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_serviceworker.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_serviceworker.xml index 1bf7499acccb10b8c48c8672b04b4b51f0d9795b..3f7b07d28fb827dc4e386582f1374971ae6aa627 100644 --- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_serviceworker.xml +++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_serviceworker.xml @@ -228,7 +228,7 @@ serial - 952.5891.40125.8465 + 976.56996.62202.65433 state @@ -246,7 +246,7 @@ - 1467035757.8 + 1562322109.66 UTC diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_site_module/renderjs_runner.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_site_module/renderjs_runner.xml index a611df1bbd44e27a8a9694979123e196bf3bc0f1..8baccec07c75c3da1a6a196c578f819e98b427fa 100644 --- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_site_module/renderjs_runner.xml +++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_site_module/renderjs_runner.xml @@ -279,6 +279,16 @@ string + + + id + configuration_service_worker_url + + + type + string + + @@ -353,12 +363,18 @@ configuration_manifest_url - gadget_erp5.appcache + + + configuration_panel_gadget_url gadget_erp5_panel.html + + configuration_service_worker_url + gadget_erp5_serviceworker.js + configuration_translation_gadget_url gadget_translation.html @@ -600,7 +616,7 @@ serial - 965.19244.13768.6758 + 973.33482.4166.8669 state @@ -618,7 +634,7 @@ - 1517843997.55 + 1553593373.77 UTC diff --git a/bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/Base_createTranslateData.py b/bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/Base_createTranslateData.py index 403f2553f93d2d7544cc9d417a9ca35b36901757..f96655a06a9d9ef43a5c1ae744d68e97239be739 100644 --- a/bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/Base_createTranslateData.py +++ b/bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/Base_createTranslateData.py @@ -15,7 +15,7 @@ tmp_re = re.compile(r"""/[{}]/g, """"") translate_word = [] for web_page in portal.web_page_module.searchFolder(portal_type='Web Page', - reference=context.Base_getListFileFromAppcache(only_html=1)): + reference=context.Base_getTranslationSourceFileList(only_html=1)): data = attribute_filter_re.findall(web_page.getTextContent()) for attribute in data: a = re.sub(r'[{|}]', "", attribute[1]) diff --git a/bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/Base_getListFileFromAppcache.py b/bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/Base_getListFileFromAppcache.py deleted file mode 100644 index abfbeb8f01508bf29ae14c15e7563e8a597fd12a..0000000000000000000000000000000000000000 --- a/bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/Base_getListFileFromAppcache.py +++ /dev/null @@ -1,21 +0,0 @@ -appcache_file = context.getLayoutProperty("configuration_manifest_url", default="gadget_erp5.appcache") - - -text_content = context.web_page_module.searchFolder( - portal_type= 'Web Manifest', - reference = appcache_file)[0].getTextContent() - -translation_data_file = [] -file_list = [] -for file in text_content.split('\n'): - file = file.split('/')[-1] - if file.endswith('.html'): - file_list.append(file) - continue - - if file.endswith('.js') and not only_html: - if file.endswith('translation_data.js'): - translation_data_file = [file] - continue - file_list.append(file) -return translation_data_file + file_list diff --git a/bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/Base_getTranslationSourceFileList.py b/bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/Base_getTranslationSourceFileList.py new file mode 100644 index 0000000000000000000000000000000000000000..280375918d95b40afcb1834bbcfd4b008741cd80 --- /dev/null +++ b/bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/Base_getTranslationSourceFileList.py @@ -0,0 +1,40 @@ +import re + +service_worker_reference = context.getLayoutProperty("configuration_service_worker_url", default="gadget_erp5_serviceworker.js") + +text_content = context.web_page_module.searchFolder( + portal_type='Web Script', + reference=service_worker_reference)[0].getTextContent() + +filename_pattern = re.compile("'(?P[a-zA-Z0-9-_\.\?=]*)'") +filename_list = [] + +start = False +for line in text_content.split('\n'): + if start is False and 'REQUIRED_FILES' in line: + start = True + continue + if not line: + continue + if start: + if ']' in line: + break + matched = filename_pattern.search(line) + if matched is not None: + filename = matched.groupdict().get('filename') + if filename: + filename_list.append(filename) + +file_list = [] +translation_data_file = [] +for filename in filename_list: + if filename.endswith('.html'): + file_list.append(filename) + continue + + if filename.endswith('.js') and not only_html: + if filename.endswith('translation_data.js'): + translation_data_file = [filename] + continue + file_list.append(filename) +return translation_data_file + file_list diff --git a/bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/Base_getListFileFromAppcache.xml b/bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/Base_getTranslationSourceFileList.xml similarity index 93% rename from bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/Base_getListFileFromAppcache.xml rename to bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/Base_getTranslationSourceFileList.xml index f7d497e57e17124e7ae5fced7c599eee7f3aaf0c..3240f07cc5fded60945af1770a9d612e060fcbcc 100644 --- a/bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/Base_getListFileFromAppcache.xml +++ b/bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/Base_getTranslationSourceFileList.xml @@ -50,11 +50,11 @@ _params - only_html = 0 + only_html=0 id - Base_getListFileFromAppcache + Base_getTranslationSourceFileList diff --git a/bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/WebSite_createTranslationData/your_translation_data_file.xml b/bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/WebSite_createTranslationData/your_translation_data_file.xml index 1246765abd292e9e581cd0482e20a016e319d36d..73d7ae53e9f73103b39aba4e18c2dd940c7fdb6c 100644 --- a/bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/WebSite_createTranslationData/your_translation_data_file.xml +++ b/bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs/WebSite_createTranslationData/your_translation_data_file.xml @@ -54,6 +54,10 @@ field_id + + first_item + + form_id @@ -64,6 +68,10 @@ AAAAAAAAAAI= + + title + + @@ -107,7 +115,7 @@ _text - python: [ (x,x) for x in here.Base_getListFileFromAppcache()] + python: [ (x,x) for x in here.Base_getTranslationSourceFileList()] diff --git a/tests/__init__.py b/tests/__init__.py index 580935d622e98b70ce2b2f976a2339adbca29f28..408e1366e5501c3770a6bb1a74b7bc39021b9450 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,12 +1,13 @@ from glob import glob import os, subprocess, re # test_suite is provided by 'run_test_suite' -from test_suite import ERP5TypeTestSuite +from test_suite import SavedTestSuite import sys HERE = os.path.dirname(__file__) -class _ERP5(ERP5TypeTestSuite): +class _ERP5(SavedTestSuite): + _saved_test_id = "erp5_web_renderjs_ui_test:testFunctionalRJSInterfaceValidator" realtime_output = False enabled_product_list = ('CMFActivity', 'CMFCategory', 'ERP5', 'ERP5Catalog', 'ERP5eGovSecurity', 'ERP5Form', @@ -35,9 +36,27 @@ class _ERP5(ERP5TypeTestSuite): component_re = re.compile(".*/([^/]+)/TestTemplateItem/portal_components" "/test\.[^.]+\.([^.]+).py$") for test_path in ( - glob('%s/product/*/tests/test*.py' % path) + - glob('%s/bt5/*/TestTemplateItem/test*.py' % path) + - glob('%s/bt5/*/TestTemplateItem/portal_components/test.*.test*.py' % path)): + # glob('%s/product/Formulator/tests/test*.py' % path) + + # glob('%s/product/ERP5Form/tests/test*.py' % path) + + # ['%s/product/ERP5/tests/testXHTML.py' % path] + + # ['%s/product/ERP5Type/tests/testFunctionalCore.py' % path] + + # ['%s/product/ERP5Type/tests/testFunctionalAnonymousSelection.py' % path] + + glob('%s/bt5/erp5_hal_json_style/TestTemplateItem/portal_components/test.*.test*.py' % path) + + glob('%s/bt5/erp5_web_renderjs_ui_test/TestTemplateItem/portal_components/test.*.test*.py' % path) + + # glob('%s/bt5/erp5_web_ui_test/TestTemplateItem/portal_components/test.*.test*.py' % path) + + # glob('%s/bt5/erp5_ui_test/TestTemplateItem/portal_components/test.*.test*.py' % path) + + # glob('%s/bt5/erp5_token_login/TestTemplateItem/portal_components/test.*.test*.py' % path) + + glob('%s/bt5/erp5_pdm_renderjs_ui_test/TestTemplateItem/portal_components/test.*.test*.py' % path) + + glob('%s/bt5/erp5_crm_renderjs_ui_test/TestTemplateItem/portal_components/test.*.test*.py' % path) + + glob('%s/bt5/erp5_accounting_renderjs_ui_test/TestTemplateItem/portal_components/test.*.test*.py' % path) + + glob('%s/bt5/erp5_gadget_interface_validator_ui_test/TestTemplateItem/portal_components/test.*.test*.py' % path) + # glob('%s/bt5/erp5_web_monitoring_ui_test/TestTemplateItem/portal_components/test.*.test*.py' % path) + + # glob('%s/bt5/erp5_travel_expense_ui_test/TestTemplateItem/portal_components/test.*.test*.py' % path) + + # glob('%s/bt5/erp5_officejs_support_request_ui_test/TestTemplateItem/portal_components/test.*.test*.py' % path) + + # glob('%s/bt5/erp5_officejs_afs_directory_ui_test/TestTemplateItem/portal_components/test.*.test*.py' % path) + + # glob('%s/bt5/erp5_officejs_ui_test/TestTemplateItem/portal_components/test.*.test*.py' % path) + ): + # glob('%s/bt5/erp5_web/TestTemplateItem/portal_components/test.*.test*.py' % path)): component_re_match = component_re.match(test_path) if component_re_match is not None: test_case = "%s:%s" % (component_re_match.group(1),