From 1600216c1da0fcbb7c91819b103242fa69337c67 Mon Sep 17 00:00:00 2001 From: Lucas Perais Date: Tue, 21 Mar 2017 11:50:12 +0100 Subject: [PATCH] [ADD] hw_screen: implement support for customer facing displays (#15303) This adds the hw_screen module which is responsible for receiving rendered HTML from a POS client and sending it to a running Chromium browser. This is done by sending Remote Debugging Protocol messages over a WebSocket provided by Chromium. This allows hw_screen to evaluate arbitrary JS. This is used to seamlessly (without flickering) update the browser. This also includes changes to the POSBox. X, Chromium and some miscellaneous other programs were added. Functionality was added that automatically displays a fullscreen, UI-less Chromium browser when the POSBox starts up. This is accomplished through x_application.sh, which gets executed only when a display is detected. After the browser starts, it will display a specific screen until it receives the first order update from a POS client. Creates a public controller to be able to display the interface on an external device not connected to the posbox (e.g. tablet) Courtesy of JOV, LPE, ODO and MAT --- addons/hw_posbox_homepage/controllers/main.py | 5 +- addons/hw_screen/__init__.py | 22 +++ addons/hw_screen/__openerp__.py | 42 ++++ addons/hw_screen/controllers/__init__.py | 22 +++ addons/hw_screen/controllers/main.py | 185 ++++++++++++++++++ addons/hw_screen/static/src/css/cust_css.css | 21 ++ addons/hw_screen/static/src/js/worker.js | 60 ++++++ .../posbox/configuration/setup_ramdisks.sh | 2 +- .../etc/lightdm/lightdm.conf | 8 + .../etc/xdg/openbox/autostart | 6 + .../META-INF/manifest.mf | 32 +++ .../META-INF/mozilla.rsa | Bin 0 -> 4197 bytes .../META-INF/mozilla.sf | 4 + .../README | 3 + .../chrome.manifest | 4 + .../content/rkioskbrowser.js | 34 ++++ .../content/rkioskbrowser.xul | 175 +++++++++++++++++ .../content/rkioskunknownContentType.xul | 9 + .../content/rkioskxpinstallConfirm.xul | 9 + .../install.rdf | 19 ++ .../defaults/preferences/all-posbox.js | 7 + .../overwrite_before_init/etc/init.d/odoo | 2 +- .../etc/init_posbox_image.sh | 47 ++++- .../etc/udev/rules.d/99-z-input.rules | 2 + .../tools/posbox/posbox_create_image.sh | 23 ++- 25 files changed, 729 insertions(+), 14 deletions(-) create mode 100644 addons/hw_screen/__init__.py create mode 100644 addons/hw_screen/__openerp__.py create mode 100644 addons/hw_screen/controllers/__init__.py create mode 100644 addons/hw_screen/controllers/main.py create mode 100644 addons/hw_screen/static/src/css/cust_css.css create mode 100644 addons/hw_screen/static/src/js/worker.js create mode 100644 addons/point_of_sale/tools/posbox/overwrite_after_init/etc/lightdm/lightdm.conf create mode 100755 addons/point_of_sale/tools/posbox/overwrite_after_init/etc/xdg/openbox/autostart create mode 100644 addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/manifest.mf create mode 100644 addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/mozilla.rsa create mode 100644 addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/mozilla.sf create mode 100644 addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/README create mode 100644 addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/chrome.manifest create mode 100644 addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskbrowser.js create mode 100644 addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskbrowser.xul create mode 100644 addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskunknownContentType.xul create mode 100644 addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskxpinstallConfirm.xul create mode 100644 addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/install.rdf create mode 100644 addons/point_of_sale/tools/posbox/overwrite_after_init/usr/share/firefox-esr/browser/defaults/preferences/all-posbox.js create mode 100644 addons/point_of_sale/tools/posbox/overwrite_before_init/etc/udev/rules.d/99-z-input.rules diff --git a/addons/hw_posbox_homepage/controllers/main.py b/addons/hw_posbox_homepage/controllers/main.py index 65b276075d2..8a448e386f5 100644 --- a/addons/hw_posbox_homepage/controllers/main.py +++ b/addons/hw_posbox_homepage/controllers/main.py @@ -58,7 +58,10 @@ index_template = """ If you need to grant remote debugging access to a developer, you can do it here.

- The PosBox software installed on this posbox is version 15, + If you need to display the current customer basket on another device, you can do it here. +

+

+ The PosBox software installed on this posbox is version 16, the posbox version number is independent from Odoo. You can upgrade the software on the upgrade page.

diff --git a/addons/hw_screen/__init__.py b/addons/hw_screen/__init__.py new file mode 100644 index 00000000000..502f47ce57c --- /dev/null +++ b/addons/hw_screen/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2015 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +import controllers diff --git a/addons/hw_screen/__openerp__.py b/addons/hw_screen/__openerp__.py new file mode 100644 index 00000000000..1e6438bf25c --- /dev/null +++ b/addons/hw_screen/__openerp__.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2015 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + + +{ + 'name': 'Screen Driver', + 'version': '1.0', + 'category': 'Hardware Drivers', + 'sequence': 6, + 'summary': 'Provides support for customer facing displays', + 'website': 'https://www.odoo.com/page/point-of-sale', + 'description': """ +Screen Driver +============= + +This module allows the POS client to send rendered HTML to a remotely +installed screen. This module then displays this HTML using a web +browser. +""", + 'author': 'OpenERP SA', + 'depends': ['hw_proxy'], + 'installable': False, + 'auto_install': False, +} diff --git a/addons/hw_screen/controllers/__init__.py b/addons/hw_screen/controllers/__init__.py new file mode 100644 index 00000000000..517985a53ef --- /dev/null +++ b/addons/hw_screen/controllers/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2015 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +import main diff --git a/addons/hw_screen/controllers/main.py b/addons/hw_screen/controllers/main.py new file mode 100644 index 00000000000..aa4b8a1a729 --- /dev/null +++ b/addons/hw_screen/controllers/main.py @@ -0,0 +1,185 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2015 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + + +from openerp import http +from openerp.tools import config +from openerp.addons.web.controllers import main as web + +import logging +import netifaces as ni +import os +from subprocess import call +import time +import threading + +self_port = str(config['xmlrpc_port'] or 8069) + +_logger = logging.getLogger(__name__) + + +class HardwareScreen(web.Home): + + event_data = threading.Event() + pos_client_data = {'rendered_html': False, + 'ip_from': False} + display_in_use = '' + failure_count = {} + + def _call_xdotools(self, keystroke): + os.environ['DISPLAY'] = ":0.0" + os.environ['XAUTHORITY'] = "/run/lightdm/pi/xauthority" + try: + call(['xdotool', 'key', keystroke]) + return "xdotool succeeded in stroking " + keystroke + except: + return "xdotool threw an error, maybe it is not installed on the posbox" + + @http.route('/hw_proxy/display_refresh', type='json', auth='none', cors='*') + def display_refresh(self): + return self._call_xdotools('F5') + + # POS CASHIER'S ROUTES + @http.route('/hw_proxy/customer_facing_display', type='json', auth='none', cors='*') + def update_user_facing_display(self, html=None): + request_ip = http.request.httprequest.remote_addr + if request_ip == HardwareScreen.pos_client_data.get('ip_from', ''): + HardwareScreen.pos_client_data['rendered_html'] = html + HardwareScreen.event_data.set() + + return {'status': 'updated'} + else: + return {'status': 'failed'} + + @http.route('/hw_proxy/take_control', type='json', auth='none', cors='*') + def take_control(self, html=None): + # ALLOW A CASHIER TO TAKE CONTROL OVER THE POSBOX, IN CASE OF MULTIPLE CASHIER PER POSBOX + HardwareScreen.pos_client_data['rendered_html'] = html + HardwareScreen.pos_client_data['ip_from'] = http.request.httprequest.remote_addr + HardwareScreen.event_data.set() + + return {'status': 'success', + 'message': 'You now have access to the display'} + + @http.route('/hw_proxy/test_ownership', type='json', auth='none', cors='*') + def test_ownership(self): + if HardwareScreen.pos_client_data.get('ip_from') == http.request.httprequest.remote_addr: + return {'status': 'OWNER'} + else: + return {'status': 'NOWNER'} + + # POSBOX ROUTES (SELF) + @http.route('/point_of_sale/display', type='http', auth='none') + def render_main_display(self): + return self._get_html() + + @http.route('/point_of_sale/get_serialized_order', type='json', auth='none') + def get_serialized_order(self): + request_addr = http.request.httprequest.remote_addr + result = HardwareScreen.pos_client_data + if HardwareScreen.display_in_use and request_addr != HardwareScreen.display_in_use: + if not HardwareScreen.failure_count.get(request_addr): + HardwareScreen.failure_count[request_addr] = 0 + if HardwareScreen.failure_count[request_addr] > 0: + time.sleep(10) + HardwareScreen.failure_count[request_addr] += 1 + return {'rendered_html': """

Not Authorized. Another browser is in use to display for the client. Please refresh.

""", + 'stop_longpolling': True, + 'ip_from': request_addr} + + # IMPLEMENTATION OF LONGPOLLING + # Times out 2 seconds before the JS request does + if HardwareScreen.event_data.wait(28): + HardwareScreen.event_data.clear() + HardwareScreen.failure_count[request_addr] = 0 + return result + return {'rendered_html': False, + 'ip_from': HardwareScreen.pos_client_data['ip_from']} + + def _get_html(self): + cust_js = None + interfaces = ni.interfaces() + my_ip = '127.0.0.1' + HardwareScreen.display_in_use = http.request.httprequest.remote_addr + + with open(os.path.join(os.path.dirname(__file__), "../static/src/js/worker.js")) as js: + cust_js = js.read() + + with open(os.path.join(os.path.dirname(__file__), "../static/src/css/cust_css.css")) as css: + cust_css = css.read() + + display_ifaces = "" + for iface_id in interfaces: + iface_obj = ni.ifaddresses(iface_id) + ifconfigs = iface_obj.get(ni.AF_INET, []) + for conf in ifconfigs: + if conf.get('addr'): + display_ifaces += "" + iface_id + "" + display_ifaces += "" + conf.get('addr') + "" + display_ifaces += "" + conf.get('netmask') + "" + # What is my external IP ? + if iface_id != 'lo': + my_ip = conf.get('addr') + + my_ip_port = my_ip + ":" + self_port + + html = """ + + + + Odoo -- Point of Sale + + + + + + + + + +
+
+
+

Odoo Point of Sale

+

POSBox Client display

+

My IPs

+ + + + + + + """ + display_ifaces + """ +
InterfaceIPNetmask
+

The customer cart will be displayed here once a Point of Sale session is started.

+

Odoo version 11 or above is required.

+
+
+
+ + + """ + return html diff --git a/addons/hw_screen/static/src/css/cust_css.css b/addons/hw_screen/static/src/css/cust_css.css new file mode 100644 index 00000000000..69fddb25457 --- /dev/null +++ b/addons/hw_screen/static/src/css/cust_css.css @@ -0,0 +1,21 @@ +html { + width: 100%; + height: 100%; + font-size: 11px; +} + +body { + width: 100%; + height: 100%; + font-size: 14px; + margin: 0; +} + +.original_body { + background-color: #797083; + color: white; +} + +.ajax_got_body { + color: black; +} \ No newline at end of file diff --git a/addons/hw_screen/static/src/js/worker.js b/addons/hw_screen/static/src/js/worker.js new file mode 100644 index 00000000000..55e389e78ab --- /dev/null +++ b/addons/hw_screen/static/src/js/worker.js @@ -0,0 +1,60 @@ + $(function() { + "use strict"; + // mergedHead will be turned to true the first time we receive something from a new host + // It allows to transform the only once + var mergedHead = false; + var current_client_url = ""; + var stop_longpolling = false; + + function longpolling() { + $.ajax({ + type: 'POST', + url: 'http://'+window.location.host+'/point_of_sale/get_serialized_order', + dataType: 'json', + beforeSend: function(xhr){xhr.setRequestHeader('Content-Type', 'application/json');}, + data: JSON.stringify({jsonrpc: '2.0'}), + + success: function(data) { + if (typeof data.result.stop_longpolling !== 'undefined') { + stop_longpolling = data.result.stop_longpolling; + } + if (data.result.ip_from && data.result.rendered_html) { + var trimmed = $.trim(data.result.rendered_html); + var $parsedHTML = $('
').html($.parseHTML(trimmed,true)); // WARNING: the true here will executes any script present in the string to parse + var new_client_url = $parsedHTML.find(".resources > base").attr('href'); + + if (!mergedHead || (current_client_url !== new_client_url)) { + + mergedHead = true; + current_client_url = new_client_url; + $("body").removeClass('original_body').addClass('ajax_got_body'); + $("head").children().not('.origin').remove(); + $("head").append($parsedHTML.find(".resources").html()); + } + + $(".container").html($parsedHTML.find('.pos-customer_facing_display').html()); + $(".container").attr('class', 'container').addClass($parsedHTML.find('.pos-customer_facing_display').attr('class')); + + var d = $('.pos_orderlines_list'); + d.scrollTop(d.prop("scrollHeight")); + + // Here we execute the code coming from the pos, apparently $.parseHTML() executes scripts right away, + // Since we modify the dom afterwards, the script might not have any effect + if (typeof foreign_js !== 'undefined' && $.isFunction(foreign_js)) { + foreign_js(); + } + } + }, + + complete: function(jqXHR,err) { + if (!stop_longpolling) { + longpolling(); + } + }, + + timeout: 30000, + }); + }; + + longpolling(); + }); \ No newline at end of file diff --git a/addons/point_of_sale/tools/posbox/configuration/setup_ramdisks.sh b/addons/point_of_sale/tools/posbox/configuration/setup_ramdisks.sh index ce2f2e633e6..618c4b1fd48 100755 --- a/addons/point_of_sale/tools/posbox/configuration/setup_ramdisks.sh +++ b/addons/point_of_sale/tools/posbox/configuration/setup_ramdisks.sh @@ -11,7 +11,7 @@ create_ramdisk () { echo "Creating ramdisk for ${1} of size ${SIZE}..." mount -t tmpfs -o size="${SIZE}" tmpfs "${RAMDISK}" - rsync -a --exclude="swap" --exclude="apt" --exclude="dpkg" "${ORIGINAL}/" "${RAMDISK}/" + rsync -a --exclude="swap" --exclude="apt" --exclude="dpkg" --exclude=".mozilla" "${ORIGINAL}/" "${RAMDISK}/" mount --bind "${RAMDISK}" "${ORIGINAL}" } diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/lightdm/lightdm.conf b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/lightdm/lightdm.conf new file mode 100644 index 00000000000..977903c1c90 --- /dev/null +++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/lightdm/lightdm.conf @@ -0,0 +1,8 @@ + +[LightDM] +user-authority-in-system-dir=true + +[SeatDefaults] +xserver-command=/usr/bin/X -s 0 dpms -nolisten tcp +greeter-hide-users=false +autologin-user=pi \ No newline at end of file diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/xdg/openbox/autostart b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/xdg/openbox/autostart new file mode 100755 index 00000000000..e2b61e2f591 --- /dev/null +++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/xdg/openbox/autostart @@ -0,0 +1,6 @@ +#!/bin/bash +xset s off +xset -dpms + +export HOME=/tmp +/usr/bin/firefox http://localhost:8069/point_of_sale/display & diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/manifest.mf b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/manifest.mf new file mode 100644 index 00000000000..63a9098e00d --- /dev/null +++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/manifest.mf @@ -0,0 +1,32 @@ +Manifest-Version: 1.0 + +Name: install.rdf +Digest-Algorithms: MD5 SHA1 +MD5-Digest: xnFKNbJgc33dy/FJ+4cmHA== +SHA1-Digest: 4YLgHgdgCw4lGCfsX7+r4zVmKJ4= + +Name: chrome.manifest +Digest-Algorithms: MD5 SHA1 +MD5-Digest: O5ce4bajAqUxG6iVul0K2w== +SHA1-Digest: wb6VleWnV5GgLypmg1ij9TfmPLE= + +Name: content/rkioskbrowser.js +Digest-Algorithms: MD5 SHA1 +MD5-Digest: /cF15tfVnbkfbxRVTL5N+g== +SHA1-Digest: lvbY92PbsjwY+0TguEYoXWw0lxQ= + +Name: content/rkioskbrowser.xul +Digest-Algorithms: MD5 SHA1 +MD5-Digest: NFOIpAmZtn20Y+XfTo4cpw== +SHA1-Digest: VVIo7GdG+4mvAOtgR0DJUsSc/yg= + +Name: content/rkioskunknownContentType.xul +Digest-Algorithms: MD5 SHA1 +MD5-Digest: 6cNGoHJS9Xvm+wmvo4IesQ== +SHA1-Digest: T8i1MkMKjmn5HICqWv+iXSPRKIU= + +Name: content/rkioskxpinstallConfirm.xul +Digest-Algorithms: MD5 SHA1 +MD5-Digest: SxN1YnRJiuood2WhU85v9g== +SHA1-Digest: Msj21u4bTAKUi496xld5YCGdjiA= + diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/mozilla.rsa b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/mozilla.rsa new file mode 100644 index 0000000000000000000000000000000000000000..521b08d182a938ae7a831df4a347f00b9f42e54d GIT binary patch literal 4197 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 literal 0 HcmV?d00001 diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/mozilla.sf b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/mozilla.sf new file mode 100644 index 00000000000..37eae3e21fb --- /dev/null +++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/mozilla.sf @@ -0,0 +1,4 @@ +Signature-Version: 1.0 +MD5-Digest-Manifest: 7hFyhNW67+H+rf9OhWGDkA== +SHA1-Digest-Manifest: HvfAQQLXphSZ9m8KBorJMX8MUnE= + diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/README b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/README new file mode 100644 index 00000000000..c8c1ce58823 --- /dev/null +++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/README @@ -0,0 +1,3 @@ +The R-kiosk module has been downloaded from https://addons.mozilla.org/en-US/firefox/addon/r-kiosk/ +It is in the public domain as stated on https://addons.mozilla.org/en-US/firefox/addon/r-kiosk/eula/ +This mozilla module is shipped by Odoo to provide out of the box Client facing display to Odoo's Posbox \ No newline at end of file diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/chrome.manifest b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/chrome.manifest new file mode 100644 index 00000000000..e4957b8d5e8 --- /dev/null +++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/chrome.manifest @@ -0,0 +1,4 @@ +content RKiosk content/ +overlay chrome://browser/content/browser.xul chrome://rkiosk/content/rkioskbrowser.xul +overlay chrome://mozapps/content/xpinstall/xpinstallConfirm.xul chrome://rkiosk/content/rkioskxpinstallConfirm.xul +overlay chrome://mozapps/content/downloads/unknownContentType.xul chrome://rkiosk/content/rkioskunknownContentType.xul diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskbrowser.js b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskbrowser.js new file mode 100644 index 00000000000..5ece9a9e06b --- /dev/null +++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskbrowser.js @@ -0,0 +1,34 @@ +function Rkiosk_donothing() +{ + + +} + +function rkioskclose() +{ + close(); +} + +function Rkiosk_navbar_setting() +{ + var rkiosk_navbar_enable="true"; + var prefs = Components.classes["@mozilla.org/preferences-service;1"]. + getService(Components.interfaces.nsIPrefBranch); + if (prefs.getPrefType("rkiosk.navbar") == prefs.PREF_BOOL){ + if (prefs.getBoolPref("rkiosk.navbar")) rkiosk_navbar_enable = "false"; + } + var rkiosk_element = document.getElementById("navigator-toolbox"); + rkiosk_element.setAttribute("hidden", rkiosk_navbar_enable); +} + +function RkioskBrowserStartup() +{ + Rkiosk_navbar_setting(); + BrowserStartup(); + setTimeout(RkioskdelayedStartup, 1000); +} + +function RkioskdelayedStartup() +{ + window.fullScreen = true; +} diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskbrowser.xul b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskbrowser.xul new file mode 100644 index 00000000000..d5fb0c140d1 --- /dev/null +++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskbrowser.xul @@ -0,0 +1,175 @@ + + + + + + + +