From cc72ede9aa991b750a2acfbc8e753f61d62343db Mon Sep 17 00:00:00 2001 From: MuK IT GmbH Date: Mon, 27 Jul 2020 22:26:11 +0000 Subject: [PATCH] publish muk_web_utils - 13.0 --- muk_web_utils/LICENSE | 165 + muk_web_utils/README.rst | 113 + muk_web_utils/__init__.py | 24 + muk_web_utils/__manifest__.py | 58 + muk_web_utils/controllers/__init__.py | 24 + muk_web_utils/controllers/attachment.py | 56 + muk_web_utils/controllers/backend.py | 37 + muk_web_utils/data/autovacuum.xml | 36 + muk_web_utils/doc/changelog.rst | 54 + muk_web_utils/doc/index.rst | 113 + muk_web_utils/i18n/de.po | 340 ++ muk_web_utils/i18n/es.po | 326 ++ muk_web_utils/i18n/fr.po | 326 ++ muk_web_utils/i18n/muk_web_utils.pot | 326 ++ muk_web_utils/i18n/nl.po | 326 ++ muk_web_utils/models/__init__.py | 25 + muk_web_utils/models/ir_attachment.py | 46 + muk_web_utils/models/res_config_settings.py | 79 + muk_web_utils/static/description/banner.png | Bin 0 -> 46485 bytes muk_web_utils/static/description/icon.png | Bin 0 -> 15746 bytes muk_web_utils/static/description/icon.svg | 1 + muk_web_utils/static/description/index.html | 124 + muk_web_utils/static/description/logo.png | Bin 0 -> 38064 bytes muk_web_utils/static/description/preview.png | Bin 0 -> 33203 bytes .../description/service_customization.png | Bin 0 -> 27452 bytes .../description/service_development.png | Bin 0 -> 28929 bytes .../description/service_implementation.png | Bin 0 -> 26148 bytes .../description/service_integration.png | Bin 0 -> 24862 bytes .../static/description/service_support.png | Bin 0 -> 24150 bytes .../static/libs/simplebar/simplebar.css | 160 + .../static/libs/simplebar/simplebar.js | 4389 +++++++++++++++++ muk_web_utils/static/src/img/module.png | Bin 0 -> 4921 bytes muk_web_utils/static/src/js/core/async.js | 85 + muk_web_utils/static/src/js/core/dialog.js | 68 + muk_web_utils/static/src/js/core/dropzone.js | 132 + muk_web_utils/static/src/js/core/files.js | 176 + muk_web_utils/static/src/js/core/mimetype.js | 110 + muk_web_utils/static/src/js/core/utils.js | 85 + .../static/src/js/fields/abstract.js | 46 + muk_web_utils/static/src/js/fields/binary.js | 86 + muk_web_utils/static/src/js/fields/color.js | 130 + muk_web_utils/static/src/js/fields/copy.js | 135 + muk_web_utils/static/src/js/fields/domain.js | 54 + muk_web_utils/static/src/js/fields/image.js | 58 + muk_web_utils/static/src/js/fields/module.js | 96 + muk_web_utils/static/src/js/fields/path.js | 119 + muk_web_utils/static/src/js/fields/share.js | 226 + muk_web_utils/static/src/js/fields/utils.js | 54 + muk_web_utils/static/src/js/libs/jquery.js | 104 + muk_web_utils/static/src/js/libs/scrollbar.js | 27 + .../static/src/js/libs/underscore.js | 47 + .../src/js/services/notification_service.js | 37 + .../static/src/js/views/form/renderer.js | 47 + .../static/src/js/widgets/notification.js | 46 + muk_web_utils/static/src/scss/binary.scss | 28 + muk_web_utils/static/src/scss/color.scss | 66 + muk_web_utils/static/src/scss/copy.scss | 34 + muk_web_utils/static/src/scss/dropzone.scss | 64 + muk_web_utils/static/src/scss/image.scss | 84 + muk_web_utils/static/src/scss/mixins.scss | 40 + muk_web_utils/static/src/scss/module.scss | 33 + .../static/src/scss/notification.scss | 30 + muk_web_utils/static/src/scss/share.scss | 54 + muk_web_utils/static/src/scss/switch.scss | 158 + muk_web_utils/static/src/scss/variables.scss | 39 + muk_web_utils/static/src/xml/color.xml | 65 + muk_web_utils/static/src/xml/copy.xml | 35 + muk_web_utils/static/src/xml/image.xml | 34 + muk_web_utils/static/src/xml/module.xml | 39 + muk_web_utils/static/src/xml/notification.xml | 39 + muk_web_utils/static/src/xml/share.xml | 106 + muk_web_utils/static/src/xml/switch.xml | 54 + muk_web_utils/static/tests/fields.js | 205 + muk_web_utils/template/assets.xml | 79 + muk_web_utils/tests/__init__.py | 23 + muk_web_utils/tests/test_js.py | 41 + .../views/res_config_settings_view.xml | 49 + 77 files changed, 10515 insertions(+) create mode 100644 muk_web_utils/LICENSE create mode 100644 muk_web_utils/README.rst create mode 100644 muk_web_utils/__init__.py create mode 100644 muk_web_utils/__manifest__.py create mode 100644 muk_web_utils/controllers/__init__.py create mode 100644 muk_web_utils/controllers/attachment.py create mode 100644 muk_web_utils/controllers/backend.py create mode 100644 muk_web_utils/data/autovacuum.xml create mode 100644 muk_web_utils/doc/changelog.rst create mode 100644 muk_web_utils/doc/index.rst create mode 100644 muk_web_utils/i18n/de.po create mode 100644 muk_web_utils/i18n/es.po create mode 100644 muk_web_utils/i18n/fr.po create mode 100644 muk_web_utils/i18n/muk_web_utils.pot create mode 100644 muk_web_utils/i18n/nl.po create mode 100644 muk_web_utils/models/__init__.py create mode 100644 muk_web_utils/models/ir_attachment.py create mode 100644 muk_web_utils/models/res_config_settings.py create mode 100644 muk_web_utils/static/description/banner.png create mode 100644 muk_web_utils/static/description/icon.png create mode 100644 muk_web_utils/static/description/icon.svg create mode 100644 muk_web_utils/static/description/index.html create mode 100644 muk_web_utils/static/description/logo.png create mode 100644 muk_web_utils/static/description/preview.png create mode 100644 muk_web_utils/static/description/service_customization.png create mode 100644 muk_web_utils/static/description/service_development.png create mode 100644 muk_web_utils/static/description/service_implementation.png create mode 100644 muk_web_utils/static/description/service_integration.png create mode 100644 muk_web_utils/static/description/service_support.png create mode 100644 muk_web_utils/static/libs/simplebar/simplebar.css create mode 100644 muk_web_utils/static/libs/simplebar/simplebar.js create mode 100644 muk_web_utils/static/src/img/module.png create mode 100644 muk_web_utils/static/src/js/core/async.js create mode 100644 muk_web_utils/static/src/js/core/dialog.js create mode 100644 muk_web_utils/static/src/js/core/dropzone.js create mode 100644 muk_web_utils/static/src/js/core/files.js create mode 100644 muk_web_utils/static/src/js/core/mimetype.js create mode 100644 muk_web_utils/static/src/js/core/utils.js create mode 100644 muk_web_utils/static/src/js/fields/abstract.js create mode 100644 muk_web_utils/static/src/js/fields/binary.js create mode 100644 muk_web_utils/static/src/js/fields/color.js create mode 100644 muk_web_utils/static/src/js/fields/copy.js create mode 100644 muk_web_utils/static/src/js/fields/domain.js create mode 100644 muk_web_utils/static/src/js/fields/image.js create mode 100644 muk_web_utils/static/src/js/fields/module.js create mode 100644 muk_web_utils/static/src/js/fields/path.js create mode 100644 muk_web_utils/static/src/js/fields/share.js create mode 100644 muk_web_utils/static/src/js/fields/utils.js create mode 100644 muk_web_utils/static/src/js/libs/jquery.js create mode 100644 muk_web_utils/static/src/js/libs/scrollbar.js create mode 100644 muk_web_utils/static/src/js/libs/underscore.js create mode 100644 muk_web_utils/static/src/js/services/notification_service.js create mode 100644 muk_web_utils/static/src/js/views/form/renderer.js create mode 100644 muk_web_utils/static/src/js/widgets/notification.js create mode 100644 muk_web_utils/static/src/scss/binary.scss create mode 100644 muk_web_utils/static/src/scss/color.scss create mode 100644 muk_web_utils/static/src/scss/copy.scss create mode 100644 muk_web_utils/static/src/scss/dropzone.scss create mode 100644 muk_web_utils/static/src/scss/image.scss create mode 100644 muk_web_utils/static/src/scss/mixins.scss create mode 100644 muk_web_utils/static/src/scss/module.scss create mode 100644 muk_web_utils/static/src/scss/notification.scss create mode 100644 muk_web_utils/static/src/scss/share.scss create mode 100644 muk_web_utils/static/src/scss/switch.scss create mode 100644 muk_web_utils/static/src/scss/variables.scss create mode 100644 muk_web_utils/static/src/xml/color.xml create mode 100644 muk_web_utils/static/src/xml/copy.xml create mode 100644 muk_web_utils/static/src/xml/image.xml create mode 100644 muk_web_utils/static/src/xml/module.xml create mode 100644 muk_web_utils/static/src/xml/notification.xml create mode 100644 muk_web_utils/static/src/xml/share.xml create mode 100644 muk_web_utils/static/src/xml/switch.xml create mode 100644 muk_web_utils/static/tests/fields.js create mode 100644 muk_web_utils/template/assets.xml create mode 100644 muk_web_utils/tests/__init__.py create mode 100644 muk_web_utils/tests/test_js.py create mode 100644 muk_web_utils/views/res_config_settings_view.xml diff --git a/muk_web_utils/LICENSE b/muk_web_utils/LICENSE new file mode 100644 index 0000000..153d416 --- /dev/null +++ b/muk_web_utils/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/muk_web_utils/README.rst b/muk_web_utils/README.rst new file mode 100644 index 0000000..1d9ac57 --- /dev/null +++ b/muk_web_utils/README.rst @@ -0,0 +1,113 @@ +============= +MuK Web Utils +============= + +Technical module to provide some utility features and libraries that can be used +in other applications. This module has no direct effect on the running system. + +Installation +============ + +To install this module, you need to: + +Download the module and add it to your Odoo addons folder. Afterward, log on to +your Odoo server and go to the Apps menu. Trigger the debug mode and update the +list by clicking on the "Update Apps List" link. Now install the module by +clicking on the install button. + +Another way to install this module is via the package management for Python +(`PyPI `_). + +To install our modules using the package manager make sure +`odoo-autodiscover `_ is installed +correctly. Then open a console and install the module by entering the following +command: + +``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple `` + +The module name consists of the Odoo version and the module name, where +underscores are replaced by a dash. + +**Module:** + +``odoo-addon-`` + +**Example:** + +``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils`` + +Once the installation has been successfully completed, the app is already in the +correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the +debug mode and update the list by clicking on the "Update Apps List" link. Now +install the module by clicking on the install button. + +The biggest advantage of this variant is that you can now also update the app +using the "pip" command. To do this, enter the following command in your console: + +``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple `` + +When the process is finished, restart your server and update the application in +Odoo. The steps are the same as for the installation only the button has changed +from "Install" to "Upgrade". + +You can also view available Apps directly in our `repository `_ +and find a more detailed installation guide on our `website `_. + +For modules licensed under OPL-1, you will receive access data when you purchase +the module. If the modules were not purchased directly from +`MuK IT `_ please contact our support (support@mukit.at) +with a confirmation of purchase to receive the corresponding access data. + +Upgrade +============ + +To upgrade this module, you need to: + +Download the module and add it to your Odoo addons folder. Restart the server +and log on to your Odoo server. Select the Apps menu and upgrade the module by +clicking on the upgrade button. + +If you installed the module using the "pip" command, you can also update the +module in the same way. Just type the following command into the console: + +``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple `` + +When the process is finished, restart your server and update the application in +Odoo, just like you would normally. + +Configuration +============= + +No additional configuration is needed to use this module. + +Usage +============= + +This module has no direct visible effect on the system. It provide utility features. + +Credits +======= + +Contributors +------------ + +* Mathias Markl + +Images +------------ + +Some pictures are based on or inspired by the icon set of Font Awesome: + +* `Font Awesome `_ + +Author & Maintainer +------------------- + +This module is maintained by the `MuK IT GmbH `_. + +MuK IT is an Austrian company specialized in customizing and extending Odoo. +We develop custom solutions for your individual needs to help you focus on +your strength and expertise to grow your business. + +If you want to get in touch please contact us via mail +(sale@mukit.at) or visit our website (https://mukit.at). diff --git a/muk_web_utils/__init__.py b/muk_web_utils/__init__.py new file mode 100644 index 0000000..bbab24a --- /dev/null +++ b/muk_web_utils/__init__.py @@ -0,0 +1,24 @@ +################################################################################### +# +# Copyright (c) 2017-2019 MuK IT GmbH. +# +# This file is part of MuK Web Utils +# (see https://mukit.at). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +################################################################################### + +from . import models +from . import controllers \ No newline at end of file diff --git a/muk_web_utils/__manifest__.py b/muk_web_utils/__manifest__.py new file mode 100644 index 0000000..9fd7dbc --- /dev/null +++ b/muk_web_utils/__manifest__.py @@ -0,0 +1,58 @@ +################################################################################### +# +# Copyright (c) 2017-2019 MuK IT GmbH. +# +# This file is part of MuK Web Utils +# (see https://mukit.at). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +################################################################################### + +{ + "name": "MuK Web Utils", + "summary": """Utility Features""", + "version": "13.0.1.0.0", + "category": "Extra Tools", + "license": "LGPL-3", + "author": "MuK IT", + "website": "http://www.mukit.at", + 'live_test_url': 'https://mukit.at/r/SgN', + "contributors": [ + "Mathias Markl ", + "Benedikt Jilek ", + ], + "depends": [ + "web_editor", + "muk_autovacuum", + ], + "data": [ + "template/assets.xml", + "views/res_config_settings_view.xml", + "data/autovacuum.xml", + ], + "qweb": [ + "static/src/xml/*.xml", + ], + "images": [ + 'static/description/banner.png' + ], + "external_dependencies": { + "python": [], + "bin": [], + }, + "application": False, + "installable": True, + 'auto_install': False, +} diff --git a/muk_web_utils/controllers/__init__.py b/muk_web_utils/controllers/__init__.py new file mode 100644 index 0000000..5caf3fa --- /dev/null +++ b/muk_web_utils/controllers/__init__.py @@ -0,0 +1,24 @@ +################################################################################### +# +# Copyright (c) 2017-2019 MuK IT GmbH. +# +# This file is part of MuK Web Utils +# (see https://mukit.at). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +################################################################################### + +from . import backend +from . import attachment diff --git a/muk_web_utils/controllers/attachment.py b/muk_web_utils/controllers/attachment.py new file mode 100644 index 0000000..6f62a21 --- /dev/null +++ b/muk_web_utils/controllers/attachment.py @@ -0,0 +1,56 @@ +################################################################################### +# +# Copyright (c) 2017-2019 MuK IT GmbH. +# +# This file is part of MuK Web Utils +# (see https://mukit.at). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +################################################################################### + +import json +import base64 +import logging + +from odoo import http, SUPERUSER_ID +from odoo.http import request +from odoo.tools.misc import str2bool + +_logger = logging.getLogger(__name__) + +class AttachmentController(http.Controller): + + @http.route('/utils/attachment/add', type='http', auth="user", methods=['POST']) + def add_attachment(self, ufile, temporary=False, **kw): + tmp = temporary and str2bool(temporary) or False + name = "Access Attachment: %s" % ufile.filename + attachment = request.env['ir.attachment'].create({ + 'name': tmp and "%s (Temporary)" % name or name, + 'datas': base64.b64encode(ufile.read()), + 'datas_fname': ufile.filename, + 'type': 'binary', + 'public': False, + 'temporary': tmp, + }) + attachment.generate_access_token() + if ufile.mimetype and ufile.mimetype != 'application/octet-stream': + attachment.with_user(request.env['res.users'].browse(SUPERUSER_ID)).write({ + 'mimetype': ufile.mimetype, + }) + base_url = request.env['ir.config_parameter'].with_user(request.env['res.users'].browse(SUPERUSER_ID)).get_param('web.base.url') + result = attachment.read(['name', 'datas_fname', 'mimetype', 'checksum', 'access_token'])[0] + result['url'] = '%s/web/content/%s?access_token=%s' % (base_url, attachment.id, attachment.access_token) + return json.dumps(result) + \ No newline at end of file diff --git a/muk_web_utils/controllers/backend.py b/muk_web_utils/controllers/backend.py new file mode 100644 index 0000000..b17f109 --- /dev/null +++ b/muk_web_utils/controllers/backend.py @@ -0,0 +1,37 @@ +################################################################################### +# +# Copyright (c) 2017-2019 MuK IT GmbH. +# +# This file is part of MuK Web Utils +# (see https://mukit.at). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +################################################################################### + +import logging + +from odoo import http, SUPERUSER_ID +from odoo.http import request + +_logger = logging.getLogger(__name__) + +class BackendController(http.Controller): + + @http.route('/config/muk_web_utils.binary_max_size', type='json', auth="user") + def max_upload_size(self, **kw): + params = request.env['ir.config_parameter'].with_user(request.env['res.users'].browse(SUPERUSER_ID)) + return { + 'max_upload_size': int(params.get_param('muk_web_utils.binary_max_size', default=25)) + } \ No newline at end of file diff --git a/muk_web_utils/data/autovacuum.xml b/muk_web_utils/data/autovacuum.xml new file mode 100644 index 0000000..c3c3f22 --- /dev/null +++ b/muk_web_utils/data/autovacuum.xml @@ -0,0 +1,36 @@ + + + + + + + + Delete temporary Attachments + + + domain + [('temporary','=',True), ('create_date', '<=', (datetime.datetime.utcnow() - datetime.timedelta(hours=24)).strftime('%Y-%m-%d %H:%M:%S'))] + + + + \ No newline at end of file diff --git a/muk_web_utils/doc/changelog.rst b/muk_web_utils/doc/changelog.rst new file mode 100644 index 0000000..faf2ed6 --- /dev/null +++ b/muk_web_utils/doc/changelog.rst @@ -0,0 +1,54 @@ +`2.9.0` +------- + +- Temporary attachments + +`2.8.0` +------- + +- Added path field widgets + +`2.7.0` +------- + +- Added color index field widget + +`2.6.0` +------- + +- Moved editor features to separate module + +`2.5.0` +------- + +- Added color field widget + +`2.4.0` +------- + +- Added widget to share binary fields + +`2.3.0` +------- + +- Added custom colors to snippet options + +`2.2.0` +------- + +- Added widget to share text fields + +`2.1.0` +------- + +- Automatic labels on settings + +`2.0.0` +------- + +- Migrated to Python 3 + +`1.0.0` +------- + +- Init version diff --git a/muk_web_utils/doc/index.rst b/muk_web_utils/doc/index.rst new file mode 100644 index 0000000..1d9ac57 --- /dev/null +++ b/muk_web_utils/doc/index.rst @@ -0,0 +1,113 @@ +============= +MuK Web Utils +============= + +Technical module to provide some utility features and libraries that can be used +in other applications. This module has no direct effect on the running system. + +Installation +============ + +To install this module, you need to: + +Download the module and add it to your Odoo addons folder. Afterward, log on to +your Odoo server and go to the Apps menu. Trigger the debug mode and update the +list by clicking on the "Update Apps List" link. Now install the module by +clicking on the install button. + +Another way to install this module is via the package management for Python +(`PyPI `_). + +To install our modules using the package manager make sure +`odoo-autodiscover `_ is installed +correctly. Then open a console and install the module by entering the following +command: + +``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple `` + +The module name consists of the Odoo version and the module name, where +underscores are replaced by a dash. + +**Module:** + +``odoo-addon-`` + +**Example:** + +``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils`` + +Once the installation has been successfully completed, the app is already in the +correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the +debug mode and update the list by clicking on the "Update Apps List" link. Now +install the module by clicking on the install button. + +The biggest advantage of this variant is that you can now also update the app +using the "pip" command. To do this, enter the following command in your console: + +``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple `` + +When the process is finished, restart your server and update the application in +Odoo. The steps are the same as for the installation only the button has changed +from "Install" to "Upgrade". + +You can also view available Apps directly in our `repository `_ +and find a more detailed installation guide on our `website `_. + +For modules licensed under OPL-1, you will receive access data when you purchase +the module. If the modules were not purchased directly from +`MuK IT `_ please contact our support (support@mukit.at) +with a confirmation of purchase to receive the corresponding access data. + +Upgrade +============ + +To upgrade this module, you need to: + +Download the module and add it to your Odoo addons folder. Restart the server +and log on to your Odoo server. Select the Apps menu and upgrade the module by +clicking on the upgrade button. + +If you installed the module using the "pip" command, you can also update the +module in the same way. Just type the following command into the console: + +``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple `` + +When the process is finished, restart your server and update the application in +Odoo, just like you would normally. + +Configuration +============= + +No additional configuration is needed to use this module. + +Usage +============= + +This module has no direct visible effect on the system. It provide utility features. + +Credits +======= + +Contributors +------------ + +* Mathias Markl + +Images +------------ + +Some pictures are based on or inspired by the icon set of Font Awesome: + +* `Font Awesome `_ + +Author & Maintainer +------------------- + +This module is maintained by the `MuK IT GmbH `_. + +MuK IT is an Austrian company specialized in customizing and extending Odoo. +We develop custom solutions for your individual needs to help you focus on +your strength and expertise to grow your business. + +If you want to get in touch please contact us via mail +(sale@mukit.at) or visit our website (https://mukit.at). diff --git a/muk_web_utils/i18n/de.po b/muk_web_utils/i18n/de.po new file mode 100644 index 0000000..9b89532 --- /dev/null +++ b/muk_web_utils/i18n/de.po @@ -0,0 +1,340 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * muk_web_utils +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0-20190128\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-02-27 09:28+0000\n" +"PO-Revision-Date: 2019-06-27 08:23+0000\n" +"Last-Translator: MuK IT \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.7\n" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/color.js:113 +#, python-format +msgid "'%s' is not a correct color index (0-12)" +msgstr "%s' ist kein korrekter Farbindex (0-12)." + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/color.js:68 +#, python-format +msgid "'%s' is not a correct color value" +msgstr "%s' ist kein korrekter Farbwert." + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/share.js:175 +#, python-format +msgid "<%= name %> shared a file!" +msgstr "<%= name %> teilte eine Datei!" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/share.js:115 +#: code:addons/muk_web_utils/static/src/js/fields/share.js:144 +#, python-format +msgid "<%= name %> shared a message!" +msgstr "<%= name %> teilte eine Nachricht!" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/share.js:116 +#: code:addons/muk_web_utils/static/src/js/fields/share.js:145 +#: code:addons/muk_web_utils/static/src/js/fields/share.js:176 +#, python-format +msgid "<%= value %>" +msgstr "<%= Wert %>" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/dialog.js:51 +#: code:addons/muk_web_utils/static/src/js/fields/module.js:50 +#, python-format +msgid "Cancel" +msgstr "Abbrechen" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/module.xml:30 +#, python-format +msgid "Click on the download button to be redirected to the store and download the corresponding module." +msgstr "" +"Klicken Sie auf den Download-Button, um in den Shop weitergeleitet zu werden " +"und das entsprechende Modul herunterzuladen." + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:46 +#, python-format +msgid "Color 0" +msgstr "Farbe 0" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:47 +#, python-format +msgid "Color 1" +msgstr "Farbe 1" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:56 +#, python-format +msgid "Color 10" +msgstr "Farbe 10" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:57 +#, python-format +msgid "Color 11" +msgstr "Farbe 11" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:48 +#, python-format +msgid "Color 2" +msgstr "Farbe 2" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:49 +#, python-format +msgid "Color 3" +msgstr "Farbe 3" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:50 +#, python-format +msgid "Color 4" +msgstr "Farbe 4" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:51 +#, python-format +msgid "Color 5" +msgstr "Farbe 5" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:52 +#, python-format +msgid "Color 6" +msgstr "Farbe 6" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:53 +#, python-format +msgid "Color 7" +msgstr "Farbe 7" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:54 +#, python-format +msgid "Color 8" +msgstr "Farbe 8" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:55 +#, python-format +msgid "Color 9" +msgstr "Farbe 9" + +#. module: muk_web_utils +#: model:ir.model,name:muk_web_utils.model_res_config_settings +msgid "Config Settings" +msgstr "Konfiguration " + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/module.js:45 +#: code:addons/muk_web_utils/static/src/xml/share.xml:97 +#, python-format +msgid "Download" +msgstr "Herunterladen" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/dropzone.js:108 +#, python-format +msgid "Drop files here to upload!" +msgstr "Lassen Sie Dateien hier zum Hochladen fallen!" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:45 +#, python-format +msgid "External" +msgstr "Extern" + +#. module: muk_web_utils +#: model:ir.model.fields,field_description:muk_web_utils.field_res_config_settings__binary_max_size +msgid "File Size Limit" +msgstr "Dateigrößenbegrenzung" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:35 +#, python-format +msgid "Internal" +msgstr "Intern" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/copy.js:107 +#, python-format +msgid "Link Copied!" +msgstr "Link kopiert!" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:48 +#, python-format +msgid "Mail" +msgstr "Mail" + +#. module: muk_web_utils +#: model_terms:ir.ui.view,arch_db:muk_web_utils.res_config_settings_view_form +msgid "Maximum allowed file size in MB" +msgstr "Maximal zulässige Dateigröße in MB" + +#. module: muk_web_utils +#: model:ir.model.fields,help:muk_web_utils.field_res_config_settings__binary_max_size +msgid "Maximum allowed file size in megabytes. Note that this setting only adjusts\n" +" the binary widgets accordingly. The maximum file size on your server can probably\n" +" be restricted in several places. Note that a large file size limit and therefore\n" +" large files in your system can significantly limit performance." +msgstr "" +"Maximal zulässige Dateigröße in Megabyte. Beachten Sie, dass diese " +"Einstellung nur angepasst wird._x000D_\n" +" die binären Widgets entsprechend. Die maximale Dateigröße auf " +"Ihrem Server kann wahrscheinlich_x000D_\n" +" an mehreren Stellen eingeschränkt sein. Beachten Sie, dass eine " +"große Dateigröße und damit eine große Dateigröße begrenzt ist._x000D_\n" +" können große Dateien in Ihrem System die Leistung erheblich " +"einschränken." + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:38 +#, python-format +msgid "Message" +msgstr "Nachricht" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/module.js:59 +#: code:addons/muk_web_utils/static/src/xml/module.xml:26 +#, python-format +msgid "Missing Module" +msgstr "Fehlende Module" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:42 +#, python-format +msgid "Note" +msgstr "Hinweis" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:83 +#, python-format +msgid "Open" +msgstr "Offen" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/dialog.js:45 +#, python-format +msgid "Save" +msgstr "Speichern" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:52 +#, python-format +msgid "Send" +msgstr "Senden" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:27 +#, python-format +msgid "Share" +msgstr "Teilen" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/module.js:74 +#, python-format +msgid "Store" +msgstr "Laden" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/copy.js:35 +#, python-format +msgid "The field '%s' must be a binary field with an set attachment flag for the share widget to work." +msgstr "" +"Das Feld'%s' muss ein Binärfeld mit einem gesetzten Attachment-Flag sein, " +"damit das Share-Widget funktioniert." + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/module.xml:29 +#, python-format +msgid "The module could not be found on the server." +msgstr "Das Modul konnte auf dem Server nicht gefunden werden." + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/async.js:46 +#, python-format +msgid "Upload" +msgstr "Hochladen" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/async.js:47 +#, python-format +msgid "Uploading..." +msgstr "Hochladen....." + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:95 +#, python-format +msgid "shared a file with you!" +msgstr "hat eine Datei mit dir geteilt!" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:81 +#, python-format +msgid "shared a link with you!" +msgstr "einen Link mit dir geteilt!" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:87 +#, python-format +msgid "shared a message with you!" +msgstr "hat eine Nachricht mit dir geteilt!" diff --git a/muk_web_utils/i18n/es.po b/muk_web_utils/i18n/es.po new file mode 100644 index 0000000..72ab6d3 --- /dev/null +++ b/muk_web_utils/i18n/es.po @@ -0,0 +1,326 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * muk_web_utils +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0-20190128\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-02-27 09:28+0000\n" +"PO-Revision-Date: 2019-02-27 09:28+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/color.js:113 +#, python-format +msgid "'%s' is not a correct color index (0-12)" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/color.js:68 +#, python-format +msgid "'%s' is not a correct color value" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/share.js:175 +#, python-format +msgid "<%= name %> shared a file!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/share.js:115 +#: code:addons/muk_web_utils/static/src/js/fields/share.js:144 +#, python-format +msgid "<%= name %> shared a message!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/share.js:116 +#: code:addons/muk_web_utils/static/src/js/fields/share.js:145 +#: code:addons/muk_web_utils/static/src/js/fields/share.js:176 +#, python-format +msgid "<%= value %>" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/dialog.js:51 +#: code:addons/muk_web_utils/static/src/js/fields/module.js:50 +#, python-format +msgid "Cancel" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/module.xml:30 +#, python-format +msgid "Click on the download button to be redirected to the store and download the corresponding module." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:46 +#, python-format +msgid "Color 0" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:47 +#, python-format +msgid "Color 1" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:56 +#, python-format +msgid "Color 10" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:57 +#, python-format +msgid "Color 11" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:48 +#, python-format +msgid "Color 2" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:49 +#, python-format +msgid "Color 3" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:50 +#, python-format +msgid "Color 4" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:51 +#, python-format +msgid "Color 5" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:52 +#, python-format +msgid "Color 6" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:53 +#, python-format +msgid "Color 7" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:54 +#, python-format +msgid "Color 8" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:55 +#, python-format +msgid "Color 9" +msgstr "" + +#. module: muk_web_utils +#: model:ir.model,name:muk_web_utils.model_res_config_settings +msgid "Config Settings" +msgstr "Opciones de Configuración" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/module.js:45 +#: code:addons/muk_web_utils/static/src/xml/share.xml:97 +#, python-format +msgid "Download" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/dropzone.js:108 +#, python-format +msgid "Drop files here to upload!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:45 +#, python-format +msgid "External" +msgstr "" + +#. module: muk_web_utils +#: model:ir.model.fields,field_description:muk_web_utils.field_res_config_settings__binary_max_size +msgid "File Size Limit" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:35 +#, python-format +msgid "Internal" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/copy.js:107 +#, python-format +msgid "Link Copied!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:48 +#, python-format +msgid "Mail" +msgstr "" + +#. module: muk_web_utils +#: model_terms:ir.ui.view,arch_db:muk_web_utils.res_config_settings_view_form +msgid "Maximum allowed file size in MB" +msgstr "" + +#. module: muk_web_utils +#: model:ir.model.fields,help:muk_web_utils.field_res_config_settings__binary_max_size +msgid "Maximum allowed file size in megabytes. Note that this setting only adjusts\n" +" the binary widgets accordingly. The maximum file size on your server can probably\n" +" be restricted in several places. Note that a large file size limit and therefore\n" +" large files in your system can significantly limit performance." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:38 +#, python-format +msgid "Message" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/module.js:59 +#: code:addons/muk_web_utils/static/src/xml/module.xml:26 +#, python-format +msgid "Missing Module" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:42 +#, python-format +msgid "Note" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:83 +#, python-format +msgid "Open" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/dialog.js:45 +#, python-format +msgid "Save" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:52 +#, python-format +msgid "Send" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:27 +#, python-format +msgid "Share" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/module.js:74 +#, python-format +msgid "Store" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/copy.js:35 +#, python-format +msgid "The field '%s' must be a binary field with an set attachment flag for the share widget to work." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/module.xml:29 +#, python-format +msgid "The module could not be found on the server." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/async.js:46 +#, python-format +msgid "Upload" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/async.js:47 +#, python-format +msgid "Uploading..." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:95 +#, python-format +msgid "shared a file with you!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:81 +#, python-format +msgid "shared a link with you!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:87 +#, python-format +msgid "shared a message with you!" +msgstr "" + diff --git a/muk_web_utils/i18n/fr.po b/muk_web_utils/i18n/fr.po new file mode 100644 index 0000000..d00b7e5 --- /dev/null +++ b/muk_web_utils/i18n/fr.po @@ -0,0 +1,326 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * muk_web_utils +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0-20190128\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-02-27 09:28+0000\n" +"PO-Revision-Date: 2019-02-27 09:28+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/color.js:113 +#, python-format +msgid "'%s' is not a correct color index (0-12)" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/color.js:68 +#, python-format +msgid "'%s' is not a correct color value" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/share.js:175 +#, python-format +msgid "<%= name %> shared a file!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/share.js:115 +#: code:addons/muk_web_utils/static/src/js/fields/share.js:144 +#, python-format +msgid "<%= name %> shared a message!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/share.js:116 +#: code:addons/muk_web_utils/static/src/js/fields/share.js:145 +#: code:addons/muk_web_utils/static/src/js/fields/share.js:176 +#, python-format +msgid "<%= value %>" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/dialog.js:51 +#: code:addons/muk_web_utils/static/src/js/fields/module.js:50 +#, python-format +msgid "Cancel" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/module.xml:30 +#, python-format +msgid "Click on the download button to be redirected to the store and download the corresponding module." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:46 +#, python-format +msgid "Color 0" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:47 +#, python-format +msgid "Color 1" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:56 +#, python-format +msgid "Color 10" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:57 +#, python-format +msgid "Color 11" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:48 +#, python-format +msgid "Color 2" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:49 +#, python-format +msgid "Color 3" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:50 +#, python-format +msgid "Color 4" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:51 +#, python-format +msgid "Color 5" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:52 +#, python-format +msgid "Color 6" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:53 +#, python-format +msgid "Color 7" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:54 +#, python-format +msgid "Color 8" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:55 +#, python-format +msgid "Color 9" +msgstr "" + +#. module: muk_web_utils +#: model:ir.model,name:muk_web_utils.model_res_config_settings +msgid "Config Settings" +msgstr "Paramètres de config" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/module.js:45 +#: code:addons/muk_web_utils/static/src/xml/share.xml:97 +#, python-format +msgid "Download" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/dropzone.js:108 +#, python-format +msgid "Drop files here to upload!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:45 +#, python-format +msgid "External" +msgstr "" + +#. module: muk_web_utils +#: model:ir.model.fields,field_description:muk_web_utils.field_res_config_settings__binary_max_size +msgid "File Size Limit" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:35 +#, python-format +msgid "Internal" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/copy.js:107 +#, python-format +msgid "Link Copied!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:48 +#, python-format +msgid "Mail" +msgstr "" + +#. module: muk_web_utils +#: model_terms:ir.ui.view,arch_db:muk_web_utils.res_config_settings_view_form +msgid "Maximum allowed file size in MB" +msgstr "" + +#. module: muk_web_utils +#: model:ir.model.fields,help:muk_web_utils.field_res_config_settings__binary_max_size +msgid "Maximum allowed file size in megabytes. Note that this setting only adjusts\n" +" the binary widgets accordingly. The maximum file size on your server can probably\n" +" be restricted in several places. Note that a large file size limit and therefore\n" +" large files in your system can significantly limit performance." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:38 +#, python-format +msgid "Message" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/module.js:59 +#: code:addons/muk_web_utils/static/src/xml/module.xml:26 +#, python-format +msgid "Missing Module" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:42 +#, python-format +msgid "Note" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:83 +#, python-format +msgid "Open" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/dialog.js:45 +#, python-format +msgid "Save" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:52 +#, python-format +msgid "Send" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:27 +#, python-format +msgid "Share" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/module.js:74 +#, python-format +msgid "Store" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/copy.js:35 +#, python-format +msgid "The field '%s' must be a binary field with an set attachment flag for the share widget to work." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/module.xml:29 +#, python-format +msgid "The module could not be found on the server." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/async.js:46 +#, python-format +msgid "Upload" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/async.js:47 +#, python-format +msgid "Uploading..." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:95 +#, python-format +msgid "shared a file with you!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:81 +#, python-format +msgid "shared a link with you!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:87 +#, python-format +msgid "shared a message with you!" +msgstr "" + diff --git a/muk_web_utils/i18n/muk_web_utils.pot b/muk_web_utils/i18n/muk_web_utils.pot new file mode 100644 index 0000000..cefad22 --- /dev/null +++ b/muk_web_utils/i18n/muk_web_utils.pot @@ -0,0 +1,326 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * muk_web_utils +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0-20190128\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-02-27 09:28+0000\n" +"PO-Revision-Date: 2019-02-27 09:28+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/color.js:113 +#, python-format +msgid "'%s' is not a correct color index (0-12)" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/color.js:68 +#, python-format +msgid "'%s' is not a correct color value" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/share.js:175 +#, python-format +msgid "<%= name %> shared a file!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/share.js:115 +#: code:addons/muk_web_utils/static/src/js/fields/share.js:144 +#, python-format +msgid "<%= name %> shared a message!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/share.js:116 +#: code:addons/muk_web_utils/static/src/js/fields/share.js:145 +#: code:addons/muk_web_utils/static/src/js/fields/share.js:176 +#, python-format +msgid "<%= value %>" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/dialog.js:51 +#: code:addons/muk_web_utils/static/src/js/fields/module.js:50 +#, python-format +msgid "Cancel" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/module.xml:30 +#, python-format +msgid "Click on the download button to be redirected to the store and download the corresponding module." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:46 +#, python-format +msgid "Color 0" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:47 +#, python-format +msgid "Color 1" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:56 +#, python-format +msgid "Color 10" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:57 +#, python-format +msgid "Color 11" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:48 +#, python-format +msgid "Color 2" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:49 +#, python-format +msgid "Color 3" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:50 +#, python-format +msgid "Color 4" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:51 +#, python-format +msgid "Color 5" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:52 +#, python-format +msgid "Color 6" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:53 +#, python-format +msgid "Color 7" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:54 +#, python-format +msgid "Color 8" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:55 +#, python-format +msgid "Color 9" +msgstr "" + +#. module: muk_web_utils +#: model:ir.model,name:muk_web_utils.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/module.js:45 +#: code:addons/muk_web_utils/static/src/xml/share.xml:97 +#, python-format +msgid "Download" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/dropzone.js:108 +#, python-format +msgid "Drop files here to upload!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:45 +#, python-format +msgid "External" +msgstr "" + +#. module: muk_web_utils +#: model:ir.model.fields,field_description:muk_web_utils.field_res_config_settings__binary_max_size +msgid "File Size Limit" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:35 +#, python-format +msgid "Internal" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/copy.js:107 +#, python-format +msgid "Link Copied!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:48 +#, python-format +msgid "Mail" +msgstr "" + +#. module: muk_web_utils +#: model_terms:ir.ui.view,arch_db:muk_web_utils.res_config_settings_view_form +msgid "Maximum allowed file size in MB" +msgstr "" + +#. module: muk_web_utils +#: model:ir.model.fields,help:muk_web_utils.field_res_config_settings__binary_max_size +msgid "Maximum allowed file size in megabytes. Note that this setting only adjusts\n" +" the binary widgets accordingly. The maximum file size on your server can probably\n" +" be restricted in several places. Note that a large file size limit and therefore\n" +" large files in your system can significantly limit performance." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:38 +#, python-format +msgid "Message" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/module.js:59 +#: code:addons/muk_web_utils/static/src/xml/module.xml:26 +#, python-format +msgid "Missing Module" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:42 +#, python-format +msgid "Note" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:83 +#, python-format +msgid "Open" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/dialog.js:45 +#, python-format +msgid "Save" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:52 +#, python-format +msgid "Send" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:27 +#, python-format +msgid "Share" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/module.js:74 +#, python-format +msgid "Store" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/copy.js:35 +#, python-format +msgid "The field '%s' must be a binary field with an set attachment flag for the share widget to work." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/module.xml:29 +#, python-format +msgid "The module could not be found on the server." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/async.js:46 +#, python-format +msgid "Upload" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/async.js:47 +#, python-format +msgid "Uploading..." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:95 +#, python-format +msgid "shared a file with you!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:81 +#, python-format +msgid "shared a link with you!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:87 +#, python-format +msgid "shared a message with you!" +msgstr "" + diff --git a/muk_web_utils/i18n/nl.po b/muk_web_utils/i18n/nl.po new file mode 100644 index 0000000..032b13b --- /dev/null +++ b/muk_web_utils/i18n/nl.po @@ -0,0 +1,326 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * muk_web_utils +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0-20190128\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-02-27 09:28+0000\n" +"PO-Revision-Date: 2019-02-27 09:28+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/color.js:113 +#, python-format +msgid "'%s' is not a correct color index (0-12)" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/color.js:68 +#, python-format +msgid "'%s' is not a correct color value" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/share.js:175 +#, python-format +msgid "<%= name %> shared a file!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/share.js:115 +#: code:addons/muk_web_utils/static/src/js/fields/share.js:144 +#, python-format +msgid "<%= name %> shared a message!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/share.js:116 +#: code:addons/muk_web_utils/static/src/js/fields/share.js:145 +#: code:addons/muk_web_utils/static/src/js/fields/share.js:176 +#, python-format +msgid "<%= value %>" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/dialog.js:51 +#: code:addons/muk_web_utils/static/src/js/fields/module.js:50 +#, python-format +msgid "Cancel" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/module.xml:30 +#, python-format +msgid "Click on the download button to be redirected to the store and download the corresponding module." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:46 +#, python-format +msgid "Color 0" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:47 +#, python-format +msgid "Color 1" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:56 +#, python-format +msgid "Color 10" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:57 +#, python-format +msgid "Color 11" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:48 +#, python-format +msgid "Color 2" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:49 +#, python-format +msgid "Color 3" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:50 +#, python-format +msgid "Color 4" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:51 +#, python-format +msgid "Color 5" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:52 +#, python-format +msgid "Color 6" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:53 +#, python-format +msgid "Color 7" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:54 +#, python-format +msgid "Color 8" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/color.xml:55 +#, python-format +msgid "Color 9" +msgstr "" + +#. module: muk_web_utils +#: model:ir.model,name:muk_web_utils.model_res_config_settings +msgid "Config Settings" +msgstr "Configuratie instellingen" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/module.js:45 +#: code:addons/muk_web_utils/static/src/xml/share.xml:97 +#, python-format +msgid "Download" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/dropzone.js:108 +#, python-format +msgid "Drop files here to upload!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:45 +#, python-format +msgid "External" +msgstr "" + +#. module: muk_web_utils +#: model:ir.model.fields,field_description:muk_web_utils.field_res_config_settings__binary_max_size +msgid "File Size Limit" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:35 +#, python-format +msgid "Internal" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/copy.js:107 +#, python-format +msgid "Link Copied!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:48 +#, python-format +msgid "Mail" +msgstr "" + +#. module: muk_web_utils +#: model_terms:ir.ui.view,arch_db:muk_web_utils.res_config_settings_view_form +msgid "Maximum allowed file size in MB" +msgstr "" + +#. module: muk_web_utils +#: model:ir.model.fields,help:muk_web_utils.field_res_config_settings__binary_max_size +msgid "Maximum allowed file size in megabytes. Note that this setting only adjusts\n" +" the binary widgets accordingly. The maximum file size on your server can probably\n" +" be restricted in several places. Note that a large file size limit and therefore\n" +" large files in your system can significantly limit performance." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:38 +#, python-format +msgid "Message" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/module.js:59 +#: code:addons/muk_web_utils/static/src/xml/module.xml:26 +#, python-format +msgid "Missing Module" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:42 +#, python-format +msgid "Note" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:83 +#, python-format +msgid "Open" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/dialog.js:45 +#, python-format +msgid "Save" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:52 +#, python-format +msgid "Send" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:27 +#, python-format +msgid "Share" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/module.js:74 +#, python-format +msgid "Store" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/fields/copy.js:35 +#, python-format +msgid "The field '%s' must be a binary field with an set attachment flag for the share widget to work." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/module.xml:29 +#, python-format +msgid "The module could not be found on the server." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/async.js:46 +#, python-format +msgid "Upload" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/js/core/async.js:47 +#, python-format +msgid "Uploading..." +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:95 +#, python-format +msgid "shared a file with you!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:81 +#, python-format +msgid "shared a link with you!" +msgstr "" + +#. module: muk_web_utils +#. openerp-web +#: code:addons/muk_web_utils/static/src/xml/share.xml:87 +#, python-format +msgid "shared a message with you!" +msgstr "" + diff --git a/muk_web_utils/models/__init__.py b/muk_web_utils/models/__init__.py new file mode 100644 index 0000000..b692fb1 --- /dev/null +++ b/muk_web_utils/models/__init__.py @@ -0,0 +1,25 @@ +################################################################################### +# +# Copyright (c) 2017-2019 MuK IT GmbH. +# +# This file is part of MuK Web Utils +# (see https://mukit.at). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +################################################################################### + +from . import ir_attachment +from . import res_config_settings + diff --git a/muk_web_utils/models/ir_attachment.py b/muk_web_utils/models/ir_attachment.py new file mode 100644 index 0000000..bb5d745 --- /dev/null +++ b/muk_web_utils/models/ir_attachment.py @@ -0,0 +1,46 @@ +################################################################################### +# +# Copyright (c) 2017-2019 MuK IT GmbH. +# +# This file is part of MuK Web Utils +# (see https://mukit.at). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +################################################################################### + +import base64 +import logging +import mimetypes + +from odoo import api, models, fields, _ +from odoo.exceptions import AccessError +from odoo.tools.mimetypes import guess_mimetype + +_logger = logging.getLogger(__name__) + +class IrAttachment(models.Model): + + _inherit = 'ir.attachment' + + #---------------------------------------------------------- + # Database + #---------------------------------------------------------- + + temporary = fields.Boolean( + string="Temporary", + default=False, + help="Attachments will be deleted by Autovacuum.", + ) + \ No newline at end of file diff --git a/muk_web_utils/models/res_config_settings.py b/muk_web_utils/models/res_config_settings.py new file mode 100644 index 0000000..fc1da59 --- /dev/null +++ b/muk_web_utils/models/res_config_settings.py @@ -0,0 +1,79 @@ +################################################################################### +# +# Copyright (c) 2017-2019 MuK IT GmbH. +# +# This file is part of MuK Web Utils +# (see https://mukit.at). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +################################################################################### + +import re +import json +import logging + +from lxml import etree + +from odoo import api, fields, models + +_logger = logging.getLogger(__name__) + +class ResConfigSettings(models.TransientModel): + + _inherit = 'res.config.settings' + + #---------------------------------------------------------- + # Database + #---------------------------------------------------------- + + binary_max_size = fields.Integer( + string='File Size Limit', + required=True, + default=25, + help="""Maximum allowed file size in megabytes. Note that this setting only adjusts + the binary widgets accordingly. The maximum file size on your server can probably + be restricted in several places. Note that a large file size limit and therefore + large files in your system can significantly limit performance.""") + + #---------------------------------------------------------- + # Functions + #---------------------------------------------------------- + + def set_values(self): + res = super(ResConfigSettings, self).set_values() + param = self.env['ir.config_parameter'].with_user(self.env.ref('base.user_admin')) + param.set_param('muk_web_utils.binary_max_size', self.binary_max_size) + return res + + @api.model + def get_values(self): + res = super(ResConfigSettings, self).get_values() + params = self.env['ir.config_parameter'].with_user(self.env.ref('base.user_admin')) + res.update(binary_max_size=int(params.get_param('muk_web_utils.binary_max_size', 25))) + return res + + @api.model + def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False): + ret_val = super(ResConfigSettings, self).fields_view_get( + view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu) + modules = self.env['ir.module.module'].with_user(self.env.ref('base.user_admin')).search([]).mapped('name') + document = etree.XML(ret_val['arch']) + for field in ret_val['fields']: + if field.startswith("module_") and field[len("module_"):] not in modules: + for node in document.xpath("//field[@name='%s']" % field): + if node.get("widget") != 'upgrade_boolean': + node.set("widget", "module_boolean") + ret_val['arch'] = etree.tostring(document, encoding='unicode') + return ret_val \ No newline at end of file diff --git a/muk_web_utils/static/description/banner.png b/muk_web_utils/static/description/banner.png new file mode 100644 index 0000000000000000000000000000000000000000..98df572acdafaa00de90b40ba1ff7a81c3f61042 GIT binary patch literal 46485 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%0DGtr~Th# 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%0DTc3q4=)>Iz;<6>6AOHOda>wBbkKe$aG^7% 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 rSQgc2)<0GWR;(2XeEmPZ)`(attCeN literal 0 HcmV?d00001 diff --git a/muk_web_utils/static/description/icon.png b/muk_web_utils/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..858ea62ff40d4e2e214e72ceb99fe9a2edfb5db9 GIT binary patch literal 15746 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 O2Fb}NOIN-#`uacn \ No newline at end of file diff --git a/muk_web_utils/static/description/index.html b/muk_web_utils/static/description/index.html new file mode 100644 index 0000000..2cccde3 --- /dev/null +++ b/muk_web_utils/static/description/index.html @@ -0,0 +1,124 @@ +
+
+

MuK Web Utils

+

Utility Features

+

MuK IT GmbH - + www.mukit.at

+
+
+ +
+
+
+

Overview

+

Technical module to provide some utility + features. The module is mainly used as a dependency by other modules + and to provide a collection of common libraries. It has no direct + visible effect on the system.

+
+
+
+ +
+ +
+ +
+
+
+ + +
+
+
+ +
+

Help and Support

+
Feel free to + contact us, if you need any help with your Odoo integration or + addiontal features.
+ + +
\ No newline at end of file diff --git a/muk_web_utils/static/description/logo.png b/muk_web_utils/static/description/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9427ce33ea36c2ec961356d01d612bae02d48ce2 GIT binary patch literal 38064 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 literal 0 HcmV?d00001 diff --git a/muk_web_utils/static/description/preview.png b/muk_web_utils/static/description/preview.png new file mode 100644 index 0000000000000000000000000000000000000000..1deb1cceffc3f73a70dca6d35f1f7868d1507dcc GIT binary patch literal 33203 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 literal 0 HcmV?d00001 diff --git a/muk_web_utils/static/description/service_customization.png b/muk_web_utils/static/description/service_customization.png new file mode 100644 index 0000000000000000000000000000000000000000..3eac66488b63820f69634bfab8d45b94039651c3 GIT binary patch literal 27452 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 literal 0 HcmV?d00001 diff --git a/muk_web_utils/static/description/service_implementation.png b/muk_web_utils/static/description/service_implementation.png new file mode 100644 index 0000000000000000000000000000000000000000..d64b66bda3e4827e7cfba4ec4e5ed8414c4381ad GIT binary patch literal 26148 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 Hu0mjfz33;t literal 0 HcmV?d00001 diff --git a/muk_web_utils/static/description/service_integration.png b/muk_web_utils/static/description/service_integration.png new file mode 100644 index 0000000000000000000000000000000000000000..76c5e80f4798a3a9c9154dc00283dcb4eaa47f5b GIT binary patch literal 24862 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
'; + var scrollbarDummyEl = dummyDiv.firstElementChild; + document.body.appendChild(scrollbarDummyEl); + var dummyContainerChild = scrollbarDummyEl.firstElementChild; + scrollbarDummyEl.scrollLeft = 0; + var dummyContainerOffset = SimpleBar.getOffset(scrollbarDummyEl); + var dummyContainerChildOffset = SimpleBar.getOffset(dummyContainerChild); + scrollbarDummyEl.scrollLeft = 999; + var dummyContainerScrollOffsetAfterScroll = SimpleBar.getOffset(dummyContainerChild); + return { + // determines if the scrolling is responding with negative values + isRtlScrollingInverted: dummyContainerOffset.left !== dummyContainerChildOffset.left && dummyContainerChildOffset.left - dummyContainerScrollOffsetAfterScroll.left !== 0, + // determines if the origin scrollbar position is inverted or not (positioned on left or right) + isRtlScrollbarInverted: dummyContainerOffset.left !== dummyContainerChildOffset.left + }; + } + }, { + key: "initHtmlApi", + value: function initHtmlApi() { + this.initDOMLoadedElements = this.initDOMLoadedElements.bind(this); // MutationObserver is IE11+ + + if (typeof MutationObserver !== 'undefined') { + // Mutation observer to observe dynamically added elements + this.globalObserver = new MutationObserver(function (mutations) { + mutations.forEach(function (mutation) { + Array.from(mutation.addedNodes).forEach(function (addedNode) { + if (addedNode.nodeType === 1) { + if (addedNode.hasAttribute('data-simplebar')) { + !addedNode.SimpleBar && new SimpleBar(addedNode, SimpleBar.getElOptions(addedNode)); + } else { + Array.from(addedNode.querySelectorAll('[data-simplebar]')).forEach(function (el) { + !el.SimpleBar && new SimpleBar(el, SimpleBar.getElOptions(el)); + }); + } + } + }); + Array.from(mutation.removedNodes).forEach(function (removedNode) { + if (removedNode.nodeType === 1) { + if (removedNode.hasAttribute('data-simplebar')) { + removedNode.SimpleBar && removedNode.SimpleBar.unMount(); + } else { + Array.from(removedNode.querySelectorAll('[data-simplebar]')).forEach(function (el) { + el.SimpleBar && el.SimpleBar.unMount(); + }); + } + } + }); + }); + }); + this.globalObserver.observe(document, { + childList: true, + subtree: true + }); + } // Taken from jQuery `ready` function + // Instantiate elements already present on the page + + + if (document.readyState === 'complete' || document.readyState !== 'loading' && !document.documentElement.doScroll) { + // Handle it asynchronously to allow scripts the opportunity to delay init + window.setTimeout(this.initDOMLoadedElements); + } else { + document.addEventListener('DOMContentLoaded', this.initDOMLoadedElements); + window.addEventListener('load', this.initDOMLoadedElements); + } + } // Helper function to retrieve options from element attributes + + }, { + key: "getElOptions", + value: function getElOptions(el) { + var options = Array.from(el.attributes).reduce(function (acc, attribute) { + var option = attribute.name.match(/data-simplebar-(.+)/); + + if (option) { + var key = option[1].replace(/\W+(.)/g, function (x, chr) { + return chr.toUpperCase(); + }); + + switch (attribute.value) { + case 'true': + acc[key] = true; + break; + + case 'false': + acc[key] = false; + break; + + case undefined: + acc[key] = true; + break; + + default: + acc[key] = attribute.value; + } + } + + return acc; + }, {}); + return options; + } + }, { + key: "removeObserver", + value: function removeObserver() { + this.globalObserver.disconnect(); + } + }, { + key: "initDOMLoadedElements", + value: function initDOMLoadedElements() { + document.removeEventListener('DOMContentLoaded', this.initDOMLoadedElements); + window.removeEventListener('load', this.initDOMLoadedElements); + Array.from(document.querySelectorAll('[data-simplebar]')).forEach(function (el) { + if (!el.SimpleBar) new SimpleBar(el, SimpleBar.getElOptions(el)); + }); + } + }, { + key: "getOffset", + value: function getOffset(el) { + var rect = el.getBoundingClientRect(); + return { + top: rect.top + (window.pageYOffset || document.documentElement.scrollTop), + left: rect.left + (window.pageXOffset || document.documentElement.scrollLeft) + }; + } + }]); + + return SimpleBar; + }(); + /** + * HTML API + * Called only in a browser env. + */ + + + SimpleBar.defaultOptions = { + autoHide: true, + forceVisible: false, + classNames: { + content: 'simplebar-content', + offset: 'simplebar-offset', + placeholder: 'simplebar-placeholder', + scrollbar: 'simplebar-scrollbar', + track: 'simplebar-track', + heightAutoObserverWrapperEl: 'simplebar-height-auto-observer-wrapper', + heightAutoObserverEl: 'simplebar-height-auto-observer', + visible: 'simplebar-visible', + horizontal: 'simplebar-horizontal', + vertical: 'simplebar-vertical', + hover: 'simplebar-hover' + }, + scrollbarMinSize: 25, + scrollbarMaxSize: 0, + timeout: 1000 + }; + + if (canUseDom) { + SimpleBar.initHtmlApi(); + } + + return SimpleBar; + +})); \ No newline at end of file diff --git a/muk_web_utils/static/src/img/module.png b/muk_web_utils/static/src/img/module.png new file mode 100644 index 0000000000000000000000000000000000000000..74ca4c7e2846629e520458daa42e4049c40ae41a GIT binary patch literal 4921 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. +* +**********************************************************************************/ + +odoo.define('muk_web_utils.async', function (require) { +"use strict"; + +var core = require('web.core'); + +var _t = core._t; +var QWeb = core.qweb; + +var syncLoop = function(items, func, callback) { + items.reduce(function(promise, item) { + return promise.then(func.bind(this, item)); + }, $.Deferred().resolve()).then(callback); +}; + +var syncProgress = function(items, func, callback, update) { + var progress = 0; + items.reduce(function(promise, item) { + return promise.then(function() { + update(++progress / items.length); + return func(item); + }); + }, $.Deferred().resolve()).then(callback); +}; + +var createNotification = function(widget, title) { + return widget.call('notification', 'notify', { + title: title || _t('Upload'), + message: _t('Uploading...'), + icon: 'fa-upload', + sticky: true, + progress: { + text: "0%", + state: 0.0, + }, + }); +}; + +var updateNotification = function(widget, notification, progress) { + widget.call('notification', 'progress', notification, { + text: (progress * 100).toFixed(2) + "%", + state: (progress * 100).toFixed(2), + }); +}; + +var closeNotification = function(widget, notification) { + widget.call('notification', 'close', notification); +}; + +var syncNotification = function(widget, title, items, func, callback) { + var notification = createNotification(widget, title); + var update = _.partial(updateNotification, widget, notification); + syncProgress(items, func, function() { + Promise.resolve(closeNotification(widget, notification)).then(callback); + }, update); +}; + +return { + syncLoop: syncLoop, + syncProgress: syncProgress, + syncNotification: syncNotification, +}; + +}); \ No newline at end of file diff --git a/muk_web_utils/static/src/js/core/dialog.js b/muk_web_utils/static/src/js/core/dialog.js new file mode 100644 index 0000000..efbb02a --- /dev/null +++ b/muk_web_utils/static/src/js/core/dialog.js @@ -0,0 +1,68 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +odoo.define('muk_web_utils.Dialog', function (require) { +"use strict"; + +var core = require('web.core'); + +var Dialog = require('web.Dialog'); + +var QWeb = core.qweb; +var _t = core._t; + +Dialog.input = function (owner, title, options) { + var $content = $('
'); + var $input = $('', { + type: 'text', + class: options && options.input && options.input.class, + value: options && options.input && options.input.value, + }); + $content.append($input); + var confirm = function(event) { + if(options && options.confirm_callback) { + options.confirm_callback.call(self, event, $input.val()); + } + } + var buttons = [ + { + text: _t("Save"), + classes: 'btn-primary', + close: true, + click: confirm, + }, + { + text: _t("Cancel"), + close: true, + click: options && options.cancel_callback + } + ]; + return new Dialog(owner, _.extend({ + size: 'medium', + buttons: buttons, + $content: $content, + title: title, + }, options)).open({shouldFocusButtons:true}); +}; + + +}); diff --git a/muk_web_utils/static/src/js/core/dropzone.js b/muk_web_utils/static/src/js/core/dropzone.js new file mode 100644 index 0000000..8c12fce --- /dev/null +++ b/muk_web_utils/static/src/js/core/dropzone.js @@ -0,0 +1,132 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +odoo.define('muk_web_utils.dropzone', function (require) { +"use strict"; + +var core = require('web.core'); + +var _t = core._t; +var QWeb = core.qweb; + +var DropzoneMixin = { + dropzoneData: {}, + dropzoneClasses: ['mk_dropzone'], + _checkDropzoneEvent: function(event) { + return true; + }, + _startDropzone: function($dropzone) { + if(this.$dropzone) { + this._destroyDropzone(); + } + this.$dropzone = $dropzone; + this.$dropzone.dndHover().on({ + 'dndHoverStart.dropzone': this._hoverDropzoneEnter.bind(this), + 'dndHoverEnd.dropzone': this._hoverDropzoneLeave.bind(this), + }); + this.$dropzone.on('dragenter.dropzone', this._dragenterDropzone.bind(this)); + this.$dropzone.on('dragover.dropzone', this._dragoverDropzone.bind(this)); + this.$dropzone.on('dragleave.dropzone', this._dragleaveDropzone.bind(this)); + this.$dropzone.on('drop.dropzone', this._dropDropzone.bind(this)); + _.each(this.dropzoneData, function(value, key) { + this.$dropzone.attr(key, value) + }, this); + }, + _destroyDropzone: function() { + if(this.$dropzone) { + this.$dropzone.off('.dropzone'); + this.$dropzone.dndHover('destroy'); + _.each(this.dropzoneData, function(value, key) { + this.$dropzone.removeAttr(key) + }, this); + this.$dropzone = false; + } + }, + _toggleDropzone: function(state) { + this.$dropzone.toggleClass(this.dropzoneClasses.join(" "), state); + }, + _hoverDropzoneEnter: function(event, originalEvent) { + if(this._checkDropzoneEvent(originalEvent)) { + this._toggleDropzone(true); + event.preventDefault(); + return false; + } + }, + _hoverDropzoneLeave: function(event, originalEvent) { + this._toggleDropzone(false); + event.stopPropagation(); + event.preventDefault(); + return false; + }, + _handleDrag: function(event) { + }, + _handleDrop: function(event) { + }, + _dragenterDropzone: function(event) { + if(this._checkDropzoneEvent(event)) { + event.preventDefault(); + } + }, + _dragoverDropzone: function(event) { + if(this._checkDropzoneEvent(event)) { + event.preventDefault(); + this._handleDrag(event); + } + }, + _dragleaveDropzone: function(event) { + if(this._checkDropzoneEvent(event)) { + event.preventDefault(); + } + }, + _dropDropzone: function(event) { + if(this._checkDropzoneEvent(event)) { + event.preventDefault(); +// event.stopPropagation(); + this._handleDrop(event); + } + } +}; + +var FileDropzoneMixin = _.extend({}, DropzoneMixin, { + dropzoneData: { + 'data-dropzone-text': _t("Drop files here to upload!"), + }, + dropzoneClasses: DropzoneMixin.dropzoneClasses.concat(['mk_dropzone_file']), + dropzoneCheck: window.File && window.FileReader && window.FileList && window.Blob, + _checkDropzoneEvent: function(event) { + var dataTransfer = event.originalEvent && event.originalEvent.dataTransfer; + var fileCheck = dataTransfer && _.some(dataTransfer.types, function(type) { + return type == "Files"; + }); + return this.dropzoneCheck && fileCheck; + }, + _handleDrag: function(event) { + event.originalEvent.dataTransfer.dropEffect = 'copy'; + }, +}); + +return { + DropzoneMixin: DropzoneMixin, + FileDropzoneMixin: FileDropzoneMixin, +}; + +}); \ No newline at end of file diff --git a/muk_web_utils/static/src/js/core/files.js b/muk_web_utils/static/src/js/core/files.js new file mode 100644 index 0000000..8839ab0 --- /dev/null +++ b/muk_web_utils/static/src/js/core/files.js @@ -0,0 +1,176 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +odoo.define('muk_web_utils.files', function (require) { +"use strict"; + +var core = require('web.core'); + +var QWeb = core.qweb; +var _t = core._t; + +var traverseItems = function(items, tree) { + var def = $.Deferred(); + var files = []; + var defs = []; + _.each(items, function(item, index) { + var entry = item.webkitGetAsEntry(); + if(entry) { + var traverse = $.Deferred(); + traverseEntry(entry, tree).then(function(result) { + if(tree) { + files = files.concat(result); + } else { + files = _.union(files, result); + } + traverse.resolve(); + }); + defs.push(traverse); + } else { + var file = item.getAsFile(); + if(file) { + if(file.size) { + files.push(_.extend({}, file, {isFileItem: true})); + } + } else { + console.warn("Your browser doesn't support Drag and Drop!"); + } + } + }); + Promise.resolve().apply($, defs).then(function () { + def.resolve(files); + }); + return def; +}; + +var traverseEntries = function(entries, tree) { + var def = $.Deferred(); + var files = []; + var defs = []; + _.each(entries, function(entry, index) { + var traverse = $.Deferred(); + traverseEntry(entry, tree).then(function(result) { + if(tree) { + files = files.concat(result); + } else { + files = _.union(files, result); + } + traverse.resolve(); + }); + defs.push(traverse); + }); + Promise.resolve().apply($, defs).then(function () { + def.resolve(files); + }); + return def; +} + +var traverseEntry = function(entry, tree) { + var def = $.Deferred(); + if(entry.isFile) { + def.resolve([entry]); + } else if(entry.isDirectory) { + entry.createReader().readEntries(function (entries) { + traverseEntries(entries, tree).then(function (files) { + if(tree) { + def.resolve([{ + name: entry.name, + files: files, + isFile: false, + isDirectory: true, + childCount: files.length, + fullPath: entry.fullPath, + fileCount: _.reduce(files, function(sum, item) { + return item.isFile ? sum + 1 : sum + item.fileCount || 0; + }, 0), + }]); + } else { + def.resolve(files); + } + }); + }); + } else { + def.resolve([]); + } + return def; +}; + +var getFileTree = function(items, count) { + var traverse = traverseItems(items, true); + if(count) { + var def = $.Deferred(); + traverse.then(function(files) { + def.resolve({ + files: files, + count: _.reduce(files, function(sum, item) { + return item.isFile ? sum + 1 : sum + item.fileCount || 0; + }, 0), + }); + }); + return def; + } + return traverse; +}; + +var getFileList = function(items, count) { + var traverse = traverseItems(items, false); + if(count) { + var def = $.Deferred(); + traverse.then(function(files) { + def.resolve({ + files: files, + count: files.length, + }); + + }); + return def; + } + return traverse; +}; + +var loadFile = function(file, callback) { + var fileReader = new FileReader(); + fileReader.readAsDataURL(file); + fileReader.onloadend = callback; +}; + +var readFile = function(file, callback) { + if(file.isFile) { + file.file(function(file) { + loadFile(file, callback); + }); + } else { + loadFile(file, callback); + } +}; + +return { + traverseItems: traverseItems, + traverseEntries: traverseEntries, + traverseEntry: traverseEntry, + getFileTree: getFileTree, + getFileList: getFileList, + loadFile: loadFile, + readFile: readFile, +}; + +}); diff --git a/muk_web_utils/static/src/js/core/mimetype.js b/muk_web_utils/static/src/js/core/mimetype.js new file mode 100644 index 0000000..e874d30 --- /dev/null +++ b/muk_web_utils/static/src/js/core/mimetype.js @@ -0,0 +1,110 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +odoo.define('muk_web_utils.mimetype', function (require) { +"use strict"; + +var core = require('web.core'); +var utils = require('web.utils'); + +var QWeb = core.qweb; +var _t = core._t; + +var mapping = [ + ['file-image-o', /^image\//], + ['file-audio-o', /^audio\//], + ['file-video-o', /^video\//], + ['file-pdf-o', 'application/pdf'], + ['file-text-o', 'text/plain'], + ['file-code-o', [ + 'text/html', + 'text/javascript', + 'application/javascript' + ]], + ['file-archive-o', [ + /^application\/x-(g?tar|xz|compress|bzip2|g?zip)$/, + /^application\/x-(7z|rar|zip)-compressed$/, + /^application\/(zip|gzip|tar)$/ + ]], + ['file-word-o', [ + /ms-?word/, 'application/vnd.oasis.opendocument.text', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' + ]], + ['file-powerpoint-o', [ + /ms-?powerpoint/, + 'application/vnd.openxmlformats-officedocument.presentationml.presentation' + ]], + ['file-excel-o', [ + /ms-?excel/, + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + ]], + ['file-o' ] +]; + +function match(mimetype, cond) { + if (Array.isArray(cond)) { + return cond.reduce(function(v, c) { + return v || match(mimetype, c); + }, false); + } else if (cond instanceof RegExp) { + return cond.test(mimetype); + } else if (cond === undefined) { + return true; + } else { + return mimetype === cond; + } +} + +var cache = {}; +function resolve(mimetype) { + if (cache[mimetype]) { + return cache[mimetype]; + } + for (var i = 0; i < mapping.length; i++) { + if (match(mimetype, mapping[i][1])) { + cache[mimetype] = mapping[i][0]; + return mapping[i][0]; + } + } +} + +function mimetype2fa(mimetype, options) { + if (typeof mimetype === 'object') { + options = mimetype; + return function(mimetype) { + return mimetype2fa(mimetype, options); + }; + } else { + var icon = resolve(mimetype); + if (icon && options && options.prefix) { + return options.prefix + icon; + } else { + return icon; + } + } +} + +return { + mimetype2fa: mimetype2fa, +}; + +}); \ No newline at end of file diff --git a/muk_web_utils/static/src/js/core/utils.js b/muk_web_utils/static/src/js/core/utils.js new file mode 100644 index 0000000..b0c9734 --- /dev/null +++ b/muk_web_utils/static/src/js/core/utils.js @@ -0,0 +1,85 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +odoo.define('muk_web_utils.utils', function (require) { +"use strict"; + +var core = require('web.core'); + +var _t = core._t; +var QWeb = core.qweb; + +var isUrl = function(string) { + var protocol = string.match(/^(?:\w+:)?\/\/(\S+)$/); + if (protocol && protocol[1]) { + var localHost = (/^localhost[\:?\d]*(?:[^\:?\d]\S*)?$/).test(protocol[1]); + var nonLocalHost = (/^localhost[\:?\d]*(?:[^\:?\d]\S*)?$/).test(protocol[1]); + return !!(localHost || nonLocalHost); + } + return false; +} + +var parseText2Html= function(text) { + return text + .replace(/((?:https?|ftp):\/\/[\S]+)/g,'$1 ') + .replace(/[\n\r]/g,'
'); +} + +var closedRange = function(start, end) { + return _.range(start, end + 1); +} + +var partitionPageList = function(pages, page, size) { + if (!size || size < 5) { + throw "The size must be at least 5 to partition the list."; + } + var sideSize = size < 9 ? 1 : 2; + var leftSize = (size - sideSize * 2 - 3) >> 1; + var rightSize = (size - sideSize * 2 - 2) >> 1; + if (pages <= size) { + return closedRange(1, pages); + } + if (page <= size - sideSize - 1 - rightSize) { + return closedRange(1, size - sideSize - 1) + .concat([false]) + .concat(closedRange(pages - sideSize + 1, pages)); + } + if (page >= pages - sideSize - 1 - rightSize) { + return closedRange(1, sideSize) + .concat([false]) + .concat(closedRange(pages - sideSize - 1 - rightSize - leftSize, pages)); + } + return closedRange(1, sideSize) + .concat([false]) + .concat(closedRange(page - leftSize, page + rightSize)) + .concat([false]) + .concat(closedRange(pages - sideSize + 1, pages)); +} + +return { + isUrl: isUrl, + closedRange: closedRange, + parseText2Html: parseText2Html, + partitionPageList: partitionPageList, +}; + +}); \ No newline at end of file diff --git a/muk_web_utils/static/src/js/fields/abstract.js b/muk_web_utils/static/src/js/fields/abstract.js new file mode 100644 index 0000000..39ac1bd --- /dev/null +++ b/muk_web_utils/static/src/js/fields/abstract.js @@ -0,0 +1,46 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +odoo.define('muk_web_utils.abstract', function(require) { +"use strict"; + +var core = require('web.core'); +var session = require('web.session'); +var utils = require('web.field_utils'); +var fields = require('web.basic_fields'); +var registry = require('web.field_registry'); + +var AbstractField = require('web.AbstractField'); + +var _t = core._t; +var QWeb = core.qweb; + +AbstractField.include({ + isFocusable: function () { + if(!!this.attrs.skip_focus){ + return false; + } + return this._super.apply(this, arguments); + }, +}); + +}); diff --git a/muk_web_utils/static/src/js/fields/binary.js b/muk_web_utils/static/src/js/fields/binary.js new file mode 100644 index 0000000..188587d --- /dev/null +++ b/muk_web_utils/static/src/js/fields/binary.js @@ -0,0 +1,86 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +odoo.define('muk_web_utils.binary', function(require) { +"use strict"; + +var core = require('web.core'); +var session = require('web.session'); +var utils = require('web.field_utils'); +var fields = require('web.basic_fields'); +var registry = require('web.field_registry'); + +var _t = core._t; +var QWeb = core.qweb; + +fields.FieldBinaryFile.extend({ + willStart: function () { + var def = this._rpc({ + route: '/config/muk_web_utils.binary_max_size', + }).then(function(result) { + this.max_upload_size = result.max_upload_size * 1024 * 1024; + }.bind(this)); + return this._super.apply(this, arguments); + }, + _renderReadonly: function () { + this._super.apply(this, arguments); + var $wrapper = $('
', { + class: "mk_field_binary_wrapper" + }); + $wrapper.addClass(this.$el.attr('class')); + this.$el.removeClass("o_field_widget"); + this.$el.removeClass("o_hidden"); + $wrapper.append(this.$el); + this.setElement($wrapper); + }, + _renderEdit: function () { + this._super.apply(this, arguments); + if (this.nodeOptions && this.nodeOptions.accept) { + this.$('input[name="ufile"]').prop("accept", this.nodeOptions.accept); + } + }, +}); + +var FieldBinarySize = fields.FieldFloat.extend({ + init: function(parent, name, record) { + this._super.apply(this, arguments); + this.nodeOptions = _.defaults(this.nodeOptions, { + si: true, + }); + }, + _formatValue: function (value) { + var options = _.extend({}, + this.nodeOptions, + { data: this.recordData }, + this.formatOptions + ); + return utils.format['binary_size'](value, this.field, options) + }, +}); + +registry.add('binary_size', FieldBinarySize); + +return { + FieldBinarySize: FieldBinarySize, +}; + +}); diff --git a/muk_web_utils/static/src/js/fields/color.js b/muk_web_utils/static/src/js/fields/color.js new file mode 100644 index 0000000..fad9160 --- /dev/null +++ b/muk_web_utils/static/src/js/fields/color.js @@ -0,0 +1,130 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +odoo.define('muk_web_utils.color', function (require) { +"use strict"; + +var core = require('web.core'); +var fields = require('web.basic_fields'); +var registry = require('web.field_registry'); +var colorpicker = require('web.colorpicker'); + +var AbstractField = require('web.AbstractField'); + +var _t = core._t; +var QWeb = core.qweb; + +var FieldColor = fields.InputField.extend({ + events: _.extend({}, fields.InputField.prototype.events, { + "click .mk_field_color_button": "_onCustomColorButtonClick", + }), + template: "muk_web_utils.FieldColor", + supportedFieldTypes: ['char'], + start: function() { + this.$input = this.$('.mk_field_color_input'); + return this._super.apply(this, arguments); + }, + _renderEdit: function () { + this.$('.mk_field_color_input').val( + this._formatValue(this.value) + ); + this.$('.mk_field_color_input').css({ + 'background-color': this._formatValue(this.value), + }); + }, + _renderReadonly: function () { + this.$el.text(this._formatValue(this.value)); + this.$el.css({'color': this._formatValue(this.value)}); + }, + _doAction: function() { + this._super.apply(this, arguments); + this.$('.mk_field_color_input').css({ + 'background-color': this._getValue(), + }); + }, + _formatValue: function (value) { + return value; + }, + _parseValue: function (value) { + if((/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i).test(value)) { + return value; + } else { + throw new Error(_.str.sprintf(_t("'%s' is not a correct color value"), value)); + } + }, + _onCustomColorButtonClick: function () { + var ColorpickerDialog = new colorpicker(this, { + dialogClass: 'mk_field_color_picker', + defaultColor: this._getValue(), + }); + ColorpickerDialog.on('colorpicker:saved', this, function (event) { + this.$input.val(event.data.hex); + this._doAction(); + }); + ColorpickerDialog.open(); + }, +}); + +var FieldColorIndex = AbstractField.extend({ + events: _.extend({}, AbstractField.prototype.events, { + 'change': '_onChange', + }), + template: 'muk_web_utils.FieldColorIndex', + supportedFieldTypes: ['integer'], + isSet: function () { + return this.value === 0 || this._super.apply(this, arguments); + }, + getFocusableElement: function () { + return this.$el.is('select') ? this.$el : $(); + }, + _renderEdit: function () { + this.$el.addClass('mk_color_index_' + this.value); + this.$('option[value="' + this.value + '"]').prop('selected', true); + }, + _renderReadonly: function () { + this.$el.addClass('mk_color_index_' + this.value); + this.$el.empty().text('Color ' + this._formatValue(this.value)); + }, + _onChange: function (event) { + this.$el.removeClass(function (index, className) { + return (className.match (/(^|\s)mk_color_index_\S+/g) || []).join(' '); + }); + this.$el.addClass('mk_color_index_' + this.$el.val()); + this._setValue(this.$el.val()); + }, + _parseValue: function (value) { + if(0 > value || value > 12) { + throw new Error(_.str.sprintf(_t("'%s' is not a correct color index (0-12)"), value)); + } + return value; + }, +}); + +registry.add('color_char', FieldColor); +registry.add('color_index', FieldColorIndex); + +return { + FieldColor: FieldColor, + FieldColorIndex: FieldColorIndex, +}; + +}); \ No newline at end of file diff --git a/muk_web_utils/static/src/js/fields/copy.js b/muk_web_utils/static/src/js/fields/copy.js new file mode 100644 index 0000000..07c5eef --- /dev/null +++ b/muk_web_utils/static/src/js/fields/copy.js @@ -0,0 +1,135 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +odoo.define('muk_web_utils.copy', function (require) { +"use strict"; + +var core = require('web.core'); +var session = require('web.session'); +var fields = require('web.basic_fields'); +var registry = require('web.field_registry'); + +var _t = core._t; +var QWeb = core.qweb; + +var BinaryFileCopy = fields.FieldBinaryFile.extend({ + init: function () { + this._super.apply(this, arguments); + if (!this.field.attachment) { + throw _.str.sprintf(_t( + "The field '%s' must be a binary field with an set " + + "attachment flag for the share widget to work." + ), this.field.string); + } + this.accessToken = !!this.nodeOptions.token; + }, + willStart: function() { + var def = this.value && this.res_id ? this._fetchShareUrl() : Promise.resolve(); + return Promise.resolve(this._super.apply(this, arguments), def); + }, + _fetchShareUrl: function() { + var self = this; + var def = $.Deferred(); + if (this.accessToken) { + this._rpc({ + model: 'ir.attachment', + method: 'search', + args: [[ + ['res_id', '=', this.res_id], + ['res_field', '=', this.name], + ['res_model', '=', this.model], + ]], + kwargs: { + context: session.user_context, + }, + }).then(function(attchments) { + self._rpc({ + model: 'ir.attachment', + method: 'generate_access_token', + args: attchments + }).then(function(access_token) { + self.shareUrl = session.url('/web/content', { + model: self.model, + field: self.name, + id: self.res_id, + access_token: access_token.shift(), + }); + def.resolve(); + }); + }); + } else { + this.shareUrl = session.url('/web/content', { + model: self.model, + field: self.name, + id: self.res_id, + }); + def.resolve(); + } + return def; + }, + _setUpClipboad: function() { + var self = this; + var $clipboardBtn = this.$('.mk_copy_binary'); + this.clipboard = new ClipboardJS($clipboardBtn[0], { + text: function (trigger) { + return self.shareUrl; + }, + container: self.$el[0] + }); + this.clipboard.on('success', function (event) { + _.defer(function () { + $clipboardBtn.tooltip('show'); + _.delay(function () { + $clipboardBtn.tooltip('hide'); + }, 800); + }); + }); + $clipboardBtn.click(function(event) { + event.stopPropagation(); + }); + $clipboardBtn.tooltip({ + title: _t('Link Copied!'), + trigger: 'manual', + placement: 'bottom' + }); + }, + _renderReadonly: function () { + this._super.apply(this, arguments); + this.$el.addClass('mk_field_copy'); + this.$el.append($(QWeb.render('muk_web_utils.BinaryFieldCopy'))); + this._setUpClipboad(); + }, + destroy: function () { + this._super.apply(this, arguments); + if (this.clipboard) { + this.clipboard.destroy(); + } + }, +}); + +registry.add('copy_binary', BinaryFileCopy); + +return { + BinaryFileCopy: BinaryFileCopy, +}; + +}); \ No newline at end of file diff --git a/muk_web_utils/static/src/js/fields/domain.js b/muk_web_utils/static/src/js/fields/domain.js new file mode 100644 index 0000000..4204f42 --- /dev/null +++ b/muk_web_utils/static/src/js/fields/domain.js @@ -0,0 +1,54 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +odoo.define('muk_web_utils.domain', function (require) { +"use strict"; + +var core = require('web.core'); +var session = require('web.session'); +var fields = require('web.basic_fields'); +var view_dialogs = require('web.view_dialogs'); + +var _t = core._t; +var QWeb = core.qweb; + +fields.FieldDomain.include({ + _onShowSelectionButtonClick: function (e) { + e.preventDefault(); + new view_dialogs.SelectCreateDialog(this, { + context: this.attrs.context || {}, + title: _t("Selected records"), + res_model: this._domainModel, + domain: this.value || "[]", + no_create: true, + readonly: true, + disable_multiple_selection: true, + }).open(); + }, + isValid: function () { + return ( + this._isValid && (!this.domainSelector || this.domainSelector.isValid()) + ); + }, +}); + +}); diff --git a/muk_web_utils/static/src/js/fields/image.js b/muk_web_utils/static/src/js/fields/image.js new file mode 100644 index 0000000..c8907e3 --- /dev/null +++ b/muk_web_utils/static/src/js/fields/image.js @@ -0,0 +1,58 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +odoo.define('muk_web_utils.image', function (require) { +"use strict"; + +var core = require('web.core'); +var session = require('web.session'); +var fields = require('web.basic_fields'); + +var _t = core._t; +var QWeb = core.qweb; + +fields.FieldBinaryImage.extend({ + willStart: function () { + var def = this._rpc({ + route: '/config/muk_web_utils.binary_max_size', + }).then(function(result) { + this.max_upload_size = result.max_upload_size * 1024 * 1024; + }.bind(this)); + return this._super.apply(this, arguments); + }, + _render: function () { + this._super.apply(this, arguments); + this.$('.mk_field_image_wrapper').remove(); + this.$('img').wrap($('
', { + class: "mk_field_image_wrapper" + })); + var $wrapper = $('.mk_field_image_wrapper'); + var width = this.nodeOptions.size ? + this.nodeOptions.size[0] : this.attrs.width; + var height = this.nodeOptions.size ? + this.nodeOptions.size[1] : this.attrs.height; + $wrapper.css('min-width', (width || 50) + 'px'); + $wrapper.css('min-height', (height || 50) + 'px'); + }, +}); + +}); diff --git a/muk_web_utils/static/src/js/fields/module.js b/muk_web_utils/static/src/js/fields/module.js new file mode 100644 index 0000000..59eaed9 --- /dev/null +++ b/muk_web_utils/static/src/js/fields/module.js @@ -0,0 +1,96 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +odoo.define('muk_web_utils.ModuleBoolean', function (require) { +"use strict"; + +var core = require('web.core'); +var fields = require('web.basic_fields'); +var registry = require('web.field_registry'); +var framework = require('web.framework'); + +var Dialog = require('web.Dialog'); +var AbstractField = require('web.AbstractField'); + +var _t = core._t; +var QWeb = core.qweb; + +var ModuleBoolean = fields.FieldBoolean.extend({ + supportedFieldTypes: [], + events: _.extend({}, AbstractField.prototype.events, { + 'click input': '_onInputClicked', + }), + renderWithLabel: function ($label) { + this.$label = $label; + this._render(); + }, + _openDialog: function () { + var buttons = [{ + text: _t("Download"), + classes: 'btn-primary', + close: true, + click: this._confirmRedirect.bind(this), + }, { + text: _t("Cancel"), + close: true, + }]; + return new Dialog(this, { + size: 'medium', + buttons: buttons, + $content: $('
', { + html: $(QWeb.render('muk_web_utils.MissingModuleDialog')), + }), + title: _t("Missing Module"), + }).open(); + }, + _confirmRedirect: function () { + if(this.nodeOptions.url) { + framework.redirect(this.nodeOptions.url); + } else { + var module = this.name.replace("module_", ""); + framework.redirect("https://apps.odoo.com/apps/modules/browse?search=" + module); + } + }, + _render: function () { + this._super.apply(this, arguments); + var $element = this.$label || this.$el; + $element.append(' ').append($("", { + 'text': _t("Store"), + 'class': "badge badge-primary oe_inline mk_module_label" + })); + }, + _onInputClicked: function (event) { + if ($(event.currentTarget).prop("checked")) { + var dialog = this._openDialog(); + dialog.on('closed', this, this._resetValue.bind(this)); + } + }, + _resetValue: function () { + this.$input.prop("checked", false).change(); + }, +}); + +registry.add('module_boolean', ModuleBoolean); + +return ModuleBoolean; + +}); \ No newline at end of file diff --git a/muk_web_utils/static/src/js/fields/path.js b/muk_web_utils/static/src/js/fields/path.js new file mode 100644 index 0000000..ffc2bc1 --- /dev/null +++ b/muk_web_utils/static/src/js/fields/path.js @@ -0,0 +1,119 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +odoo.define('muk_web_utils.path', function (require) { +"use strict"; + +var core = require('web.core'); +var fields = require('web.basic_fields'); +var registry = require('web.field_registry'); +var colorpicker = require('web.colorpicker'); + +var AbstractField = require('web.AbstractField'); + +var _t = core._t; +var QWeb = core.qweb; + +var FieldPathNames = fields.FieldChar.extend({ + init: function(parent, name, record) { + this._super.apply(this, arguments); + this.max_width = this.nodeOptions.width || 500; + }, + _renderReadonly: function() { + var show_value = this._formatValue(this.value); + var text_witdh = $.fn.textWidth(show_value); + if(text_witdh >= this.max_width) { + var ratio_start = (1 - (this.max_width / text_witdh)) * show_value.length; + show_value = ".." + show_value.substring(ratio_start, show_value.length); + } + this.$el.text(show_value); + }, +}); + +var FieldPathJson = fields.FieldText.extend({ + events: _.extend({}, fields.FieldText.prototype.events, { + 'click a' : '_onNodeClicked', + }), + init: function(parent, name, record) { + this._super.apply(this, arguments); + this.max_width = this.nodeOptions.width || 500; + this.seperator = this.nodeOptions.seperator || "/"; + this.prefix = this.nodeOptions.prefix || false; + this.suffix = this.nodeOptions.suffix || false; + }, + _renderReadonly: function() { + this.$el.empty(); + this._renderPath(); + }, + _renderPath: function() { + var text_width_measure = ""; + var path = JSON.parse(this.value || "[]"); + $.each(_.clone(path).reverse(), function(index, element) { + text_width_measure += element.name + "/"; + if($.fn.textWidth(text_width_measure) >= this.max_width) { + this.$el.prepend($('').text("..")); + } else { + if (index == 0) { + if(this.suffix) { + this.$el.prepend($('').text(this.seperator)); + } + this.$el.prepend($('').text(element.name)); + this.$el.prepend($('').text(this.seperator)); + } else { + this.$el.prepend($('', { + 'class': 'oe_form_uri', + 'data-model': element.model, + 'data-id': element.id, + 'href': "javascript:void(0);", + 'text': element.name, + })); + if (index != path.length - 1) { + this.$el.prepend($('').text(this.seperator)); + } else if (this.prefix) { + this.$el.prepend($('').text(this.seperator)); + } + } + } + return ($.fn.textWidth(text_width_measure) < this.max_width); + }.bind(this)); + }, + _onNodeClicked : function(event) { + this.do_action({ + type: 'ir.actions.act_window', + res_model: $(event.currentTarget).data('model'), + res_id: $(event.currentTarget).data('id'), + views: [[false, 'form']], + target: 'current', + context: {}, + }); + } +}); + +registry.add('path_names', FieldPathNames); +registry.add('path_json', FieldPathJson); + +return { + FieldPathNames: FieldPathNames, + FieldPathJson: FieldPathJson, +}; + +}); \ No newline at end of file diff --git a/muk_web_utils/static/src/js/fields/share.js b/muk_web_utils/static/src/js/fields/share.js new file mode 100644 index 0000000..c25564b --- /dev/null +++ b/muk_web_utils/static/src/js/fields/share.js @@ -0,0 +1,226 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +odoo.define('muk_web_utils.share', function (require) { +"use strict"; + +var core = require('web.core'); +var session = require('web.session'); +var fields = require('web.basic_fields'); +var registry = require('web.field_registry'); + +var utils = require('muk_web_utils.utils'); +var copy = require('muk_web_utils.copy'); + +var _t = core._t; +var QWeb = core.qweb; + +var ShareMixin = { + shareEvents: { + 'click .mk_share_dropdown_message': '_onShareMessageClick', + 'click .mk_share_dropdown_note': '_onShareNoteClick', + 'click .mk_share_dropdown_mail': '_onShareMailClick', + 'click .mk_share_dropdown_send': '_onShareSendClick', + }, + getShareMessageValues: function(message) { + var values = { + name: session.partner_display_name, + record: this.recordData.display_name, + url: utils.isUrl(this.value) && this.value, + value: this.value, + }; + return { + subject: _.template(this.shareOptions.subjectTemplate)(values), + body: QWeb.render(this.shareOptions.bodyTemplate, values), + text: _.template(this.shareOptions.textTemplate)(values), + url: utils.isUrl(this.value) && this.value, + } + }, + openShareChat: function(note) { + var values = this.getShareMessageValues(); + var context = { + default_is_log: note, + default_body: values.body, + default_subject: values.subject, + default_model: this.shareOptions.res_model, + default_res_id: this.shareOptions.res_id, + mail_post_autofollow: false, + }; + this.do_action({ + type: 'ir.actions.act_window', + res_model: 'mail.compose.message', + view_mode: 'form', + views: [[false, 'form']], + target: 'new', + context: context, + }); + }, + _onShareMessageClick: function(event) { + event.preventDefault(); + event.stopPropagation(); + this.openShareChat(false); + }, + _onShareNoteClick: function(event) { + event.preventDefault(); + event.stopPropagation(); + this.openShareChat(true); + }, + _onShareMailClick: function(event) { + event.preventDefault(); + event.stopPropagation(); + var values = this.getShareMessageValues(); + var subject = "subject=" + values.subject; + var body = "&body=" + encodeURIComponent(values.text); + window.location.href = "mailto:?" + subject + body; + }, + _onShareSendClick: function(event) { + event.preventDefault(); + event.stopPropagation(); + var values = this.getShareMessageValues(); + navigator.share({ + title: values.subject, + text: values.text, + url: values.url, + }); + }, +}; + +var CharShare = fields.CharCopyClipboard.extend(ShareMixin, { + fieldDependencies: _.extend({}, fields.CharCopyClipboard.prototype.fieldDependencies, { + display_name: {type: 'char'}, + }), + events: _.extend({}, fields.CharCopyClipboard.prototype.events, ShareMixin.shareEvents), + init: function(parent, name, record) { + this._super.apply(this, arguments); + this.navigator = window.navigator.share; + this.chatter = _.contains(odoo._modules, "mail"); + this.shareOptions = _.defaults(this.nodeOptions, { + subjectTemplate: _t("<%= name %> shared a message!"), + textTemplate: _t("<%= value %>"), + bodyTemplate: 'muk_web_utils.ShareMessage', + }); + this.shareOptions = _.extend({}, this.shareOptions, { + res_model: this.recordData[this.nodeOptions.res_model] || this.model, + res_id: this.recordData[this.nodeOptions.res_id] || this.res_id, + }); + }, + _render: function() { + this._super.apply(this, arguments); + this.$el.addClass('mk_field_share'); + this.$el.prepend($(QWeb.render('muk_web_utils.CharShare', { + navigator: !!this.navigator, + chatter: !!this.chatter, + }))); + }, +}); + +var TextShare = fields.TextCopyClipboard.extend(ShareMixin, { + fieldDependencies: _.extend({}, fields.TextCopyClipboard.prototype.fieldDependencies, { + display_name: {type: 'char'}, + }), + events: _.extend({}, fields.TextCopyClipboard.prototype.events, ShareMixin.shareEvents), + init: function(parent, name, record) { + this._super.apply(this, arguments); + this.navigator = window.navigator.share; + this.chatter = _.contains(odoo._modules, "mail"); + this.shareOptions = _.defaults(this.nodeOptions, { + subjectTemplate: _t("<%= name %> shared a message!"), + textTemplate: _t("<%= value %>"), + bodyTemplate: 'muk_web_utils.ShareMessage', + }); + this.shareOptions = _.extend({}, this.shareOptions, { + res_model: this.recordData[this.nodeOptions.res_model] || this.model, + res_id: this.recordData[this.nodeOptions.res_id] || this.res_id, + }); + }, + _render: function() { + this._super.apply(this, arguments); + this.$el.addClass('mk_field_share'); + this.$el.prepend($(QWeb.render('muk_web_utils.TextShare', { + navigator: !!this.navigator, + chatter: !!this.chatter, + }))); + } +}); + +var BinaryFileShare = copy.BinaryFileCopy.extend(ShareMixin, { + fieldDependencies: _.extend({}, fields.FieldBinaryFile.prototype.fieldDependencies, { + display_name: {type: 'char'}, + }), + events: _.extend({}, copy.BinaryFileCopy.prototype.events, ShareMixin.shareEvents, { + 'click .mk_share_button': '_onShareDropdownClick', + }), + init: function () { + this._super.apply(this, arguments); + this.navigator = window.navigator.share; + this.chatter = _.contains(odoo._modules, "mail"); + this.shareOptions = _.defaults(this.nodeOptions, { + subjectTemplate: _t("<%= name %> shared a file!"), + textTemplate: _t("<%= value %>"), + bodyTemplate: 'muk_web_utils.ShareBinaryMessage', + }); + this.shareOptions = _.extend({}, this.shareOptions, { + res_model: this.recordData[this.nodeOptions.res_model] || this.model, + res_id: this.recordData[this.nodeOptions.res_id] || this.res_id, + }); + }, + getShareMessageValues: function() { + var values = { + name: session.partner_display_name, + record: this.recordData.display_name, + url: this.shareUrl, + value: this.shareUrl, + }; + return { + subject: _.template(this.shareOptions.subjectTemplate)(values), + body: QWeb.render(this.shareOptions.bodyTemplate, values), + text: _.template(this.shareOptions.textTemplate)(values), + url: this.shareUrl, + } + }, + _renderReadonly: function () { + this._super.apply(this, arguments); + this.$el.addClass('mk_field_share'); + this.$el.append($(QWeb.render('muk_web_utils.BinaryShare', { + navigator: !!this.navigator, + chatter: !!this.chatter, + share: !!this.shareUrl, + }))); + }, + _onShareDropdownClick: function(event) { + $(event.currentTarget).dropdown("toggle"); + event.stopPropagation(); + }, +}); + +registry.add('share_char', CharShare); +registry.add('share_text', TextShare); +registry.add('share_binary', BinaryFileShare); + +return { + ShareMixin: ShareMixin, + CharShare: CharShare, + TextShare: TextShare, + BinaryFileShare: BinaryFileShare, +}; + +}); \ No newline at end of file diff --git a/muk_web_utils/static/src/js/fields/utils.js b/muk_web_utils/static/src/js/fields/utils.js new file mode 100644 index 0000000..001acdd --- /dev/null +++ b/muk_web_utils/static/src/js/fields/utils.js @@ -0,0 +1,54 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +odoo.define('muk_web_utils.field_utils', function(require) { +"use strict"; + +var core = require('web.core'); +var session = require('web.session'); +var utils = require('web.field_utils'); + +var _t = core._t; +var QWeb = core.qweb; + +function formatBinarySize(value, field, options) { + options = _.defaults(options || {}, { + si: true, + }); + var thresh = options.si ? 1000 : 1024; + if(Math.abs(value) < thresh) { + return utils.format['float'](value, field, options) + ' B'; + } + var units = options.si + ? ['KB','MB','GB','TB','PB','EB','ZB','YB'] + : ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB']; + var unit = -1; + do { + value /= thresh; + ++unit; + } while(Math.abs(value) >= thresh && unit < units.length - 1); + return utils.format['float'](value, field, options) + ' ' + units[unit]; +} + +utils.format.binary_size = formatBinarySize; + +}); diff --git a/muk_web_utils/static/src/js/libs/jquery.js b/muk_web_utils/static/src/js/libs/jquery.js new file mode 100644 index 0000000..84b3314 --- /dev/null +++ b/muk_web_utils/static/src/js/libs/jquery.js @@ -0,0 +1,104 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +$.fn.textWidth = function(text, font) { + if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('').hide().appendTo(document.body); + $.fn.textWidth.fakeEl.text(text || this.val() || this.text()).css('font', font || this.css('font')); + return $.fn.textWidth.fakeEl.width(); +}; + +$.fn.dndHover = function(options) { + return this.each(function() { + var self = $(this); + var collection = $(); + var dragenter = function(event) { + if (collection.size() === 0) { + self.trigger('dndHoverStart', [event]); + } + collection = collection.add(event.target); + }; + var dragleave = function(event) { + setTimeout(function() { + collection = collection.not(event.target); + if (collection.size() === 0) { + self.trigger('dndHoverEnd', [event]); + } + }, 1); + }; + var drop = function(event) { + setTimeout(function() { + collection = $(); + self.trigger('dndHoverEnd', [event]); + }, 1); + }; + if(options && options === 'destroy') { + self.off('dragenter.dnd_hover'); + self.off('dragleave.dnd_hover'); + self.off('drop.dnd_hover'); + } else { + self.on('dragenter.dnd_hover', dragenter); + self.on('dragleave.dnd_hover', dragleave); + self.on('drop.dnd_hover', drop); + } + }); +}; + +$.ajaxTransport("+binary", function(options, originalOptions, jqXHR) { + if (window.FormData && ((options.dataType && (options.dataType == 'binary')) || + (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || + (window.Blob && options.data instanceof Blob))))) { + return { + send: function(headers, callback){ + var xhr = new XMLHttpRequest(); + var url = options.url, + type = options.type, + async = options.async || true, + dataType = options.responseType || 'blob', + data = options.data || null, + username = options.username, + password = options.password; + xhr.addEventListener('load', function(){ + var data = {}; + data[options.dataType] = xhr.response; + callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders()); + }); + xhr.open(type, url, async, username, password); + for (var i in headers ) { + xhr.setRequestHeader(i, headers[i] ); + } + if (options.xhrFields) { + for (var key in options.xhrFields) { + if (key in xhr) { + xhr[key] = options.xhrFields[key]; + } + } + } + xhr.responseType = dataType; + xhr.send(data); + }, + abort: function(){ + jqXHR.abort(); + } + }; + } +}); + diff --git a/muk_web_utils/static/src/js/libs/scrollbar.js b/muk_web_utils/static/src/js/libs/scrollbar.js new file mode 100644 index 0000000..2c889fd --- /dev/null +++ b/muk_web_utils/static/src/js/libs/scrollbar.js @@ -0,0 +1,27 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +$.fn.renderScrollBar = function() { + this.each(function() { + new SimpleBar(this); + }); +}; diff --git a/muk_web_utils/static/src/js/libs/underscore.js b/muk_web_utils/static/src/js/libs/underscore.js new file mode 100644 index 0000000..a8a4aa8 --- /dev/null +++ b/muk_web_utils/static/src/js/libs/underscore.js @@ -0,0 +1,47 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +_.mixin({ + memoizeDebounce: function(func, wait, options) { + wait = (typeof wait !== 'undefined') ? wait : 0; + options = (typeof options !== 'undefined') ? options : {}; + var mem = _.memoize(function() { + return _.debounce(func, wait, options) + }, options.resolver); + return function() { + mem.apply(this, arguments).apply(this, arguments) + } + } +}); + +_.mixin({ + memoizeThrottle: function(func, wait, options) { + wait = (typeof wait !== 'undefined') ? wait : 0; + options = (typeof options !== 'undefined') ? options : {}; + var mem = _.memoize(function() { + return _.throttle(func, wait, options) + }, options.resolver); + return function() { + mem.apply(this, arguments).apply(this, arguments) + } + } +}); \ No newline at end of file diff --git a/muk_web_utils/static/src/js/services/notification_service.js b/muk_web_utils/static/src/js/services/notification_service.js new file mode 100644 index 0000000..8f5787e --- /dev/null +++ b/muk_web_utils/static/src/js/services/notification_service.js @@ -0,0 +1,37 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +odoo.define('muk_web_utils.NotificationService', function (require) { +"use strict"; + +var NotificationService = require('web.NotificationService'); + +NotificationService.include({ + progress: function (notificationId, progress) { + if(notificationId in this.notifications) { + var notification = this.notifications[notificationId]; + notification.updateProgress(progress.state, progress.text); + } + }, +}); + +}); diff --git a/muk_web_utils/static/src/js/views/form/renderer.js b/muk_web_utils/static/src/js/views/form/renderer.js new file mode 100644 index 0000000..496211a --- /dev/null +++ b/muk_web_utils/static/src/js/views/form/renderer.js @@ -0,0 +1,47 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +odoo.define('muk_web_utils.FormRenderer', function (require) { +"use strict"; + +var core = require('web.core'); + +var FormRenderer = require('web.FormRenderer'); + +var _t = core._t; +var QWeb = core.qweb; + +FormRenderer.include({ + _updateView: function ($newContent) { + this._super.apply(this, arguments); + _.each(this.allFieldWidgets[this.state.id], function (widget) { + if (widget.attrs.widget === 'module_boolean') { + var inputID = this.idsForLabels[widget.name]; + var $widgets = this.$('.o_field_widget[name=' + widget.name + ']'); + var $label = inputID ? this.$('.o_form_label[for=' + inputID + ']') : $(); + widget.renderWithLabel($label.eq($widgets.index(widget.$el))); + } + }, this); + } +}); + +}); \ No newline at end of file diff --git a/muk_web_utils/static/src/js/widgets/notification.js b/muk_web_utils/static/src/js/widgets/notification.js new file mode 100644 index 0000000..b51b636 --- /dev/null +++ b/muk_web_utils/static/src/js/widgets/notification.js @@ -0,0 +1,46 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +odoo.define('muk_web_utils.Notification', function (require) { +"use strict"; + +var core = require('web.core'); + +var Notification = require('web.Notification'); + +var _t = core._t; +var QWeb = core.qweb; + +Notification.include({ + init: function (parent, params) { + this._super.apply(this, arguments); + this.icon = params.icon || this.icon; + this.progress = params.progress; + }, + updateProgress: function(state, text) { + this.progress = {state: state, text: text}; + this.$(".progress-bar").text(text); + this.$(".progress-bar").width(state + "%"); + }, +}); + +}); \ No newline at end of file diff --git a/muk_web_utils/static/src/scss/binary.scss b/muk_web_utils/static/src/scss/binary.scss new file mode 100644 index 0000000..d4541e2 --- /dev/null +++ b/muk_web_utils/static/src/scss/binary.scss @@ -0,0 +1,28 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +.o_list_view .o_field_widget.o_field_binary_file { + height: 100%; + button.btn { + padding-top: 0.25rem; + } +} diff --git a/muk_web_utils/static/src/scss/color.scss b/muk_web_utils/static/src/scss/color.scss new file mode 100644 index 0000000..297f8f9 --- /dev/null +++ b/muk_web_utils/static/src/scss/color.scss @@ -0,0 +1,66 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +.mk_field_color_picker { + .o_opacity_slider { + display: none ! important; + } + input#opacity { + display: none ! important; + } + label[for="opacity"] { + display: none ! important; + } +} + +.o_field_widget.mk_field_color { + .mk_field_color_input { + width: auto; + display: inline-block; + } + .mk_field_color_button { + display: inline-block; + margin-bottom: 0.25rem; + line-height: 1.42rem; + } +} + +span.mk_field_color_index { + @for $size from 1 through length($o-colors) { + &.mk_color_index_#{$size - 1} { + color: nth($o-colors, $size); + } + } +} + +select.mk_field_color_index { + &.mk_color_index_0, .mk_color_index_0 { + background-color: $white ! important; + color: nth($o-colors, 1) ! important; + } + @for $size from 2 through length($o-colors) { + &.mk_color_index_#{$size - 1}, .mk_color_index_#{$size - 1} { + background-color: nth($o-colors, $size) ! important; + color: $white ! important; + } + } +} \ No newline at end of file diff --git a/muk_web_utils/static/src/scss/copy.scss b/muk_web_utils/static/src/scss/copy.scss new file mode 100644 index 0000000..ff67504 --- /dev/null +++ b/muk_web_utils/static/src/scss/copy.scss @@ -0,0 +1,34 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +.o_field_widget.mk_field_copy { + .mk_copy_binary { + margin-left: 0.5rem; + .mk_copy_button { + font-size: 0.8rem; + line-height: 0.5; + border-radius: 0.2rem; + margin-bottom: 0.12rem; + padding: 0.25rem 0.4rem; + } + } +} \ No newline at end of file diff --git a/muk_web_utils/static/src/scss/dropzone.scss b/muk_web_utils/static/src/scss/dropzone.scss new file mode 100644 index 0000000..337ffbf --- /dev/null +++ b/muk_web_utils/static/src/scss/dropzone.scss @@ -0,0 +1,64 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +.mk_dropzone { + position: relative; + &:before { + display:flex; + z-index: 1052; + color: gray('700'); + flex-direction:row; + align-items: center; + justify-content: center; + width: #{"calc(100% - 20px)"}; + height: #{"calc(100% - 20px)"}; + border: 2px dashed gray('700'); + @include gradient-y($white, gray('100')); + @include o-position-absolute(10px, 0, 0, 10px); + } + &:after { + display:flex; + z-index: 1052; + color: gray('700'); + flex-direction:row; + align-items: center; + justify-content: center; + width: #{"calc(100% - 20px)"}; + height: #{"calc(100% - 10px)"}; + @include o-position-absolute(0, 0, 0, 0); + } + &.mk_dropzone_file { + &:before { + font-family: FontAwesome; + text-decoration: inherit; + font-style: normal; + font-weight: normal; + font-size: 15rem; + content: "\f0ee"; + } + &:after { + padding-top: 18rem; + font-size: 3rem; + content: attr(data-dropzone-text); + } + } +} \ No newline at end of file diff --git a/muk_web_utils/static/src/scss/image.scss b/muk_web_utils/static/src/scss/image.scss new file mode 100644 index 0000000..e78e9a3 --- /dev/null +++ b/muk_web_utils/static/src/scss/image.scss @@ -0,0 +1,84 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +.o_field_widget.o_field_image { + @include media-breakpoint-up(sm, $o-extra-grid-breakpoints) { + .mk_field_image_wrapper { + min-height: 60px; + min-width: 80px; + } + } + .mk_form_image_controls { + @include o-position-absolute($left: 0, $bottom: 0); + width: 100%; + color: white; + background-color: $o-brand-primary; + opacity: 0; + transition: opacity ease 400ms; + > button.fa { + border: none; + background-color: transparent; + } + > .fa { + margin: 5px; + cursor: pointer; + } + } + &:hover .mk_form_image_controls { + opacity: 0.8; + } + @include media-breakpoint-down(xs, $o-extra-grid-breakpoints) { + .mk_form_image_controls{ + position: initial; + opacity: 1; + > .fa{ + width: 50%; + padding: 6px; + margin: 0px; + text-align: center; + background: $o-brand-secondary; + } + } + } +} + +.o_field_widget.o_field_image.oe_avatar { + .mk_form_image_controls { + @include o-position-absolute($left: 0, $bottom: 10px); + } + img { + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4); + max-width: $o-avatar-size; + max-height: $o-avatar-size; + vertical-align: top; + margin-bottom: 10px; + border: none; + } + @include media-breakpoint-down(xs, $o-extra-grid-breakpoints) { + .mk_form_image_controls{ + position: initial; + > .fa{ + background: $o-brand-secondary; + } + } + } +} diff --git a/muk_web_utils/static/src/scss/mixins.scss b/muk_web_utils/static/src/scss/mixins.scss new file mode 100644 index 0000000..4c6e540 --- /dev/null +++ b/muk_web_utils/static/src/scss/mixins.scss @@ -0,0 +1,40 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +@mixin mk-flex-container ($direction: row, $wrap: nowrap, $justify: flex-start, $items: stretch, $content: stretch) { + display: flex; + flex-wrap: $wrap; + flex-direction: $direction; + justify-content: $justify; + align-content: $content; + align-items: $items; +} + +@mixin mk-flex-child ($grow: 0, $shrink: 1, $basis: auto, $order: 0) { + display: flex; + flex-grow: $grow; + flex-shrink: $shrink; + flex-basis: $basis; + order: $order; +} + + diff --git a/muk_web_utils/static/src/scss/module.scss b/muk_web_utils/static/src/scss/module.scss new file mode 100644 index 0000000..0a30d94 --- /dev/null +++ b/muk_web_utils/static/src/scss/module.scss @@ -0,0 +1,33 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +.o_settings_container { + .o_setting_box { + .o_setting_left_pane { + .mk_module_label { + position: absolute; + top: 0px; + right: 40px; + } + } + } +} \ No newline at end of file diff --git a/muk_web_utils/static/src/scss/notification.scss b/muk_web_utils/static/src/scss/notification.scss new file mode 100644 index 0000000..4caf339 --- /dev/null +++ b/muk_web_utils/static/src/scss/notification.scss @@ -0,0 +1,30 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +.o_notification { + .mk_notification_progress { + padding: 2px 10px 10px 10px; + .progress { + background-color: rgba(0, 0, 0, 0.3); + } + } +} diff --git a/muk_web_utils/static/src/scss/share.scss b/muk_web_utils/static/src/scss/share.scss new file mode 100644 index 0000000..37fa64e --- /dev/null +++ b/muk_web_utils/static/src/scss/share.scss @@ -0,0 +1,54 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +.o_field_widget.mk_field_share { + &.o_field_copy { + padding-left: 90px; + .mk_share_dropdown { + @include o-position-absolute($top: 0, $left: 0); + .mk_share_button { + padding: 0 10px; + } + &.mk_share_char { + height: 100%; + + } + &.mk_share_text { + .dropdown-menu { + line-height: 0.1 + } + } + } + } + &.o_form_uri { + .mk_share_dropdown { + margin-left: 0.2rem; + .mk_share_button { + padding: 0.25rem 0.4rem; + font-size: 0.8rem; + line-height: 0.5; + border-radius: 0.2rem; + margin-bottom: 0.12rem; + } + } + } +} \ No newline at end of file diff --git a/muk_web_utils/static/src/scss/switch.scss b/muk_web_utils/static/src/scss/switch.scss new file mode 100644 index 0000000..7fe9d6e --- /dev/null +++ b/muk_web_utils/static/src/scss/switch.scss @@ -0,0 +1,158 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +.switch { + font-size: $font-size-base; + position: relative; + + input { + position: absolute; + height: 1px; + width: 1px; + background: none; + border: 0; + clip: rect(0 0 0 0); + clip-path: inset(50%); + overflow: hidden; + padding: 0; + + + label { + position: relative; + min-width: calc(#{$switch-height} * 2); + border-radius: $switch-border-radius; + height: $switch-height; + line-height: $switch-height; + display: inline-block; + cursor: pointer; + outline: none; + user-select: none; + vertical-align: middle; + text-indent: calc(calc(#{$switch-height} * 2) + .5rem); + } + + + label::before, + + label::after { + content: ''; + position: absolute; + top: 0; + left: 0; + width: calc(#{$switch-height} * 2); + bottom: 0; + display: block; + } + + + label::before { + right: 0; + background-color: $switch-bg; + border-radius: $switch-border-radius; + transition: $switch-transition; + } + + + label::after { + top: $switch-thumb-padding; + left: $switch-thumb-padding; + width: calc(#{$switch-height} - calc(#{$switch-thumb-padding} * 2)); + height: calc(#{$switch-height} - calc(#{$switch-thumb-padding} * 2)); + border-radius: $switch-thumb-border-radius; + background-color: $switch-thumb-bg; + transition: $switch-transition; + } + + &:checked + label::before { + background-color: $switch-checked-bg; + } + + &:checked + label::after { + margin-left: $switch-height; + } + + &:focus + label::before { + outline: none; + box-shadow: $switch-focus-box-shadow; + } + + &:disabled + label { + color: $switch-disabled-color; + cursor: not-allowed; + } + + &:disabled + label::before { + background-color: $switch-disabled-bg; + } + } + + &.switch-sm { + font-size: $font-size-sm; + + input { + + label { + min-width: calc(#{$switch-height-sm} * 2); + height: $switch-height-sm; + line-height: $switch-height-sm; + text-indent: calc(calc(#{$switch-height-sm} * 2) + .5rem); + } + + + label::before { + width: calc(#{$switch-height-sm} * 2); + } + + + label::after { + width: calc(#{$switch-height-sm} - calc(#{$switch-thumb-padding} * 2)); + height: calc(#{$switch-height-sm} - calc(#{$switch-thumb-padding} * 2)); + } + + &:checked + label::after { + margin-left: $switch-height-sm; + } + } + } + + &.switch-lg { + font-size: $font-size-lg; + + input { + + label { + min-width: calc(#{$switch-height-lg} * 2); + height: $switch-height-lg; + line-height: $switch-height-lg; + text-indent: calc(calc(#{$switch-height-lg} * 2) + .5rem); + } + + + label::before { + width: calc(#{$switch-height-lg} * 2); + } + + + label::after { + width: calc(#{$switch-height-lg} - calc(#{$switch-thumb-padding} * 2)); + height: calc(#{$switch-height-lg} - calc(#{$switch-thumb-padding} * 2)); + } + + &:checked + label::after { + margin-left: $switch-height-lg; + } + } + } + + + .switch { + margin-left: 1rem; + } +} \ No newline at end of file diff --git a/muk_web_utils/static/src/scss/variables.scss b/muk_web_utils/static/src/scss/variables.scss new file mode 100644 index 0000000..74fa8ca --- /dev/null +++ b/muk_web_utils/static/src/scss/variables.scss @@ -0,0 +1,39 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ + +//---------------------------------------------------------- +// Switch +//---------------------------------------------------------- + +$switch-bg: #dee2e6; +$switch-disabled-bg: #e9ecef; +$switch-disabled-color: #868e96; +$switch-height: calc(#{$input-height} * .8) !default; +$switch-height-sm: calc(#{$input-height-sm} * .8) !default; +$switch-height-lg: calc(#{$input-height-lg} * .8) !default; +$switch-checked-bg: map-get($theme-colors, 'primary') !default; +$switch-thumb-bg: $white !default; +$switch-thumb-border-radius: 50% !default; +$switch-thumb-padding: 2px !default; +$switch-transition: .2s all !default; +$switch-border-radius: $switch-height; +$switch-focus-box-shadow: 0 0 0 $input-btn-focus-width rgba(map-get($theme-colors, 'primary'), .25); \ No newline at end of file diff --git a/muk_web_utils/static/src/xml/color.xml b/muk_web_utils/static/src/xml/color.xml new file mode 100644 index 0000000..ecbc10d --- /dev/null +++ b/muk_web_utils/static/src/xml/color.xml @@ -0,0 +1,65 @@ + + + + + + + + +
+ + +
+
+ + + + + + +
\ No newline at end of file diff --git a/muk_web_utils/static/src/xml/copy.xml b/muk_web_utils/static/src/xml/copy.xml new file mode 100644 index 0000000..4a21900 --- /dev/null +++ b/muk_web_utils/static/src/xml/copy.xml @@ -0,0 +1,35 @@ + + + + + + + +
+ +
+
+ +
\ No newline at end of file diff --git a/muk_web_utils/static/src/xml/image.xml b/muk_web_utils/static/src/xml/image.xml new file mode 100644 index 0000000..824c3af --- /dev/null +++ b/muk_web_utils/static/src/xml/image.xml @@ -0,0 +1,34 @@ + + + + + + + + +
+
+
+
+ +
\ No newline at end of file diff --git a/muk_web_utils/static/src/xml/module.xml b/muk_web_utils/static/src/xml/module.xml new file mode 100644 index 0000000..0709de4 --- /dev/null +++ b/muk_web_utils/static/src/xml/module.xml @@ -0,0 +1,39 @@ + + + + + + + +
+
+ Missing Module +
+
+

The module could not be found on the server.

+

Click on the download button to be redirected to the store and download the corresponding module.

+
+
+
+ +
\ No newline at end of file diff --git a/muk_web_utils/static/src/xml/notification.xml b/muk_web_utils/static/src/xml/notification.xml new file mode 100644 index 0000000..2ed595a --- /dev/null +++ b/muk_web_utils/static/src/xml/notification.xml @@ -0,0 +1,39 @@ + + + + + + + + +
+
+
+ +
+
+
+
+
+ +
\ No newline at end of file diff --git a/muk_web_utils/static/src/xml/share.xml b/muk_web_utils/static/src/xml/share.xml new file mode 100644 index 0000000..5e149d5 --- /dev/null +++ b/muk_web_utils/static/src/xml/share.xml @@ -0,0 +1,106 @@ + + + + + + + +
+ + +
+
+ + +
+ + + + + + + + + + + + + + + +
+ + +
+
+ + +
+ +

shared a link with you!

+ + Open + +
+ +

shared a message with you!

+

+ +

+
+ + +
+

shared a file with you!

+ + Download + +
+
+ + \ No newline at end of file diff --git a/muk_web_utils/static/src/xml/switch.xml b/muk_web_utils/static/src/xml/switch.xml new file mode 100644 index 0000000..cb9e742 --- /dev/null +++ b/muk_web_utils/static/src/xml/switch.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/muk_web_utils/static/tests/fields.js b/muk_web_utils/static/tests/fields.js new file mode 100644 index 0000000..6af0e6f --- /dev/null +++ b/muk_web_utils/static/tests/fields.js @@ -0,0 +1,205 @@ +/********************************************************************************** +* +* Copyright (c) 2017-2019 MuK IT GmbH. +* +* This file is part of MuK Web Utils +* (see https://mukit.at). +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +**********************************************************************************/ +odoo.define('muk_web_utils.tests.fields', function (require) { +"use strict"; + +var basicFields = require('web.basic_fields'); +var concurrency = require('web.concurrency'); +var config = require('web.config'); +var core = require('web.core'); +var FormView = require('web.FormView'); +var KanbanView = require('web.KanbanView'); +var ListView = require('web.ListView'); +var session = require('web.session'); +var testUtils = require('web.test_utils'); +var field_registry = require('web.field_registry'); + +var createView = testUtils.createView; +var createAsyncView = testUtils.createAsyncView; +var DebouncedField = basicFields.DebouncedField; +var JournalDashboardGraph = basicFields.JournalDashboardGraph; +var _t = core._t; + +QUnit.module('muk_web_utils', {}, function () { + +QUnit.module('fields', { + beforeEach: function () { + this.data = { + partner: { + fields: { + display_name: { + string: "Displayed name", + type: "char", + searchable: true + }, + short: { + string: "Short", + type: "char", + searchable: true, + trim: true + }, + long: { + string: "Long", + string: "txt", + type: "text", + }, + document: { + string: "Binary", + type: "binary", + attachment: true, + }, + }, + records: [{ + id: 1, + display_name: "first record", + short: "Short Text", + long: "Super looooooong Text", + document: 'coucou==\n', + }], + }, + }; + } +}, function () { + QUnit.module('BinaryFileCopy'); + + QUnit.test('Fields is correctly rendered', function (assert) { + assert.expect(2); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: ( + '
' + + '' + + '' + + '' + ), + res_id: 1, + }); + + assert.strictEqual( + form.$('a.o_field_widget[name="document"] > .mk_copy_binary > .mk_copy_button').length, + 1, "the copy button should be visible in readonly mode" + ); + + form.$buttons.find('.o_form_button_edit').click(); + + assert.strictEqual( + form.$('a.o_field_widget[name="document"] > .mk_copy_binary').length, + 0, "the copy button shouldn't be visible in edit mode" + ); + + form.destroy(); + }); + + QUnit.module('CharShare'); + + QUnit.test('Fields is correctly rendered', function (assert) { + assert.expect(1); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: ( + '
' + + '
' + + '' + + '
' + + '
' + ), + res_id: 1, + }); + + assert.strictEqual( + form.$('span.o_field_widget[name="short"] > .mk_share_dropdown.mk_share_char').length, + 1, "the copy button should be visible in readonly mode" + ); + + form.destroy(); + }); + + QUnit.module('TextShare'); + + QUnit.test('Fields is correctly rendered', function (assert) { + assert.expect(1); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: ( + '
' + + '
' + + '' + + '
' + + '
' + ), + res_id: 1, + }); + + assert.strictEqual( + form.$('span.o_field_widget[name="long"] > .mk_share_dropdown.mk_share_text').length, + 1, "the copy button should be visible in readonly mode" + ); + + form.destroy(); + }); + + QUnit.module('BinaryFileShare'); + + QUnit.test('Fields is correctly rendered', function (assert) { + assert.expect(2); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: ( + '
' + + '' + + '' + + '' + ), + res_id: 1, + }); + + assert.strictEqual( + form.$('a.o_field_widget[name="document"] > .mk_share_dropdown > .mk_share_button').length, + 1, "the share dropdown should be visible in readonly mode" + ); + + form.$buttons.find('.o_form_button_edit').click(); + + assert.strictEqual( + form.$('a.o_field_widget[name="document"] > .mk_share_dropdown > .mk_share_button').length, + 0, "the share dropdown shouldn't be visible in edit mode" + ); + + form.destroy(); + }); +}); + +}); + +}); \ No newline at end of file diff --git a/muk_web_utils/template/assets.xml b/muk_web_utils/template/assets.xml new file mode 100644 index 0000000..1386b49 --- /dev/null +++ b/muk_web_utils/template/assets.xml @@ -0,0 +1,79 @@ + + + + + + +

-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 0 ? floor : ceil)(it); + }; + + // 7.1.15 ToLength + + var min = Math.min; + var _toLength = function (it) { + return it > 0 ? min(_toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 + }; + + // true -> String#at + // false -> String#codePointAt + var _stringAt = function (TO_STRING) { + return function (that, pos) { + var s = String(_defined(that)); + var i = _toInteger(pos); + var l = s.length; + var a, b; + if (i < 0 || i >= l) return TO_STRING ? '' : undefined; + a = s.charCodeAt(i); + return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff + ? TO_STRING ? s.charAt(i) : a + : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; + }; + }; + + var at = _stringAt(true); + + // `AdvanceStringIndex` abstract operation + // https://tc39.github.io/ecma262/#sec-advancestringindex + var _advanceStringIndex = function (S, index, unicode) { + return index + (unicode ? at(S, index).length : 1); + }; + + var toString = {}.toString; + + var _cof = function (it) { + return toString.call(it).slice(8, -1); + }; + + var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; + } + + var _core = createCommonjsModule(function (module) { + var core = module.exports = { version: '2.6.2' }; + if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef + }); + var _core_1 = _core.version; + + var _global = createCommonjsModule(function (module) { + // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 + var global = module.exports = typeof window != 'undefined' && window.Math == Math + ? window : typeof self != 'undefined' && self.Math == Math ? self + // eslint-disable-next-line no-new-func + : Function('return this')(); + if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef + }); + + var _library = false; + + var _shared = createCommonjsModule(function (module) { + var SHARED = '__core-js_shared__'; + var store = _global[SHARED] || (_global[SHARED] = {}); + + (module.exports = function (key, value) { + return store[key] || (store[key] = value !== undefined ? value : {}); + })('versions', []).push({ + version: _core.version, + mode: _library ? 'pure' : 'global', + copyright: '© 2019 Denis Pushkarev (zloirock.ru)' + }); + }); + + var id = 0; + var px = Math.random(); + var _uid = function (key) { + return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); + }; + + var _wks = createCommonjsModule(function (module) { + var store = _shared('wks'); + + var Symbol = _global.Symbol; + var USE_SYMBOL = typeof Symbol == 'function'; + + var $exports = module.exports = function (name) { + return store[name] || (store[name] = + USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : _uid)('Symbol.' + name)); + }; + + $exports.store = store; + }); + + // getting tag from 19.1.3.6 Object.prototype.toString() + + var TAG = _wks('toStringTag'); + // ES3 wrong here + var ARG = _cof(function () { return arguments; }()) == 'Arguments'; + + // fallback for IE11 Script Access Denied error + var tryGet = function (it, key) { + try { + return it[key]; + } catch (e) { /* empty */ } + }; + + var _classof = function (it) { + var O, T, B; + return it === undefined ? 'Undefined' : it === null ? 'Null' + // @@toStringTag case + : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T + // builtinTag case + : ARG ? _cof(O) + // ES3 arguments fallback + : (B = _cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B; + }; + + var builtinExec = RegExp.prototype.exec; + + // `RegExpExec` abstract operation + // https://tc39.github.io/ecma262/#sec-regexpexec + var _regexpExecAbstract = function (R, S) { + var exec = R.exec; + if (typeof exec === 'function') { + var result = exec.call(R, S); + if (typeof result !== 'object') { + throw new TypeError('RegExp exec method returned something other than an Object or null'); + } + return result; + } + if (_classof(R) !== 'RegExp') { + throw new TypeError('RegExp#exec called on incompatible receiver'); + } + return builtinExec.call(R, S); + }; + + // 21.2.5.3 get RegExp.prototype.flags + + var _flags = function () { + var that = _anObject(this); + var result = ''; + if (that.global) result += 'g'; + if (that.ignoreCase) result += 'i'; + if (that.multiline) result += 'm'; + if (that.unicode) result += 'u'; + if (that.sticky) result += 'y'; + return result; + }; + + var nativeExec = RegExp.prototype.exec; + // This always refers to the native implementation, because the + // String#replace polyfill uses ./fix-regexp-well-known-symbol-logic.js, + // which loads this file before patching the method. + var nativeReplace = String.prototype.replace; + + var patchedExec = nativeExec; + + var LAST_INDEX = 'lastIndex'; + + var UPDATES_LAST_INDEX_WRONG = (function () { + var re1 = /a/, + re2 = /b*/g; + nativeExec.call(re1, 'a'); + nativeExec.call(re2, 'a'); + return re1[LAST_INDEX] !== 0 || re2[LAST_INDEX] !== 0; + })(); + + // nonparticipating capturing group, copied from es5-shim's String#split patch. + var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined; + + var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED; + + if (PATCH) { + patchedExec = function exec(str) { + var re = this; + var lastIndex, reCopy, match, i; + + if (NPCG_INCLUDED) { + reCopy = new RegExp('^' + re.source + '$(?!\\s)', _flags.call(re)); + } + if (UPDATES_LAST_INDEX_WRONG) lastIndex = re[LAST_INDEX]; + + match = nativeExec.call(re, str); + + if (UPDATES_LAST_INDEX_WRONG && match) { + re[LAST_INDEX] = re.global ? match.index + match[0].length : lastIndex; + } + if (NPCG_INCLUDED && match && match.length > 1) { + // Fix browsers whose `exec` methods don't consistently return `undefined` + // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/ + // eslint-disable-next-line no-loop-func + nativeReplace.call(match[0], reCopy, function () { + for (i = 1; i < arguments.length - 2; i++) { + if (arguments[i] === undefined) match[i] = undefined; + } + }); + } + + return match; + }; + } + + var _regexpExec = patchedExec; + + var _fails = function (exec) { + try { + return !!exec(); + } catch (e) { + return true; + } + }; + + // Thank's IE8 for his funny defineProperty + var _descriptors = !_fails(function () { + return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7; + }); + + var document$1 = _global.document; + // typeof document.createElement is 'object' in old IE + var is = _isObject(document$1) && _isObject(document$1.createElement); + var _domCreate = function (it) { + return is ? document$1.createElement(it) : {}; + }; + + var _ie8DomDefine = !_descriptors && !_fails(function () { + return Object.defineProperty(_domCreate('div'), 'a', { get: function () { return 7; } }).a != 7; + }); + + // 7.1.1 ToPrimitive(input [, PreferredType]) + + // instead of the ES6 spec version, we didn't implement @@toPrimitive case + // and the second argument - flag - preferred type is a string + var _toPrimitive = function (it, S) { + if (!_isObject(it)) return it; + var fn, val; + if (S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val; + if (typeof (fn = it.valueOf) == 'function' && !_isObject(val = fn.call(it))) return val; + if (!S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val; + throw TypeError("Can't convert object to primitive value"); + }; + + var dP = Object.defineProperty; + + var f = _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes) { + _anObject(O); + P = _toPrimitive(P, true); + _anObject(Attributes); + if (_ie8DomDefine) try { + return dP(O, P, Attributes); + } catch (e) { /* empty */ } + if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!'); + if ('value' in Attributes) O[P] = Attributes.value; + return O; + }; + + var _objectDp = { + f: f + }; + + var _propertyDesc = function (bitmap, value) { + return { + enumerable: !(bitmap & 1), + configurable: !(bitmap & 2), + writable: !(bitmap & 4), + value: value + }; + }; + + var _hide = _descriptors ? function (object, key, value) { + return _objectDp.f(object, key, _propertyDesc(1, value)); + } : function (object, key, value) { + object[key] = value; + return object; + }; + + var hasOwnProperty = {}.hasOwnProperty; + var _has = function (it, key) { + return hasOwnProperty.call(it, key); + }; + + var _redefine = createCommonjsModule(function (module) { + var SRC = _uid('src'); + var TO_STRING = 'toString'; + var $toString = Function[TO_STRING]; + var TPL = ('' + $toString).split(TO_STRING); + + _core.inspectSource = function (it) { + return $toString.call(it); + }; + + (module.exports = function (O, key, val, safe) { + var isFunction = typeof val == 'function'; + if (isFunction) _has(val, 'name') || _hide(val, 'name', key); + if (O[key] === val) return; + if (isFunction) _has(val, SRC) || _hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key))); + if (O === _global) { + O[key] = val; + } else if (!safe) { + delete O[key]; + _hide(O, key, val); + } else if (O[key]) { + O[key] = val; + } else { + _hide(O, key, val); + } + // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative + })(Function.prototype, TO_STRING, function toString() { + return typeof this == 'function' && this[SRC] || $toString.call(this); + }); + }); + + var _aFunction = function (it) { + if (typeof it != 'function') throw TypeError(it + ' is not a function!'); + return it; + }; + + // optional / simple context binding + + var _ctx = function (fn, that, length) { + _aFunction(fn); + if (that === undefined) return fn; + switch (length) { + case 1: return function (a) { + return fn.call(that, a); + }; + case 2: return function (a, b) { + return fn.call(that, a, b); + }; + case 3: return function (a, b, c) { + return fn.call(that, a, b, c); + }; + } + return function (/* ...args */) { + return fn.apply(that, arguments); + }; + }; + + var PROTOTYPE = 'prototype'; + + var $export = function (type, name, source) { + var IS_FORCED = type & $export.F; + var IS_GLOBAL = type & $export.G; + var IS_STATIC = type & $export.S; + var IS_PROTO = type & $export.P; + var IS_BIND = type & $export.B; + var target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] || (_global[name] = {}) : (_global[name] || {})[PROTOTYPE]; + var exports = IS_GLOBAL ? _core : _core[name] || (_core[name] = {}); + var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {}); + var key, own, out, exp; + if (IS_GLOBAL) source = name; + for (key in source) { + // contains in native + own = !IS_FORCED && target && target[key] !== undefined; + // export native or passed + out = (own ? target : source)[key]; + // bind timers to global for call from export context + exp = IS_BIND && own ? _ctx(out, _global) : IS_PROTO && typeof out == 'function' ? _ctx(Function.call, out) : out; + // extend global + if (target) _redefine(target, key, out, type & $export.U); + // export + if (exports[key] != out) _hide(exports, key, exp); + if (IS_PROTO && expProto[key] != out) expProto[key] = out; + } + }; + _global.core = _core; + // type bitmap + $export.F = 1; // forced + $export.G = 2; // global + $export.S = 4; // static + $export.P = 8; // proto + $export.B = 16; // bind + $export.W = 32; // wrap + $export.U = 64; // safe + $export.R = 128; // real proto method for `library` + var _export = $export; + + _export({ + target: 'RegExp', + proto: true, + forced: _regexpExec !== /./.exec + }, { + exec: _regexpExec + }); + + var SPECIES = _wks('species'); + + var REPLACE_SUPPORTS_NAMED_GROUPS = !_fails(function () { + // #replace needs built-in support for named groups. + // #match works fine because it just return the exec results, even if it has + // a "grops" property. + var re = /./; + re.exec = function () { + var result = []; + result.groups = { a: '7' }; + return result; + }; + return ''.replace(re, '$') !== '7'; + }); + + var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = (function () { + // Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec + var re = /(?:)/; + var originalExec = re.exec; + re.exec = function () { return originalExec.apply(this, arguments); }; + var result = 'ab'.split(re); + return result.length === 2 && result[0] === 'a' && result[1] === 'b'; + })(); + + var _fixReWks = function (KEY, length, exec) { + var SYMBOL = _wks(KEY); + + var DELEGATES_TO_SYMBOL = !_fails(function () { + // String methods call symbol-named RegEp methods + var O = {}; + O[SYMBOL] = function () { return 7; }; + return ''[KEY](O) != 7; + }); + + var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL ? !_fails(function () { + // Symbol-named RegExp methods call .exec + var execCalled = false; + var re = /a/; + re.exec = function () { execCalled = true; return null; }; + if (KEY === 'split') { + // RegExp[@@split] doesn't call the regex's exec method, but first creates + // a new one. We need to return the patched regex when creating the new one. + re.constructor = {}; + re.constructor[SPECIES] = function () { return re; }; + } + re[SYMBOL](''); + return !execCalled; + }) : undefined; + + if ( + !DELEGATES_TO_SYMBOL || + !DELEGATES_TO_EXEC || + (KEY === 'replace' && !REPLACE_SUPPORTS_NAMED_GROUPS) || + (KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC) + ) { + var nativeRegExpMethod = /./[SYMBOL]; + var fns = exec( + _defined, + SYMBOL, + ''[KEY], + function maybeCallNative(nativeMethod, regexp, str, arg2, forceStringMethod) { + if (regexp.exec === _regexpExec) { + if (DELEGATES_TO_SYMBOL && !forceStringMethod) { + // The native String method already delegates to @@method (this + // polyfilled function), leasing to infinite recursion. + // We avoid it by directly calling the native @@method method. + return { done: true, value: nativeRegExpMethod.call(regexp, str, arg2) }; + } + return { done: true, value: nativeMethod.call(str, regexp, arg2) }; + } + return { done: false }; + } + ); + var strfn = fns[0]; + var rxfn = fns[1]; + + _redefine(String.prototype, KEY, strfn); + _hide(RegExp.prototype, SYMBOL, length == 2 + // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue) + // 21.2.5.11 RegExp.prototype[@@split](string, limit) + ? function (string, arg) { return rxfn.call(string, this, arg); } + // 21.2.5.6 RegExp.prototype[@@match](string) + // 21.2.5.9 RegExp.prototype[@@search](string) + : function (string) { return rxfn.call(string, this); } + ); + } + }; + + var max = Math.max; + var min$1 = Math.min; + var floor$1 = Math.floor; + var SUBSTITUTION_SYMBOLS = /\$([$&`']|\d\d?|<[^>]*>)/g; + var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&`']|\d\d?)/g; + + var maybeToString = function (it) { + return it === undefined ? it : String(it); + }; + + // @@replace logic + _fixReWks('replace', 2, function (defined, REPLACE, $replace, maybeCallNative) { + return [ + // `String.prototype.replace` method + // https://tc39.github.io/ecma262/#sec-string.prototype.replace + function replace(searchValue, replaceValue) { + var O = defined(this); + var fn = searchValue == undefined ? undefined : searchValue[REPLACE]; + return fn !== undefined + ? fn.call(searchValue, O, replaceValue) + : $replace.call(String(O), searchValue, replaceValue); + }, + // `RegExp.prototype[@@replace]` method + // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@replace + function (regexp, replaceValue) { + var res = maybeCallNative($replace, regexp, this, replaceValue); + if (res.done) return res.value; + + var rx = _anObject(regexp); + var S = String(this); + var functionalReplace = typeof replaceValue === 'function'; + if (!functionalReplace) replaceValue = String(replaceValue); + var global = rx.global; + if (global) { + var fullUnicode = rx.unicode; + rx.lastIndex = 0; + } + var results = []; + while (true) { + var result = _regexpExecAbstract(rx, S); + if (result === null) break; + results.push(result); + if (!global) break; + var matchStr = String(result[0]); + if (matchStr === '') rx.lastIndex = _advanceStringIndex(S, _toLength(rx.lastIndex), fullUnicode); + } + var accumulatedResult = ''; + var nextSourcePosition = 0; + for (var i = 0; i < results.length; i++) { + result = results[i]; + var matched = String(result[0]); + var position = max(min$1(_toInteger(result.index), S.length), 0); + var captures = []; + // NOTE: This is equivalent to + // captures = result.slice(1).map(maybeToString) + // but for some reason `nativeSlice.call(result, 1, result.length)` (called in + // the slice polyfill when slicing native arrays) "doesn't work" in safari 9 and + // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it. + for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j])); + var namedCaptures = result.groups; + if (functionalReplace) { + var replacerArgs = [matched].concat(captures, position, S); + if (namedCaptures !== undefined) replacerArgs.push(namedCaptures); + var replacement = String(replaceValue.apply(undefined, replacerArgs)); + } else { + replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue); + } + if (position >= nextSourcePosition) { + accumulatedResult += S.slice(nextSourcePosition, position) + replacement; + nextSourcePosition = position + matched.length; + } + } + return accumulatedResult + S.slice(nextSourcePosition); + } + ]; + + // https://tc39.github.io/ecma262/#sec-getsubstitution + function getSubstitution(matched, str, position, captures, namedCaptures, replacement) { + var tailPos = position + matched.length; + var m = captures.length; + var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED; + if (namedCaptures !== undefined) { + namedCaptures = _toObject(namedCaptures); + symbols = SUBSTITUTION_SYMBOLS; + } + return $replace.call(replacement, symbols, function (match, ch) { + var capture; + switch (ch.charAt(0)) { + case '$': return '$'; + case '&': return matched; + case '`': return str.slice(0, position); + case "'": return str.slice(tailPos); + case '<': + capture = namedCaptures[ch.slice(1, -1)]; + break; + default: // \d\d? + var n = +ch; + if (n === 0) return match; + if (n > m) { + var f = floor$1(n / 10); + if (f === 0) return match; + if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1); + return match; + } + capture = captures[n - 1]; + } + return capture === undefined ? '' : capture; + }); + } + }); + + var dP$1 = _objectDp.f; + var FProto = Function.prototype; + var nameRE = /^\s*function ([^ (]*)/; + var NAME = 'name'; + + // 19.2.4.2 name + NAME in FProto || _descriptors && dP$1(FProto, NAME, { + configurable: true, + get: function () { + try { + return ('' + this).match(nameRE)[1]; + } catch (e) { + return ''; + } + } + }); + + // @@match logic + _fixReWks('match', 1, function (defined, MATCH, $match, maybeCallNative) { + return [ + // `String.prototype.match` method + // https://tc39.github.io/ecma262/#sec-string.prototype.match + function match(regexp) { + var O = defined(this); + var fn = regexp == undefined ? undefined : regexp[MATCH]; + return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O)); + }, + // `RegExp.prototype[@@match]` method + // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@match + function (regexp) { + var res = maybeCallNative($match, regexp, this); + if (res.done) return res.value; + var rx = _anObject(regexp); + var S = String(this); + if (!rx.global) return _regexpExecAbstract(rx, S); + var fullUnicode = rx.unicode; + rx.lastIndex = 0; + var A = []; + var n = 0; + var result; + while ((result = _regexpExecAbstract(rx, S)) !== null) { + var matchStr = String(result[0]); + A[n] = matchStr; + if (matchStr === '') rx.lastIndex = _advanceStringIndex(S, _toLength(rx.lastIndex), fullUnicode); + n++; + } + return n === 0 ? null : A; + } + ]; + }); + + // 22.1.3.31 Array.prototype[@@unscopables] + var UNSCOPABLES = _wks('unscopables'); + var ArrayProto = Array.prototype; + if (ArrayProto[UNSCOPABLES] == undefined) _hide(ArrayProto, UNSCOPABLES, {}); + var _addToUnscopables = function (key) { + ArrayProto[UNSCOPABLES][key] = true; + }; + + var _iterStep = function (done, value) { + return { value: value, done: !!done }; + }; + + var _iterators = {}; + + // fallback for non-array-like ES3 and non-enumerable old V8 strings + + // eslint-disable-next-line no-prototype-builtins + var _iobject = Object('z').propertyIsEnumerable(0) ? Object : function (it) { + return _cof(it) == 'String' ? it.split('') : Object(it); + }; + + // to indexed object, toObject with fallback for non-array-like ES3 strings + + + var _toIobject = function (it) { + return _iobject(_defined(it)); + }; + + var max$1 = Math.max; + var min$2 = Math.min; + var _toAbsoluteIndex = function (index, length) { + index = _toInteger(index); + return index < 0 ? max$1(index + length, 0) : min$2(index, length); + }; + + // false -> Array#indexOf + // true -> Array#includes + + + + var _arrayIncludes = function (IS_INCLUDES) { + return function ($this, el, fromIndex) { + var O = _toIobject($this); + var length = _toLength(O.length); + var index = _toAbsoluteIndex(fromIndex, length); + var value; + // Array#includes uses SameValueZero equality algorithm + // eslint-disable-next-line no-self-compare + if (IS_INCLUDES && el != el) while (length > index) { + value = O[index++]; + // eslint-disable-next-line no-self-compare + if (value != value) return true; + // Array#indexOf ignores holes, Array#includes - not + } else for (;length > index; index++) if (IS_INCLUDES || index in O) { + if (O[index] === el) return IS_INCLUDES || index || 0; + } return !IS_INCLUDES && -1; + }; + }; + + var shared = _shared('keys'); + + var _sharedKey = function (key) { + return shared[key] || (shared[key] = _uid(key)); + }; + + var arrayIndexOf = _arrayIncludes(false); + var IE_PROTO = _sharedKey('IE_PROTO'); + + var _objectKeysInternal = function (object, names) { + var O = _toIobject(object); + var i = 0; + var result = []; + var key; + for (key in O) if (key != IE_PROTO) _has(O, key) && result.push(key); + // Don't enum bug & hidden keys + while (names.length > i) if (_has(O, key = names[i++])) { + ~arrayIndexOf(result, key) || result.push(key); + } + return result; + }; + + // IE 8- don't enum bug keys + var _enumBugKeys = ( + 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf' + ).split(','); + + // 19.1.2.14 / 15.2.3.14 Object.keys(O) + + + + var _objectKeys = Object.keys || function keys(O) { + return _objectKeysInternal(O, _enumBugKeys); + }; + + var _objectDps = _descriptors ? Object.defineProperties : function defineProperties(O, Properties) { + _anObject(O); + var keys = _objectKeys(Properties); + var length = keys.length; + var i = 0; + var P; + while (length > i) _objectDp.f(O, P = keys[i++], Properties[P]); + return O; + }; + + var document$2 = _global.document; + var _html = document$2 && document$2.documentElement; + + // 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties]) + + + + var IE_PROTO$1 = _sharedKey('IE_PROTO'); + var Empty = function () { /* empty */ }; + var PROTOTYPE$1 = 'prototype'; + + // Create object with fake `null` prototype: use iframe Object with cleared prototype + var createDict = function () { + // Thrash, waste and sodomy: IE GC bug + var iframe = _domCreate('iframe'); + var i = _enumBugKeys.length; + var lt = '<'; + var gt = '>'; + var iframeDocument; + iframe.style.display = 'none'; + _html.appendChild(iframe); + iframe.src = 'javascript:'; // eslint-disable-line no-script-url + // createDict = iframe.contentWindow.Object; + // html.removeChild(iframe); + iframeDocument = iframe.contentWindow.document; + iframeDocument.open(); + iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt); + iframeDocument.close(); + createDict = iframeDocument.F; + while (i--) delete createDict[PROTOTYPE$1][_enumBugKeys[i]]; + return createDict(); + }; + + var _objectCreate = Object.create || function create(O, Properties) { + var result; + if (O !== null) { + Empty[PROTOTYPE$1] = _anObject(O); + result = new Empty(); + Empty[PROTOTYPE$1] = null; + // add "__proto__" for Object.getPrototypeOf polyfill + result[IE_PROTO$1] = O; + } else result = createDict(); + return Properties === undefined ? result : _objectDps(result, Properties); + }; + + var def = _objectDp.f; + + var TAG$1 = _wks('toStringTag'); + + var _setToStringTag = function (it, tag, stat) { + if (it && !_has(it = stat ? it : it.prototype, TAG$1)) def(it, TAG$1, { configurable: true, value: tag }); + }; + + var IteratorPrototype = {}; + + // 25.1.2.1.1 %IteratorPrototype%[@@iterator]() + _hide(IteratorPrototype, _wks('iterator'), function () { return this; }); + + var _iterCreate = function (Constructor, NAME, next) { + Constructor.prototype = _objectCreate(IteratorPrototype, { next: _propertyDesc(1, next) }); + _setToStringTag(Constructor, NAME + ' Iterator'); + }; + + // 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O) + + + var IE_PROTO$2 = _sharedKey('IE_PROTO'); + var ObjectProto = Object.prototype; + + var _objectGpo = Object.getPrototypeOf || function (O) { + O = _toObject(O); + if (_has(O, IE_PROTO$2)) return O[IE_PROTO$2]; + if (typeof O.constructor == 'function' && O instanceof O.constructor) { + return O.constructor.prototype; + } return O instanceof Object ? ObjectProto : null; + }; + + var ITERATOR = _wks('iterator'); + var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next` + var FF_ITERATOR = '@@iterator'; + var KEYS = 'keys'; + var VALUES = 'values'; + + var returnThis = function () { return this; }; + + var _iterDefine = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) { + _iterCreate(Constructor, NAME, next); + var getMethod = function (kind) { + if (!BUGGY && kind in proto) return proto[kind]; + switch (kind) { + case KEYS: return function keys() { return new Constructor(this, kind); }; + case VALUES: return function values() { return new Constructor(this, kind); }; + } return function entries() { return new Constructor(this, kind); }; + }; + var TAG = NAME + ' Iterator'; + var DEF_VALUES = DEFAULT == VALUES; + var VALUES_BUG = false; + var proto = Base.prototype; + var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]; + var $default = $native || getMethod(DEFAULT); + var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined; + var $anyNative = NAME == 'Array' ? proto.entries || $native : $native; + var methods, key, IteratorPrototype; + // Fix native + if ($anyNative) { + IteratorPrototype = _objectGpo($anyNative.call(new Base())); + if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) { + // Set @@toStringTag to native iterators + _setToStringTag(IteratorPrototype, TAG, true); + // fix for some old engines + if (!_library && typeof IteratorPrototype[ITERATOR] != 'function') _hide(IteratorPrototype, ITERATOR, returnThis); + } + } + // fix Array#{values, @@iterator}.name in V8 / FF + if (DEF_VALUES && $native && $native.name !== VALUES) { + VALUES_BUG = true; + $default = function values() { return $native.call(this); }; + } + // Define iterator + if ((!_library || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) { + _hide(proto, ITERATOR, $default); + } + // Plug for library + _iterators[NAME] = $default; + _iterators[TAG] = returnThis; + if (DEFAULT) { + methods = { + values: DEF_VALUES ? $default : getMethod(VALUES), + keys: IS_SET ? $default : getMethod(KEYS), + entries: $entries + }; + if (FORCED) for (key in methods) { + if (!(key in proto)) _redefine(proto, key, methods[key]); + } else _export(_export.P + _export.F * (BUGGY || VALUES_BUG), NAME, methods); + } + return methods; + }; + + // 22.1.3.4 Array.prototype.entries() + // 22.1.3.13 Array.prototype.keys() + // 22.1.3.29 Array.prototype.values() + // 22.1.3.30 Array.prototype[@@iterator]() + var es6_array_iterator = _iterDefine(Array, 'Array', function (iterated, kind) { + this._t = _toIobject(iterated); // target + this._i = 0; // next index + this._k = kind; // kind + // 22.1.5.2.1 %ArrayIteratorPrototype%.next() + }, function () { + var O = this._t; + var kind = this._k; + var index = this._i++; + if (!O || index >= O.length) { + this._t = undefined; + return _iterStep(1); + } + if (kind == 'keys') return _iterStep(0, index); + if (kind == 'values') return _iterStep(0, O[index]); + return _iterStep(0, [index, O[index]]); + }, 'values'); + + // argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7) + _iterators.Arguments = _iterators.Array; + + _addToUnscopables('keys'); + _addToUnscopables('values'); + _addToUnscopables('entries'); + + var ITERATOR$1 = _wks('iterator'); + var TO_STRING_TAG = _wks('toStringTag'); + var ArrayValues = _iterators.Array; + + var DOMIterables = { + CSSRuleList: true, // TODO: Not spec compliant, should be false. + CSSStyleDeclaration: false, + CSSValueList: false, + ClientRectList: false, + DOMRectList: false, + DOMStringList: false, + DOMTokenList: true, + DataTransferItemList: false, + FileList: false, + HTMLAllCollection: false, + HTMLCollection: false, + HTMLFormElement: false, + HTMLSelectElement: false, + MediaList: true, // TODO: Not spec compliant, should be false. + MimeTypeArray: false, + NamedNodeMap: false, + NodeList: true, + PaintRequestList: false, + Plugin: false, + PluginArray: false, + SVGLengthList: false, + SVGNumberList: false, + SVGPathSegList: false, + SVGPointList: false, + SVGStringList: false, + SVGTransformList: false, + SourceBufferList: false, + StyleSheetList: true, // TODO: Not spec compliant, should be false. + TextTrackCueList: false, + TextTrackList: false, + TouchList: false + }; + + for (var collections = _objectKeys(DOMIterables), i = 0; i < collections.length; i++) { + var NAME$1 = collections[i]; + var explicit = DOMIterables[NAME$1]; + var Collection = _global[NAME$1]; + var proto = Collection && Collection.prototype; + var key; + if (proto) { + if (!proto[ITERATOR$1]) _hide(proto, ITERATOR$1, ArrayValues); + if (!proto[TO_STRING_TAG]) _hide(proto, TO_STRING_TAG, NAME$1); + _iterators[NAME$1] = ArrayValues; + if (explicit) for (key in es6_array_iterator) if (!proto[key]) _redefine(proto, key, es6_array_iterator[key], true); + } + } + + var $at = _stringAt(true); + + // 21.1.3.27 String.prototype[@@iterator]() + _iterDefine(String, 'String', function (iterated) { + this._t = String(iterated); // target + this._i = 0; // next index + // 21.1.5.2.1 %StringIteratorPrototype%.next() + }, function () { + var O = this._t; + var index = this._i; + var point; + if (index >= O.length) return { value: undefined, done: true }; + point = $at(O, index); + this._i += point.length; + return { value: point, done: false }; + }); + + // call something on iterator step with safe closing on error + + var _iterCall = function (iterator, fn, value, entries) { + try { + return entries ? fn(_anObject(value)[0], value[1]) : fn(value); + // 7.4.6 IteratorClose(iterator, completion) + } catch (e) { + var ret = iterator['return']; + if (ret !== undefined) _anObject(ret.call(iterator)); + throw e; + } + }; + + // check on default Array iterator + + var ITERATOR$2 = _wks('iterator'); + var ArrayProto$1 = Array.prototype; + + var _isArrayIter = function (it) { + return it !== undefined && (_iterators.Array === it || ArrayProto$1[ITERATOR$2] === it); + }; + + var _createProperty = function (object, index, value) { + if (index in object) _objectDp.f(object, index, _propertyDesc(0, value)); + else object[index] = value; + }; + + var ITERATOR$3 = _wks('iterator'); + + var core_getIteratorMethod = _core.getIteratorMethod = function (it) { + if (it != undefined) return it[ITERATOR$3] + || it['@@iterator'] + || _iterators[_classof(it)]; + }; + + var ITERATOR$4 = _wks('iterator'); + var SAFE_CLOSING = false; + + try { + var riter = [7][ITERATOR$4](); + riter['return'] = function () { SAFE_CLOSING = true; }; + } catch (e) { /* empty */ } + + var _iterDetect = function (exec, skipClosing) { + if (!skipClosing && !SAFE_CLOSING) return false; + var safe = false; + try { + var arr = [7]; + var iter = arr[ITERATOR$4](); + iter.next = function () { return { done: safe = true }; }; + arr[ITERATOR$4] = function () { return iter; }; + exec(arr); + } catch (e) { /* empty */ } + return safe; + }; + + _export(_export.S + _export.F * !_iterDetect(function (iter) { }), 'Array', { + // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined) + from: function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) { + var O = _toObject(arrayLike); + var C = typeof this == 'function' ? this : Array; + var aLen = arguments.length; + var mapfn = aLen > 1 ? arguments[1] : undefined; + var mapping = mapfn !== undefined; + var index = 0; + var iterFn = core_getIteratorMethod(O); + var length, result, step, iterator; + if (mapping) mapfn = _ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2); + // if object isn't iterable or it's array with default iterator - use simple case + if (iterFn != undefined && !(C == Array && _isArrayIter(iterFn))) { + for (iterator = iterFn.call(O), result = new C(); !(step = iterator.next()).done; index++) { + _createProperty(result, index, mapping ? _iterCall(iterator, mapfn, [step.value, index], true) : step.value); + } + } else { + length = _toLength(O.length); + for (result = new C(length); length > index; index++) { + _createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]); + } + } + result.length = index; + return result; + } + }); + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; + } + + function _objectSpread(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; + var ownKeys = Object.keys(source); + + if (typeof Object.getOwnPropertySymbols === 'function') { + ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { + return Object.getOwnPropertyDescriptor(source, sym).enumerable; + })); + } + + ownKeys.forEach(function (key) { + _defineProperty(target, key, source[key]); + }); + } + + return target; + } + + var scrollbarWidth = createCommonjsModule(function (module, exports) { + /*! scrollbarWidth.js v0.1.3 | felixexter | MIT | https://github.com/felixexter/scrollbarWidth */ + (function (root, factory) { + { + module.exports = factory(); + } + }(commonjsGlobal, function () { + + function scrollbarWidth() { + if (typeof document === 'undefined') { + return 0 + } + + var + body = document.body, + box = document.createElement('div'), + boxStyle = box.style, + width; + + boxStyle.position = 'absolute'; + boxStyle.top = boxStyle.left = '-9999px'; + boxStyle.width = boxStyle.height = '100px'; + boxStyle.overflow = 'scroll'; + + body.appendChild(box); + + width = box.offsetWidth - box.clientWidth; + + body.removeChild(box); + + return width; + } + + return scrollbarWidth; + })); + }); + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + + /** Used as the `TypeError` message for "Functions" methods. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used as references for various `Number` constants. */ + var NAN = 0 / 0; + + /** `Object#toString` result references. */ + var symbolTag = '[object Symbol]'; + + /** Used to match leading and trailing whitespace. */ + var reTrim = /^\s+|\s+$/g; + + /** Used to detect bad signed hexadecimal string values. */ + var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + + /** Used to detect binary string values. */ + var reIsBinary = /^0b[01]+$/i; + + /** Used to detect octal string values. */ + var reIsOctal = /^0o[0-7]+$/i; + + /** Built-in method references without a dependency on `root`. */ + var freeParseInt = parseInt; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Used for built-in method references. */ + var objectProto = Object.prototype; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString = objectProto.toString; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeMax = Math.max, + nativeMin = Math.min; + + /** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ + var now = function() { + return root.Date.now(); + }; + + /** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide `options` to indicate whether `func` should be invoked on the + * leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent + * calls to the debounced function return the result of the last `func` + * invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the debounced function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=false] + * Specify invoking on the leading edge of the timeout. + * @param {number} [options.maxWait] + * The maximum time `func` is allowed to be delayed before it's invoked. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ + function debounce(func, wait, options) { + var lastArgs, + lastThis, + maxWait, + result, + timerId, + lastCallTime, + lastInvokeTime = 0, + leading = false, + maxing = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = toNumber(wait) || 0; + if (isObject(options)) { + leading = !!options.leading; + maxing = 'maxWait' in options; + maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function invokeFunc(time) { + var args = lastArgs, + thisArg = lastThis; + + lastArgs = lastThis = undefined; + lastInvokeTime = time; + result = func.apply(thisArg, args); + return result; + } + + function leadingEdge(time) { + // Reset any `maxWait` timer. + lastInvokeTime = time; + // Start the timer for the trailing edge. + timerId = setTimeout(timerExpired, wait); + // Invoke the leading edge. + return leading ? invokeFunc(time) : result; + } + + function remainingWait(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime, + result = wait - timeSinceLastCall; + + return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result; + } + + function shouldInvoke(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime; + + // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge, or we've hit the `maxWait` limit. + return (lastCallTime === undefined || (timeSinceLastCall >= wait) || + (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); + } + + function timerExpired() { + var time = now(); + if (shouldInvoke(time)) { + return trailingEdge(time); + } + // Restart the timer. + timerId = setTimeout(timerExpired, remainingWait(time)); + } + + function trailingEdge(time) { + timerId = undefined; + + // Only invoke if we have `lastArgs` which means `func` has been + // debounced at least once. + if (trailing && lastArgs) { + return invokeFunc(time); + } + lastArgs = lastThis = undefined; + return result; + } + + function cancel() { + if (timerId !== undefined) { + clearTimeout(timerId); + } + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = undefined; + } + + function flush() { + return timerId === undefined ? result : trailingEdge(now()); + } + + function debounced() { + var time = now(), + isInvoking = shouldInvoke(time); + + lastArgs = arguments; + lastThis = this; + lastCallTime = time; + + if (isInvoking) { + if (timerId === undefined) { + return leadingEdge(lastCallTime); + } + if (maxing) { + // Handle invocations in a tight loop. + timerId = setTimeout(timerExpired, wait); + return invokeFunc(lastCallTime); + } + } + if (timerId === undefined) { + timerId = setTimeout(timerExpired, wait); + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; + } + + /** + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed `func` invocations and a `flush` method to + * immediately invoke them. Provide `options` to indicate whether `func` + * should be invoked on the leading and/or trailing edge of the `wait` + * timeout. The `func` is invoked with the last arguments provided to the + * throttled function. Subsequent calls to the throttled function return the + * result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the throttled function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=true] + * Specify invoking on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // Avoid excessively updating the position while scrolling. + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. + * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); + * jQuery(element).on('click', throttled); + * + * // Cancel the trailing throttled invocation. + * jQuery(window).on('popstate', throttled.cancel); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + return debounce(func, wait, { + 'leading': leading, + 'maxWait': wait, + 'trailing': trailing + }); + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); + } + + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ + function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ''); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); + } + + var lodash_throttle = throttle; + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + + /** Used as the `TypeError` message for "Functions" methods. */ + var FUNC_ERROR_TEXT$1 = 'Expected a function'; + + /** Used as references for various `Number` constants. */ + var NAN$1 = 0 / 0; + + /** `Object#toString` result references. */ + var symbolTag$1 = '[object Symbol]'; + + /** Used to match leading and trailing whitespace. */ + var reTrim$1 = /^\s+|\s+$/g; + + /** Used to detect bad signed hexadecimal string values. */ + var reIsBadHex$1 = /^[-+]0x[0-9a-f]+$/i; + + /** Used to detect binary string values. */ + var reIsBinary$1 = /^0b[01]+$/i; + + /** Used to detect octal string values. */ + var reIsOctal$1 = /^0o[0-7]+$/i; + + /** Built-in method references without a dependency on `root`. */ + var freeParseInt$1 = parseInt; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal$1 = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; + + /** Detect free variable `self`. */ + var freeSelf$1 = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root$1 = freeGlobal$1 || freeSelf$1 || Function('return this')(); + + /** Used for built-in method references. */ + var objectProto$1 = Object.prototype; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString$1 = objectProto$1.toString; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeMax$1 = Math.max, + nativeMin$1 = Math.min; + + /** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ + var now$1 = function() { + return root$1.Date.now(); + }; + + /** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide `options` to indicate whether `func` should be invoked on the + * leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent + * calls to the debounced function return the result of the last `func` + * invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the debounced function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=false] + * Specify invoking on the leading edge of the timeout. + * @param {number} [options.maxWait] + * The maximum time `func` is allowed to be delayed before it's invoked. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ + function debounce$1(func, wait, options) { + var lastArgs, + lastThis, + maxWait, + result, + timerId, + lastCallTime, + lastInvokeTime = 0, + leading = false, + maxing = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT$1); + } + wait = toNumber$1(wait) || 0; + if (isObject$1(options)) { + leading = !!options.leading; + maxing = 'maxWait' in options; + maxWait = maxing ? nativeMax$1(toNumber$1(options.maxWait) || 0, wait) : maxWait; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function invokeFunc(time) { + var args = lastArgs, + thisArg = lastThis; + + lastArgs = lastThis = undefined; + lastInvokeTime = time; + result = func.apply(thisArg, args); + return result; + } + + function leadingEdge(time) { + // Reset any `maxWait` timer. + lastInvokeTime = time; + // Start the timer for the trailing edge. + timerId = setTimeout(timerExpired, wait); + // Invoke the leading edge. + return leading ? invokeFunc(time) : result; + } + + function remainingWait(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime, + result = wait - timeSinceLastCall; + + return maxing ? nativeMin$1(result, maxWait - timeSinceLastInvoke) : result; + } + + function shouldInvoke(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime; + + // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge, or we've hit the `maxWait` limit. + return (lastCallTime === undefined || (timeSinceLastCall >= wait) || + (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); + } + + function timerExpired() { + var time = now$1(); + if (shouldInvoke(time)) { + return trailingEdge(time); + } + // Restart the timer. + timerId = setTimeout(timerExpired, remainingWait(time)); + } + + function trailingEdge(time) { + timerId = undefined; + + // Only invoke if we have `lastArgs` which means `func` has been + // debounced at least once. + if (trailing && lastArgs) { + return invokeFunc(time); + } + lastArgs = lastThis = undefined; + return result; + } + + function cancel() { + if (timerId !== undefined) { + clearTimeout(timerId); + } + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = undefined; + } + + function flush() { + return timerId === undefined ? result : trailingEdge(now$1()); + } + + function debounced() { + var time = now$1(), + isInvoking = shouldInvoke(time); + + lastArgs = arguments; + lastThis = this; + lastCallTime = time; + + if (isInvoking) { + if (timerId === undefined) { + return leadingEdge(lastCallTime); + } + if (maxing) { + // Handle invocations in a tight loop. + timerId = setTimeout(timerExpired, wait); + return invokeFunc(lastCallTime); + } + } + if (timerId === undefined) { + timerId = setTimeout(timerExpired, wait); + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject$1(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike$1(value) { + return !!value && typeof value == 'object'; + } + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol$1(value) { + return typeof value == 'symbol' || + (isObjectLike$1(value) && objectToString$1.call(value) == symbolTag$1); + } + + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ + function toNumber$1(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol$1(value)) { + return NAN$1; + } + if (isObject$1(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject$1(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim$1, ''); + var isBinary = reIsBinary$1.test(value); + return (isBinary || reIsOctal$1.test(value)) + ? freeParseInt$1(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex$1.test(value) ? NAN$1 : +value); + } + + var lodash_debounce = debounce$1; + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + + /** Used as the `TypeError` message for "Functions" methods. */ + var FUNC_ERROR_TEXT$2 = 'Expected a function'; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** `Object#toString` result references. */ + var funcTag = '[object Function]', + genTag = '[object GeneratorFunction]'; + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal$2 = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; + + /** Detect free variable `self`. */ + var freeSelf$2 = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root$2 = freeGlobal$2 || freeSelf$2 || Function('return this')(); + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ + function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; + } + + /** Used for built-in method references. */ + var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto$2 = Object.prototype; + + /** Used to detect overreaching core-js shims. */ + var coreJsData = root$2['__core-js_shared__']; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty$1 = objectProto$2.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString$2 = objectProto$2.toString; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty$1).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Built-in value references. */ + var splice = arrayProto.splice; + + /* Built-in method references that are verified to be native. */ + var Map$1 = getNative(root$2, 'Map'), + nativeCreate = getNative(Object, 'create'); + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + } + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + return this.has(key) && delete this.__data__[key]; + } + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty$1.call(data, key) ? data[key] : undefined; + } + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined : hasOwnProperty$1.call(data, key); + } + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + } + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.__data__ = { + 'hash': new Hash, + 'map': new (Map$1 || ListCache), + 'string': new Hash + }; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + return getMapData(this, key)['delete'](key); + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + getMapData(this, key).set(key, value); + return this; + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject$2(value) || isMasked(value)) { + return false; + } + var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to process. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoized function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; + */ + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT$2); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result); + return result; + }; + memoized.cache = new (memoize.Cache || MapCache); + return memoized; + } + + // Assign cache to `_.memoize`. + memoize.Cache = MapCache; + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject$2(value) ? objectToString$2.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject$2(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + var lodash_memoize = memoize; + + /** + * A collection of shims that provide minimal functionality of the ES6 collections. + * + * These implementations are not meant to be used outside of the ResizeObserver + * modules as they cover only a limited range of use cases. + */ + /* eslint-disable require-jsdoc, valid-jsdoc */ + var MapShim = (function () { + if (typeof Map !== 'undefined') { + return Map; + } + /** + * Returns index in provided array that matches the specified key. + * + * @param {Array} arr + * @param {*} key + * @returns {number} + */ + function getIndex(arr, key) { + var result = -1; + arr.some(function (entry, index) { + if (entry[0] === key) { + result = index; + return true; + } + return false; + }); + return result; + } + return /** @class */ (function () { + function class_1() { + this.__entries__ = []; + } + Object.defineProperty(class_1.prototype, "size", { + /** + * @returns {boolean} + */ + get: function () { + return this.__entries__.length; + }, + enumerable: true, + configurable: true + }); + /** + * @param {*} key + * @returns {*} + */ + class_1.prototype.get = function (key) { + var index = getIndex(this.__entries__, key); + var entry = this.__entries__[index]; + return entry && entry[1]; + }; + /** + * @param {*} key + * @param {*} value + * @returns {void} + */ + class_1.prototype.set = function (key, value) { + var index = getIndex(this.__entries__, key); + if (~index) { + this.__entries__[index][1] = value; + } + else { + this.__entries__.push([key, value]); + } + }; + /** + * @param {*} key + * @returns {void} + */ + class_1.prototype.delete = function (key) { + var entries = this.__entries__; + var index = getIndex(entries, key); + if (~index) { + entries.splice(index, 1); + } + }; + /** + * @param {*} key + * @returns {void} + */ + class_1.prototype.has = function (key) { + return !!~getIndex(this.__entries__, key); + }; + /** + * @returns {void} + */ + class_1.prototype.clear = function () { + this.__entries__.splice(0); + }; + /** + * @param {Function} callback + * @param {*} [ctx=null] + * @returns {void} + */ + class_1.prototype.forEach = function (callback, ctx) { + if (ctx === void 0) { ctx = null; } + for (var _i = 0, _a = this.__entries__; _i < _a.length; _i++) { + var entry = _a[_i]; + callback.call(ctx, entry[1], entry[0]); + } + }; + return class_1; + }()); + })(); + + /** + * Detects whether window and document objects are available in current environment. + */ + var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document; + + // Returns global object of a current environment. + var global$1 = (function () { + if (typeof global !== 'undefined' && global.Math === Math) { + return global; + } + if (typeof self !== 'undefined' && self.Math === Math) { + return self; + } + if (typeof window !== 'undefined' && window.Math === Math) { + return window; + } + // eslint-disable-next-line no-new-func + return Function('return this')(); + })(); + + /** + * A shim for the requestAnimationFrame which falls back to the setTimeout if + * first one is not supported. + * + * @returns {number} Requests' identifier. + */ + var requestAnimationFrame$1 = (function () { + if (typeof requestAnimationFrame === 'function') { + // It's required to use a bounded function because IE sometimes throws + // an "Invalid calling object" error if rAF is invoked without the global + // object on the left hand side. + return requestAnimationFrame.bind(global$1); + } + return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); }; + })(); + + // Defines minimum timeout before adding a trailing call. + var trailingTimeout = 2; + /** + * Creates a wrapper function which ensures that provided callback will be + * invoked only once during the specified delay period. + * + * @param {Function} callback - Function to be invoked after the delay period. + * @param {number} delay - Delay after which to invoke callback. + * @returns {Function} + */ + function throttle$1 (callback, delay) { + var leadingCall = false, trailingCall = false, lastCallTime = 0; + /** + * Invokes the original callback function and schedules new invocation if + * the "proxy" was called during current request. + * + * @returns {void} + */ + function resolvePending() { + if (leadingCall) { + leadingCall = false; + callback(); + } + if (trailingCall) { + proxy(); + } + } + /** + * Callback invoked after the specified delay. It will further postpone + * invocation of the original function delegating it to the + * requestAnimationFrame. + * + * @returns {void} + */ + function timeoutCallback() { + requestAnimationFrame$1(resolvePending); + } + /** + * Schedules invocation of the original function. + * + * @returns {void} + */ + function proxy() { + var timeStamp = Date.now(); + if (leadingCall) { + // Reject immediately following calls. + if (timeStamp - lastCallTime < trailingTimeout) { + return; + } + // Schedule new call to be in invoked when the pending one is resolved. + // This is important for "transitions" which never actually start + // immediately so there is a chance that we might miss one if change + // happens amids the pending invocation. + trailingCall = true; + } + else { + leadingCall = true; + trailingCall = false; + setTimeout(timeoutCallback, delay); + } + lastCallTime = timeStamp; + } + return proxy; + } + + // Minimum delay before invoking the update of observers. + var REFRESH_DELAY = 20; + // A list of substrings of CSS properties used to find transition events that + // might affect dimensions of observed elements. + var transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight']; + // Check if MutationObserver is available. + var mutationObserverSupported = typeof MutationObserver !== 'undefined'; + /** + * Singleton controller class which handles updates of ResizeObserver instances. + */ + var ResizeObserverController = /** @class */ (function () { + /** + * Creates a new instance of ResizeObserverController. + * + * @private + */ + function ResizeObserverController() { + /** + * Indicates whether DOM listeners have been added. + * + * @private {boolean} + */ + this.connected_ = false; + /** + * Tells that controller has subscribed for Mutation Events. + * + * @private {boolean} + */ + this.mutationEventsAdded_ = false; + /** + * Keeps reference to the instance of MutationObserver. + * + * @private {MutationObserver} + */ + this.mutationsObserver_ = null; + /** + * A list of connected observers. + * + * @private {Array} + */ + this.observers_ = []; + this.onTransitionEnd_ = this.onTransitionEnd_.bind(this); + this.refresh = throttle$1(this.refresh.bind(this), REFRESH_DELAY); + } + /** + * Adds observer to observers list. + * + * @param {ResizeObserverSPI} observer - Observer to be added. + * @returns {void} + */ + ResizeObserverController.prototype.addObserver = function (observer) { + if (!~this.observers_.indexOf(observer)) { + this.observers_.push(observer); + } + // Add listeners if they haven't been added yet. + if (!this.connected_) { + this.connect_(); + } + }; + /** + * Removes observer from observers list. + * + * @param {ResizeObserverSPI} observer - Observer to be removed. + * @returns {void} + */ + ResizeObserverController.prototype.removeObserver = function (observer) { + var observers = this.observers_; + var index = observers.indexOf(observer); + // Remove observer if it's present in registry. + if (~index) { + observers.splice(index, 1); + } + // Remove listeners if controller has no connected observers. + if (!observers.length && this.connected_) { + this.disconnect_(); + } + }; + /** + * Invokes the update of observers. It will continue running updates insofar + * it detects changes. + * + * @returns {void} + */ + ResizeObserverController.prototype.refresh = function () { + var changesDetected = this.updateObservers_(); + // Continue running updates if changes have been detected as there might + // be future ones caused by CSS transitions. + if (changesDetected) { + this.refresh(); + } + }; + /** + * Updates every observer from observers list and notifies them of queued + * entries. + * + * @private + * @returns {boolean} Returns "true" if any observer has detected changes in + * dimensions of it's elements. + */ + ResizeObserverController.prototype.updateObservers_ = function () { + // Collect observers that have active observations. + var activeObservers = this.observers_.filter(function (observer) { + return observer.gatherActive(), observer.hasActive(); + }); + // Deliver notifications in a separate cycle in order to avoid any + // collisions between observers, e.g. when multiple instances of + // ResizeObserver are tracking the same element and the callback of one + // of them changes content dimensions of the observed target. Sometimes + // this may result in notifications being blocked for the rest of observers. + activeObservers.forEach(function (observer) { return observer.broadcastActive(); }); + return activeObservers.length > 0; + }; + /** + * Initializes DOM listeners. + * + * @private + * @returns {void} + */ + ResizeObserverController.prototype.connect_ = function () { + // Do nothing if running in a non-browser environment or if listeners + // have been already added. + if (!isBrowser || this.connected_) { + return; + } + // Subscription to the "Transitionend" event is used as a workaround for + // delayed transitions. This way it's possible to capture at least the + // final state of an element. + document.addEventListener('transitionend', this.onTransitionEnd_); + window.addEventListener('resize', this.refresh); + if (mutationObserverSupported) { + this.mutationsObserver_ = new MutationObserver(this.refresh); + this.mutationsObserver_.observe(document, { + attributes: true, + childList: true, + characterData: true, + subtree: true + }); + } + else { + document.addEventListener('DOMSubtreeModified', this.refresh); + this.mutationEventsAdded_ = true; + } + this.connected_ = true; + }; + /** + * Removes DOM listeners. + * + * @private + * @returns {void} + */ + ResizeObserverController.prototype.disconnect_ = function () { + // Do nothing if running in a non-browser environment or if listeners + // have been already removed. + if (!isBrowser || !this.connected_) { + return; + } + document.removeEventListener('transitionend', this.onTransitionEnd_); + window.removeEventListener('resize', this.refresh); + if (this.mutationsObserver_) { + this.mutationsObserver_.disconnect(); + } + if (this.mutationEventsAdded_) { + document.removeEventListener('DOMSubtreeModified', this.refresh); + } + this.mutationsObserver_ = null; + this.mutationEventsAdded_ = false; + this.connected_ = false; + }; + /** + * "Transitionend" event handler. + * + * @private + * @param {TransitionEvent} event + * @returns {void} + */ + ResizeObserverController.prototype.onTransitionEnd_ = function (_a) { + var _b = _a.propertyName, propertyName = _b === void 0 ? '' : _b; + // Detect whether transition may affect dimensions of an element. + var isReflowProperty = transitionKeys.some(function (key) { + return !!~propertyName.indexOf(key); + }); + if (isReflowProperty) { + this.refresh(); + } + }; + /** + * Returns instance of the ResizeObserverController. + * + * @returns {ResizeObserverController} + */ + ResizeObserverController.getInstance = function () { + if (!this.instance_) { + this.instance_ = new ResizeObserverController(); + } + return this.instance_; + }; + /** + * Holds reference to the controller's instance. + * + * @private {ResizeObserverController} + */ + ResizeObserverController.instance_ = null; + return ResizeObserverController; + }()); + + /** + * Defines non-writable/enumerable properties of the provided target object. + * + * @param {Object} target - Object for which to define properties. + * @param {Object} props - Properties to be defined. + * @returns {Object} Target object. + */ + var defineConfigurable = (function (target, props) { + for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) { + var key = _a[_i]; + Object.defineProperty(target, key, { + value: props[key], + enumerable: false, + writable: false, + configurable: true + }); + } + return target; + }); + + /** + * Returns the global object associated with provided element. + * + * @param {Object} target + * @returns {Object} + */ + var getWindowOf = (function (target) { + // Assume that the element is an instance of Node, which means that it + // has the "ownerDocument" property from which we can retrieve a + // corresponding global object. + var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView; + // Return the local global object if it's not possible extract one from + // provided element. + return ownerGlobal || global$1; + }); + + // Placeholder of an empty content rectangle. + var emptyRect = createRectInit(0, 0, 0, 0); + /** + * Converts provided string to a number. + * + * @param {number|string} value + * @returns {number} + */ + function toFloat(value) { + return parseFloat(value) || 0; + } + /** + * Extracts borders size from provided styles. + * + * @param {CSSStyleDeclaration} styles + * @param {...string} positions - Borders positions (top, right, ...) + * @returns {number} + */ + function getBordersSize(styles) { + var positions = []; + for (var _i = 1; _i < arguments.length; _i++) { + positions[_i - 1] = arguments[_i]; + } + return positions.reduce(function (size, position) { + var value = styles['border-' + position + '-width']; + return size + toFloat(value); + }, 0); + } + /** + * Extracts paddings sizes from provided styles. + * + * @param {CSSStyleDeclaration} styles + * @returns {Object} Paddings box. + */ + function getPaddings(styles) { + var positions = ['top', 'right', 'bottom', 'left']; + var paddings = {}; + for (var _i = 0, positions_1 = positions; _i < positions_1.length; _i++) { + var position = positions_1[_i]; + var value = styles['padding-' + position]; + paddings[position] = toFloat(value); + } + return paddings; + } + /** + * Calculates content rectangle of provided SVG element. + * + * @param {SVGGraphicsElement} target - Element content rectangle of which needs + * to be calculated. + * @returns {DOMRectInit} + */ + function getSVGContentRect(target) { + var bbox = target.getBBox(); + return createRectInit(0, 0, bbox.width, bbox.height); + } + /** + * Calculates content rectangle of provided HTMLElement. + * + * @param {HTMLElement} target - Element for which to calculate the content rectangle. + * @returns {DOMRectInit} + */ + function getHTMLElementContentRect(target) { + // Client width & height properties can't be + // used exclusively as they provide rounded values. + var clientWidth = target.clientWidth, clientHeight = target.clientHeight; + // By this condition we can catch all non-replaced inline, hidden and + // detached elements. Though elements with width & height properties less + // than 0.5 will be discarded as well. + // + // Without it we would need to implement separate methods for each of + // those cases and it's not possible to perform a precise and performance + // effective test for hidden elements. E.g. even jQuery's ':visible' filter + // gives wrong results for elements with width & height less than 0.5. + if (!clientWidth && !clientHeight) { + return emptyRect; + } + var styles = getWindowOf(target).getComputedStyle(target); + var paddings = getPaddings(styles); + var horizPad = paddings.left + paddings.right; + var vertPad = paddings.top + paddings.bottom; + // Computed styles of width & height are being used because they are the + // only dimensions available to JS that contain non-rounded values. It could + // be possible to utilize the getBoundingClientRect if only it's data wasn't + // affected by CSS transformations let alone paddings, borders and scroll bars. + var width = toFloat(styles.width), height = toFloat(styles.height); + // Width & height include paddings and borders when the 'border-box' box + // model is applied (except for IE). + if (styles.boxSizing === 'border-box') { + // Following conditions are required to handle Internet Explorer which + // doesn't include paddings and borders to computed CSS dimensions. + // + // We can say that if CSS dimensions + paddings are equal to the "client" + // properties then it's either IE, and thus we don't need to subtract + // anything, or an element merely doesn't have paddings/borders styles. + if (Math.round(width + horizPad) !== clientWidth) { + width -= getBordersSize(styles, 'left', 'right') + horizPad; + } + if (Math.round(height + vertPad) !== clientHeight) { + height -= getBordersSize(styles, 'top', 'bottom') + vertPad; + } + } + // Following steps can't be applied to the document's root element as its + // client[Width/Height] properties represent viewport area of the window. + // Besides, it's as well not necessary as the itself neither has + // rendered scroll bars nor it can be clipped. + if (!isDocumentElement(target)) { + // In some browsers (only in Firefox, actually) CSS width & height + // include scroll bars size which can be removed at this step as scroll + // bars are the only difference between rounded dimensions + paddings + // and "client" properties, though that is not always true in Chrome. + var vertScrollbar = Math.round(width + horizPad) - clientWidth; + var horizScrollbar = Math.round(height + vertPad) - clientHeight; + // Chrome has a rather weird rounding of "client" properties. + // E.g. for an element with content width of 314.2px it sometimes gives + // the client width of 315px and for the width of 314.7px it may give + // 314px. And it doesn't happen all the time. So just ignore this delta + // as a non-relevant. + if (Math.abs(vertScrollbar) !== 1) { + width -= vertScrollbar; + } + if (Math.abs(horizScrollbar) !== 1) { + height -= horizScrollbar; + } + } + return createRectInit(paddings.left, paddings.top, width, height); + } + /** + * Checks whether provided element is an instance of the SVGGraphicsElement. + * + * @param {Element} target - Element to be checked. + * @returns {boolean} + */ + var isSVGGraphicsElement = (function () { + // Some browsers, namely IE and Edge, don't have the SVGGraphicsElement + // interface. + if (typeof SVGGraphicsElement !== 'undefined') { + return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; }; + } + // If it's so, then check that element is at least an instance of the + // SVGElement and that it has the "getBBox" method. + // eslint-disable-next-line no-extra-parens + return function (target) { return (target instanceof getWindowOf(target).SVGElement && + typeof target.getBBox === 'function'); }; + })(); + /** + * Checks whether provided element is a document element (). + * + * @param {Element} target - Element to be checked. + * @returns {boolean} + */ + function isDocumentElement(target) { + return target === getWindowOf(target).document.documentElement; + } + /** + * Calculates an appropriate content rectangle for provided html or svg element. + * + * @param {Element} target - Element content rectangle of which needs to be calculated. + * @returns {DOMRectInit} + */ + function getContentRect(target) { + if (!isBrowser) { + return emptyRect; + } + if (isSVGGraphicsElement(target)) { + return getSVGContentRect(target); + } + return getHTMLElementContentRect(target); + } + /** + * Creates rectangle with an interface of the DOMRectReadOnly. + * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly + * + * @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions. + * @returns {DOMRectReadOnly} + */ + function createReadOnlyRect(_a) { + var x = _a.x, y = _a.y, width = _a.width, height = _a.height; + // If DOMRectReadOnly is available use it as a prototype for the rectangle. + var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object; + var rect = Object.create(Constr.prototype); + // Rectangle's properties are not writable and non-enumerable. + defineConfigurable(rect, { + x: x, y: y, width: width, height: height, + top: y, + right: x + width, + bottom: height + y, + left: x + }); + return rect; + } + /** + * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates. + * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit + * + * @param {number} x - X coordinate. + * @param {number} y - Y coordinate. + * @param {number} width - Rectangle's width. + * @param {number} height - Rectangle's height. + * @returns {DOMRectInit} + */ + function createRectInit(x, y, width, height) { + return { x: x, y: y, width: width, height: height }; + } + + /** + * Class that is responsible for computations of the content rectangle of + * provided DOM element and for keeping track of it's changes. + */ + var ResizeObservation = /** @class */ (function () { + /** + * Creates an instance of ResizeObservation. + * + * @param {Element} target - Element to be observed. + */ + function ResizeObservation(target) { + /** + * Broadcasted width of content rectangle. + * + * @type {number} + */ + this.broadcastWidth = 0; + /** + * Broadcasted height of content rectangle. + * + * @type {number} + */ + this.broadcastHeight = 0; + /** + * Reference to the last observed content rectangle. + * + * @private {DOMRectInit} + */ + this.contentRect_ = createRectInit(0, 0, 0, 0); + this.target = target; + } + /** + * Updates content rectangle and tells whether it's width or height properties + * have changed since the last broadcast. + * + * @returns {boolean} + */ + ResizeObservation.prototype.isActive = function () { + var rect = getContentRect(this.target); + this.contentRect_ = rect; + return (rect.width !== this.broadcastWidth || + rect.height !== this.broadcastHeight); + }; + /** + * Updates 'broadcastWidth' and 'broadcastHeight' properties with a data + * from the corresponding properties of the last observed content rectangle. + * + * @returns {DOMRectInit} Last observed content rectangle. + */ + ResizeObservation.prototype.broadcastRect = function () { + var rect = this.contentRect_; + this.broadcastWidth = rect.width; + this.broadcastHeight = rect.height; + return rect; + }; + return ResizeObservation; + }()); + + var ResizeObserverEntry = /** @class */ (function () { + /** + * Creates an instance of ResizeObserverEntry. + * + * @param {Element} target - Element that is being observed. + * @param {DOMRectInit} rectInit - Data of the element's content rectangle. + */ + function ResizeObserverEntry(target, rectInit) { + var contentRect = createReadOnlyRect(rectInit); + // According to the specification following properties are not writable + // and are also not enumerable in the native implementation. + // + // Property accessors are not being used as they'd require to define a + // private WeakMap storage which may cause memory leaks in browsers that + // don't support this type of collections. + defineConfigurable(this, { target: target, contentRect: contentRect }); + } + return ResizeObserverEntry; + }()); + + var ResizeObserverSPI = /** @class */ (function () { + /** + * Creates a new instance of ResizeObserver. + * + * @param {ResizeObserverCallback} callback - Callback function that is invoked + * when one of the observed elements changes it's content dimensions. + * @param {ResizeObserverController} controller - Controller instance which + * is responsible for the updates of observer. + * @param {ResizeObserver} callbackCtx - Reference to the public + * ResizeObserver instance which will be passed to callback function. + */ + function ResizeObserverSPI(callback, controller, callbackCtx) { + /** + * Collection of resize observations that have detected changes in dimensions + * of elements. + * + * @private {Array} + */ + this.activeObservations_ = []; + /** + * Registry of the ResizeObservation instances. + * + * @private {Map} + */ + this.observations_ = new MapShim(); + if (typeof callback !== 'function') { + throw new TypeError('The callback provided as parameter 1 is not a function.'); + } + this.callback_ = callback; + this.controller_ = controller; + this.callbackCtx_ = callbackCtx; + } + /** + * Starts observing provided element. + * + * @param {Element} target - Element to be observed. + * @returns {void} + */ + ResizeObserverSPI.prototype.observe = function (target) { + if (!arguments.length) { + throw new TypeError('1 argument required, but only 0 present.'); + } + // Do nothing if current environment doesn't have the Element interface. + if (typeof Element === 'undefined' || !(Element instanceof Object)) { + return; + } + if (!(target instanceof getWindowOf(target).Element)) { + throw new TypeError('parameter 1 is not of type "Element".'); + } + var observations = this.observations_; + // Do nothing if element is already being observed. + if (observations.has(target)) { + return; + } + observations.set(target, new ResizeObservation(target)); + this.controller_.addObserver(this); + // Force the update of observations. + this.controller_.refresh(); + }; + /** + * Stops observing provided element. + * + * @param {Element} target - Element to stop observing. + * @returns {void} + */ + ResizeObserverSPI.prototype.unobserve = function (target) { + if (!arguments.length) { + throw new TypeError('1 argument required, but only 0 present.'); + } + // Do nothing if current environment doesn't have the Element interface. + if (typeof Element === 'undefined' || !(Element instanceof Object)) { + return; + } + if (!(target instanceof getWindowOf(target).Element)) { + throw new TypeError('parameter 1 is not of type "Element".'); + } + var observations = this.observations_; + // Do nothing if element is not being observed. + if (!observations.has(target)) { + return; + } + observations.delete(target); + if (!observations.size) { + this.controller_.removeObserver(this); + } + }; + /** + * Stops observing all elements. + * + * @returns {void} + */ + ResizeObserverSPI.prototype.disconnect = function () { + this.clearActive(); + this.observations_.clear(); + this.controller_.removeObserver(this); + }; + /** + * Collects observation instances the associated element of which has changed + * it's content rectangle. + * + * @returns {void} + */ + ResizeObserverSPI.prototype.gatherActive = function () { + var _this = this; + this.clearActive(); + this.observations_.forEach(function (observation) { + if (observation.isActive()) { + _this.activeObservations_.push(observation); + } + }); + }; + /** + * Invokes initial callback function with a list of ResizeObserverEntry + * instances collected from active resize observations. + * + * @returns {void} + */ + ResizeObserverSPI.prototype.broadcastActive = function () { + // Do nothing if observer doesn't have active observations. + if (!this.hasActive()) { + return; + } + var ctx = this.callbackCtx_; + // Create ResizeObserverEntry instance for every active observation. + var entries = this.activeObservations_.map(function (observation) { + return new ResizeObserverEntry(observation.target, observation.broadcastRect()); + }); + this.callback_.call(ctx, entries, ctx); + this.clearActive(); + }; + /** + * Clears the collection of active observations. + * + * @returns {void} + */ + ResizeObserverSPI.prototype.clearActive = function () { + this.activeObservations_.splice(0); + }; + /** + * Tells whether observer has active observations. + * + * @returns {boolean} + */ + ResizeObserverSPI.prototype.hasActive = function () { + return this.activeObservations_.length > 0; + }; + return ResizeObserverSPI; + }()); + + // Registry of internal observers. If WeakMap is not available use current shim + // for the Map collection as it has all required methods and because WeakMap + // can't be fully polyfilled anyway. + var observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim(); + /** + * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation + * exposing only those methods and properties that are defined in the spec. + */ + var ResizeObserver = /** @class */ (function () { + /** + * Creates a new instance of ResizeObserver. + * + * @param {ResizeObserverCallback} callback - Callback that is invoked when + * dimensions of the observed elements change. + */ + function ResizeObserver(callback) { + if (!(this instanceof ResizeObserver)) { + throw new TypeError('Cannot call a class as a function.'); + } + if (!arguments.length) { + throw new TypeError('1 argument required, but only 0 present.'); + } + var controller = ResizeObserverController.getInstance(); + var observer = new ResizeObserverSPI(callback, controller, this); + observers.set(this, observer); + } + return ResizeObserver; + }()); + // Expose public methods of ResizeObserver. + [ + 'observe', + 'unobserve', + 'disconnect' + ].forEach(function (method) { + ResizeObserver.prototype[method] = function () { + var _a; + return (_a = observers.get(this))[method].apply(_a, arguments); + }; + }); + + var index = (function () { + // Export existing implementation if available. + if (typeof global$1.ResizeObserver !== 'undefined') { + return global$1.ResizeObserver; + } + return ResizeObserver; + })(); + + var canUseDOM = !!( + typeof window !== 'undefined' && + window.document && + window.document.createElement + ); + + var canUseDom = canUseDOM; + + var SimpleBar = + /*#__PURE__*/ + function () { + function SimpleBar(element, options) { + var _this = this; + + _classCallCheck(this, SimpleBar); + + this.onScroll = function () { + if (!_this.scrollXTicking) { + window.requestAnimationFrame(_this.scrollX); + _this.scrollXTicking = true; + } + + if (!_this.scrollYTicking) { + window.requestAnimationFrame(_this.scrollY); + _this.scrollYTicking = true; + } + }; + + this.scrollX = function () { + if (_this.axis.x.isOverflowing) { + _this.showScrollbar('x'); + + _this.positionScrollbar('x'); + } + + _this.scrollXTicking = false; + }; + + this.scrollY = function () { + if (_this.axis.y.isOverflowing) { + _this.showScrollbar('y'); + + _this.positionScrollbar('y'); + } + + _this.scrollYTicking = false; + }; + + this.onMouseEnter = function () { + _this.showScrollbar('x'); + + _this.showScrollbar('y'); + }; + + this.onMouseMove = function (e) { + _this.mouseX = e.clientX; + _this.mouseY = e.clientY; + + if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) { + _this.onMouseMoveForAxis('x'); + } + + if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) { + _this.onMouseMoveForAxis('y'); + } + }; + + this.onMouseLeave = function () { + _this.onMouseMove.cancel(); + + if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) { + _this.onMouseLeaveForAxis('x'); + } + + if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) { + _this.onMouseLeaveForAxis('y'); + } + + _this.mouseX = -1; + _this.mouseY = -1; + }; + + this.onWindowResize = function () { + // Recalculate scrollbarWidth in case it's a zoom + _this.scrollbarWidth = scrollbarWidth(); + + _this.hideNativeScrollbar(); + }; + + this.hideScrollbars = function () { + _this.axis.x.track.rect = _this.axis.x.track.el.getBoundingClientRect(); + _this.axis.y.track.rect = _this.axis.y.track.el.getBoundingClientRect(); + + if (!_this.isWithinBounds(_this.axis.y.track.rect)) { + _this.axis.y.scrollbar.el.classList.remove(_this.classNames.visible); + + _this.axis.y.isVisible = false; + } + + if (!_this.isWithinBounds(_this.axis.x.track.rect)) { + _this.axis.x.scrollbar.el.classList.remove(_this.classNames.visible); + + _this.axis.x.isVisible = false; + } + }; + + this.onPointerEvent = function (e) { + var isWithinBoundsY, isWithinBoundsX; + _this.axis.x.scrollbar.rect = _this.axis.x.scrollbar.el.getBoundingClientRect(); + _this.axis.y.scrollbar.rect = _this.axis.y.scrollbar.el.getBoundingClientRect(); + + if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) { + isWithinBoundsX = _this.isWithinBounds(_this.axis.x.scrollbar.rect); + } + + if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) { + isWithinBoundsY = _this.isWithinBounds(_this.axis.y.scrollbar.rect); + } // If any pointer event is called on the scrollbar + + + if (isWithinBoundsY || isWithinBoundsX) { + // Preventing the event's default action stops text being + // selectable during the drag. + e.preventDefault(); // Prevent event leaking + + e.stopPropagation(); + + if (e.type === 'mousedown') { + if (isWithinBoundsY) { + _this.onDragStart(e, 'y'); + } + + if (isWithinBoundsX) { + _this.onDragStart(e, 'x'); + } + } + } + }; + + this.drag = function (e) { + var eventOffset; + var track = _this.axis[_this.draggedAxis].track; + var trackSize = track.rect[_this.axis[_this.draggedAxis].sizeAttr]; + var scrollbar = _this.axis[_this.draggedAxis].scrollbar; + e.preventDefault(); + e.stopPropagation(); + + if (_this.draggedAxis === 'y') { + eventOffset = e.pageY; + } else { + eventOffset = e.pageX; + } // Calculate how far the user's mouse is from the top/left of the scrollbar (minus the dragOffset). + + + var dragPos = eventOffset - track.rect[_this.axis[_this.draggedAxis].offsetAttr] - _this.axis[_this.draggedAxis].dragOffset; // Convert the mouse position into a percentage of the scrollbar height/width. + + var dragPerc = dragPos / track.rect[_this.axis[_this.draggedAxis].sizeAttr]; // Scroll the content by the same percentage. + + var scrollPos = dragPerc * _this.contentEl[_this.axis[_this.draggedAxis].scrollSizeAttr]; // Fix browsers inconsistency on RTL + + if (_this.draggedAxis === 'x') { + scrollPos = _this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollbarInverted ? scrollPos - (trackSize + scrollbar.size) : scrollPos; + scrollPos = _this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollingInverted ? -scrollPos : scrollPos; + } + + _this.contentEl[_this.axis[_this.draggedAxis].scrollOffsetAttr] = scrollPos; + }; + + this.onEndDrag = function (e) { + e.preventDefault(); + e.stopPropagation(); + document.removeEventListener('mousemove', _this.drag); + document.removeEventListener('mouseup', _this.onEndDrag); + }; + + this.el = element; + this.flashTimeout; + this.contentEl; + this.offsetEl; + this.maskEl; + this.globalObserver; + this.mutationObserver; + this.resizeObserver; + this.scrollbarWidth; + this.minScrollbarWidth = 20; + this.options = _objectSpread({}, SimpleBar.defaultOptions, options); + this.classNames = _objectSpread({}, SimpleBar.defaultOptions.classNames, this.options.classNames); + this.isRtl; + this.axis = { + x: { + scrollOffsetAttr: 'scrollLeft', + sizeAttr: 'width', + scrollSizeAttr: 'scrollWidth', + offsetAttr: 'left', + overflowAttr: 'overflowX', + dragOffset: 0, + isOverflowing: true, + isVisible: false, + forceVisible: false, + track: {}, + scrollbar: {} + }, + y: { + scrollOffsetAttr: 'scrollTop', + sizeAttr: 'height', + scrollSizeAttr: 'scrollHeight', + offsetAttr: 'top', + overflowAttr: 'overflowY', + dragOffset: 0, + isOverflowing: true, + isVisible: false, + forceVisible: false, + track: {}, + scrollbar: {} + } + }; + this.recalculate = lodash_throttle(this.recalculate.bind(this), 64); + this.onMouseMove = lodash_throttle(this.onMouseMove.bind(this), 64); + this.hideScrollbars = lodash_debounce(this.hideScrollbars.bind(this), this.options.timeout); + this.onWindowResize = lodash_debounce(this.onWindowResize.bind(this), 64, { + leading: true + }); + SimpleBar.getRtlHelpers = lodash_memoize(SimpleBar.getRtlHelpers); // getContentElement is deprecated + + this.getContentElement = this.getScrollElement; + this.init(); + } + /** + * Static properties + */ + + /** + * Helper to fix browsers inconsistency on RTL: + * - Firefox inverts the scrollbar initial position + * - IE11 inverts both scrollbar position and scrolling offset + * Directly inspired by @KingSora's OverlayScrollbars https://github.com/KingSora/OverlayScrollbars/blob/master/js/OverlayScrollbars.js#L1634 + */ + + + _createClass(SimpleBar, [{ + key: "init", + value: function init() { + // Save a reference to the instance, so we know this DOM node has already been instancied + this.el.SimpleBar = this; // We stop here on server-side + + if (canUseDom) { + this.initDOM(); + this.scrollbarWidth = scrollbarWidth(); + this.recalculate(); + this.initListeners(); + } + } + }, { + key: "initDOM", + value: function initDOM() { + var _this2 = this; + + // make sure this element doesn't have the elements yet + if (Array.from(this.el.children).filter(function (child) { + return child.classList.contains(_this2.classNames.wrapper); + }).length) { + // assume that element has his DOM already initiated + this.wrapperEl = this.el.querySelector(".".concat(this.classNames.wrapper)); + this.contentEl = this.el.querySelector(".".concat(this.classNames.content)); + this.offsetEl = this.el.querySelector(".".concat(this.classNames.offset)); + this.maskEl = this.el.querySelector(".".concat(this.classNames.mask)); + this.placeholderEl = this.el.querySelector(".".concat(this.classNames.placeholder)); + this.heightAutoObserverWrapperEl = this.el.querySelector(".".concat(this.classNames.heightAutoObserverWrapperEl)); + this.heightAutoObserverEl = this.el.querySelector(".".concat(this.classNames.heightAutoObserverEl)); + this.axis.x.track.el = this.el.querySelector(".".concat(this.classNames.track, ".").concat(this.classNames.horizontal)); + this.axis.y.track.el = this.el.querySelector(".".concat(this.classNames.track, ".").concat(this.classNames.vertical)); + } else { + // Prepare DOM + this.wrapperEl = document.createElement('div'); + this.contentEl = document.createElement('div'); + this.offsetEl = document.createElement('div'); + this.maskEl = document.createElement('div'); + this.placeholderEl = document.createElement('div'); + this.heightAutoObserverWrapperEl = document.createElement('div'); + this.heightAutoObserverEl = document.createElement('div'); + this.wrapperEl.classList.add(this.classNames.wrapper); + this.contentEl.classList.add(this.classNames.content); + this.offsetEl.classList.add(this.classNames.offset); + this.maskEl.classList.add(this.classNames.mask); + this.placeholderEl.classList.add(this.classNames.placeholder); + this.heightAutoObserverWrapperEl.classList.add(this.classNames.heightAutoObserverWrapperEl); + this.heightAutoObserverEl.classList.add(this.classNames.heightAutoObserverEl); + + while (this.el.firstChild) { + this.contentEl.appendChild(this.el.firstChild); + } + + this.offsetEl.appendChild(this.contentEl); + this.maskEl.appendChild(this.offsetEl); + this.heightAutoObserverWrapperEl.appendChild(this.heightAutoObserverEl); + this.wrapperEl.appendChild(this.heightAutoObserverWrapperEl); + this.wrapperEl.appendChild(this.maskEl); + this.wrapperEl.appendChild(this.placeholderEl); + this.el.appendChild(this.wrapperEl); + } + + if (!this.axis.x.track.el || !this.axis.y.track.el) { + var track = document.createElement('div'); + var scrollbar = document.createElement('div'); + track.classList.add(this.classNames.track); + scrollbar.classList.add(this.classNames.scrollbar); + + if (!this.options.autoHide) { + scrollbar.classList.add(this.classNames.visible); + } + + track.appendChild(scrollbar); + this.axis.x.track.el = track.cloneNode(true); + this.axis.x.track.el.classList.add(this.classNames.horizontal); + this.axis.y.track.el = track.cloneNode(true); + this.axis.y.track.el.classList.add(this.classNames.vertical); + this.el.appendChild(this.axis.x.track.el); + this.el.appendChild(this.axis.y.track.el); + } + + this.axis.x.scrollbar.el = this.axis.x.track.el.querySelector(".".concat(this.classNames.scrollbar)); + this.axis.y.scrollbar.el = this.axis.y.track.el.querySelector(".".concat(this.classNames.scrollbar)); + this.el.setAttribute('data-simplebar', 'init'); + } + }, { + key: "initListeners", + value: function initListeners() { + var _this3 = this; + + // Event listeners + if (this.options.autoHide) { + this.el.addEventListener('mouseenter', this.onMouseEnter); + } + + ['mousedown', 'click', 'dblclick', 'touchstart', 'touchend', 'touchmove'].forEach(function (e) { + _this3.el.addEventListener(e, _this3.onPointerEvent, true); + }); + this.el.addEventListener('mousemove', this.onMouseMove); + this.el.addEventListener('mouseleave', this.onMouseLeave); + this.contentEl.addEventListener('scroll', this.onScroll); // Browser zoom triggers a window resize + + window.addEventListener('resize', this.onWindowResize); // MutationObserver is IE11+ + + if (typeof MutationObserver !== 'undefined') { + // create an observer instance + this.mutationObserver = new MutationObserver(function (mutations) { + mutations.forEach(function (mutation) { + if (mutation.target === _this3.el || !_this3.isChildNode(mutation.target) || mutation.addedNodes.length || mutation.removedNodes.length) { + _this3.recalculate(); + } + }); + }); // pass in the target node, as well as the observer options + + this.mutationObserver.observe(this.el, { + attributes: true, + childList: true, + characterData: true, + subtree: true + }); + } + + this.resizeObserver = new index(this.recalculate); + this.resizeObserver.observe(this.el); + } + }, { + key: "recalculate", + value: function recalculate() { + var isHeightAuto = this.heightAutoObserverEl.offsetHeight <= 1; + this.elStyles = window.getComputedStyle(this.el); + this.isRtl = this.elStyles.direction === 'rtl'; + this.contentEl.style.padding = "".concat(this.elStyles.paddingTop, " ").concat(this.elStyles.paddingRight, " ").concat(this.elStyles.paddingBottom, " ").concat(this.elStyles.paddingLeft); + this.contentEl.style.height = isHeightAuto ? 'auto' : '100%'; + this.placeholderEl.style.width = "".concat(this.contentEl.scrollWidth, "px"); + this.placeholderEl.style.height = "".concat(this.contentEl.scrollHeight, "px"); + this.wrapperEl.style.margin = "-".concat(this.elStyles.paddingTop, " -").concat(this.elStyles.paddingRight, " -").concat(this.elStyles.paddingBottom, " -").concat(this.elStyles.paddingLeft); + this.axis.x.track.rect = this.axis.x.track.el.getBoundingClientRect(); + this.axis.y.track.rect = this.axis.y.track.el.getBoundingClientRect(); // Set isOverflowing to false if scrollbar is not necessary (content is shorter than offset) + + this.axis.x.isOverflowing = (this.scrollbarWidth ? this.contentEl.scrollWidth : this.contentEl.scrollWidth - this.minScrollbarWidth) > Math.ceil(this.axis.x.track.rect.width); + this.axis.y.isOverflowing = (this.scrollbarWidth ? this.contentEl.scrollHeight : this.contentEl.scrollHeight - this.minScrollbarWidth) > Math.ceil(this.axis.y.track.rect.height); // Set isOverflowing to false if user explicitely set hidden overflow + + this.axis.x.isOverflowing = this.elStyles.overflowX === 'hidden' ? false : this.axis.x.isOverflowing; + this.axis.y.isOverflowing = this.elStyles.overflowY === 'hidden' ? false : this.axis.y.isOverflowing; + this.axis.x.forceVisible = this.options.forceVisible === "x" || this.options.forceVisible === true; + this.axis.y.forceVisible = this.options.forceVisible === "y" || this.options.forceVisible === true; + this.axis.x.scrollbar.size = this.getScrollbarSize('x'); + this.axis.y.scrollbar.size = this.getScrollbarSize('y'); + this.axis.x.scrollbar.el.style.width = "".concat(this.axis.x.scrollbar.size, "px"); + this.axis.y.scrollbar.el.style.height = "".concat(this.axis.y.scrollbar.size, "px"); + this.positionScrollbar('x'); + this.positionScrollbar('y'); + this.toggleTrackVisibility('x'); + this.toggleTrackVisibility('y'); + this.hideNativeScrollbar(); + } + /** + * Calculate scrollbar size + */ + + }, { + key: "getScrollbarSize", + value: function getScrollbarSize() { + var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y'; + var contentSize = this.scrollbarWidth ? this.contentEl[this.axis[axis].scrollSizeAttr] : this.contentEl[this.axis[axis].scrollSizeAttr] - this.minScrollbarWidth; + var trackSize = this.axis[axis].track.rect[this.axis[axis].sizeAttr]; + var scrollbarSize; + + if (!this.axis[axis].isOverflowing) { + return; + } + + var scrollbarRatio = trackSize / contentSize; // Calculate new height/position of drag handle. + + scrollbarSize = Math.max(~~(scrollbarRatio * trackSize), this.options.scrollbarMinSize); + + if (this.options.scrollbarMaxSize) { + scrollbarSize = Math.min(scrollbarSize, this.options.scrollbarMaxSize); + } + + return scrollbarSize; + } + }, { + key: "positionScrollbar", + value: function positionScrollbar() { + var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y'; + var contentSize = this.contentEl[this.axis[axis].scrollSizeAttr]; + var trackSize = this.axis[axis].track.rect[this.axis[axis].sizeAttr]; + var hostSize = parseInt(this.elStyles[this.axis[axis].sizeAttr], 10); + var scrollbar = this.axis[axis].scrollbar; + var scrollOffset = this.contentEl[this.axis[axis].scrollOffsetAttr]; + scrollOffset = axis === 'x' && this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollingInverted ? -scrollOffset : scrollOffset; + var scrollPourcent = scrollOffset / (contentSize - hostSize); + var handleOffset = ~~((trackSize - scrollbar.size) * scrollPourcent); + handleOffset = axis === 'x' && this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollbarInverted ? handleOffset + (trackSize - scrollbar.size) : handleOffset; + scrollbar.el.style.transform = axis === 'x' ? "translate3d(".concat(handleOffset, "px, 0, 0)") : "translate3d(0, ".concat(handleOffset, "px, 0)"); + } + }, { + key: "toggleTrackVisibility", + value: function toggleTrackVisibility() { + var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y'; + var track = this.axis[axis].track.el; + var scrollbar = this.axis[axis].scrollbar.el; + + if (this.axis[axis].isOverflowing || this.axis[axis].forceVisible) { + track.style.visibility = 'visible'; + this.contentEl.style[this.axis[axis].overflowAttr] = 'scroll'; + } else { + track.style.visibility = 'hidden'; + this.contentEl.style[this.axis[axis].overflowAttr] = 'hidden'; + } // Even if forceVisible is enabled, scrollbar itself should be hidden + + + if (this.axis[axis].isOverflowing) { + scrollbar.style.visibility = 'visible'; + } else { + scrollbar.style.visibility = 'hidden'; + } + } + }, { + key: "hideNativeScrollbar", + value: function hideNativeScrollbar() { + this.offsetEl.style[this.isRtl ? 'left' : 'right'] = this.axis.y.isOverflowing || this.axis.y.forceVisible ? "-".concat(this.scrollbarWidth || this.minScrollbarWidth, "px") : 0; + this.offsetEl.style.bottom = this.axis.x.isOverflowing || this.axis.x.forceVisible ? "-".concat(this.scrollbarWidth || this.minScrollbarWidth, "px") : 0; // If floating scrollbar + + if (!this.scrollbarWidth) { + var paddingDirection = [this.isRtl ? 'paddingLeft' : 'paddingRight']; + this.contentEl.style[paddingDirection] = this.axis.y.isOverflowing || this.axis.y.forceVisible ? "calc(".concat(this.elStyles[paddingDirection], " + ").concat(this.minScrollbarWidth, "px)") : this.elStyles[paddingDirection]; + this.contentEl.style.paddingBottom = this.axis.x.isOverflowing || this.axis.x.forceVisible ? "calc(".concat(this.elStyles.paddingBottom, " + ").concat(this.minScrollbarWidth, "px)") : this.elStyles.paddingBottom; + } + } + /** + * On scroll event handling + */ + + }, { + key: "onMouseMoveForAxis", + value: function onMouseMoveForAxis() { + var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y'; + this.axis[axis].track.rect = this.axis[axis].track.el.getBoundingClientRect(); + this.axis[axis].scrollbar.rect = this.axis[axis].scrollbar.el.getBoundingClientRect(); + var isWithinScrollbarBoundsX = this.isWithinBounds(this.axis[axis].scrollbar.rect); + + if (isWithinScrollbarBoundsX) { + this.axis[axis].scrollbar.el.classList.add(this.classNames.hover); + } else { + this.axis[axis].scrollbar.el.classList.remove(this.classNames.hover); + } + + if (this.isWithinBounds(this.axis[axis].track.rect)) { + this.showScrollbar(axis); + this.axis[axis].track.el.classList.add(this.classNames.hover); + } else { + this.axis[axis].track.el.classList.remove(this.classNames.hover); + } + } + }, { + key: "onMouseLeaveForAxis", + value: function onMouseLeaveForAxis() { + var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y'; + this.axis[axis].track.el.classList.remove(this.classNames.hover); + this.axis[axis].scrollbar.el.classList.remove(this.classNames.hover); + } + }, { + key: "showScrollbar", + + /** + * Show scrollbar + */ + value: function showScrollbar() { + var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y'; + var scrollbar = this.axis[axis].scrollbar.el; + + if (!this.axis[axis].isVisible) { + scrollbar.classList.add(this.classNames.visible); + this.axis[axis].isVisible = true; + } + + if (this.options.autoHide) { + this.hideScrollbars(); + } + } + /** + * Hide Scrollbar + */ + + }, { + key: "onDragStart", + + /** + * on scrollbar handle drag movement starts + */ + value: function onDragStart(e) { + var axis = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'y'; + var scrollbar = this.axis[axis].scrollbar.el; // Measure how far the user's mouse is from the top of the scrollbar drag handle. + + var eventOffset = axis === 'y' ? e.pageY : e.pageX; + this.axis[axis].dragOffset = eventOffset - scrollbar.getBoundingClientRect()[this.axis[axis].offsetAttr]; + this.draggedAxis = axis; + document.addEventListener('mousemove', this.drag); + document.addEventListener('mouseup', this.onEndDrag); + } + /** + * Drag scrollbar handle + */ + + }, { + key: "getScrollElement", + + /** + * Getter for original scrolling element + */ + value: function getScrollElement() { + return this.contentEl; + } + }, { + key: "removeListeners", + value: function removeListeners() { + var _this4 = this; + + // Event listeners + if (this.options.autoHide) { + this.el.removeEventListener('mouseenter', this.onMouseEnter); + } + + ['mousedown', 'click', 'dblclick', 'touchstart', 'touchend', 'touchmove'].forEach(function (e) { + _this4.el.removeEventListener(e, _this4.onPointerEvent); + }); + this.el.removeEventListener('mousemove', this.onMouseMove); + this.el.removeEventListener('mouseleave', this.onMouseLeave); + this.contentEl.removeEventListener('scroll', this.onScroll); + window.removeEventListener('resize', this.onWindowResize); + this.mutationObserver && this.mutationObserver.disconnect(); + this.resizeObserver.disconnect(); // Cancel all debounced functions + + this.recalculate.cancel(); + this.onMouseMove.cancel(); + this.hideScrollbars.cancel(); + this.onWindowResize.cancel(); + } + /** + * UnMount mutation observer and delete SimpleBar instance from DOM element + */ + + }, { + key: "unMount", + value: function unMount() { + this.removeListeners(); + this.el.SimpleBar = null; + } + /** + * Recursively walks up the parent nodes looking for this.el + */ + + }, { + key: "isChildNode", + value: function isChildNode(el) { + if (el === null) return false; + if (el === this.el) return true; + return this.isChildNode(el.parentNode); + } + /** + * Check if mouse is within bounds + */ + + }, { + key: "isWithinBounds", + value: function isWithinBounds(bbox) { + return this.mouseX >= bbox.left && this.mouseX <= bbox.left + bbox.width && this.mouseY >= bbox.top && this.mouseY <= bbox.top + bbox.height; + } + }], [{ + key: "getRtlHelpers", + value: function getRtlHelpers() { + var dummyDiv = document.createElement('div'); + dummyDiv.innerHTML = '