From 71cff3064c1c9bff8b5515a264da2b36ce526f1b Mon Sep 17 00:00:00 2001 From: MuK IT GmbH Date: Sat, 13 Jul 2019 16:01:55 +0000 Subject: [PATCH] publish muk_web_utils - 12.0 --- muk_web_utils/LICENSE | 776 +- muk_web_utils/README.rst | 226 +- muk_web_utils/__init__.py | 17 +- muk_web_utils/__manifest__.py | 21 +- muk_web_utils/controllers/__init__.py | 19 +- muk_web_utils/controllers/attachment.py | 107 +- muk_web_utils/controllers/backend.py | 69 +- muk_web_utils/data/autovacuum.xml | 25 +- muk_web_utils/doc/index.rst | 226 +- muk_web_utils/models/__init__.py | 17 +- muk_web_utils/models/ir_attachment.py | 17 +- muk_web_utils/models/res_config_settings.py | 17 +- .../static/libs/simplebar/simplebar.css | 385 +- .../static/libs/simplebar/simplebar.js | 8793 +++++++++-------- muk_web_utils/static/src/js/core/async.js | 165 +- muk_web_utils/static/src/js/core/dialog.js | 19 +- muk_web_utils/static/src/js/core/dropzone.js | 259 +- muk_web_utils/static/src/js/core/files.js | 349 +- muk_web_utils/static/src/js/core/mimetype.js | 215 +- muk_web_utils/static/src/js/core/utils.js | 165 +- muk_web_utils/static/src/js/fields/binary.js | 19 +- muk_web_utils/static/src/js/fields/color.js | 255 +- muk_web_utils/static/src/js/fields/copy.js | 265 +- muk_web_utils/static/src/js/fields/domain.js | 111 +- muk_web_utils/static/src/js/fields/image.js | 129 +- muk_web_utils/static/src/js/fields/module.js | 187 +- muk_web_utils/static/src/js/fields/path.js | 233 +- muk_web_utils/static/src/js/fields/share.js | 449 +- muk_web_utils/static/src/js/fields/utils.js | 105 +- muk_web_utils/static/src/js/libs/jquery.js | 205 +- muk_web_utils/static/src/js/libs/scrollbar.js | 51 +- .../static/src/js/libs/underscore.js | 89 +- .../src/js/services/notification_service.js | 19 +- .../static/src/js/views/form/renderer.js | 89 +- .../static/src/js/widgets/notification.js | 19 +- muk_web_utils/static/src/scss/binary.scss | 53 +- muk_web_utils/static/src/scss/color.scss | 127 +- muk_web_utils/static/src/scss/copy.scss | 63 +- muk_web_utils/static/src/scss/dropzone.scss | 123 +- muk_web_utils/static/src/scss/image.scss | 165 +- muk_web_utils/static/src/scss/mixins.scss | 77 +- muk_web_utils/static/src/scss/module.scss | 61 +- .../static/src/scss/notification.scss | 57 +- muk_web_utils/static/src/scss/share.scss | 103 +- muk_web_utils/static/src/scss/switch.scss | 311 +- muk_web_utils/static/src/scss/variables.scss | 73 +- muk_web_utils/static/src/xml/color.xml | 123 +- muk_web_utils/static/src/xml/copy.xml | 63 +- muk_web_utils/static/src/xml/image.xml | 61 +- muk_web_utils/static/src/xml/module.xml | 71 +- muk_web_utils/static/src/xml/notification.xml | 71 +- muk_web_utils/static/src/xml/share.xml | 205 +- muk_web_utils/static/src/xml/switch.xml | 101 +- muk_web_utils/static/tests/fields.js | 387 +- muk_web_utils/template/assets.xml | 149 +- muk_web_utils/tests/__init__.py | 17 +- muk_web_utils/tests/test_js.py | 17 +- .../views/res_config_settings_view.xml | 91 +- 58 files changed, 8213 insertions(+), 8468 deletions(-) diff --git a/muk_web_utils/LICENSE b/muk_web_utils/LICENSE index faf7bf4..153d416 100644 --- a/muk_web_utils/LICENSE +++ b/muk_web_utils/LICENSE @@ -1,619 +1,165 @@ - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 - Copyright (C) 2007 Free Software Foundation, Inc. + 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. - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero 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 -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS \ No newline at end of file + + 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 index 10c17e4..1d9ac57 100644 --- a/muk_web_utils/README.rst +++ b/muk_web_utils/README.rst @@ -1,113 +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). +============= +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 index 7c3419b..bbab24a 100644 --- a/muk_web_utils/__init__.py +++ b/muk_web_utils/__init__.py @@ -1,19 +1,22 @@ ################################################################################### # -# Copyright (C) 2018 MuK IT GmbH +# 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 Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. +# 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 Affero General Public License for more details. +# GNU Lesser General Public License for more details. # -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . # ################################################################################### diff --git a/muk_web_utils/__manifest__.py b/muk_web_utils/__manifest__.py index 4dee688..7a8b6b1 100644 --- a/muk_web_utils/__manifest__.py +++ b/muk_web_utils/__manifest__.py @@ -1,28 +1,31 @@ ################################################################################### # -# Copyright (C) 2018 MuK IT GmbH +# 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 Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. +# 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 Affero General Public License for more details. +# GNU Lesser General Public License for more details. # -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# 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": "12.0.2.9.7", + "version": "12.0.3.0.0", "category": "Extra Tools", - "license": "AGPL-3", + "license": "LGPL-3", "author": "MuK IT", "website": "http://www.mukit.at", 'live_test_url': 'https://mukit.at/r/SgN', diff --git a/muk_web_utils/controllers/__init__.py b/muk_web_utils/controllers/__init__.py index bc915bd..5caf3fa 100644 --- a/muk_web_utils/controllers/__init__.py +++ b/muk_web_utils/controllers/__init__.py @@ -1,19 +1,22 @@ ################################################################################### -# -# Copyright (C) 2017 MuK IT GmbH +# +# 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 Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. +# 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 Affero General Public License for more details. +# GNU Lesser General Public License for more details. # -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . # ################################################################################### diff --git a/muk_web_utils/controllers/attachment.py b/muk_web_utils/controllers/attachment.py index 6db9935..e951353 100644 --- a/muk_web_utils/controllers/attachment.py +++ b/muk_web_utils/controllers/attachment.py @@ -1,53 +1,56 @@ -################################################################################### -# -# Copyright (C) 2017 MuK IT GmbH -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -################################################################################### - -import json -import base64 -import logging - -from odoo import http -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.sudo().write({ - 'mimetype': ufile.mimetype, - }) - base_url = request.env['ir.config_parameter'].sudo().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) +################################################################################### +# +# 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 +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.sudo().write({ + 'mimetype': ufile.mimetype, + }) + base_url = request.env['ir.config_parameter'].sudo().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 index 3a3ae40..80a9fec 100644 --- a/muk_web_utils/controllers/backend.py +++ b/muk_web_utils/controllers/backend.py @@ -1,34 +1,37 @@ -################################################################################### -# -# Copyright (C) 2017 MuK IT GmbH -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -################################################################################### - -import logging - -from odoo import http -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'].sudo() - return { - 'max_upload_size': int(params.get_param('muk_web_utils.binary_max_size', default=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 . +# +################################################################################### + +import logging + +from odoo import http +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'].sudo() + 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 index e11924e..c3c3f22 100644 --- a/muk_web_utils/data/autovacuum.xml +++ b/muk_web_utils/data/autovacuum.xml @@ -1,21 +1,26 @@ - + --> diff --git a/muk_web_utils/doc/index.rst b/muk_web_utils/doc/index.rst index 10c17e4..1d9ac57 100644 --- a/muk_web_utils/doc/index.rst +++ b/muk_web_utils/doc/index.rst @@ -1,113 +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). +============= +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/models/__init__.py b/muk_web_utils/models/__init__.py index 5d586a5..b692fb1 100644 --- a/muk_web_utils/models/__init__.py +++ b/muk_web_utils/models/__init__.py @@ -1,19 +1,22 @@ ################################################################################### # -# Copyright (C) 2018 MuK IT GmbH +# 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 Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. +# 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 Affero General Public License for more details. +# GNU Lesser General Public License for more details. # -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . # ################################################################################### diff --git a/muk_web_utils/models/ir_attachment.py b/muk_web_utils/models/ir_attachment.py index 74fe88c..bb5d745 100644 --- a/muk_web_utils/models/ir_attachment.py +++ b/muk_web_utils/models/ir_attachment.py @@ -1,19 +1,22 @@ ################################################################################### # -# Copyright (C) 2018 MuK IT GmbH +# 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 Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. +# 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 Affero General Public License for more details. +# GNU Lesser General Public License for more details. # -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . # ################################################################################### diff --git a/muk_web_utils/models/res_config_settings.py b/muk_web_utils/models/res_config_settings.py index 43febf3..d9284d6 100644 --- a/muk_web_utils/models/res_config_settings.py +++ b/muk_web_utils/models/res_config_settings.py @@ -1,19 +1,22 @@ ################################################################################### # -# Copyright (C) 2017 MuK IT GmbH +# 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 Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. +# 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 Affero General Public License for more details. +# GNU Lesser General Public License for more details. # -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . # ################################################################################### diff --git a/muk_web_utils/static/libs/simplebar/simplebar.css b/muk_web_utils/static/libs/simplebar/simplebar.css index 35eddba..dcdfdf2 100644 --- a/muk_web_utils/static/libs/simplebar/simplebar.css +++ b/muk_web_utils/static/libs/simplebar/simplebar.css @@ -1,183 +1,204 @@ -[data-simplebar] { - position: relative; - flex-direction: column; - flex-wrap: wrap; - justify-content: flex-start; - align-content: flex-start; - align-items: flex-start; - width: inherit; - height: inherit; - max-width: inherit; - max-height: inherit; -} - -.simplebar-wrapper { - overflow: hidden; - width: inherit; - height: inherit; - max-width: inherit; - max-height: inherit; -} - -.simplebar-mask { - direction: inherit; - position: absolute; - overflow: hidden; - padding: 0; - margin: 0; - left: 0; - top: 0; - bottom: 0; - right: 0; - width: auto !important; - height: auto !important; - z-index: 0; -} - -.simplebar-offset { - direction: inherit !important; - box-sizing: inherit !important; - resize: none !important; - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - padding: 0; - margin: 0; - -webkit-overflow-scrolling: touch; -} - -.simplebar-content { - direction: inherit; - box-sizing: border-box !important; - position: relative; - display: block; - height: 100%; /* Required for horizontal native scrollbar to not appear if parent is taller than natural height */ - width: auto; - visibility: visible; - overflow: scroll; /* Scroll on this element otherwise element can't have a padding applied properly */ - max-width: 100%; /* Not required for horizontal scroll to trigger */ - max-height: 100%; /* Needed for vertical scroll to trigger */ -} - -.simplebar-placeholder { - max-height: 100%; - max-width: 100%; - width: 100%; - pointer-events: none; -} - -.simplebar-height-auto-observer-wrapper { - box-sizing: inherit !important; - height: 100%; - width: inherit; - max-width: 1px; - position: relative; - float: left; - max-height: 1px; - overflow: hidden; - z-index: -1; - padding: 0; - margin: 0; - pointer-events: none; - flex-grow: inherit; - flex-shrink: 0; - flex-basis: 0; -} - -.simplebar-height-auto-observer { - box-sizing: inherit; - display: block; - opacity: 0; - position: absolute; - top: 0; - left: 0; - height: 1000%; - width: 1000%; - min-height: 1px; - min-width: 1px; - overflow: hidden; - pointer-events: none; - z-index: -1; -} - -.simplebar-track { - z-index: 1; - position: absolute; - right: 0; - bottom: 0; - pointer-events: none; -} - -.simplebar-scrollbar { - position: absolute; - right: 2px; - width: 7px; - min-height: 10px; -} - -.simplebar-scrollbar:before { - position: absolute; - content: ""; - background: black; - border-radius: 7px; - left: 0; - right: 0; - opacity: 0; - transition: opacity 0.2s linear; -} - -.simplebar-track .simplebar-scrollbar.simplebar-visible:before { - /* When hovered, remove all transitions from drag handle */ - opacity: 0.5; - transition: opacity 0s linear; -} - -.simplebar-track.simplebar-vertical { - top: 0; - width: 11px; -} - -.simplebar-track.simplebar-vertical .simplebar-scrollbar:before { - top: 2px; - bottom: 2px; -} - -.simplebar-track.simplebar-horizontal { - left: 0; - height: 11px; -} - -.simplebar-track.simplebar-horizontal .simplebar-scrollbar:before { - height: 100%; - left: 2px; - right: 2px; -} - -.simplebar-track.simplebar-horizontal .simplebar-scrollbar { - right: auto; - left: 0; - top: 2px; - height: 7px; - min-height: 0; - min-width: 10px; - width: auto; -} - -/* Rtl support */ -[data-simplebar-direction="rtl"] .simplebar-track.simplebar-vertical { - right: auto; - left: 0; -} - -.hs-dummy-scrollbar-size { - direction: rtl; - position: fixed; - opacity: 0; - visibility: hidden; - height: 500px; - width: 500px; - overflow-y: hidden; - overflow-x: scroll; +/********************************************************************************** +* +* 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 . +* +**********************************************************************************/ +[data-simplebar] { + position: relative; + flex-direction: column; + flex-wrap: wrap; + justify-content: flex-start; + align-content: flex-start; + align-items: flex-start; + width: inherit; + height: inherit; + max-width: inherit; + max-height: inherit; +} + +.simplebar-wrapper { + overflow: hidden; + width: inherit; + height: inherit; + max-width: inherit; + max-height: inherit; +} + +.simplebar-mask { + direction: inherit; + position: absolute; + overflow: hidden; + padding: 0; + margin: 0; + left: 0; + top: 0; + bottom: 0; + right: 0; + width: auto !important; + height: auto !important; + z-index: 0; +} + +.simplebar-offset { + direction: inherit !important; + box-sizing: inherit !important; + resize: none !important; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + padding: 0; + margin: 0; + -webkit-overflow-scrolling: touch; +} + +.simplebar-content { + direction: inherit; + box-sizing: border-box !important; + position: relative; + display: block; + height: 100%; /* Required for horizontal native scrollbar to not appear if parent is taller than natural height */ + width: auto; + visibility: visible; + overflow: scroll; /* Scroll on this element otherwise element can't have a padding applied properly */ + max-width: 100%; /* Not required for horizontal scroll to trigger */ + max-height: 100%; /* Needed for vertical scroll to trigger */ +} + +.simplebar-placeholder { + max-height: 100%; + max-width: 100%; + width: 100%; + pointer-events: none; +} + +.simplebar-height-auto-observer-wrapper { + box-sizing: inherit !important; + height: 100%; + width: inherit; + max-width: 1px; + position: relative; + float: left; + max-height: 1px; + overflow: hidden; + z-index: -1; + padding: 0; + margin: 0; + pointer-events: none; + flex-grow: inherit; + flex-shrink: 0; + flex-basis: 0; +} + +.simplebar-height-auto-observer { + box-sizing: inherit; + display: block; + opacity: 0; + position: absolute; + top: 0; + left: 0; + height: 1000%; + width: 1000%; + min-height: 1px; + min-width: 1px; + overflow: hidden; + pointer-events: none; + z-index: -1; +} + +.simplebar-track { + z-index: 1; + position: absolute; + right: 0; + bottom: 0; + pointer-events: none; +} + +.simplebar-scrollbar { + position: absolute; + right: 2px; + width: 7px; + min-height: 10px; +} + +.simplebar-scrollbar:before { + position: absolute; + content: ""; + background: black; + border-radius: 7px; + left: 0; + right: 0; + opacity: 0; + transition: opacity 0.2s linear; +} + +.simplebar-track .simplebar-scrollbar.simplebar-visible:before { + /* When hovered, remove all transitions from drag handle */ + opacity: 0.5; + transition: opacity 0s linear; +} + +.simplebar-track.simplebar-vertical { + top: 0; + width: 11px; +} + +.simplebar-track.simplebar-vertical .simplebar-scrollbar:before { + top: 2px; + bottom: 2px; +} + +.simplebar-track.simplebar-horizontal { + left: 0; + height: 11px; +} + +.simplebar-track.simplebar-horizontal .simplebar-scrollbar:before { + height: 100%; + left: 2px; + right: 2px; +} + +.simplebar-track.simplebar-horizontal .simplebar-scrollbar { + right: auto; + left: 0; + top: 2px; + height: 7px; + min-height: 0; + min-width: 10px; + width: auto; +} + +/* Rtl support */ +[data-simplebar-direction="rtl"] .simplebar-track.simplebar-vertical { + right: auto; + left: 0; +} + +.hs-dummy-scrollbar-size { + direction: rtl; + position: fixed; + opacity: 0; + visibility: hidden; + height: 500px; + width: 500px; + overflow-y: hidden; + overflow-x: scroll; } \ No newline at end of file diff --git a/muk_web_utils/static/libs/simplebar/simplebar.js b/muk_web_utils/static/libs/simplebar/simplebar.js index ed14573..fc43889 100644 --- a/muk_web_utils/static/libs/simplebar/simplebar.js +++ b/muk_web_utils/static/libs/simplebar/simplebar.js @@ -1,4391 +1,4404 @@ -/** - * SimpleBar.js - v3.1.3 - * Scrollbars, simpler. - * https://grsmto.github.io/simplebar/ - * - * Made by Adrien Denat from a fork by Jonathan Nicol - * Under MIT License - */ - -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global = global || self, global.SimpleBar = factory()); -}(this, function () { 'use strict'; - - var _isObject = function (it) { - return typeof it === 'object' ? it !== null : typeof it === 'function'; - }; - - var _anObject = function (it) { - if (!_isObject(it)) throw TypeError(it + ' is not an object!'); - return it; - }; - - // 7.2.1 RequireObjectCoercible(argument) - var _defined = function (it) { - if (it == undefined) throw TypeError("Can't call method on " + it); - return it; - }; - - // 7.1.13 ToObject(argument) - - var _toObject = function (it) { - return Object(_defined(it)); - }; - - // 7.1.4 ToInteger - var ceil = Math.ceil; - var floor = Math.floor; - var _toInteger = function (it) { - return isNaN(it = +it) ? 0 : (it > 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 = '
'; - 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', - mask: 'simplebar-mask', - wrapper: 'simplebar-wrapper', - 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; - +/********************************************************************************** +* +* 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 . +* +**********************************************************************************/ + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = global || self, global.SimpleBar = factory()); +}(this, function () { 'use strict'; + + var _isObject = function (it) { + return typeof it === 'object' ? it !== null : typeof it === 'function'; + }; + + var _anObject = function (it) { + if (!_isObject(it)) throw TypeError(it + ' is not an object!'); + return it; + }; + + // 7.2.1 RequireObjectCoercible(argument) + var _defined = function (it) { + if (it == undefined) throw TypeError("Can't call method on " + it); + return it; + }; + + // 7.1.13 ToObject(argument) + + var _toObject = function (it) { + return Object(_defined(it)); + }; + + // 7.1.4 ToInteger + var ceil = Math.ceil; + var floor = Math.floor; + var _toInteger = function (it) { + return isNaN(it = +it) ? 0 : (it > 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 = '
'; + 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', + mask: 'simplebar-mask', + wrapper: 'simplebar-wrapper', + 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/js/core/async.js b/muk_web_utils/static/src/js/core/async.js index 779ec86..e8e7e75 100644 --- a/muk_web_utils/static/src/js/core/async.js +++ b/muk_web_utils/static/src/js/core/async.js @@ -1,82 +1,85 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -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.done(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() { - $.when(closeNotification(widget, notification)).then(callback); - }, update); -}; - -return { - syncLoop: syncLoop, - syncProgress: syncProgress, - syncNotification: syncNotification, -}; - +/********************************************************************************** +* +* 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.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.done(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() { + $.when(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 index e18344c..efbb02a 100644 --- a/muk_web_utils/static/src/js/core/dialog.js +++ b/muk_web_utils/static/src/js/core/dialog.js @@ -1,19 +1,22 @@ /********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH +* +* 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 Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. +* 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 Affero General Public License for more details. +* GNU Lesser General Public License for more details. * -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . * **********************************************************************************/ diff --git a/muk_web_utils/static/src/js/core/dropzone.js b/muk_web_utils/static/src/js/core/dropzone.js index 127623e..c316db8 100644 --- a/muk_web_utils/static/src/js/core/dropzone.js +++ b/muk_web_utils/static/src/js/core/dropzone.js @@ -1,129 +1,132 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -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, -}; - +/********************************************************************************** +* +* 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 index 428975f..6e0972e 100644 --- a/muk_web_utils/static/src/js/core/files.js +++ b/muk_web_utils/static/src/js/core/files.js @@ -1,173 +1,176 @@ -/********************************************************************************** -* -* Copyright (C) 2018 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -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!"); - } - } - }); - $.when.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); - }); - $.when.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, -}; - -}); +/********************************************************************************** +* +* 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!"); + } + } + }); + $.when.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); + }); + $.when.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 index 0ffdcdb..e874d30 100644 --- a/muk_web_utils/static/src/js/core/mimetype.js +++ b/muk_web_utils/static/src/js/core/mimetype.js @@ -1,107 +1,110 @@ -/********************************************************************************** -* -* Copyright (C) 2018 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -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, -}; - +/********************************************************************************** +* +* 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 index c5b8402..b0c9734 100644 --- a/muk_web_utils/static/src/js/core/utils.js +++ b/muk_web_utils/static/src/js/core/utils.js @@ -1,82 +1,85 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -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, -}; - +/********************************************************************************** +* +* 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/binary.js b/muk_web_utils/static/src/js/fields/binary.js index 39ada59..2a0b7da 100644 --- a/muk_web_utils/static/src/js/fields/binary.js +++ b/muk_web_utils/static/src/js/fields/binary.js @@ -1,19 +1,22 @@ /********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH +* +* 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 Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. +* 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 Affero General Public License for more details. +* GNU Lesser General Public License for more details. * -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . * **********************************************************************************/ diff --git a/muk_web_utils/static/src/js/fields/color.js b/muk_web_utils/static/src/js/fields/color.js index 66becfb..d979b00 100644 --- a/muk_web_utils/static/src/js/fields/color.js +++ b/muk_web_utils/static/src/js/fields/color.js @@ -1,127 +1,130 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -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', FieldColor); -registry.add('color_index', FieldColorIndex); - -return { - FieldColor: FieldColor, - FieldColorIndex: FieldColorIndex, -}; - +/********************************************************************************** +* +* 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', 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 index 7758f8d..ec1a22a 100644 --- a/muk_web_utils/static/src/js/fields/copy.js +++ b/muk_web_utils/static/src/js/fields/copy.js @@ -1,132 +1,135 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -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() : $.when(); - return $.when(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, -}; - +/********************************************************************************** +* +* 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() : $.when(); + return $.when(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 index c9a59e7..38fbcc7 100644 --- a/muk_web_utils/static/src/js/fields/domain.js +++ b/muk_web_utils/static/src/js/fields/domain.js @@ -1,62 +1,49 @@ -/********************************************************************************** -* -* Copyright (C) 2018 MuK IT GmbH -* -* Odoo Proprietary License v1.0 -* This software and associated files (the "Software") may only be used -* (executed, modified, executed after modifications) if you have -* purchased a valid license from the authors, typically via Odoo Apps, -* or if you have received a written agreement from the authors of the -* Software (see the COPYRIGHT file). -* -* You may develop Odoo modules that use the Software as a library -* (typically by depending on it, importing it and using its resources), -* but without copying any source code or material from the Software. -* You may distribute those modules under the license of your choice, -* provided that this license is compatible with the terms of the Odoo -* Proprietary License (For example: LGPL, MIT, or proprietary licenses -* similar to this one). -* -* It is forbidden to publish, distribute, sublicense, or sell copies of -* the Software or modified copies of the Software. -* -* The above copyright notice and this permission notice must be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -* DEALINGS IN THE SOFTWARE. -* -**********************************************************************************/ - -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(); - }, -}); - -}); +/********************************************************************************** +* +* 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(); + }, +}); + +}); diff --git a/muk_web_utils/static/src/js/fields/image.js b/muk_web_utils/static/src/js/fields/image.js index 9f8a43e..7ebd616 100644 --- a/muk_web_utils/static/src/js/fields/image.js +++ b/muk_web_utils/static/src/js/fields/image.js @@ -1,71 +1,58 @@ -/********************************************************************************** -* -* Copyright (C) 2018 MuK IT GmbH -* -* Odoo Proprietary License v1.0 -* This software and associated files (the "Software") may only be used -* (executed, modified, executed after modifications) if you have -* purchased a valid license from the authors, typically via Odoo Apps, -* or if you have received a written agreement from the authors of the -* Software (see the COPYRIGHT file). -* -* You may develop Odoo modules that use the Software as a library -* (typically by depending on it, importing it and using its resources), -* but without copying any source code or material from the Software. -* You may distribute those modules under the license of your choice, -* provided that this license is compatible with the terms of the Odoo -* Proprietary License (For example: LGPL, MIT, or proprietary licenses -* similar to this one). -* -* It is forbidden to publish, distribute, sublicense, or sell copies of -* the Software or modified copies of the Software. -* -* The above copyright notice and this permission notice must be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -* DEALINGS IN THE SOFTWARE. -* -**********************************************************************************/ - -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.include({ - willStart: function () { - var def = this._rpc({ - route: '/config/muk_web_utils.binary_max_size', - }).done(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'); - }, -}); - -}); +/********************************************************************************** +* +* 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.include({ + willStart: function () { + var def = this._rpc({ + route: '/config/muk_web_utils.binary_max_size', + }).done(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 index a79d571..59eaed9 100644 --- a/muk_web_utils/static/src/js/fields/module.js +++ b/muk_web_utils/static/src/js/fields/module.js @@ -1,93 +1,96 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -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; - +/********************************************************************************** +* +* 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 index e3c49b9..ffc2bc1 100644 --- a/muk_web_utils/static/src/js/fields/path.js +++ b/muk_web_utils/static/src/js/fields/path.js @@ -1,116 +1,119 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -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, -}; - +/********************************************************************************** +* +* 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 index c367482..eaa0eee 100644 --- a/muk_web_utils/static/src/js/fields/share.js +++ b/muk_web_utils/static/src/js/fields/share.js @@ -1,224 +1,227 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -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', - view_type: '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, -}; - +/********************************************************************************** +* +* 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', + view_type: '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 index 70d6372..001acdd 100644 --- a/muk_web_utils/static/src/js/fields/utils.js +++ b/muk_web_utils/static/src/js/fields/utils.js @@ -1,51 +1,54 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -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; - -}); +/********************************************************************************** +* +* 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 index 3e57ed1..84b3314 100644 --- a/muk_web_utils/static/src/js/libs/jquery.js +++ b/muk_web_utils/static/src/js/libs/jquery.js @@ -1,101 +1,104 @@ -/********************************************************************************** -* -* Copyright (C) 2018 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -$.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(); - } - }; - } -}); - +/********************************************************************************** +* +* 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 index 7d0bd9a..2c889fd 100644 --- a/muk_web_utils/static/src/js/libs/scrollbar.js +++ b/muk_web_utils/static/src/js/libs/scrollbar.js @@ -1,24 +1,27 @@ -/********************************************************************************** -* -* Copyright (C) 2018 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -$.fn.renderScrollBar = function() { - this.each(function() { - new SimpleBar(this); - }); -}; +/********************************************************************************** +* +* 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 index 5901f96..a8a4aa8 100644 --- a/muk_web_utils/static/src/js/libs/underscore.js +++ b/muk_web_utils/static/src/js/libs/underscore.js @@ -1,44 +1,47 @@ -/********************************************************************************** -* -* Copyright (C) 2018 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -_.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) - } - } +/********************************************************************************** +* +* 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 index 5e22029..8f5787e 100644 --- a/muk_web_utils/static/src/js/services/notification_service.js +++ b/muk_web_utils/static/src/js/services/notification_service.js @@ -1,19 +1,22 @@ /********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH +* +* 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 Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. +* 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 Affero General Public License for more details. +* GNU Lesser General Public License for more details. * -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . * **********************************************************************************/ diff --git a/muk_web_utils/static/src/js/views/form/renderer.js b/muk_web_utils/static/src/js/views/form/renderer.js index 7236c80..496211a 100644 --- a/muk_web_utils/static/src/js/views/form/renderer.js +++ b/muk_web_utils/static/src/js/views/form/renderer.js @@ -1,44 +1,47 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -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); - } -}); - +/********************************************************************************** +* +* 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 index 89a3938..b51b636 100644 --- a/muk_web_utils/static/src/js/widgets/notification.js +++ b/muk_web_utils/static/src/js/widgets/notification.js @@ -1,19 +1,22 @@ /********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH +* +* 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 Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. +* 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 Affero General Public License for more details. +* GNU Lesser General Public License for more details. * -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . * **********************************************************************************/ diff --git a/muk_web_utils/static/src/scss/binary.scss b/muk_web_utils/static/src/scss/binary.scss index 780f924..d4541e2 100644 --- a/muk_web_utils/static/src/scss/binary.scss +++ b/muk_web_utils/static/src/scss/binary.scss @@ -1,25 +1,28 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -.o_list_view .o_field_widget.o_field_binary_file { - height: 100%; - button.btn { - padding-top: 0.25rem; - } -} +/********************************************************************************** +* +* 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 index 693e7ac..297f8f9 100644 --- a/muk_web_utils/static/src/scss/color.scss +++ b/muk_web_utils/static/src/scss/color.scss @@ -1,63 +1,66 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -.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; - } - } +/********************************************************************************** +* +* 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 index 7daa798..ff67504 100644 --- a/muk_web_utils/static/src/scss/copy.scss +++ b/muk_web_utils/static/src/scss/copy.scss @@ -1,31 +1,34 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -.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; - } - } +/********************************************************************************** +* +* 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 index a4284c1..337ffbf 100644 --- a/muk_web_utils/static/src/scss/dropzone.scss +++ b/muk_web_utils/static/src/scss/dropzone.scss @@ -1,61 +1,64 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -.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); - } - } +/********************************************************************************** +* +* 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 index ed1c334..e78e9a3 100644 --- a/muk_web_utils/static/src/scss/image.scss +++ b/muk_web_utils/static/src/scss/image.scss @@ -1,81 +1,84 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -.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; - } - } - } -} +/********************************************************************************** +* +* 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 index d719f31..4c6e540 100644 --- a/muk_web_utils/static/src/scss/mixins.scss +++ b/muk_web_utils/static/src/scss/mixins.scss @@ -1,37 +1,40 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -@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; -} - - +/********************************************************************************** +* +* 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 index cde97f4..0a30d94 100644 --- a/muk_web_utils/static/src/scss/module.scss +++ b/muk_web_utils/static/src/scss/module.scss @@ -1,30 +1,33 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -.o_settings_container { - .o_setting_box { - .o_setting_left_pane { - .mk_module_label { - position: absolute; - top: 0px; - right: 40px; - } - } - } +/********************************************************************************** +* +* 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 index 9d43d60..4caf339 100644 --- a/muk_web_utils/static/src/scss/notification.scss +++ b/muk_web_utils/static/src/scss/notification.scss @@ -1,27 +1,30 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -.o_notification { - .mk_notification_progress { - padding: 2px 10px 10px 10px; - .progress { - background-color: rgba(0, 0, 0, 0.3); - } - } -} +/********************************************************************************** +* +* 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 index 8342f0c..37fa64e 100644 --- a/muk_web_utils/static/src/scss/share.scss +++ b/muk_web_utils/static/src/scss/share.scss @@ -1,51 +1,54 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -.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; - } - } - } +/********************************************************************************** +* +* 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 index c76e4f1..7fe9d6e 100644 --- a/muk_web_utils/static/src/scss/switch.scss +++ b/muk_web_utils/static/src/scss/switch.scss @@ -1,155 +1,158 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -.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; - } +/********************************************************************************** +* +* 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 index 6a4a5e9..74fa8ca 100644 --- a/muk_web_utils/static/src/scss/variables.scss +++ b/muk_web_utils/static/src/scss/variables.scss @@ -1,36 +1,39 @@ -/********************************************************************************** -* -* Copyright (C) 2017 MuK IT GmbH -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see . -* -**********************************************************************************/ - -//---------------------------------------------------------- -// 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; +/********************************************************************************** +* +* 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 index 26e38e8..ecbc10d 100644 --- a/muk_web_utils/static/src/xml/color.xml +++ b/muk_web_utils/static/src/xml/color.xml @@ -1,60 +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 index 97ff3f7..4a21900 100644 --- a/muk_web_utils/static/src/xml/copy.xml +++ b/muk_web_utils/static/src/xml/copy.xml @@ -1,30 +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 index ec5d8e9..824c3af 100644 --- a/muk_web_utils/static/src/xml/image.xml +++ b/muk_web_utils/static/src/xml/image.xml @@ -1,29 +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 index b163902..0709de4 100644 --- a/muk_web_utils/static/src/xml/module.xml +++ b/muk_web_utils/static/src/xml/module.xml @@ -1,34 +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.

-
-
-
- + + + + + + + +
+
+ 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 index 4d6a79d..2ed595a 100644 --- a/muk_web_utils/static/src/xml/notification.xml +++ b/muk_web_utils/static/src/xml/notification.xml @@ -1,34 +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 index e080565..64bcee4 100644 --- a/muk_web_utils/static/src/xml/share.xml +++ b/muk_web_utils/static/src/xml/share.xml @@ -1,101 +1,106 @@ - - - - - - - -
- - -
-
- - -
- - - - - - - - - - - - - - - -
- - -
-
- - -
- -

shared a link with you!

- - Open - -
- -

shared a message with you!

-

- -

-
- - -
-

shared a file with you!

- - Download - -
-
- + + + + + + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + +
+ + +
+
+ + +
+ +

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 index 1341ab2..cb9e742 100644 --- a/muk_web_utils/static/src/xml/switch.xml +++ b/muk_web_utils/static/src/xml/switch.xml @@ -1,49 +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 index 8b69a30..6af0e6f 100644 --- a/muk_web_utils/static/tests/fields.js +++ b/muk_web_utils/static/tests/fields.js @@ -1,184 +1,205 @@ -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(); - }); -}); - -}); - +/********************************************************************************** +* +* 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 index 0ae74d1..a74abcd 100644 --- a/muk_web_utils/template/assets.xml +++ b/muk_web_utils/template/assets.xml @@ -1,73 +1,78 @@ - - - - - - -