From 98b267a042e2ddeff31306be234f921b368abf52 Mon Sep 17 00:00:00 2001 From: Omar Reiss Date: Tue, 12 Jul 2016 13:34:05 +0200 Subject: [PATCH 001/393] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000000000..b244c04b52ce1 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# a11y-speak +JS module inspired by wp-a11y.js From 49b7efb7708fee8bad7c5a6ba413839e84e5b003 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Tue, 12 Jul 2016 15:19:37 +0200 Subject: [PATCH 002/393] Add gitignore --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000..f2d6b0823cb4f --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +temps/ +temp-spec/ +.idea/ +node_modules/ +out/ +coverage/ From a743b792c3f1e0c0dbe32d5ed3af1b60ce432b51 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Tue, 12 Jul 2016 15:19:48 +0200 Subject: [PATCH 003/393] Add license --- LICENSE | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000..ef7e7efc09c9d --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ +GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is 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. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + 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. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + 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 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. Use with the GNU Affero General Public License. + + 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 Affero 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 special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 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 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 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 + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. From 28ebb165d74f5ae4515374e28936ad2cb405c0e2 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Tue, 12 Jul 2016 15:20:00 +0200 Subject: [PATCH 004/393] Add package.json --- package.json | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000000000..4865dc7b714ac --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "a11y-speak", + "description": "", + "homepage": "https://github.com/Yoast/", + "keywords": [ + "Yoast", + "a11y", + "aria-live" + ], + "main": "a11y-speak.js", + "license": "GPL-3.0", + "version": "0.0.1", + "repository": { + "type": "git", + "url": "https://github.com/Yoast/a11y-speak" + }, + "devDependencies": { + "eslint-config-yoast": "^1.0.0", + "eslint-plugin-yoast": "^1.0.0", + "grunt": "^0.4.5", + "grunt-contrib-uglify": "^1.0.1", + "grunt-contrib-watch": "^1.0.0", + "grunt-eslint": "^18.0.0", + "load-grunt-config": "^0.19.1" + }, + "bugs": { + "url": "https://github.com/Yoast/a11y-speak/issues" + } +} From 68cfa63dd351a59828e46378eb9d33dfebe55dbd Mon Sep 17 00:00:00 2001 From: omarreiss Date: Tue, 12 Jul 2016 15:20:17 +0200 Subject: [PATCH 005/393] Add grunt and eslint config. --- .eslintignore | 1 + .eslintrc | 4 ++++ Gruntfile.js | 38 ++++++++++++++++++++++++++++++++++++++ grunt/config/aliases.yaml | 15 +++++++++++++++ grunt/config/eslint.js | 3 +++ grunt/config/uglify.js | 14 ++++++++++++++ grunt/config/watch.js | 11 +++++++++++ 7 files changed, 86 insertions(+) create mode 100644 .eslintignore create mode 100644 .eslintrc create mode 100644 Gruntfile.js create mode 100644 grunt/config/aliases.yaml create mode 100644 grunt/config/eslint.js create mode 100644 grunt/config/uglify.js create mode 100644 grunt/config/watch.js diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000000000..96212a3593bac --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +**/*{.,-}min.js diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000000000..191b629c54339 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,4 @@ +extends: yoast + +rules: + complexity: [1, 6] diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000000000..9259cc84bf389 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,38 @@ +var path = require( "path" ); +var loadGruntConfig = require( "load-grunt-config" ); + +module.exports = function( grunt ) { + "use strict"; + + // require('time-grunt')(grunt); + + // Define project configuration + var project = { + paths: { + grunt: "grunt/", + get config() { + return this.grunt + "config/"; + } + }, + files: { + js: [ + "a11y-speak.js", + "grunt/config/*.js", + ], + get config() { + return project.paths.config + "*.js"; + }, + grunt: "Gruntfile.js" + }, + pkg: grunt.file.readJSON( "package.json" ) + }; + + // Load Grunt configurations and tasks + loadGruntConfig( grunt, { + configPath: path.join( process.cwd(), project.paths.config ), + data: project, + jitGrunt: { + customTasksDir: "grunt/custom" + } + } ); +}; diff --git a/grunt/config/aliases.yaml b/grunt/config/aliases.yaml new file mode 100644 index 0000000000000..c203e02fdfa27 --- /dev/null +++ b/grunt/config/aliases.yaml @@ -0,0 +1,15 @@ +# Grunt aliases +--- +# Build everything +build: + - 'build:js' +# Build JavaScript from assets to production +'build:js': + - 'uglify' +# Check health of the project +check: + - 'eslint' +# Default task +default: + - check + - build diff --git a/grunt/config/eslint.js b/grunt/config/eslint.js new file mode 100644 index 0000000000000..4a5d9e0380ed4 --- /dev/null +++ b/grunt/config/eslint.js @@ -0,0 +1,3 @@ +module.exports = { + target: [ "<%= files.js %>" ] +}; diff --git a/grunt/config/uglify.js b/grunt/config/uglify.js new file mode 100644 index 0000000000000..651a31499da60 --- /dev/null +++ b/grunt/config/uglify.js @@ -0,0 +1,14 @@ +// See: https://github.com/gruntjs/grunt-contrib-uglify. +module.exports = { + "a11y-speak": { + options: { + comments: "some", + report: "gzip" + }, + files: { + "a11y-speak.min.js": [ + "a11y-speak.js" + ] + } + } +}; diff --git a/grunt/config/watch.js b/grunt/config/watch.js new file mode 100644 index 0000000000000..76e29ae330265 --- /dev/null +++ b/grunt/config/watch.js @@ -0,0 +1,11 @@ +// See: https://github.com/gruntjs/grunt-contrib-watch. +module.exports = { + compile: { + files: "<%= files.js %>", + tasks: [ "build:js" ] + }, + checks: { + files: [ "<%= files.js %>" ], + tasks: [ "eslint" ] + } +}; From 5df4765bd4359b921f7376167310e38679a37ee9 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Tue, 12 Jul 2016 15:30:08 +0200 Subject: [PATCH 006/393] Add a11y-speak module --- a11y-speak.js | 61 +++++++++++++++++++++++++++++++++++++++++++++++ a11y-speak.min.js | 1 + 2 files changed, 62 insertions(+) create mode 100644 a11y-speak.js create mode 100644 a11y-speak.min.js diff --git a/a11y-speak.js b/a11y-speak.js new file mode 100644 index 0000000000000..8faa601eaa25b --- /dev/null +++ b/a11y-speak.js @@ -0,0 +1,61 @@ +var containerPolite = null; +var containerAssertive = null; + +/** + * Build the live regions markup. + * + * @param {String} ariaLive Optional. Value for the "aria-live" attribute, default "polite". + * + * @returns {Object} $container The ARIA live region jQuery object. + */ +var addContainer = function( ariaLive ) { + ariaLive = ariaLive || "polite"; + + var container = document.createElement( "div" ); + container.id = "a11y-speak-" + ariaLive; + container.className = "screen-reader-text a11y-speak-region"; + container.setAttribute( "aria-live", ariaLive ); + container.setAttribute( "aria-relevant", "additions text" ); + container.setAttribute( "aria-atomic", "true" ); + + document.querySelector( "body" ).appendChild( container ); + return container; +}; + +/** + * Clear the live regions. + */ +var clear = function() { + var regions = document.querySelectorAll( ".a11y-speak-region" ); + for ( var i = 0; i < regions.length; i++ ) { + regions[ i ].textContent = ""; + } +}; + +/** + * Update the ARIA live notification area text node. + * + * @param {String} message The message to be announced by Assistive Technologies. + * @param {String} ariaLive Optional. The politeness level for aria-live. Possible values: + * polite or assertive. Default polite. + */ +var A11ySpeak = function( message, ariaLive ) { + if ( containerPolite === null ) { + containerPolite = addContainer( "polite" ); + } + + if ( containerAssertive === null ) { + containerAssertive = addContainer( "assertive" ); + } + + // Clear previous messages to allow repeated strings being read out. + clear(); + + if ( this.containerAssertive && "assertive" === ariaLive ) { + this.containerAssertive.text( message ); + } else if ( this.containerPolite ) { + this.containerPolite.text( message ); + } +}; + +module.exports = A11ySpeak; diff --git a/a11y-speak.min.js b/a11y-speak.min.js new file mode 100644 index 0000000000000..d585352ba4b66 --- /dev/null +++ b/a11y-speak.min.js @@ -0,0 +1 @@ +var containerPolite=null,containerAssertive=null,addContainer=function(a){a=a||"polite";var b=document.createElement("div");return b.id="a11y-speak-"+a,b.className="screen-reader-text a11y-speak-region",b.setAttribute("aria-live",a),b.setAttribute("aria-relevant","additions text"),b.setAttribute("aria-atomic","true"),document.querySelector("body").appendChild(b),b},clear=function(){for(var a=document.querySelectorAll(".a11y-speak-region"),b=0;b Date: Tue, 12 Jul 2016 16:04:54 +0200 Subject: [PATCH 007/393] First go at Readme --- README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.md b/README.md index b244c04b52ce1..1a9b56dfd74fa 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,29 @@ # a11y-speak JS module inspired by wp-a11y.js + +For context I'll quote [this article on WordPress.org](https://make.wordpress.org/accessibility/2015/04/15/let-wordpress-speak-new-in-wordpress-4-2/) by [@joedolson](https://github.com/joedolson): + +> ## Why. +> In modern web development, updating discrete regions of a screen with JavaScript is common. The use of AJAX responses in modern JavaScript-based User Interfaces allows web developers to create beautiful interfaces similar to Desktop applications that don’t require pages to reload or refresh. + +> JavaScript can create great usability improvements for most users – but when content is updated dynamically, it has the potential to introduce accessibility issues. This is one of the steps you can take to handle that problem. + +> ## What. +> When a portion of a page is updated with JavaScript, the update is usually highlighted with animation and bright colors, and is easy to see. But if you don’t have the ability to see the screen, you don’t know this has happened, unless the updated region is marked as an ARIA-live region. + +> If this isn’t marked, there’s no notification for screen readers. But it’s also possible that all the region content will be announced after an update, if the ARIA live region is too large. You want to provide users with just a simple, concise message. + +> ## How. +> That’s what `wp.a11y.speak()` is meant for. It’s a simple tool that creates and appends an ARIA live notifications area to the element where developers can dispatch text messages. Assistive technologies will automatically announce any text change in this area. This ARIA live region has an ARIA role of “status” so it has an implicit aria-live value of polite and an implicit aria-atomic value of true. + +> This means assistive technologies will notify users of updates but generally do not interrupt the current task, and updates take low priority. If you’re creating an application with higher priority updates (such as a notification that their current session is about to expire, for example), then you’ll want to create your own method with an aria-live value of assertive. + +## Usage + +To make the `wp.a11y.speak` functionality more universally available, we've decided to create a dedicated JS module for it, called `A11ySpeak`. Usage is very simple: + +```JS +var A11ySpeak = require("A11ySpeak"); + +AllySpeak( "The message you want to send to the ARIA live region", "polite" ); +``` From 6860832b547bbfb848b3f8019c052bb43dbd10a9 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Tue, 12 Jul 2016 16:12:58 +0200 Subject: [PATCH 008/393] There is no such thing as screen-reader-text outside of WP --- a11y-speak.js | 6 +++++- a11y-speak.min.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/a11y-speak.js b/a11y-speak.js index 8faa601eaa25b..10db71ed9b2aa 100644 --- a/a11y-speak.js +++ b/a11y-speak.js @@ -13,7 +13,11 @@ var addContainer = function( ariaLive ) { var container = document.createElement( "div" ); container.id = "a11y-speak-" + ariaLive; - container.className = "screen-reader-text a11y-speak-region"; + container.className = "a11y-speak-region"; + + var screenReaderTextStyle = "clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden;"; + container.setAttribute( "style", screenReaderTextStyle ); + container.setAttribute( "aria-live", ariaLive ); container.setAttribute( "aria-relevant", "additions text" ); container.setAttribute( "aria-atomic", "true" ); diff --git a/a11y-speak.min.js b/a11y-speak.min.js index d585352ba4b66..07a482c48ff38 100644 --- a/a11y-speak.min.js +++ b/a11y-speak.min.js @@ -1 +1 @@ -var containerPolite=null,containerAssertive=null,addContainer=function(a){a=a||"polite";var b=document.createElement("div");return b.id="a11y-speak-"+a,b.className="screen-reader-text a11y-speak-region",b.setAttribute("aria-live",a),b.setAttribute("aria-relevant","additions text"),b.setAttribute("aria-atomic","true"),document.querySelector("body").appendChild(b),b},clear=function(){for(var a=document.querySelectorAll(".a11y-speak-region"),b=0;b Date: Tue, 12 Jul 2016 16:36:21 +0200 Subject: [PATCH 009/393] Update a11y-speak.js --- a11y-speak.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/a11y-speak.js b/a11y-speak.js index 10db71ed9b2aa..8e731d33a3f29 100644 --- a/a11y-speak.js +++ b/a11y-speak.js @@ -55,10 +55,10 @@ var A11ySpeak = function( message, ariaLive ) { // Clear previous messages to allow repeated strings being read out. clear(); - if ( this.containerAssertive && "assertive" === ariaLive ) { - this.containerAssertive.text( message ); - } else if ( this.containerPolite ) { - this.containerPolite.text( message ); + if ( containerAssertive && "assertive" === ariaLive ) { + containerAssertive.text( message ); + } else if ( containerPolite ) { + containerPolite.text( message ); } }; From 8eb4a4944b9624c288f56d5b43b05abb344fb474 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Tue, 12 Jul 2016 16:43:00 +0200 Subject: [PATCH 010/393] some jQuery leftover --- a11y-speak.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/a11y-speak.js b/a11y-speak.js index 8e731d33a3f29..7c49a21dd9fc9 100644 --- a/a11y-speak.js +++ b/a11y-speak.js @@ -56,9 +56,9 @@ var A11ySpeak = function( message, ariaLive ) { clear(); if ( containerAssertive && "assertive" === ariaLive ) { - containerAssertive.text( message ); + containerAssertive.textContent = message; } else if ( containerPolite ) { - containerPolite.text( message ); + containerPolite.textContent = message; } }; From 8054038e9543f39fee35be123cee0b00bf02c01a Mon Sep 17 00:00:00 2001 From: Omar Reiss Date: Tue, 12 Jul 2016 17:10:51 +0200 Subject: [PATCH 011/393] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1a9b56dfd74fa..75320135671f0 100644 --- a/README.md +++ b/README.md @@ -25,5 +25,5 @@ To make the `wp.a11y.speak` functionality more universally available, we've deci ```JS var A11ySpeak = require("A11ySpeak"); -AllySpeak( "The message you want to send to the ARIA live region", "polite" ); +A11ySpeak( "The message you want to send to the ARIA live region", "polite" ); ``` From c1a38a7e2def47006e085248f1035e315c845420 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Tue, 12 Jul 2016 17:14:59 +0200 Subject: [PATCH 012/393] Clarify usage. --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 75320135671f0..bed52b8531731 100644 --- a/README.md +++ b/README.md @@ -25,5 +25,9 @@ To make the `wp.a11y.speak` functionality more universally available, we've deci ```JS var A11ySpeak = require("A11ySpeak"); -A11ySpeak( "The message you want to send to the ARIA live region", "polite" ); +// For polite messages that shouldn't interrupt what screen readers are currently announcing. +AllySpeak( "The message you want to send to the ARIA live region" ); + +// For assertive messages that should interrupt what screen readers are currently announcing. +AllySpeak( "The message you want to send to the ARIA live region", "assertive" ); ``` From e364583dc42eb2e5bdcb8a1b27dd7609b5511339 Mon Sep 17 00:00:00 2001 From: Omar Reiss Date: Wed, 13 Jul 2016 01:07:32 +0200 Subject: [PATCH 013/393] typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bed52b8531731..5530850001844 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,8 @@ To make the `wp.a11y.speak` functionality more universally available, we've deci var A11ySpeak = require("A11ySpeak"); // For polite messages that shouldn't interrupt what screen readers are currently announcing. -AllySpeak( "The message you want to send to the ARIA live region" ); +A11ySpeak( "The message you want to send to the ARIA live region" ); // For assertive messages that should interrupt what screen readers are currently announcing. -AllySpeak( "The message you want to send to the ARIA live region", "assertive" ); +A11ySpeak( "The message you want to send to the ARIA live region", "assertive" ); ``` From 0102884ade343e6cf810319593f7980f93dd99c5 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Wed, 13 Jul 2016 12:54:52 +0200 Subject: [PATCH 014/393] Create the ARIA live regions when the DOM is ready. --- a11y-speak.js | 34 ++++++++++++++++++++++++++-------- a11y-speak.min.js | 2 +- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/a11y-speak.js b/a11y-speak.js index 7c49a21dd9fc9..bd6d06fe0aea1 100644 --- a/a11y-speak.js +++ b/a11y-speak.js @@ -26,6 +26,32 @@ var addContainer = function( ariaLive ) { return container; }; +/** + * Specify a function to execute when the DOM is fully loaded. + * + * @param {Function} callback A function to execute after the DOM is ready. + */ +var domReady = function( callback ) { + if ( document.readyState === "complete" || ( document.readyState !== "loading" && ! document.documentElement.doScroll ) ) { + callback(); + } else { + document.addEventListener( "DOMContentLoaded", callback ); + } +}; + +/** + * Create the live regions when the DOM is fully loaded. + */ +domReady( function() { + if ( containerPolite === null ) { + containerPolite = addContainer( "polite" ); + } + + if ( containerAssertive === null ) { + containerAssertive = addContainer( "assertive" ); + } +}); + /** * Clear the live regions. */ @@ -44,14 +70,6 @@ var clear = function() { * polite or assertive. Default polite. */ var A11ySpeak = function( message, ariaLive ) { - if ( containerPolite === null ) { - containerPolite = addContainer( "polite" ); - } - - if ( containerAssertive === null ) { - containerAssertive = addContainer( "assertive" ); - } - // Clear previous messages to allow repeated strings being read out. clear(); diff --git a/a11y-speak.min.js b/a11y-speak.min.js index 07a482c48ff38..5525154152558 100644 --- a/a11y-speak.min.js +++ b/a11y-speak.min.js @@ -1 +1 @@ -var containerPolite=null,containerAssertive=null,addContainer=function(a){a=a||"polite";var b=document.createElement("div");b.id="a11y-speak-"+a,b.className="a11y-speak-region";var c="clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden;";return b.setAttribute("style",c),b.setAttribute("aria-live",a),b.setAttribute("aria-relevant","additions text"),b.setAttribute("aria-atomic","true"),document.querySelector("body").appendChild(b),b},clear=function(){for(var a=document.querySelectorAll(".a11y-speak-region"),b=0;b Date: Wed, 13 Jul 2016 15:48:09 +0200 Subject: [PATCH 015/393] Add browser support heading --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 5530850001844..36cca6c883a39 100644 --- a/README.md +++ b/README.md @@ -31,3 +31,7 @@ A11ySpeak( "The message you want to send to the ARIA live region" ); // For assertive messages that should interrupt what screen readers are currently announcing. A11ySpeak( "The message you want to send to the ARIA live region", "assertive" ); ``` + +## Browser support + +IE9+ and all modern browsers. From 2a12bfd0df92fafa6f927aa6611190c4eb3bf2e3 Mon Sep 17 00:00:00 2001 From: Omar Reiss Date: Wed, 27 Jul 2016 16:12:21 +0200 Subject: [PATCH 016/393] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 36cca6c883a39..e77cc2f6d38f1 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # a11y-speak -JS module inspired by wp-a11y.js +Allows you to easily announce dynamic interface updates to screen readers using ARIA live regions. This module is inspired by wp-a11y.js For context I'll quote [this article on WordPress.org](https://make.wordpress.org/accessibility/2015/04/15/let-wordpress-speak-new-in-wordpress-4-2/) by [@joedolson](https://github.com/joedolson): From c1ca8cda15438fa10f17da5d0772624b293d3989 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Wed, 27 Jul 2016 16:26:28 +0200 Subject: [PATCH 017/393] If another a11y-speak region already exists, use that one. --- a11y-speak.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/a11y-speak.js b/a11y-speak.js index bd6d06fe0aea1..4ffb59874b6b1 100644 --- a/a11y-speak.js +++ b/a11y-speak.js @@ -1,5 +1,4 @@ -var containerPolite = null; -var containerAssertive = null; +var containerPolite, containerAssertive; /** * Build the live regions markup. @@ -43,11 +42,11 @@ var domReady = function( callback ) { * Create the live regions when the DOM is fully loaded. */ domReady( function() { - if ( containerPolite === null ) { + if ( containerPolite = document.getElementById('a11y-speak-polite') === null ) { containerPolite = addContainer( "polite" ); } - if ( containerAssertive === null ) { + if ( containerAssertive = document.getElementById('a11y-speak-assertive') === null ) { containerAssertive = addContainer( "assertive" ); } }); From f0c46999b6bd391a5472cbb817d7646aaf0f8843 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Mon, 1 Aug 2016 15:01:32 +0200 Subject: [PATCH 018/393] improve readability and fix codestyle --- a11y-speak.js | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/a11y-speak.js b/a11y-speak.js index 4ffb59874b6b1..189460379db58 100644 --- a/a11y-speak.js +++ b/a11y-speak.js @@ -29,27 +29,31 @@ var addContainer = function( ariaLive ) { * Specify a function to execute when the DOM is fully loaded. * * @param {Function} callback A function to execute after the DOM is ready. + * + * @returns {void} */ var domReady = function( callback ) { - if ( document.readyState === "complete" || ( document.readyState !== "loading" && ! document.documentElement.doScroll ) ) { - callback(); - } else { - document.addEventListener( "DOMContentLoaded", callback ); + if ( document.readyState === "complete" || ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + return callback(); } + + document.addEventListener( "DOMContentLoaded", callback ); }; /** * Create the live regions when the DOM is fully loaded. */ domReady( function() { - if ( containerPolite = document.getElementById('a11y-speak-polite') === null ) { + containerPolite = document.getElementById( "a11y-speak-polite" ); + containerAssertive = document.getElementById( "a11y-speak-assertive" ); + + if ( containerPolite === null ) { containerPolite = addContainer( "polite" ); } - - if ( containerAssertive = document.getElementById('a11y-speak-assertive') === null ) { + if ( containerAssertive === null ) { containerAssertive = addContainer( "assertive" ); } -}); +} ); /** * Clear the live regions. From 49006b00af92b7d428e6cb89ad783a2b2f9d4519 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Wed, 26 Oct 2016 17:14:57 +0200 Subject: [PATCH 019/393] Add simple replace to strip HTML tags. --- a11y-speak.js | 2 ++ a11y-speak.min.js | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/a11y-speak.js b/a11y-speak.js index 189460379db58..379b91a3324ab 100644 --- a/a11y-speak.js +++ b/a11y-speak.js @@ -76,6 +76,8 @@ var A11ySpeak = function( message, ariaLive ) { // Clear previous messages to allow repeated strings being read out. clear(); + message = message.replace( /<[^<>]+>/g, "" ); + if ( containerAssertive && "assertive" === ariaLive ) { containerAssertive.textContent = message; } else if ( containerPolite ) { diff --git a/a11y-speak.min.js b/a11y-speak.min.js index 5525154152558..35c4083218cd4 100644 --- a/a11y-speak.min.js +++ b/a11y-speak.min.js @@ -1 +1 @@ -var containerPolite=null,containerAssertive=null,addContainer=function(a){a=a||"polite";var b=document.createElement("div");b.id="a11y-speak-"+a,b.className="a11y-speak-region";var c="clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden;";return b.setAttribute("style",c),b.setAttribute("aria-live",a),b.setAttribute("aria-relevant","additions text"),b.setAttribute("aria-atomic","true"),document.querySelector("body").appendChild(b),b},domReady=function(a){"complete"===document.readyState||"loading"!==document.readyState&&!document.documentElement.doScroll?a():document.addEventListener("DOMContentLoaded",a)};domReady(function(){null===containerPolite&&(containerPolite=addContainer("polite")),null===containerAssertive&&(containerAssertive=addContainer("assertive"))});var clear=function(){for(var a=document.querySelectorAll(".a11y-speak-region"),b=0;b]+>/g,""),containerAssertive&&"assertive"===b?containerAssertive.textContent=a:containerPolite&&(containerPolite.textContent=a)};module.exports=A11ySpeak; \ No newline at end of file From 6f5752ee8a0a21367d06c25462d9055b99d9f18a Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Thu, 27 Oct 2016 14:20:22 +0200 Subject: [PATCH 020/393] Update regex to replace HTML with a space. Added comment. --- a11y-speak.js | 9 ++++++++- a11y-speak.min.js | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/a11y-speak.js b/a11y-speak.js index 379b91a3324ab..41dec7ee8610a 100644 --- a/a11y-speak.js +++ b/a11y-speak.js @@ -76,7 +76,14 @@ var A11ySpeak = function( message, ariaLive ) { // Clear previous messages to allow repeated strings being read out. clear(); - message = message.replace( /<[^<>]+>/g, "" ); + /* + * Strip HTML tags (if any) from the message string. Ideally, messages should + * be simple strings, carefully crafted for specific use with A11ySpeak. + * When re-using already existing strings this will ensure simple HTML to be + * stripped out and replaced with a space. Browsers will collapse multiple + * spaces natively. + */ + message = message.replace( /<[^<>]+>/g, " " ); if ( containerAssertive && "assertive" === ariaLive ) { containerAssertive.textContent = message; diff --git a/a11y-speak.min.js b/a11y-speak.min.js index 35c4083218cd4..3eed26207e8b2 100644 --- a/a11y-speak.min.js +++ b/a11y-speak.min.js @@ -1 +1 @@ -var containerPolite,containerAssertive,addContainer=function(a){a=a||"polite";var b=document.createElement("div");b.id="a11y-speak-"+a,b.className="a11y-speak-region";var c="clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden;";return b.setAttribute("style",c),b.setAttribute("aria-live",a),b.setAttribute("aria-relevant","additions text"),b.setAttribute("aria-atomic","true"),document.querySelector("body").appendChild(b),b},domReady=function(a){return"complete"===document.readyState||"loading"!==document.readyState&&!document.documentElement.doScroll?a():void document.addEventListener("DOMContentLoaded",a)};domReady(function(){containerPolite=document.getElementById("a11y-speak-polite"),containerAssertive=document.getElementById("a11y-speak-assertive"),null===containerPolite&&(containerPolite=addContainer("polite")),null===containerAssertive&&(containerAssertive=addContainer("assertive"))});var clear=function(){for(var a=document.querySelectorAll(".a11y-speak-region"),b=0;b]+>/g,""),containerAssertive&&"assertive"===b?containerAssertive.textContent=a:containerPolite&&(containerPolite.textContent=a)};module.exports=A11ySpeak; \ No newline at end of file +var containerPolite,containerAssertive,addContainer=function(a){a=a||"polite";var b=document.createElement("div");b.id="a11y-speak-"+a,b.className="a11y-speak-region";var c="clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden;";return b.setAttribute("style",c),b.setAttribute("aria-live",a),b.setAttribute("aria-relevant","additions text"),b.setAttribute("aria-atomic","true"),document.querySelector("body").appendChild(b),b},domReady=function(a){return"complete"===document.readyState||"loading"!==document.readyState&&!document.documentElement.doScroll?a():void document.addEventListener("DOMContentLoaded",a)};domReady(function(){containerPolite=document.getElementById("a11y-speak-polite"),containerAssertive=document.getElementById("a11y-speak-assertive"),null===containerPolite&&(containerPolite=addContainer("polite")),null===containerAssertive&&(containerAssertive=addContainer("assertive"))});var clear=function(){for(var a=document.querySelectorAll(".a11y-speak-region"),b=0;b]+>/g," "),containerAssertive&&"assertive"===b?containerAssertive.textContent=a:containerPolite&&(containerPolite.textContent=a)};module.exports=A11ySpeak; \ No newline at end of file From 969f3bcfeb2c957e9ff2cd879b6ba2d29f75f0b7 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Tue, 18 Apr 2017 16:13:42 +0200 Subject: [PATCH 021/393] Append a no-break space to repeated messages. --- a11y-speak.js | 10 ++++++++-- a11y-speak.min.js | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/a11y-speak.js b/a11y-speak.js index 41dec7ee8610a..2383cb2da5908 100644 --- a/a11y-speak.js +++ b/a11y-speak.js @@ -1,4 +1,4 @@ -var containerPolite, containerAssertive; +var containerPolite, containerAssertive, previousMessage = ""; /** * Build the live regions markup. @@ -14,7 +14,7 @@ var addContainer = function( ariaLive ) { container.id = "a11y-speak-" + ariaLive; container.className = "a11y-speak-region"; - var screenReaderTextStyle = "clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden;"; + var screenReaderTextStyle = "clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;"; container.setAttribute( "style", screenReaderTextStyle ); container.setAttribute( "aria-live", ariaLive ); @@ -85,6 +85,12 @@ var A11ySpeak = function( message, ariaLive ) { */ message = message.replace( /<[^<>]+>/g, " " ); + if ( previousMessage === message ) { + message = message + "\u00A0"; + } + + previousMessage = message; + if ( containerAssertive && "assertive" === ariaLive ) { containerAssertive.textContent = message; } else if ( containerPolite ) { diff --git a/a11y-speak.min.js b/a11y-speak.min.js index 3eed26207e8b2..dc74062b687db 100644 --- a/a11y-speak.min.js +++ b/a11y-speak.min.js @@ -1 +1 @@ -var containerPolite,containerAssertive,addContainer=function(a){a=a||"polite";var b=document.createElement("div");b.id="a11y-speak-"+a,b.className="a11y-speak-region";var c="clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden;";return b.setAttribute("style",c),b.setAttribute("aria-live",a),b.setAttribute("aria-relevant","additions text"),b.setAttribute("aria-atomic","true"),document.querySelector("body").appendChild(b),b},domReady=function(a){return"complete"===document.readyState||"loading"!==document.readyState&&!document.documentElement.doScroll?a():void document.addEventListener("DOMContentLoaded",a)};domReady(function(){containerPolite=document.getElementById("a11y-speak-polite"),containerAssertive=document.getElementById("a11y-speak-assertive"),null===containerPolite&&(containerPolite=addContainer("polite")),null===containerAssertive&&(containerAssertive=addContainer("assertive"))});var clear=function(){for(var a=document.querySelectorAll(".a11y-speak-region"),b=0;b]+>/g," "),containerAssertive&&"assertive"===b?containerAssertive.textContent=a:containerPolite&&(containerPolite.textContent=a)};module.exports=A11ySpeak; \ No newline at end of file +var containerPolite,containerAssertive,previousMessage="",addContainer=function(a){a=a||"polite";var b=document.createElement("div");b.id="a11y-speak-"+a,b.className="a11y-speak-region";var c="clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;";return b.setAttribute("style",c),b.setAttribute("aria-live",a),b.setAttribute("aria-relevant","additions text"),b.setAttribute("aria-atomic","true"),document.querySelector("body").appendChild(b),b},domReady=function(a){return"complete"===document.readyState||"loading"!==document.readyState&&!document.documentElement.doScroll?a():void document.addEventListener("DOMContentLoaded",a)};domReady(function(){containerPolite=document.getElementById("a11y-speak-polite"),containerAssertive=document.getElementById("a11y-speak-assertive"),null===containerPolite&&(containerPolite=addContainer("polite")),null===containerAssertive&&(containerAssertive=addContainer("assertive"))});var clear=function(){for(var a=document.querySelectorAll(".a11y-speak-region"),b=0;b]+>/g," "),previousMessage===a&&(a+=" "),previousMessage=a,containerAssertive&&"assertive"===b?containerAssertive.textContent=a:containerPolite&&(containerPolite.textContent=a)};module.exports=A11ySpeak; \ No newline at end of file From ed06fb5924afa2b8191bc4084c94c4840b6973d9 Mon Sep 17 00:00:00 2001 From: Matias Ventura Date: Tue, 27 Jun 2017 16:10:12 +0200 Subject: [PATCH 022/393] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000000000..4e060a73692ac --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# packages +Collection of JS modules and tools for WordPress development From d5589780c0dc2400ce4824dfacbc58b772b35d91 Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Wed, 28 Jun 2017 11:46:45 +1000 Subject: [PATCH 023/393] chore: Add initial `.travis.yml` Travis CI configuration. --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000000..c58cf9bdd8ad3 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +sudo: false +language: node_js +node_js: + - '8' + - '6' From a0dc2042cbd4eea39925aabbcc80292a0e628f72 Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Wed, 28 Jun 2017 12:09:13 +1000 Subject: [PATCH 024/393] Add GPLv2 `LICENSE.md` license --- LICENSE.md | 361 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000000..5544f2d5528ea --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,361 @@ +### GNU GENERAL PUBLIC LICENSE + +Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +### Preamble + +The licenses for most software are designed to take away your freedom +to share and change it. By contrast, the GNU General Public License is +intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + +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 +this service 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. + +To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + +We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, +we want its recipients to know that what they have is not the +original, so that any problems introduced by others will not reflect +on the original authors' reputations. + +Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at +all. + +The precise terms and conditions for copying, distribution and +modification follow. + +### TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +**0.** This License applies to any program or other work which +contains a notice placed by the copyright holder saying it may be +distributed under the terms of this General Public License. The +"Program", below, refers to any such program or work, and a "work +based on the Program" means either the Program or any derivative work +under copyright law: that is to say, a work containing the Program or +a portion of it, either verbatim or with modifications and/or +translated into another language. (Hereinafter, translation is +included without limitation in the term "modification".) Each licensee +is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the Program +(independent of having been made by running the Program). Whether that +is true depends on what the Program does. + +**1.** You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a +fee. + +**2.** You may modify your copy or copies of the Program or any +portion of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + +**a)** You must cause the modified files to carry prominent notices +stating that you changed the files and the date of any change. + + +**b)** You must cause any work that you distribute or publish, that in +whole or in part contains or is derived from the Program or any part +thereof, to be licensed as a whole at no charge to all third parties +under the terms of this License. + + +**c)** If the modified program normally reads commands interactively +when run, you must cause it, when started running for such interactive +use in the most ordinary way, to print or display an announcement +including an appropriate copyright notice and a notice that there is +no warranty (or else, saying that you provide a warranty) and that +users may redistribute the program under these conditions, and telling +the user how to view a copy of this License. (Exception: if the +Program itself is interactive but does not normally print such an +announcement, your work based on the Program is not required to print +an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +**3.** You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + +**a)** Accompany it with the complete corresponding machine-readable +source code, which must be distributed under the terms of Sections 1 +and 2 above on a medium customarily used for software interchange; or, + + +**b)** Accompany it with a written offer, valid for at least three +years, to give any third party, for a charge no more than your cost of +physically performing source distribution, a complete machine-readable +copy of the corresponding source code, to be distributed under the +terms of Sections 1 and 2 above on a medium customarily used for +software interchange; or, + + +**c)** Accompany it with the information you received as to the offer +to distribute corresponding source code. (This alternative is allowed +only for noncommercial distribution and only if you received the +program in object code or executable form with such an offer, in +accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + +**4.** You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt otherwise +to copy, modify, sublicense or distribute the Program is void, and +will automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such +parties remain in full compliance. + +**5.** You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +**6.** Each time you redistribute the Program (or any work based on +the Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + +**7.** If, as a consequence of a court judgment or allegation of +patent infringement or for any other reason (not limited to patent +issues), 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 distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, +then as a consequence you may not distribute the Program at all. For +example, if a patent license would not permit royalty-free +redistribution of the Program by all those who receive copies directly +or indirectly through you, then the only way you could satisfy both it +and this License would be to refrain entirely from distribution of the +Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +**8.** If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + +**9.** The Free Software Foundation may publish revised and/or new +versions of the 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 a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Program does not specify a +version number of this License, you may choose any version ever +published by the Free Software Foundation. + +**10.** If you wish to incorporate parts of the Program into other +free programs whose distribution conditions are different, write to +the author to ask for permission. For software which is copyrighted by +the Free Software Foundation, write to the Free Software Foundation; +we sometimes make exceptions for this. Our decision will be guided by +the two goals of preserving the free status of all derivatives of our +free software and of promoting the sharing and reuse of software +generally. + +**NO WARRANTY** + +**11.** BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + +**12.** IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE 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. + +### END OF TERMS AND CONDITIONS + +### How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these +terms. + +To do so, attach the following notices to the program. It is safest to +attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + one line to give the program's name and an idea of what it does. + Copyright (C) yyyy name of author + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +Also add information on how to contact you by electronic and paper +mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details + type `show w'. This is free software, and you are welcome + to redistribute it under certain conditions; type `show c' + for details. + +The hypothetical commands \`show w' and \`show c' should show the +appropriate parts of the General Public License. Of course, the +commands you use may be called something other than \`show w' and +\`show c'; they could even be mouse-clicks or menu items--whatever +suits your program. + +You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the program, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright + interest in the program `Gnomovision' + (which makes passes at compilers) written + by James Hacker. + + signature of Ty Coon, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, +you may consider it more useful to permit linking proprietary +applications with the library. If this is what you want to do, use the +[GNU Lesser General Public +License](http://www.gnu.org/licenses/lgpl.html) instead of this +License. From ab5bbaffadfe3dd8ea3ffca6b6925e965a3fa5a6 Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Wed, 28 Jun 2017 13:15:46 +1000 Subject: [PATCH 025/393] Update `LICENSE.md` with WordPress Core Licensing --- LICENSE.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/LICENSE.md b/LICENSE.md index 5544f2d5528ea..34301d8f2ced4 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,3 +1,42 @@ +### WordPress - Web publishing software + + Copyright 2011-2017 by the contributors + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +This program incorporates work covered by the following copyright and +permission notices: + + b2 is (c) 2001, 2002 Michel Valdrighi - m@tidakada.com - + http://tidakada.com + + Wherever third party code has been used, credit has been given in the code's + comments. + + b2 is released under the GPL + +and + + WordPress - Web publishing software + + Copyright 2003-2010 by the contributors + + WordPress is released under the GPL + +--- + ### GNU GENERAL PUBLIC LICENSE Version 2, June 1991 From 8cf8b579f57e00ca4b5540bd65725331aae8905f Mon Sep 17 00:00:00 2001 From: Gary Pendergast Date: Wed, 28 Jun 2017 15:26:32 +1000 Subject: [PATCH 026/393] Add Travis Slack notifications Includes a default `script`, so that Travis doesn't spam Slack with unnecessary fail messages. --- .travis.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.travis.yml b/.travis.yml index c58cf9bdd8ad3..1790f9d00c73c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,3 +3,11 @@ language: node_js node_js: - '8' - '6' +script: true +notifications: + slack: + rooms: + secure: p6bTA+Tfevko/4mdKjSB1xv8cCKJbMut6o6J49X2nXecNdiZ3tseA0ctbXsMgsQgXoU74imLtNOqC5ufs83TLy4D+J4vnfJ8XPCAecTZtq3qFl/8/QFB4ozxyVfVIaxhIVDJGcrQOWARB/NLk7v1arCHjyD3eVabAPGfwhtRxOhoD2c7B3mhQq0qNh1q7MHhWPWG8bmpbZeZfjvheRjpj6uNh7unxg3sY3AiMyg//W0vgub/LfZwhpS1YCbUmKhmmmdT3wqBH4+Q3LMcNN2tcVfBI/ajhR9akpuhxRorO9/a49WQ5HeHEPAbAC4bjk0/V9XiFaiKYk+vJowEX8i1mladvBiYQcLfUPl2tg2zxgAs9aXigMLd+6F9rm2tx039wKp7zKAcNioR5IcJcLrmOarsJivVyiO/DBC0IsJ9GPCk5Me6GV5dIOOCG/IywW3sF5FMbcBGZaJEf2AV+m2eETbXXcJyOyci5OCVr2oaAdaphf+kzesSt5Ir05I6kxDBh6czRHkBJ+KoLtGpnO+4YrMEuPPpZSqe5BCKzrLixggcGfk3OLUek1+DVTfdGDwUZf8p7kmXYm9IWqJ36kdg1vI9B5aZh6+ZW0RXqZeAImhn5mkkQTmyoTmX0uo8HvrBtAOQI9Gss9UkP5BYwpmxTBGvgCqwwCRyDKZAF2GFGBU= + on_start: never + on_success: change + on_failure: always From 3bb936cc4ffe1490d1baa3a1062378f03185875c Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Wed, 28 Jun 2017 15:58:08 +1000 Subject: [PATCH 027/393] docs: Initial `CONTRIBUTING.md` file --- CONTRIBUTING.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000000..b8076a73114d5 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,15 @@ +# Contributing + +## Workflow + +A good workflow is to work directly in this repo, branch off `master`, and submit your changes as a pull request. + +Ideally name your branches with prefixes and descriptions, like this: `[type]/[change]`. A good prefix would be: + +- `add/` = add a new feature +- `try/` = experimental feature, "tentatively add" +- `update/` = update an existing feature + +For example, `add/foo-module` means you're working on adding a new foo module. + +You can pick among all the tickets, or some of the ones labelled Good First Task. From b0deb3c5b357c16003ea7c28d76634f914958b7a Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Wed, 28 Jun 2017 12:54:57 +1000 Subject: [PATCH 028/393] Add `.editorconfig` --- .editorconfig | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000000..4ca196b1ed12a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# http://editorconfig.org +root = true + +[*] +indent_style = tab +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[{package.json,*.yml}] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false From 736c86ea347771fcf8879c925fdd838c8745e9d2 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 28 Jun 2017 22:45:15 +0100 Subject: [PATCH 029/393] Url Module: Bootstrap the repository and add the first module (#1) --- .babelrc | 21 ++++++ .gitignore | 5 ++ lerna.json | 7 ++ package.json | 17 +++++ packages/url/package.json | 18 +++++ packages/url/src/index.js | 21 ++++++ scripts/build.js | 151 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 240 insertions(+) create mode 100644 .babelrc create mode 100644 .gitignore create mode 100644 lerna.json create mode 100644 package.json create mode 100644 packages/url/package.json create mode 100644 packages/url/src/index.js create mode 100644 scripts/build.js diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000000000..4fb873a397e37 --- /dev/null +++ b/.babelrc @@ -0,0 +1,21 @@ +{ + "presets": [ + [ "env", { + "targets": { + "browsers": [ + "last 2 Chrome versions", + "last 2 Firefox versions", + "last 2 Safari versions", + "last 2 Edge versions", + "last 2 iOS versions", + "last 1 Android version", + "last 1 ChromeAndroid version", + "ie 11" + ] + } + } ] + ], + "plugins": [ + "transform-object-rest-spread" + ] +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000..559243dc69994 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +node_modules/ + +/packages/*/build/ +/packages/*/build-module/ +/packages/*/build-browser/ diff --git a/lerna.json b/lerna.json new file mode 100644 index 0000000000000..14b21512a980c --- /dev/null +++ b/lerna.json @@ -0,0 +1,7 @@ +{ + "lerna": "2.0.0-rc.5", + "packages": [ + "packages/*" + ], + "version": "0.0.0" +} diff --git a/package.json b/package.json new file mode 100644 index 0000000000000..11eded499daf9 --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "devDependencies": { + "babel-core": "^6.25.0", + "babel-plugin-transform-object-rest-spread": "^6.23.0", + "babel-plugin-transform-runtime": "^6.23.0", + "babel-preset-env": "^1.5.2", + "chalk": "^1.1.3", + "glob": "^7.1.2", + "lerna": "^2.0.0-rc.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.6.1" + }, + "scripts": { + "build-clean": "rimraf ./packages/*/build ./packages/*/build-browser ./packages/*/build-module", + "build": "node ./scripts/build.js" + } +} diff --git a/packages/url/package.json b/packages/url/package.json new file mode 100644 index 0000000000000..cd84d89347361 --- /dev/null +++ b/packages/url/package.json @@ -0,0 +1,18 @@ +{ + "name": "@wordpress/url", + "version": "0.0.1", + "repository": { + "type": "git", + "url": "https://github.com/WordPress/packages.git" + }, + "description": "WordPress URL utilities", + "main": "build/index.js", + "module": "build-module/index.js", + "browser": "build-browser/index.js", + "author": "WordPress", + "license": "GPL-2.0+", + "dependencies": { + "querystring": "^0.2.0", + "url": "^0.11.0" + } +} diff --git a/packages/url/src/index.js b/packages/url/src/index.js new file mode 100644 index 0000000000000..ff94aefa70524 --- /dev/null +++ b/packages/url/src/index.js @@ -0,0 +1,21 @@ +/** + * External dependencies + */ +import { parse, format } from 'url'; +import { parse as parseQueryString, stringify } from 'querystring'; + +/** + * Appends arguments to the query string of the url + * + * @param {String} url URL + * @param {Object} args Query Args + * + * @return {String} Updated URL + */ +export function addQueryArgs( url, args ) { + const parsedURL = parse( url, true ); + const query = { ...parsedURL.query, ...args }; + delete parsedURL.search; + + return format( { ...parsedURL, query } ); +} diff --git a/scripts/build.js b/scripts/build.js new file mode 100644 index 0000000000000..e19761780d50d --- /dev/null +++ b/scripts/build.js @@ -0,0 +1,151 @@ +/** + * script to build WordPress packages into `build/` directory. + * + * Example: + * node ./scripts/build.js + */ + +/** + * External Dependenceis + */ +const fs = require( 'fs' ); +const path = require( 'path' ); +const glob = require( 'glob' ); +const babel = require( 'babel-core' ); +const chalk = require( 'chalk' ); +const mkdirp = require( 'mkdirp' ); + +/** + * Module Constants + */ +const PACKAGES_DIR = path.resolve( __dirname, '../packages' ); +const SRC_DIR = 'src'; +const BUILD_DIR = { + main: 'build', + module: 'build-module', + browser: 'build-browser', +}; +const OK = chalk.reset.inverse.bold.green( ' DONE ' ); + +/** + * Babel Configuration + */ +const babelDefaultConfig = JSON.parse( + fs.readFileSync( path.resolve( __dirname, '..', '.babelrc' ), 'utf8' ) +); +babelDefaultConfig.babelrc = false; +const presetEnvConfig = babelDefaultConfig.presets[ 0 ][ 1 ]; +const babelConfigs = { + main: babelDefaultConfig, + module: Object.assign( + {}, + babelDefaultConfig, + { presets: [ + [ "env", Object.assign( {}, + presetEnvConfig, + { modules: false } + ) ], + ] } + ), + browser: Object.assign( + {}, + babelDefaultConfig, + { plugins: [ ...babelDefaultConfig.plugins, 'transform-runtime' ] } + ) +}; + +/** + * Returns the absolute path of all WordPress packages + * + * @return {Array} Package paths + */ +function getAllPackages() { + return fs + .readdirSync( PACKAGES_DIR ) + .map( ( file ) => path.resolve( PACKAGES_DIR, file ) ) + .filter( ( f ) => fs.lstatSync( path.resolve( f ) ).isDirectory() ); +} + +/** + * Get the package name for a specified file + * + * @param {String} file File name + * @return {String} Package name + */ +function getPackageName(file) { + return path.relative( PACKAGES_DIR, file ).split( path.sep )[ 0 ]; +} + +/** + * Get Build Path for a specified file + * + * @param {String} file File to build + * @param {String} buildFolder Output folder + * @return {String} Build path + */ +function getBuildPath( file, buildFolder ) { + const pkgName = getPackageName( file ); + const pkgSrcPath = path.resolve( PACKAGES_DIR, pkgName, SRC_DIR ); + const pkgBuildPath = path.resolve( PACKAGES_DIR, pkgName, buildFolder ); + const relativeToSrcPath = path.relative( pkgSrcPath, file ); + return path.resolve( pkgBuildPath, relativeToSrcPath ); +} + +/** + * Build a file for the required environments (node and ES5) + * + * @param {String} file File path to build + * @param {Boolean} silent Show logs + */ +function buildFile( file, silent ) { + buildFileFor( file, silent, 'main' ); + buildFileFor( file, silent, 'module' ); + buildFileFor( file, silent, 'browser' ); +} + +/** + * Build a file for a specific environment + * + * @param {String} file File path to build + * @param {Boolean} silent Show logs + * @param {String} environment Dist environment (node or es5) + */ +function buildFileFor( file, silent, environment ) { + const buildDir = BUILD_DIR[ environment ]; + const destPath = getBuildPath( file, buildDir ); + const babelOptions = babelConfigs[ environment ]; + + mkdirp.sync( path.dirname( destPath ) ); + const transformed = babel.transformFileSync( file, babelOptions ).code; + fs.writeFileSync(destPath, transformed); + if ( ! silent ) { + process.stdout.write( + chalk.green(' \u2022 ') + + path.relative(PACKAGES_DIR, file) + + chalk.green(' \u21D2 ') + + path.relative(PACKAGES_DIR, destPath) + + '\n' + ); + } +} + +/** + * Build the provided package path + * + * @param {String} packagePath absolute package path + */ +function buildPackage( packagePath ) { + const srcDir = path.resolve( packagePath, SRC_DIR ); + const pattern = path.resolve( srcDir, '**/*' ); + const files = glob.sync( pattern, { nodir: true } ); + + process.stdout.write( `${ path.basename( packagePath ) }\n` ); + + files.forEach( file => buildFile( file, true ) ); + process.stdout.write( `${ OK }\n` ); +} + +process.stdout.write( chalk.inverse( '>> Building packages \n' ) ); +getAllPackages() + .forEach( buildPackage ); +process.stdout.write('\n'); From 442b40d36b27332172d2c2ebe5f26cf277a7cbab Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Thu, 29 Jun 2017 11:01:47 +1000 Subject: [PATCH 030/393] Update browserlist supported browsers matrix WordPress supported browsers: https://make.wordpress.org/design/handbook/design-guide/browser-support/ --- .babelrc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.babelrc b/.babelrc index 4fb873a397e37..8a2bfa73ec3f4 100644 --- a/.babelrc +++ b/.babelrc @@ -7,10 +7,12 @@ "last 2 Firefox versions", "last 2 Safari versions", "last 2 Edge versions", + "last 2 Opera versions" "last 2 iOS versions", "last 1 Android version", "last 1 ChromeAndroid version", - "ie 11" + "ie 11", + "> 1%" ] } } ] From 37c92c1bb0b857d2edda6bf12349f41e3f804c38 Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Thu, 29 Jun 2017 17:02:10 +1000 Subject: [PATCH 031/393] Add missing comma --- .babelrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.babelrc b/.babelrc index 8a2bfa73ec3f4..4fc38dcb2f399 100644 --- a/.babelrc +++ b/.babelrc @@ -7,7 +7,7 @@ "last 2 Firefox versions", "last 2 Safari versions", "last 2 Edge versions", - "last 2 Opera versions" + "last 2 Opera versions", "last 2 iOS versions", "last 1 Android version", "last 1 ChromeAndroid version", From 38e34f96071049eee7d65fe35521dcd44c3592e9 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 3 Jul 2017 11:13:42 +0100 Subject: [PATCH 032/393] Test: Setup unit testing using Jest --- .gitignore | 2 ++ package.json | 4 +++- packages/url/src/test/index.test.js | 20 ++++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 packages/url/src/test/index.test.js diff --git a/.gitignore b/.gitignore index 559243dc69994..1e386cf42fc58 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ node_modules/ /packages/*/build/ /packages/*/build-module/ /packages/*/build-browser/ + +coverage/ diff --git a/package.json b/package.json index 11eded499daf9..624fe2d368a3c 100644 --- a/package.json +++ b/package.json @@ -6,12 +6,14 @@ "babel-preset-env": "^1.5.2", "chalk": "^1.1.3", "glob": "^7.1.2", + "jest": "^20.0.4", "lerna": "^2.0.0-rc.5", "mkdirp": "^0.5.1", "rimraf": "^2.6.1" }, "scripts": { "build-clean": "rimraf ./packages/*/build ./packages/*/build-browser ./packages/*/build-module", - "build": "node ./scripts/build.js" + "build": "node ./scripts/build.js", + "test": "jest" } } diff --git a/packages/url/src/test/index.test.js b/packages/url/src/test/index.test.js new file mode 100644 index 0000000000000..82e5729a8cab2 --- /dev/null +++ b/packages/url/src/test/index.test.js @@ -0,0 +1,20 @@ +/** + * Internal Dependencies + */ +import { addQueryArgs } from '../'; + +describe( 'addQueryArgs', () => { + test( 'should append args to an URL without query string', () => { + const url = 'https://andalouses.com/beach'; + const args = { sun: 'true', sand: 'false' }; + + expect( addQueryArgs( url, args ) ).toBe( 'https://andalouses.com/beach?sun=true&sand=false' ); + } ); + + test( 'should append args to an URL with query string', () => { + const url = 'https://andalouses.com/beach?night=false'; + const args = { sun: 'true', sand: 'false' }; + + expect( addQueryArgs( url, args ) ).toBe( 'https://andalouses.com/beach?night=false&sun=true&sand=false' ); + } ); +} ); From 05af7004f5fc50a65e90e71f34df16ef0466a4ee Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 3 Jul 2017 12:46:02 +0100 Subject: [PATCH 033/393] Testing: Adding the watch command --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 624fe2d368a3c..ebc1c5328ff61 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "scripts": { "build-clean": "rimraf ./packages/*/build ./packages/*/build-browser ./packages/*/build-module", "build": "node ./scripts/build.js", - "test": "jest" + "test": "jest", + "watch": "jest --watch" } } From b8f1df480cfbbcfc36d6ec1352c988d58e41f987 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Sat, 15 Jul 2017 23:34:49 +0200 Subject: [PATCH 034/393] remove all the old config and license file --- packages/a11y-speak/.eslintignore | 1 - packages/a11y-speak/.eslintrc | 4 - packages/a11y-speak/.gitignore | 6 - packages/a11y-speak/Gruntfile.js | 38 - packages/a11y-speak/LICENSE | 674 ------------------ packages/a11y-speak/a11y-speak.min.js | 1 - packages/a11y-speak/grunt/config/aliases.yaml | 15 - packages/a11y-speak/grunt/config/eslint.js | 3 - packages/a11y-speak/grunt/config/uglify.js | 14 - packages/a11y-speak/grunt/config/watch.js | 11 - 10 files changed, 767 deletions(-) delete mode 100644 packages/a11y-speak/.eslintignore delete mode 100644 packages/a11y-speak/.eslintrc delete mode 100644 packages/a11y-speak/.gitignore delete mode 100644 packages/a11y-speak/Gruntfile.js delete mode 100644 packages/a11y-speak/LICENSE delete mode 100644 packages/a11y-speak/a11y-speak.min.js delete mode 100644 packages/a11y-speak/grunt/config/aliases.yaml delete mode 100644 packages/a11y-speak/grunt/config/eslint.js delete mode 100644 packages/a11y-speak/grunt/config/uglify.js delete mode 100644 packages/a11y-speak/grunt/config/watch.js diff --git a/packages/a11y-speak/.eslintignore b/packages/a11y-speak/.eslintignore deleted file mode 100644 index 96212a3593bac..0000000000000 --- a/packages/a11y-speak/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -**/*{.,-}min.js diff --git a/packages/a11y-speak/.eslintrc b/packages/a11y-speak/.eslintrc deleted file mode 100644 index 191b629c54339..0000000000000 --- a/packages/a11y-speak/.eslintrc +++ /dev/null @@ -1,4 +0,0 @@ -extends: yoast - -rules: - complexity: [1, 6] diff --git a/packages/a11y-speak/.gitignore b/packages/a11y-speak/.gitignore deleted file mode 100644 index f2d6b0823cb4f..0000000000000 --- a/packages/a11y-speak/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -temps/ -temp-spec/ -.idea/ -node_modules/ -out/ -coverage/ diff --git a/packages/a11y-speak/Gruntfile.js b/packages/a11y-speak/Gruntfile.js deleted file mode 100644 index 9259cc84bf389..0000000000000 --- a/packages/a11y-speak/Gruntfile.js +++ /dev/null @@ -1,38 +0,0 @@ -var path = require( "path" ); -var loadGruntConfig = require( "load-grunt-config" ); - -module.exports = function( grunt ) { - "use strict"; - - // require('time-grunt')(grunt); - - // Define project configuration - var project = { - paths: { - grunt: "grunt/", - get config() { - return this.grunt + "config/"; - } - }, - files: { - js: [ - "a11y-speak.js", - "grunt/config/*.js", - ], - get config() { - return project.paths.config + "*.js"; - }, - grunt: "Gruntfile.js" - }, - pkg: grunt.file.readJSON( "package.json" ) - }; - - // Load Grunt configurations and tasks - loadGruntConfig( grunt, { - configPath: path.join( process.cwd(), project.paths.config ), - data: project, - jitGrunt: { - customTasksDir: "grunt/custom" - } - } ); -}; diff --git a/packages/a11y-speak/LICENSE b/packages/a11y-speak/LICENSE deleted file mode 100644 index ef7e7efc09c9d..0000000000000 --- a/packages/a11y-speak/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ -GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is 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. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - 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. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - 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 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. Use with the GNU Affero General Public License. - - 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 Affero 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 special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU 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 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 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 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 - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - {one line to give the program's name and a brief idea of what it does.} - Copyright (C) {year} {name of author} - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - {project} Copyright (C) {year} {fullname} - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/packages/a11y-speak/a11y-speak.min.js b/packages/a11y-speak/a11y-speak.min.js deleted file mode 100644 index dc74062b687db..0000000000000 --- a/packages/a11y-speak/a11y-speak.min.js +++ /dev/null @@ -1 +0,0 @@ -var containerPolite,containerAssertive,previousMessage="",addContainer=function(a){a=a||"polite";var b=document.createElement("div");b.id="a11y-speak-"+a,b.className="a11y-speak-region";var c="clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;";return b.setAttribute("style",c),b.setAttribute("aria-live",a),b.setAttribute("aria-relevant","additions text"),b.setAttribute("aria-atomic","true"),document.querySelector("body").appendChild(b),b},domReady=function(a){return"complete"===document.readyState||"loading"!==document.readyState&&!document.documentElement.doScroll?a():void document.addEventListener("DOMContentLoaded",a)};domReady(function(){containerPolite=document.getElementById("a11y-speak-polite"),containerAssertive=document.getElementById("a11y-speak-assertive"),null===containerPolite&&(containerPolite=addContainer("polite")),null===containerAssertive&&(containerAssertive=addContainer("assertive"))});var clear=function(){for(var a=document.querySelectorAll(".a11y-speak-region"),b=0;b]+>/g," "),previousMessage===a&&(a+=" "),previousMessage=a,containerAssertive&&"assertive"===b?containerAssertive.textContent=a:containerPolite&&(containerPolite.textContent=a)};module.exports=A11ySpeak; \ No newline at end of file diff --git a/packages/a11y-speak/grunt/config/aliases.yaml b/packages/a11y-speak/grunt/config/aliases.yaml deleted file mode 100644 index c203e02fdfa27..0000000000000 --- a/packages/a11y-speak/grunt/config/aliases.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# Grunt aliases ---- -# Build everything -build: - - 'build:js' -# Build JavaScript from assets to production -'build:js': - - 'uglify' -# Check health of the project -check: - - 'eslint' -# Default task -default: - - check - - build diff --git a/packages/a11y-speak/grunt/config/eslint.js b/packages/a11y-speak/grunt/config/eslint.js deleted file mode 100644 index 4a5d9e0380ed4..0000000000000 --- a/packages/a11y-speak/grunt/config/eslint.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - target: [ "<%= files.js %>" ] -}; diff --git a/packages/a11y-speak/grunt/config/uglify.js b/packages/a11y-speak/grunt/config/uglify.js deleted file mode 100644 index 651a31499da60..0000000000000 --- a/packages/a11y-speak/grunt/config/uglify.js +++ /dev/null @@ -1,14 +0,0 @@ -// See: https://github.com/gruntjs/grunt-contrib-uglify. -module.exports = { - "a11y-speak": { - options: { - comments: "some", - report: "gzip" - }, - files: { - "a11y-speak.min.js": [ - "a11y-speak.js" - ] - } - } -}; diff --git a/packages/a11y-speak/grunt/config/watch.js b/packages/a11y-speak/grunt/config/watch.js deleted file mode 100644 index 76e29ae330265..0000000000000 --- a/packages/a11y-speak/grunt/config/watch.js +++ /dev/null @@ -1,11 +0,0 @@ -// See: https://github.com/gruntjs/grunt-contrib-watch. -module.exports = { - compile: { - files: "<%= files.js %>", - tasks: [ "build:js" ] - }, - checks: { - files: [ "<%= files.js %>" ], - tasks: [ "eslint" ] - } -}; From 9016eaf468ee74d320a24227e81bf77f077fff68 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Sat, 15 Jul 2017 23:48:55 +0200 Subject: [PATCH 035/393] Use const, let, es6 export --- packages/a11y-speak/a11y-speak.js | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/packages/a11y-speak/a11y-speak.js b/packages/a11y-speak/a11y-speak.js index 2383cb2da5908..8063eb6d43088 100644 --- a/packages/a11y-speak/a11y-speak.js +++ b/packages/a11y-speak/a11y-speak.js @@ -1,4 +1,4 @@ -var containerPolite, containerAssertive, previousMessage = ""; +let containerPolite, containerAssertive, previousMessage = ""; /** * Build the live regions markup. @@ -7,16 +7,15 @@ var containerPolite, containerAssertive, previousMessage = ""; * * @returns {Object} $container The ARIA live region jQuery object. */ -var addContainer = function( ariaLive ) { +const addContainer = function( ariaLive ) { ariaLive = ariaLive || "polite"; - var container = document.createElement( "div" ); + let container = document.createElement( "div" ); container.id = "a11y-speak-" + ariaLive; container.className = "a11y-speak-region"; - var screenReaderTextStyle = "clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;"; + let screenReaderTextStyle = "clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;"; container.setAttribute( "style", screenReaderTextStyle ); - container.setAttribute( "aria-live", ariaLive ); container.setAttribute( "aria-relevant", "additions text" ); container.setAttribute( "aria-atomic", "true" ); @@ -32,7 +31,7 @@ var addContainer = function( ariaLive ) { * * @returns {void} */ -var domReady = function( callback ) { +const domReady = function( callback ) { if ( document.readyState === "complete" || ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { return callback(); } @@ -58,9 +57,9 @@ domReady( function() { /** * Clear the live regions. */ -var clear = function() { - var regions = document.querySelectorAll( ".a11y-speak-region" ); - for ( var i = 0; i < regions.length; i++ ) { +const clear = function() { + let regions = document.querySelectorAll( ".a11y-speak-region" ); + for ( let i = 0; i < regions.length; i++ ) { regions[ i ].textContent = ""; } }; @@ -72,7 +71,7 @@ var clear = function() { * @param {String} ariaLive Optional. The politeness level for aria-live. Possible values: * polite or assertive. Default polite. */ -var A11ySpeak = function( message, ariaLive ) { +export const A11ySpeak = function( message, ariaLive ) { // Clear previous messages to allow repeated strings being read out. clear(); @@ -97,5 +96,3 @@ var A11ySpeak = function( message, ariaLive ) { containerPolite.textContent = message; } }; - -module.exports = A11ySpeak; From d912fef95a294bb89ff72c203e5b236a2e8f8a80 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Sat, 15 Jul 2017 23:49:59 +0200 Subject: [PATCH 036/393] move source file to src/index.js --- packages/a11y-speak/{a11y-speak.js => src/index.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/a11y-speak/{a11y-speak.js => src/index.js} (100%) diff --git a/packages/a11y-speak/a11y-speak.js b/packages/a11y-speak/src/index.js similarity index 100% rename from packages/a11y-speak/a11y-speak.js rename to packages/a11y-speak/src/index.js From d02c0066d31b2ec39d2d78f8efa23d6945b7de64 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Sat, 15 Jul 2017 23:55:09 +0200 Subject: [PATCH 037/393] update a11-speak package.json --- packages/a11y-speak/package.json | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/packages/a11y-speak/package.json b/packages/a11y-speak/package.json index 4865dc7b714ac..c7b837e1b64f3 100644 --- a/packages/a11y-speak/package.json +++ b/packages/a11y-speak/package.json @@ -1,29 +1,22 @@ { - "name": "a11y-speak", - "description": "", - "homepage": "https://github.com/Yoast/", + "name": "@wordpress/a11y-speak", + "version": "0.0.1", + "description": "Easily announce dynamic interface updates to screen readers using ARIA live regions.", + "homepage": "https://github.com/WordPress/packages/packages/a11y-speak/README.md", + "author": "WordPress", "keywords": [ - "Yoast", "a11y", "aria-live" ], - "main": "a11y-speak.js", - "license": "GPL-3.0", - "version": "0.0.1", + "main": "build/index.js", + "module": "build-module/index.js", + "browser": "build-browser/index.js", + "license": "GPL-2.0+", "repository": { "type": "git", - "url": "https://github.com/Yoast/a11y-speak" - }, - "devDependencies": { - "eslint-config-yoast": "^1.0.0", - "eslint-plugin-yoast": "^1.0.0", - "grunt": "^0.4.5", - "grunt-contrib-uglify": "^1.0.1", - "grunt-contrib-watch": "^1.0.0", - "grunt-eslint": "^18.0.0", - "load-grunt-config": "^0.19.1" + "url": "https://github.com/WordPress/packages.git" }, "bugs": { - "url": "https://github.com/Yoast/a11y-speak/issues" + "url": "https://github.com/WordPress/packages/issues" } } From bd8dbb2bf9714077177ad9ee3b46f3e766bde6e6 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Sun, 16 Jul 2017 01:05:25 +0200 Subject: [PATCH 038/393] export A11ySpeak as default --- packages/a11y-speak/src/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/a11y-speak/src/index.js b/packages/a11y-speak/src/index.js index 8063eb6d43088..dca68df7e6c72 100644 --- a/packages/a11y-speak/src/index.js +++ b/packages/a11y-speak/src/index.js @@ -71,7 +71,7 @@ const clear = function() { * @param {String} ariaLive Optional. The politeness level for aria-live. Possible values: * polite or assertive. Default polite. */ -export const A11ySpeak = function( message, ariaLive ) { +const A11ySpeak = function( message, ariaLive ) { // Clear previous messages to allow repeated strings being read out. clear(); @@ -96,3 +96,5 @@ export const A11ySpeak = function( message, ariaLive ) { containerPolite.textContent = message; } }; + +export default A11ySpeak; From 24a1ec53a3d1284bbddfdd52badfea0777f31728 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Sun, 16 Jul 2017 01:06:14 +0200 Subject: [PATCH 039/393] split out functions into separate modules. --- packages/a11y-speak/src/addContainer.js | 25 ++++++++++++ packages/a11y-speak/src/clear.js | 11 +++++ packages/a11y-speak/src/domReady.js | 16 ++++++++ packages/a11y-speak/src/index.js | 53 ++----------------------- 4 files changed, 56 insertions(+), 49 deletions(-) create mode 100644 packages/a11y-speak/src/addContainer.js create mode 100644 packages/a11y-speak/src/clear.js create mode 100644 packages/a11y-speak/src/domReady.js diff --git a/packages/a11y-speak/src/addContainer.js b/packages/a11y-speak/src/addContainer.js new file mode 100644 index 0000000000000..0e2d075f03df4 --- /dev/null +++ b/packages/a11y-speak/src/addContainer.js @@ -0,0 +1,25 @@ +/** + * Build the live regions markup. + * + * @param {String} ariaLive Optional. Value for the "aria-live" attribute, default "polite". + * + * @returns {Object} $container The ARIA live region jQuery object. + */ +const addContainer = function( ariaLive ) { + ariaLive = ariaLive || "polite"; + + let container = document.createElement( "div" ); + container.id = "a11y-speak-" + ariaLive; + container.className = "a11y-speak-region"; + + let screenReaderTextStyle = "clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;"; + container.setAttribute( "style", screenReaderTextStyle ); + container.setAttribute( "aria-live", ariaLive ); + container.setAttribute( "aria-relevant", "additions text" ); + container.setAttribute( "aria-atomic", "true" ); + + document.querySelector( "body" ).appendChild( container ); + return container; +}; + +export default addContainer; diff --git a/packages/a11y-speak/src/clear.js b/packages/a11y-speak/src/clear.js new file mode 100644 index 0000000000000..7819fc6a0e43d --- /dev/null +++ b/packages/a11y-speak/src/clear.js @@ -0,0 +1,11 @@ +/** + * Clear the live regions. + */ +const clear = function() { + let regions = document.querySelectorAll( ".a11y-speak-region" ); + for ( let i = 0; i < regions.length; i++ ) { + regions[ i ].textContent = ""; + } +}; + +export default clear; diff --git a/packages/a11y-speak/src/domReady.js b/packages/a11y-speak/src/domReady.js new file mode 100644 index 0000000000000..3df90ed5aa9e4 --- /dev/null +++ b/packages/a11y-speak/src/domReady.js @@ -0,0 +1,16 @@ +/** + * Specify a function to execute when the DOM is fully loaded. + * + * @param {Function} callback A function to execute after the DOM is ready. + * + * @returns {void} + */ +const domReady = function( callback ) { + if ( document.readyState === "complete" || ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + return callback(); + } + + document.addEventListener( "DOMContentLoaded", callback ); +}; + +export default domReady; diff --git a/packages/a11y-speak/src/index.js b/packages/a11y-speak/src/index.js index dca68df7e6c72..b1acf095d9325 100644 --- a/packages/a11y-speak/src/index.js +++ b/packages/a11y-speak/src/index.js @@ -1,43 +1,8 @@ -let containerPolite, containerAssertive, previousMessage = ""; - -/** - * Build the live regions markup. - * - * @param {String} ariaLive Optional. Value for the "aria-live" attribute, default "polite". - * - * @returns {Object} $container The ARIA live region jQuery object. - */ -const addContainer = function( ariaLive ) { - ariaLive = ariaLive || "polite"; +import addContainer from './addContainer'; +import clear from './clear'; +import domReady from './domReady'; - let container = document.createElement( "div" ); - container.id = "a11y-speak-" + ariaLive; - container.className = "a11y-speak-region"; - - let screenReaderTextStyle = "clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;"; - container.setAttribute( "style", screenReaderTextStyle ); - container.setAttribute( "aria-live", ariaLive ); - container.setAttribute( "aria-relevant", "additions text" ); - container.setAttribute( "aria-atomic", "true" ); - - document.querySelector( "body" ).appendChild( container ); - return container; -}; - -/** - * Specify a function to execute when the DOM is fully loaded. - * - * @param {Function} callback A function to execute after the DOM is ready. - * - * @returns {void} - */ -const domReady = function( callback ) { - if ( document.readyState === "complete" || ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { - return callback(); - } - - document.addEventListener( "DOMContentLoaded", callback ); -}; +let containerPolite, containerAssertive, previousMessage = ""; /** * Create the live regions when the DOM is fully loaded. @@ -54,16 +19,6 @@ domReady( function() { } } ); -/** - * Clear the live regions. - */ -const clear = function() { - let regions = document.querySelectorAll( ".a11y-speak-region" ); - for ( let i = 0; i < regions.length; i++ ) { - regions[ i ].textContent = ""; - } -}; - /** * Update the ARIA live notification area text node. * From 39bb4e89cf142d7a61328356a9d97d6f7e512953 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Sun, 16 Jul 2017 02:17:58 +0200 Subject: [PATCH 040/393] correct documentation --- packages/a11y-speak/src/clear.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/a11y-speak/src/clear.js b/packages/a11y-speak/src/clear.js index 7819fc6a0e43d..625754df9de30 100644 --- a/packages/a11y-speak/src/clear.js +++ b/packages/a11y-speak/src/clear.js @@ -1,5 +1,5 @@ /** - * Clear the live regions. + * Clear the a11y-speak-region elements. */ const clear = function() { let regions = document.querySelectorAll( ".a11y-speak-region" ); From 6f5d7d840d1e5dcaaa1674fad800410078fb63ff Mon Sep 17 00:00:00 2001 From: omarreiss Date: Sun, 16 Jul 2017 02:19:15 +0200 Subject: [PATCH 041/393] Extract filtering the message to a separate module --- packages/a11y-speak/src/filterMessage.js | 30 ++++++++++++++++++++++++ packages/a11y-speak/src/index.js | 18 +++----------- 2 files changed, 33 insertions(+), 15 deletions(-) create mode 100644 packages/a11y-speak/src/filterMessage.js diff --git a/packages/a11y-speak/src/filterMessage.js b/packages/a11y-speak/src/filterMessage.js new file mode 100644 index 0000000000000..119363f281a0f --- /dev/null +++ b/packages/a11y-speak/src/filterMessage.js @@ -0,0 +1,30 @@ +let previousMessage = '' + +/** + * Filter the message to be announced to the screenreader. + * + * @param {String} message The message to be announced. + * + * @returns {String} + */ +const filterMessage = function( message ) { + + /* + * Strip HTML tags (if any) from the message string. Ideally, messages should + * be simple strings, carefully crafted for specific use with A11ySpeak. + * When re-using already existing strings this will ensure simple HTML to be + * stripped out and replaced with a space. Browsers will collapse multiple + * spaces natively. + */ + message = message.replace( /<[^<>]+>/g, ' ' ); + + if ( previousMessage === message ) { + message = message + '\u00A0'; + } + + previousMessage = message; + + return message; +}; + +export default filterMessage; diff --git a/packages/a11y-speak/src/index.js b/packages/a11y-speak/src/index.js index b1acf095d9325..256fdbe4e35bb 100644 --- a/packages/a11y-speak/src/index.js +++ b/packages/a11y-speak/src/index.js @@ -1,8 +1,9 @@ import addContainer from './addContainer'; import clear from './clear'; import domReady from './domReady'; +import filterMessage from './filterMessage'; -let containerPolite, containerAssertive, previousMessage = ""; +let containerPolite, containerAssertive = ""; /** * Create the live regions when the DOM is fully loaded. @@ -30,20 +31,7 @@ const A11ySpeak = function( message, ariaLive ) { // Clear previous messages to allow repeated strings being read out. clear(); - /* - * Strip HTML tags (if any) from the message string. Ideally, messages should - * be simple strings, carefully crafted for specific use with A11ySpeak. - * When re-using already existing strings this will ensure simple HTML to be - * stripped out and replaced with a space. Browsers will collapse multiple - * spaces natively. - */ - message = message.replace( /<[^<>]+>/g, " " ); - - if ( previousMessage === message ) { - message = message + "\u00A0"; - } - - previousMessage = message; + message = filterMessage( message ); if ( containerAssertive && "assertive" === ariaLive ) { containerAssertive.textContent = message; From bb8da58dc150126e030896bcdaa15e38605cda1e Mon Sep 17 00:00:00 2001 From: omarreiss Date: Sun, 16 Jul 2017 02:19:50 +0200 Subject: [PATCH 042/393] extract setup functionality to a separate function. --- packages/a11y-speak/src/index.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/a11y-speak/src/index.js b/packages/a11y-speak/src/index.js index 256fdbe4e35bb..d1108d2f18e2f 100644 --- a/packages/a11y-speak/src/index.js +++ b/packages/a11y-speak/src/index.js @@ -6,9 +6,9 @@ import filterMessage from './filterMessage'; let containerPolite, containerAssertive = ""; /** - * Create the live regions when the DOM is fully loaded. + * Create the live regions. */ -domReady( function() { +const setup = function() { containerPolite = document.getElementById( "a11y-speak-polite" ); containerAssertive = document.getElementById( "a11y-speak-assertive" ); @@ -18,7 +18,12 @@ domReady( function() { if ( containerAssertive === null ) { containerAssertive = addContainer( "assertive" ); } -} ); +}; + +/** + * Run setup on domReady. + */ +domReady( setup ); /** * Update the ARIA live notification area text node. From 2d220bf2bbe67278f6a776c310f41c525609bbe0 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Sun, 16 Jul 2017 03:06:06 +0200 Subject: [PATCH 043/393] Add unit tests for all a11y-speak modules --- .../a11y-speak/src/test/addContainer.test.js | 23 ++++++++ packages/a11y-speak/src/test/clear.test.js | 19 +++++++ packages/a11y-speak/src/test/domReady.test.js | 12 ++++ .../a11y-speak/src/test/filterMessage.test.js | 25 ++++++++ packages/a11y-speak/src/test/index.test.js | 57 +++++++++++++++++++ 5 files changed, 136 insertions(+) create mode 100644 packages/a11y-speak/src/test/addContainer.test.js create mode 100644 packages/a11y-speak/src/test/clear.test.js create mode 100644 packages/a11y-speak/src/test/domReady.test.js create mode 100644 packages/a11y-speak/src/test/filterMessage.test.js create mode 100644 packages/a11y-speak/src/test/index.test.js diff --git a/packages/a11y-speak/src/test/addContainer.test.js b/packages/a11y-speak/src/test/addContainer.test.js new file mode 100644 index 0000000000000..0f1d390d3b5f4 --- /dev/null +++ b/packages/a11y-speak/src/test/addContainer.test.js @@ -0,0 +1,23 @@ +import addContainer from '../addContainer'; + +describe( 'addContainer', () => { + it( 'should create an aria-live element', () => { + let containerPolite = addContainer( 'polite' ); + let containerAssertive = addContainer( 'assertive' ); + + expect( containerPolite ).not.toBe( null ); + expect( containerAssertive ).not.toBe( null ); + expect( containerPolite.className ).toBe( 'a11y-speak-region' ); + expect( containerAssertive.className ).toBe( 'a11y-speak-region' ); + expect( containerPolite.id ).toBe( 'a11y-speak-polite' ); + expect( containerAssertive.id ).toBe( 'a11y-speak-assertive' ); + expect( containerPolite.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); + expect( containerAssertive.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); + expect( containerPolite.getAttribute( 'aria-live' ) ).toBe( 'polite' ); + expect( containerAssertive.getAttribute( 'aria-live' ) ).toBe( 'assertive' ); + expect( containerPolite.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); + expect( containerAssertive.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); + expect( containerPolite.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); + expect( containerAssertive.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); + } ); +} ); diff --git a/packages/a11y-speak/src/test/clear.test.js b/packages/a11y-speak/src/test/clear.test.js new file mode 100644 index 0000000000000..2394da31b2ec2 --- /dev/null +++ b/packages/a11y-speak/src/test/clear.test.js @@ -0,0 +1,19 @@ +import clear from '../clear'; + +describe( 'clear', () => { + it( 'should clear all a11y-speak-region elements', () => { + let container1 = document.createElement( "div" ); + container1.className = "a11y-speak-region"; + container1.textContent = "not empty"; + document.querySelector( "body" ).appendChild( container1 ); + + let container2 = document.createElement( "div" ); + container2.className = "a11y-speak-region"; + container2.textContent = "not empty"; + document.querySelector( "body" ).appendChild( container2 ); + + clear(); + expect( container1.textContent ).toBe( '' ); + expect( container2.textContent ).toBe( '' ); + } ); +} ); diff --git a/packages/a11y-speak/src/test/domReady.test.js b/packages/a11y-speak/src/test/domReady.test.js new file mode 100644 index 0000000000000..414c44150086e --- /dev/null +++ b/packages/a11y-speak/src/test/domReady.test.js @@ -0,0 +1,12 @@ +import domReady from '../domReady'; + +let callback = jest.fn( () => {} ); + +describe( 'domReady', () => { + describe( 'when document readystate is complete', () => { + it( 'should call the callback.', () => { + domReady( callback ); + expect( callback ).toHaveBeenCalled(); + } ); + } ) +} ); diff --git a/packages/a11y-speak/src/test/filterMessage.test.js b/packages/a11y-speak/src/test/filterMessage.test.js new file mode 100644 index 0000000000000..601a69e1e7568 --- /dev/null +++ b/packages/a11y-speak/src/test/filterMessage.test.js @@ -0,0 +1,25 @@ +import filterMessage from '../filterMessage'; + +describe( 'filterMessage', () => { + describe( 'when a clean message is passed in', () => { + it( 'should return the message unfiltered', () => { + let actual = filterMessage( 'clean message.' ); + expect( actual ).toBe( 'clean message.' ); + } ); + } ) + + describe( 'when a message is passed in twice in a row', () => { + it( 'should add a space to the message to make sure it is announced again', () => { + filterMessage( 'repeated message.' ); + let actual = filterMessage( 'repeated message.' ); + expect( actual ).toBe( 'repeated message.' + '\u00A0' ); + } ); + } ) + + describe( 'when a message contains html tags', () => { + it( 'should strip the html tags and replace them with spaces', () => { + let actual = filterMessage( '

html paragraph

' ); + expect( actual ).toBe( ' html paragraph ' ); + } ); + } ) +} ); diff --git a/packages/a11y-speak/src/test/index.test.js b/packages/a11y-speak/src/test/index.test.js new file mode 100644 index 0000000000000..b0bb3257de098 --- /dev/null +++ b/packages/a11y-speak/src/test/index.test.js @@ -0,0 +1,57 @@ +import A11ySpeak from '../'; + +jest.mock( "../clear", () => { + return jest.fn(); +} ); +jest.mock( "../domReady", () => { + return jest.fn( ( callback ) => { callback(); } ); +} ); +jest.mock( "../filterMessage", () => { + return jest.fn( ( message ) => { return message; } ); +} ); + +import clear from "../clear"; +import domReady from "../domReady"; +import filterMessage from "../filterMessage"; + +describe( 'A11ySpeak', () => { + let containerPolite = document.getElementById( 'a11y-speak-polite' ); + let containerAssertive = document.getElementById( 'a11y-speak-assertive' ); + + beforeEach(() => { + containerPolite.textContent = ''; + containerAssertive.textContent = ''; + }); + + describe( 'on import', () => { + it( 'should call domReady', () => { + expect( domReady ).toHaveBeenCalled(); + } ); + } ); + + describe( 'in default mode', () => { + it( 'should set the textcontent of the polite aria-live region', () => { + A11ySpeak( 'default message' ); + expect( containerPolite.textContent ).toBe( 'default message' ); + expect( containerAssertive.textContent ).toBe( '' ); + expect( clear ).toHaveBeenCalled(); + expect( filterMessage ).toHaveBeenCalledWith( 'default message' ); + } ) + } ); + + describe( 'in assertive mode', () => { + it( 'should set the textcontent of the assertive aria-live region', () => { + A11ySpeak( 'assertive message', 'assertive' ); + expect( containerPolite.textContent ).toBe( '' ); + expect( containerAssertive.textContent ).toBe( 'assertive message' ); + } ) + } ); + + describe( 'in explicit polite mode', () => { + it( 'should set the textcontent of the polite aria-live region', () => { + A11ySpeak( 'polite message', 'polite' ); + expect( containerPolite.textContent ).toBe( 'polite message' ); + expect( containerAssertive.textContent ).toBe( '' ); + } ) + } ); +} ); From b98b8589be5ab8556857912cbf19e44d60050539 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Sun, 16 Jul 2017 03:21:42 +0200 Subject: [PATCH 044/393] Use single quotes everywhere --- packages/a11y-speak/README.md | 6 +++--- packages/a11y-speak/src/addContainer.js | 22 +++++++++++----------- packages/a11y-speak/src/clear.js | 4 ++-- packages/a11y-speak/src/domReady.js | 4 ++-- packages/a11y-speak/src/index.js | 12 ++++++------ packages/a11y-speak/src/test/clear.test.js | 16 ++++++++-------- packages/a11y-speak/src/test/index.test.js | 12 ++++++------ 7 files changed, 38 insertions(+), 38 deletions(-) diff --git a/packages/a11y-speak/README.md b/packages/a11y-speak/README.md index e77cc2f6d38f1..6c4497e67e276 100644 --- a/packages/a11y-speak/README.md +++ b/packages/a11y-speak/README.md @@ -23,13 +23,13 @@ For context I'll quote [this article on WordPress.org](https://make.wordpress.or To make the `wp.a11y.speak` functionality more universally available, we've decided to create a dedicated JS module for it, called `A11ySpeak`. Usage is very simple: ```JS -var A11ySpeak = require("A11ySpeak"); +var A11ySpeak = require('A11ySpeak'); // For polite messages that shouldn't interrupt what screen readers are currently announcing. -A11ySpeak( "The message you want to send to the ARIA live region" ); +A11ySpeak( 'The message you want to send to the ARIA live region' ); // For assertive messages that should interrupt what screen readers are currently announcing. -A11ySpeak( "The message you want to send to the ARIA live region", "assertive" ); +A11ySpeak( 'The message you want to send to the ARIA live region', 'assertive' ); ``` ## Browser support diff --git a/packages/a11y-speak/src/addContainer.js b/packages/a11y-speak/src/addContainer.js index 0e2d075f03df4..d478ffcf887f3 100644 --- a/packages/a11y-speak/src/addContainer.js +++ b/packages/a11y-speak/src/addContainer.js @@ -1,24 +1,24 @@ /** * Build the live regions markup. * - * @param {String} ariaLive Optional. Value for the "aria-live" attribute, default "polite". + * @param {String} ariaLive Optional. Value for the 'aria-live' attribute, default 'polite'. * * @returns {Object} $container The ARIA live region jQuery object. */ const addContainer = function( ariaLive ) { - ariaLive = ariaLive || "polite"; + ariaLive = ariaLive || 'polite'; - let container = document.createElement( "div" ); - container.id = "a11y-speak-" + ariaLive; - container.className = "a11y-speak-region"; + let container = document.createElement( 'div' ); + container.id = 'a11y-speak-' + ariaLive; + container.className = 'a11y-speak-region'; - let screenReaderTextStyle = "clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;"; - container.setAttribute( "style", screenReaderTextStyle ); - container.setAttribute( "aria-live", ariaLive ); - container.setAttribute( "aria-relevant", "additions text" ); - container.setAttribute( "aria-atomic", "true" ); + let screenReaderTextStyle = 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;'; + container.setAttribute( 'style', screenReaderTextStyle ); + container.setAttribute( 'aria-live', ariaLive ); + container.setAttribute( 'aria-relevant', 'additions text' ); + container.setAttribute( 'aria-atomic', 'true' ); - document.querySelector( "body" ).appendChild( container ); + document.querySelector( 'body' ).appendChild( container ); return container; }; diff --git a/packages/a11y-speak/src/clear.js b/packages/a11y-speak/src/clear.js index 625754df9de30..87ae91ab2bcc9 100644 --- a/packages/a11y-speak/src/clear.js +++ b/packages/a11y-speak/src/clear.js @@ -2,9 +2,9 @@ * Clear the a11y-speak-region elements. */ const clear = function() { - let regions = document.querySelectorAll( ".a11y-speak-region" ); + let regions = document.querySelectorAll( '.a11y-speak-region' ); for ( let i = 0; i < regions.length; i++ ) { - regions[ i ].textContent = ""; + regions[ i ].textContent = ''; } }; diff --git a/packages/a11y-speak/src/domReady.js b/packages/a11y-speak/src/domReady.js index 3df90ed5aa9e4..be89fe0862bb2 100644 --- a/packages/a11y-speak/src/domReady.js +++ b/packages/a11y-speak/src/domReady.js @@ -6,11 +6,11 @@ * @returns {void} */ const domReady = function( callback ) { - if ( document.readyState === "complete" || ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + if ( document.readyState === 'complete' || ( document.readyState !== 'loading' && !document.documentElement.doScroll ) ) { return callback(); } - document.addEventListener( "DOMContentLoaded", callback ); + document.addEventListener( 'DOMContentLoaded', callback ); }; export default domReady; diff --git a/packages/a11y-speak/src/index.js b/packages/a11y-speak/src/index.js index d1108d2f18e2f..e8c1068e6b343 100644 --- a/packages/a11y-speak/src/index.js +++ b/packages/a11y-speak/src/index.js @@ -3,20 +3,20 @@ import clear from './clear'; import domReady from './domReady'; import filterMessage from './filterMessage'; -let containerPolite, containerAssertive = ""; +let containerPolite, containerAssertive = ''; /** * Create the live regions. */ const setup = function() { - containerPolite = document.getElementById( "a11y-speak-polite" ); - containerAssertive = document.getElementById( "a11y-speak-assertive" ); + containerPolite = document.getElementById( 'a11y-speak-polite' ); + containerAssertive = document.getElementById( 'a11y-speak-assertive' ); if ( containerPolite === null ) { - containerPolite = addContainer( "polite" ); + containerPolite = addContainer( 'polite' ); } if ( containerAssertive === null ) { - containerAssertive = addContainer( "assertive" ); + containerAssertive = addContainer( 'assertive' ); } }; @@ -38,7 +38,7 @@ const A11ySpeak = function( message, ariaLive ) { message = filterMessage( message ); - if ( containerAssertive && "assertive" === ariaLive ) { + if ( containerAssertive && 'assertive' === ariaLive ) { containerAssertive.textContent = message; } else if ( containerPolite ) { containerPolite.textContent = message; diff --git a/packages/a11y-speak/src/test/clear.test.js b/packages/a11y-speak/src/test/clear.test.js index 2394da31b2ec2..f3c006eebbe53 100644 --- a/packages/a11y-speak/src/test/clear.test.js +++ b/packages/a11y-speak/src/test/clear.test.js @@ -2,15 +2,15 @@ import clear from '../clear'; describe( 'clear', () => { it( 'should clear all a11y-speak-region elements', () => { - let container1 = document.createElement( "div" ); - container1.className = "a11y-speak-region"; - container1.textContent = "not empty"; - document.querySelector( "body" ).appendChild( container1 ); + let container1 = document.createElement( 'div' ); + container1.className = 'a11y-speak-region'; + container1.textContent = 'not empty'; + document.querySelector( 'body' ).appendChild( container1 ); - let container2 = document.createElement( "div" ); - container2.className = "a11y-speak-region"; - container2.textContent = "not empty"; - document.querySelector( "body" ).appendChild( container2 ); + let container2 = document.createElement( 'div' ); + container2.className = 'a11y-speak-region'; + container2.textContent = 'not empty'; + document.querySelector( 'body' ).appendChild( container2 ); clear(); expect( container1.textContent ).toBe( '' ); diff --git a/packages/a11y-speak/src/test/index.test.js b/packages/a11y-speak/src/test/index.test.js index b0bb3257de098..7b2b29774bcf0 100644 --- a/packages/a11y-speak/src/test/index.test.js +++ b/packages/a11y-speak/src/test/index.test.js @@ -1,18 +1,18 @@ import A11ySpeak from '../'; -jest.mock( "../clear", () => { +jest.mock( '../clear', () => { return jest.fn(); } ); -jest.mock( "../domReady", () => { +jest.mock( '../domReady', () => { return jest.fn( ( callback ) => { callback(); } ); } ); -jest.mock( "../filterMessage", () => { +jest.mock( '../filterMessage', () => { return jest.fn( ( message ) => { return message; } ); } ); -import clear from "../clear"; -import domReady from "../domReady"; -import filterMessage from "../filterMessage"; +import clear from '../clear'; +import domReady from '../domReady'; +import filterMessage from '../filterMessage'; describe( 'A11ySpeak', () => { let containerPolite = document.getElementById( 'a11y-speak-polite' ); From f739dd0f786504eab094feb83b12902c005391e1 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Sun, 16 Jul 2017 03:26:43 +0200 Subject: [PATCH 045/393] consistent codestyle --- packages/a11y-speak/src/addContainer.js | 22 ++--- packages/a11y-speak/src/clear.js | 8 +- packages/a11y-speak/src/domReady.js | 8 +- packages/a11y-speak/src/filterMessage.js | 26 +++--- packages/a11y-speak/src/index.js | 34 ++++---- .../a11y-speak/src/test/addContainer.test.js | 36 ++++---- packages/a11y-speak/src/test/clear.test.js | 26 +++--- packages/a11y-speak/src/test/domReady.test.js | 12 +-- .../a11y-speak/src/test/filterMessage.test.js | 38 ++++----- packages/a11y-speak/src/test/index.test.js | 84 +++++++++---------- 10 files changed, 147 insertions(+), 147 deletions(-) diff --git a/packages/a11y-speak/src/addContainer.js b/packages/a11y-speak/src/addContainer.js index d478ffcf887f3..c4b830717762c 100644 --- a/packages/a11y-speak/src/addContainer.js +++ b/packages/a11y-speak/src/addContainer.js @@ -6,20 +6,20 @@ * @returns {Object} $container The ARIA live region jQuery object. */ const addContainer = function( ariaLive ) { - ariaLive = ariaLive || 'polite'; + ariaLive = ariaLive || 'polite'; - let container = document.createElement( 'div' ); - container.id = 'a11y-speak-' + ariaLive; - container.className = 'a11y-speak-region'; + let container = document.createElement( 'div' ); + container.id = 'a11y-speak-' + ariaLive; + container.className = 'a11y-speak-region'; - let screenReaderTextStyle = 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;'; - container.setAttribute( 'style', screenReaderTextStyle ); - container.setAttribute( 'aria-live', ariaLive ); - container.setAttribute( 'aria-relevant', 'additions text' ); - container.setAttribute( 'aria-atomic', 'true' ); + let screenReaderTextStyle = 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;'; + container.setAttribute( 'style', screenReaderTextStyle ); + container.setAttribute( 'aria-live', ariaLive ); + container.setAttribute( 'aria-relevant', 'additions text' ); + container.setAttribute( 'aria-atomic', 'true' ); - document.querySelector( 'body' ).appendChild( container ); - return container; + document.querySelector( 'body' ).appendChild( container ); + return container; }; export default addContainer; diff --git a/packages/a11y-speak/src/clear.js b/packages/a11y-speak/src/clear.js index 87ae91ab2bcc9..eb05020c9a9ec 100644 --- a/packages/a11y-speak/src/clear.js +++ b/packages/a11y-speak/src/clear.js @@ -2,10 +2,10 @@ * Clear the a11y-speak-region elements. */ const clear = function() { - let regions = document.querySelectorAll( '.a11y-speak-region' ); - for ( let i = 0; i < regions.length; i++ ) { - regions[ i ].textContent = ''; - } + let regions = document.querySelectorAll( '.a11y-speak-region' ); + for ( let i = 0; i < regions.length; i++ ) { + regions[ i ].textContent = ''; + } }; export default clear; diff --git a/packages/a11y-speak/src/domReady.js b/packages/a11y-speak/src/domReady.js index be89fe0862bb2..20afbeb8b9d97 100644 --- a/packages/a11y-speak/src/domReady.js +++ b/packages/a11y-speak/src/domReady.js @@ -6,11 +6,11 @@ * @returns {void} */ const domReady = function( callback ) { - if ( document.readyState === 'complete' || ( document.readyState !== 'loading' && !document.documentElement.doScroll ) ) { - return callback(); - } + if ( document.readyState === 'complete' || ( document.readyState !== 'loading' && !document.documentElement.doScroll ) ) { + return callback(); + } - document.addEventListener( 'DOMContentLoaded', callback ); + document.addEventListener( 'DOMContentLoaded', callback ); }; export default domReady; diff --git a/packages/a11y-speak/src/filterMessage.js b/packages/a11y-speak/src/filterMessage.js index 119363f281a0f..aa0e2c16bdef7 100644 --- a/packages/a11y-speak/src/filterMessage.js +++ b/packages/a11y-speak/src/filterMessage.js @@ -9,22 +9,22 @@ let previousMessage = '' */ const filterMessage = function( message ) { - /* - * Strip HTML tags (if any) from the message string. Ideally, messages should - * be simple strings, carefully crafted for specific use with A11ySpeak. - * When re-using already existing strings this will ensure simple HTML to be - * stripped out and replaced with a space. Browsers will collapse multiple - * spaces natively. - */ - message = message.replace( /<[^<>]+>/g, ' ' ); + /* + * Strip HTML tags (if any) from the message string. Ideally, messages should + * be simple strings, carefully crafted for specific use with A11ySpeak. + * When re-using already existing strings this will ensure simple HTML to be + * stripped out and replaced with a space. Browsers will collapse multiple + * spaces natively. + */ + message = message.replace( /<[^<>]+>/g, ' ' ); - if ( previousMessage === message ) { - message = message + '\u00A0'; - } + if ( previousMessage === message ) { + message = message + '\u00A0'; + } - previousMessage = message; + previousMessage = message; - return message; + return message; }; export default filterMessage; diff --git a/packages/a11y-speak/src/index.js b/packages/a11y-speak/src/index.js index e8c1068e6b343..c0152cf6c9e19 100644 --- a/packages/a11y-speak/src/index.js +++ b/packages/a11y-speak/src/index.js @@ -9,15 +9,15 @@ let containerPolite, containerAssertive = ''; * Create the live regions. */ const setup = function() { - containerPolite = document.getElementById( 'a11y-speak-polite' ); - containerAssertive = document.getElementById( 'a11y-speak-assertive' ); - - if ( containerPolite === null ) { - containerPolite = addContainer( 'polite' ); - } - if ( containerAssertive === null ) { - containerAssertive = addContainer( 'assertive' ); - } + containerPolite = document.getElementById( 'a11y-speak-polite' ); + containerAssertive = document.getElementById( 'a11y-speak-assertive' ); + + if ( containerPolite === null ) { + containerPolite = addContainer( 'polite' ); + } + if ( containerAssertive === null ) { + containerAssertive = addContainer( 'assertive' ); + } }; /** @@ -33,16 +33,16 @@ domReady( setup ); * polite or assertive. Default polite. */ const A11ySpeak = function( message, ariaLive ) { - // Clear previous messages to allow repeated strings being read out. - clear(); + // Clear previous messages to allow repeated strings being read out. + clear(); - message = filterMessage( message ); + message = filterMessage( message ); - if ( containerAssertive && 'assertive' === ariaLive ) { - containerAssertive.textContent = message; - } else if ( containerPolite ) { - containerPolite.textContent = message; - } + if ( containerAssertive && 'assertive' === ariaLive ) { + containerAssertive.textContent = message; + } else if ( containerPolite ) { + containerPolite.textContent = message; + } }; export default A11ySpeak; diff --git a/packages/a11y-speak/src/test/addContainer.test.js b/packages/a11y-speak/src/test/addContainer.test.js index 0f1d390d3b5f4..476a7ef191e0a 100644 --- a/packages/a11y-speak/src/test/addContainer.test.js +++ b/packages/a11y-speak/src/test/addContainer.test.js @@ -1,23 +1,23 @@ import addContainer from '../addContainer'; describe( 'addContainer', () => { - it( 'should create an aria-live element', () => { - let containerPolite = addContainer( 'polite' ); - let containerAssertive = addContainer( 'assertive' ); + it( 'should create an aria-live element', () => { + let containerPolite = addContainer( 'polite' ); + let containerAssertive = addContainer( 'assertive' ); - expect( containerPolite ).not.toBe( null ); - expect( containerAssertive ).not.toBe( null ); - expect( containerPolite.className ).toBe( 'a11y-speak-region' ); - expect( containerAssertive.className ).toBe( 'a11y-speak-region' ); - expect( containerPolite.id ).toBe( 'a11y-speak-polite' ); - expect( containerAssertive.id ).toBe( 'a11y-speak-assertive' ); - expect( containerPolite.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); - expect( containerAssertive.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); - expect( containerPolite.getAttribute( 'aria-live' ) ).toBe( 'polite' ); - expect( containerAssertive.getAttribute( 'aria-live' ) ).toBe( 'assertive' ); - expect( containerPolite.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); - expect( containerAssertive.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); - expect( containerPolite.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); - expect( containerAssertive.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); - } ); + expect( containerPolite ).not.toBe( null ); + expect( containerAssertive ).not.toBe( null ); + expect( containerPolite.className ).toBe( 'a11y-speak-region' ); + expect( containerAssertive.className ).toBe( 'a11y-speak-region' ); + expect( containerPolite.id ).toBe( 'a11y-speak-polite' ); + expect( containerAssertive.id ).toBe( 'a11y-speak-assertive' ); + expect( containerPolite.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); + expect( containerAssertive.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); + expect( containerPolite.getAttribute( 'aria-live' ) ).toBe( 'polite' ); + expect( containerAssertive.getAttribute( 'aria-live' ) ).toBe( 'assertive' ); + expect( containerPolite.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); + expect( containerAssertive.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); + expect( containerPolite.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); + expect( containerAssertive.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); + } ); } ); diff --git a/packages/a11y-speak/src/test/clear.test.js b/packages/a11y-speak/src/test/clear.test.js index f3c006eebbe53..b6a07ce06b98d 100644 --- a/packages/a11y-speak/src/test/clear.test.js +++ b/packages/a11y-speak/src/test/clear.test.js @@ -1,19 +1,19 @@ import clear from '../clear'; describe( 'clear', () => { - it( 'should clear all a11y-speak-region elements', () => { - let container1 = document.createElement( 'div' ); - container1.className = 'a11y-speak-region'; - container1.textContent = 'not empty'; - document.querySelector( 'body' ).appendChild( container1 ); + it( 'should clear all a11y-speak-region elements', () => { + let container1 = document.createElement( 'div' ); + container1.className = 'a11y-speak-region'; + container1.textContent = 'not empty'; + document.querySelector( 'body' ).appendChild( container1 ); - let container2 = document.createElement( 'div' ); - container2.className = 'a11y-speak-region'; - container2.textContent = 'not empty'; - document.querySelector( 'body' ).appendChild( container2 ); + let container2 = document.createElement( 'div' ); + container2.className = 'a11y-speak-region'; + container2.textContent = 'not empty'; + document.querySelector( 'body' ).appendChild( container2 ); - clear(); - expect( container1.textContent ).toBe( '' ); - expect( container2.textContent ).toBe( '' ); - } ); + clear(); + expect( container1.textContent ).toBe( '' ); + expect( container2.textContent ).toBe( '' ); + } ); } ); diff --git a/packages/a11y-speak/src/test/domReady.test.js b/packages/a11y-speak/src/test/domReady.test.js index 414c44150086e..10fbe31aaf30e 100644 --- a/packages/a11y-speak/src/test/domReady.test.js +++ b/packages/a11y-speak/src/test/domReady.test.js @@ -3,10 +3,10 @@ import domReady from '../domReady'; let callback = jest.fn( () => {} ); describe( 'domReady', () => { - describe( 'when document readystate is complete', () => { - it( 'should call the callback.', () => { - domReady( callback ); - expect( callback ).toHaveBeenCalled(); - } ); - } ) + describe( 'when document readystate is complete', () => { + it( 'should call the callback.', () => { + domReady( callback ); + expect( callback ).toHaveBeenCalled(); + } ); + } ); } ); diff --git a/packages/a11y-speak/src/test/filterMessage.test.js b/packages/a11y-speak/src/test/filterMessage.test.js index 601a69e1e7568..4ff90e71931e6 100644 --- a/packages/a11y-speak/src/test/filterMessage.test.js +++ b/packages/a11y-speak/src/test/filterMessage.test.js @@ -1,25 +1,25 @@ import filterMessage from '../filterMessage'; describe( 'filterMessage', () => { - describe( 'when a clean message is passed in', () => { - it( 'should return the message unfiltered', () => { - let actual = filterMessage( 'clean message.' ); - expect( actual ).toBe( 'clean message.' ); - } ); - } ) + describe( 'when a clean message is passed in', () => { + it( 'should return the message unfiltered', () => { + let actual = filterMessage( 'clean message.' ); + expect( actual ).toBe( 'clean message.' ); + } ); + } ) - describe( 'when a message is passed in twice in a row', () => { - it( 'should add a space to the message to make sure it is announced again', () => { - filterMessage( 'repeated message.' ); - let actual = filterMessage( 'repeated message.' ); - expect( actual ).toBe( 'repeated message.' + '\u00A0' ); - } ); - } ) + describe( 'when a message is passed in twice in a row', () => { + it( 'should add a space to the message to make sure it is announced again', () => { + filterMessage( 'repeated message.' ); + let actual = filterMessage( 'repeated message.' ); + expect( actual ).toBe( 'repeated message.' + '\u00A0' ); + } ); + } ) - describe( 'when a message contains html tags', () => { - it( 'should strip the html tags and replace them with spaces', () => { - let actual = filterMessage( '

html paragraph

' ); - expect( actual ).toBe( ' html paragraph ' ); - } ); - } ) + describe( 'when a message contains html tags', () => { + it( 'should strip the html tags and replace them with spaces', () => { + let actual = filterMessage( '

html paragraph

' ); + expect( actual ).toBe( ' html paragraph ' ); + } ); + } ) } ); diff --git a/packages/a11y-speak/src/test/index.test.js b/packages/a11y-speak/src/test/index.test.js index 7b2b29774bcf0..291aca0e9f269 100644 --- a/packages/a11y-speak/src/test/index.test.js +++ b/packages/a11y-speak/src/test/index.test.js @@ -1,13 +1,13 @@ import A11ySpeak from '../'; jest.mock( '../clear', () => { - return jest.fn(); + return jest.fn(); } ); jest.mock( '../domReady', () => { - return jest.fn( ( callback ) => { callback(); } ); + return jest.fn( ( callback ) => { callback(); } ); } ); jest.mock( '../filterMessage', () => { - return jest.fn( ( message ) => { return message; } ); + return jest.fn( ( message ) => { return message; } ); } ); import clear from '../clear'; @@ -15,43 +15,43 @@ import domReady from '../domReady'; import filterMessage from '../filterMessage'; describe( 'A11ySpeak', () => { - let containerPolite = document.getElementById( 'a11y-speak-polite' ); - let containerAssertive = document.getElementById( 'a11y-speak-assertive' ); - - beforeEach(() => { - containerPolite.textContent = ''; - containerAssertive.textContent = ''; - }); - - describe( 'on import', () => { - it( 'should call domReady', () => { - expect( domReady ).toHaveBeenCalled(); - } ); - } ); - - describe( 'in default mode', () => { - it( 'should set the textcontent of the polite aria-live region', () => { - A11ySpeak( 'default message' ); - expect( containerPolite.textContent ).toBe( 'default message' ); - expect( containerAssertive.textContent ).toBe( '' ); - expect( clear ).toHaveBeenCalled(); - expect( filterMessage ).toHaveBeenCalledWith( 'default message' ); - } ) - } ); - - describe( 'in assertive mode', () => { - it( 'should set the textcontent of the assertive aria-live region', () => { - A11ySpeak( 'assertive message', 'assertive' ); - expect( containerPolite.textContent ).toBe( '' ); - expect( containerAssertive.textContent ).toBe( 'assertive message' ); - } ) - } ); - - describe( 'in explicit polite mode', () => { - it( 'should set the textcontent of the polite aria-live region', () => { - A11ySpeak( 'polite message', 'polite' ); - expect( containerPolite.textContent ).toBe( 'polite message' ); - expect( containerAssertive.textContent ).toBe( '' ); - } ) - } ); + let containerPolite = document.getElementById( 'a11y-speak-polite' ); + let containerAssertive = document.getElementById( 'a11y-speak-assertive' ); + + beforeEach(() => { + containerPolite.textContent = ''; + containerAssertive.textContent = ''; + }); + + describe( 'on import', () => { + it( 'should call domReady', () => { + expect( domReady ).toHaveBeenCalled(); + } ); + } ); + + describe( 'in default mode', () => { + it( 'should set the textcontent of the polite aria-live region', () => { + A11ySpeak( 'default message' ); + expect( containerPolite.textContent ).toBe( 'default message' ); + expect( containerAssertive.textContent ).toBe( '' ); + expect( clear ).toHaveBeenCalled(); + expect( filterMessage ).toHaveBeenCalledWith( 'default message' ); + } ); + } ); + + describe( 'in assertive mode', () => { + it( 'should set the textcontent of the assertive aria-live region', () => { + A11ySpeak( 'assertive message', 'assertive' ); + expect( containerPolite.textContent ).toBe( '' ); + expect( containerAssertive.textContent ).toBe( 'assertive message' ); + } ); + } ); + + describe( 'in explicit polite mode', () => { + it( 'should set the textcontent of the polite aria-live region', () => { + A11ySpeak( 'polite message', 'polite' ); + expect( containerPolite.textContent ).toBe( 'polite message' ); + expect( containerAssertive.textContent ).toBe( '' ); + } ); + } ); } ); From 6bca9da3e41141ac77ea3aecec278889472186ab Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 18 Jul 2017 15:17:34 -0400 Subject: [PATCH 046/393] add wp-hooks, first pass --- packages/hooks/package.json | 18 ++ packages/hooks/src/index.js | 333 ++++++++++++++++++++++++++ packages/hooks/src/test/index.test.js | 4 + 3 files changed, 355 insertions(+) create mode 100644 packages/hooks/package.json create mode 100644 packages/hooks/src/index.js create mode 100644 packages/hooks/src/test/index.test.js diff --git a/packages/hooks/package.json b/packages/hooks/package.json new file mode 100644 index 0000000000000..af78230374593 --- /dev/null +++ b/packages/hooks/package.json @@ -0,0 +1,18 @@ +{ + "name": "@wordpress/hooks", + "version": "1.0.0", + "repository": { + "type": "git", + "url": "https://github.com/WordPress/packages.git" + }, + "description": "WordPress Hooks library", + "main": "build/index.js", + "module": "build-module/index.js", + "browser": "build-browser/index.js", + "author": "WordPress", + "license": "GPL-2.0+", + "dependencies": { + "querystring": "^0.2.0", + "url": "^0.11.0" + } +} diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js new file mode 100644 index 0000000000000..521bcb58cf061 --- /dev/null +++ b/packages/hooks/src/index.js @@ -0,0 +1,333 @@ + +//export function addQueryArgs( url, args ) { + + +/** + * Contains the registered hooks, keyed by hook type. Each hook type is an + * array of objects with priority and callback of each registered hook. + */ +var HOOKS = {}; + +/** + * Returns a function which, when invoked, will add a hook. + * + * @param {string} type Type for which hooks are to be added + * @return {Function} Hook added + */ +function createAddHookByType( type ) { + /** + * Adds the hook to the appropriate hooks container + * + * @param {string} hook Name of hook to add + * @param {Function} callback Function to call when the hook is run + * @param {?number} priority Priority of this hook (default=10) + */ + return function( hook, callback, priority ) { + var hookObject, hooks; + if ( typeof hook !== 'string' || typeof callback !== 'function' ) { + return; + } + + // Assign default priority + if ( 'undefined' === typeof priority ) { + priority = 10; + } else { + priority = parseInt( priority, 10 ); + } + + // Validate numeric priority + if ( isNaN( priority ) ) { + return; + } + + // Check if adding first of type + if ( ! HOOKS[ type ] ) { + HOOKS[ type ] = {}; + } + + hookObject = { + callback: callback, + priority: priority + }; + + if ( HOOKS[ type ].hasOwnProperty( hook ) ) { + // Append and re-sort amongst existing + hooks = HOOKS[ type ][ hook ]; + hooks.push( hookObject ); + hooks = sortHooks( hooks ); + } else { + // First of its type needs no sort + hooks = [ hookObject ]; + } + + HOOKS[ type ][ hook ] = hooks; + }; +} + +/** + * Returns a function which, when invoked, will remove a specified hook. + * + * @param {string} type Type for which hooks are to be removed + * @return {Function} Hook remover + */ +function createRemoveHookByType( type ) { + /** + * Removes the specified hook by resetting its value. + * + * @param {string} hook Name of hook to remove + * @param {?Function} callback The specific callback to be removed. If + * omitted, clears all callbacks. + */ + return function( hook, callback ) { + var handlers, i; + + // Baily early if no hooks exist by this name + if ( ! HOOKS[ type ] || ! HOOKS[ type ].hasOwnProperty( hook ) ) { + return; + } + + if ( callback ) { + // Try to find specified callback to remove + handlers = HOOKS[ type ][ hook ]; + for ( i = handlers.length - 1; i >= 0; i-- ) { + if ( handlers[ i ].callback === callback ) { + handlers.splice( i, 1 ); + } + } + } else { + // Reset hooks to empty + delete HOOKS[ type ][ hook ]; + } + }; +} + +/** + * Returns a function which, when invoked, will execute all registered + * hooks of the specified type by calling upon runner with its hook name + * and arguments. + * + * @param {string} type Type for which hooks are to be run, one of 'action' or 'filter'. + * @param {Function} runner Function to invoke for each hook callback + * @return {Function} Hook runner + */ +function createRunHookByType( type, runner ) { + /** + * Runs the specified hook. + * + * @param {string} hook The hook to run + * @param {...*} args Arguments to pass to the action/filter + * @return {*} Return value of runner, if applicable + * @private + */ + return function( /* hook, ...args */ ) { + var args, hook; + + args = Array.prototype.slice.call( arguments ); + hook = args.shift(); + + if ( typeof hook === 'string' ) { + return runner( hook, args ); + } + }; +} + +/** + * Performs an action if it exists. + * + * @param {string} action The action to perform. + * @param {...*} args Optional args to pass to the action. + * @private + */ +function runDoAction( action, args ) { + var handlers, i; + if ( HOOKS.actions ) { + handlers = HOOKS.actions[ action ]; + } + + if ( ! handlers ) { + return; + } + + HOOKS.actions.current = action; + + for ( i = 0; i < handlers.length; i++ ) { + handlers[ i ].callback.apply( null, args ); + HOOKS.actions[ action ].runs = HOOKS.actions[ action ].runs ? HOOKS.actions[ action ].runs + 1 : 1; + } + +} + +/** + * Performs a filter if it exists. + * + * @param {string} filter The filter to apply. + * @param {...*} args Optional args to pass to the filter. + * @return {*} The filtered value + * @private + */ +function runApplyFilters( filter, args ) { + var handlers, i; + if ( HOOKS.filters ) { + handlers = HOOKS.filters[ filter ]; + } + + if ( ! handlers ) { + return args[ 0 ]; + } + + HOOKS.filters.current = filter; + HOOKS.filters[ filter ].runs = HOOKS.filters[ filter ].runs ? HOOKS.filters[ filter ].runs + 1 : 1; + + for ( i = 0; i < handlers.length; i++ ) { + args[ 0 ] = handlers[ i ].callback.apply( null, args ); + } + delete( HOOKS.filters.current ); + + return args[ 0 ]; +} + +/** + * Use an insert sort for keeping our hooks organized based on priority. + * + * @see http://jsperf.com/javascript-sort + * + * @param {Array} hooks Array of the hooks to sort + * @return {Array} The sorted array + * @private + */ +function sortHooks( hooks ) { + var i, tmpHook, j, prevHook; + for ( i = 1; i < hooks.length; i++ ) { + tmpHook = hooks[ i ]; + j = i; + while ( ( prevHook = hooks[ j - 1 ] ) && prevHook.priority > tmpHook.priority ) { + hooks[ j ] = hooks[ j - 1 ]; + --j; + } + hooks[ j ] = tmpHook; + } + + return hooks; +} + + +/** + * See what action is currently being executed. + * + * @param {string} type Type of hooks to check, one of 'action' or 'filter'. + * @param {string} action The name of the action to check for. + * + * @return {[type]} [description] + */ +function createCurrentHookByType( type ) { + return function( action ) { + + // If the action was not passed, check for any current hook. + if ( 'undefined' === typeof action ) { + return false; + } + + // Return the current hook. + return HOOKS[ type ] && HOOKS[ type ].current ? + HOOKS[ type ].current : + false; + }; +} + + + +/** + * Checks to see if an action is currently being executed. + * + * @param {string} type Type of hooks to check, one of 'action' or 'filter'. + * @param {string} action The name of the action to check for, if omitted will check for any action being performed. + * + * @return {[type]} [description] + */ +function createDoingHookByType( type ) { + return function( action ) { + + // If the action was not passed, check for any current hook. + if ( 'undefined' === typeof action ) { + return 'undefined' !== typeof HOOKS[ type ].current; + } + + // Return the current hook. + return HOOKS[ type ] && HOOKS[ type ].current ? + action === HOOKS[ type ].current : + false; + }; +} + +/** + * Retrieve the number of times an action is fired. + * + * @param {string} type Type for which hooks to check, one of 'action' or 'filter'. + * @param {string} action The action to check. + * + * @return {[type]} [description] + */ +function createDidHookByType( type ) { + return function( action ) { + return HOOKS[ type ] && HOOKS[ type ][ action ] && HOOKS[ type ][ action ].runs ? + HOOKS[ type ][ action ].runs : + 0; + }; +} + +/** + * Check to see if an action is registered for a hook. + * + * @param {string} type Type for which hooks to check, one of 'action' or 'filter'. + * @param {string} action The action to check. + * + * @return {bool} Whether an action has been registered for a hook. + */ +function createHasHookByType( type ) { + return function( action ) { + return HOOKS[ type ] && HOOKS[ type ][ action ] ? + !! HOOKS[ type ][ action ] : + false; + }; +} + +/** + * Remove all the actions registered to a hook, + */ +function createRemoveAllByType( type ) { + return function( action, type ) { + + }; +} + +// Remove functions. +export removeFilter = createRemoveHookByType( 'filters' ); +export removeAction = createRemoveHookByType( 'actions' ); + + +// Do action/apply filter functions. +export doAction = createRunHookByType( 'actions', runDoAction ); +export applyFilters = createRunHookByType( 'filters', runApplyFilters ); + +// Add functions. +export addAction = createAddHookByType( 'actions' ); +export addFilter = createAddHookByType( 'filters' ); + +// Doing functions. +export doingAction = createDoingHookByType( 'actions' ), /* True for actions until;next action fired. */ +export doingFilter = createDoingHookByType( 'filters' ), /* True for filters while;filter is being applied. */ + +// Did functions. +export didAction = createDidHookByType( 'actions' ); +export didFilter = createDidHookByType( 'filters' ); + +// Has functions. +export hasAction = createHasHookByType( 'actions' ); +export hasFilter = createHasHookByType( 'filters' ); + +// Remove all functions. +export removeAllActions = createRemoveAllByType( 'actions' ); +export removeAllFilters = createRemoveAllByType( 'filters' ); + +// Current filter. +export currentFilter = createCurrentHookByType( 'filters' ); diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js new file mode 100644 index 0000000000000..27d9ce5052477 --- /dev/null +++ b/packages/hooks/src/test/index.test.js @@ -0,0 +1,4 @@ +/** + * Internal Dependencies + */ +import { doAction, applyFilters, addAction, addFilter, doingAction, doingFilter, didAction, didFilter, hasAction, hasFilter, removeAllActions, removeAllFilters, currentFilter } from '../'; From 9e96a3dfff2ef3ab42928a4c526e7f528003453b Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Wed, 19 Jul 2017 23:41:06 +1000 Subject: [PATCH 047/393] chore: Update lerna to 2.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ebc1c5328ff61..2ed94f7f2f5ac 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "chalk": "^1.1.3", "glob": "^7.1.2", "jest": "^20.0.4", - "lerna": "^2.0.0-rc.5", + "lerna": "^2.0.0", "mkdirp": "^0.5.1", "rimraf": "^2.6.1" }, From 85c73bea6defa1a63c4c8d10a33c23c07f60d0c2 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Wed, 19 Jul 2017 10:28:00 -0400 Subject: [PATCH 048/393] updates from ticket, flesh out removeAll, cleanup --- packages/hooks/src/index.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index 521bcb58cf061..d37d6d973d956 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -67,10 +67,12 @@ function createAddHookByType( type ) { /** * Returns a function which, when invoked, will remove a specified hook. * - * @param {string} type Type for which hooks are to be removed - * @return {Function} Hook remover + * @param {string} type Type for which hooks are to be removed. + * @param {bool} removeAll Whether to always remove all hooked callbacks. + * + * @return {Function} Hook remover. */ -function createRemoveHookByType( type ) { +function createRemoveHookByType( type, removeAll ) { /** * Removes the specified hook by resetting its value. * @@ -86,7 +88,7 @@ function createRemoveHookByType( type ) { return; } - if ( callback ) { + if ( callback && ! removeAll ) { // Try to find specified callback to remove handlers = HOOKS[ type ][ hook ]; for ( i = handlers.length - 1; i >= 0; i-- ) { @@ -154,7 +156,6 @@ function runDoAction( action, args ) { handlers[ i ].callback.apply( null, args ); HOOKS.actions[ action ].runs = HOOKS.actions[ action ].runs ? HOOKS.actions[ action ].runs + 1 : 1; } - } /** @@ -292,12 +293,10 @@ function createHasHookByType( type ) { } /** - * Remove all the actions registered to a hook, + * Remove all the actions registered to a hook. */ function createRemoveAllByType( type ) { - return function( action, type ) { - - }; + return createRemoveHookByType( type, true ); } // Remove functions. From dc71cd1d7766892e2f2430d2b8c40cf153546d88 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Wed, 19 Jul 2017 10:32:29 -0400 Subject: [PATCH 049/393] inline docs cleanup --- packages/hooks/src/index.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index d37d6d973d956..259c14eb87930 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -303,7 +303,6 @@ function createRemoveAllByType( type ) { export removeFilter = createRemoveHookByType( 'filters' ); export removeAction = createRemoveHookByType( 'actions' ); - // Do action/apply filter functions. export doAction = createRunHookByType( 'actions', runDoAction ); export applyFilters = createRunHookByType( 'filters', runApplyFilters ); @@ -312,9 +311,11 @@ export applyFilters = createRunHookByType( 'filters', runApplyFilters ); export addAction = createAddHookByType( 'actions' ); export addFilter = createAddHookByType( 'filters' ); -// Doing functions. -export doingAction = createDoingHookByType( 'actions' ), /* True for actions until;next action fired. */ -export doingFilter = createDoingHookByType( 'filters' ), /* True for filters while;filter is being applied. */ +// Doing action: true until next action fired. +export doingAction = createDoingHookByType( 'actions' ), + +// Doing filter: true while filter is being applied. +export doingFilter = createDoingHookByType( 'filters' ), // Did functions. export didAction = createDidHookByType( 'actions' ); From 4013c9a4e2ec3f297c97aea807c373dba97f0567 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Wed, 19 Jul 2017 10:33:41 -0400 Subject: [PATCH 050/393] remove some commented code --- packages/hooks/src/index.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index 259c14eb87930..a9bae3377d939 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -1,7 +1,3 @@ - -//export function addQueryArgs( url, args ) { - - /** * Contains the registered hooks, keyed by hook type. Each hook type is an * array of objects with priority and callback of each registered hook. From ff65810fbe8d83f66ad6f237c1e24c55ca3c5ed8 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Wed, 19 Jul 2017 10:33:56 -0400 Subject: [PATCH 051/393] downgrade initial version --- packages/hooks/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/hooks/package.json b/packages/hooks/package.json index af78230374593..4724aff1efadf 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/hooks", - "version": "1.0.0", + "version": "0.1.0", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" From be62409416336566ae6db268a33fd4556fa067b7 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Wed, 19 Jul 2017 10:35:23 -0400 Subject: [PATCH 052/393] clean up imports for (empty) tests file --- packages/hooks/src/test/index.test.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 27d9ce5052477..247e922d73bde 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -1,4 +1,20 @@ /** - * Internal Dependencies + * Internal Dependencies. */ -import { doAction, applyFilters, addAction, addFilter, doingAction, doingFilter, didAction, didFilter, hasAction, hasFilter, removeAllActions, removeAllFilters, currentFilter } from '../'; +import { + doAction + applyFilters + addAction + addFilter + doingAction + doingFilter + didAction + didFilter + hasAction + hasFilter + removeAllActions + removeAllFilters + currentFilter +} from '../'; + +// @todo port over qunit tests from core. From 45d70c38df2485d73f248b28562706d5a8f24ccc Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Wed, 19 Jul 2017 23:42:30 -0400 Subject: [PATCH 053/393] bring over object approach from core instead of passing around string --- packages/hooks/src/index.js | 132 ++++++++++++++------------ packages/hooks/src/test/index.test.js | 24 ++--- 2 files changed, 84 insertions(+), 72 deletions(-) diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index a9bae3377d939..f5544c1549f7c 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -2,15 +2,18 @@ * Contains the registered hooks, keyed by hook type. Each hook type is an * array of objects with priority and callback of each registered hook. */ -var HOOKS = {}; +var HOOKS = { + actions: [], + filters: [] +}; /** * Returns a function which, when invoked, will add a hook. * - * @param {string} type Type for which hooks are to be added - * @return {Function} Hook added + * @param {string} hooksArray Hooks array to which hooks are to be added + * @return {Function} Hook added. */ -function createAddHookByType( type ) { +function createAddHook( hooksArray ) { /** * Adds the hook to the appropriate hooks container * @@ -36,19 +39,14 @@ function createAddHookByType( type ) { return; } - // Check if adding first of type - if ( ! HOOKS[ type ] ) { - HOOKS[ type ] = {}; - } - hookObject = { callback: callback, priority: priority }; - if ( HOOKS[ type ].hasOwnProperty( hook ) ) { + if ( hooksArray.hasOwnProperty( hook ) ) { // Append and re-sort amongst existing - hooks = HOOKS[ type ][ hook ]; + hooks = hooksArray[ hook ]; hooks.push( hookObject ); hooks = sortHooks( hooks ); } else { @@ -56,37 +54,37 @@ function createAddHookByType( type ) { hooks = [ hookObject ]; } - HOOKS[ type ][ hook ] = hooks; + hooksArray[ hook ] = hooks; }; } /** * Returns a function which, when invoked, will remove a specified hook. * - * @param {string} type Type for which hooks are to be removed. - * @param {bool} removeAll Whether to always remove all hooked callbacks. + * @param {string} hooksArray Hooks array from which hooks are to be removed. + * @param {bool} removeAll Whether to always remove all hooked callbacks. * * @return {Function} Hook remover. */ -function createRemoveHookByType( type, removeAll ) { +function createRemoveHook( hooksArray, removeAll ) { /** * Removes the specified hook by resetting its value. * * @param {string} hook Name of hook to remove - * @param {?Function} callback The specific callback to be removed. If + * @param {?Function} callback The specific callback to be removed. Optional, if * omitted, clears all callbacks. */ return function( hook, callback ) { var handlers, i; // Baily early if no hooks exist by this name - if ( ! HOOKS[ type ] || ! HOOKS[ type ].hasOwnProperty( hook ) ) { + if ( ! hooksArray || ! hooksArray.hasOwnProperty( hook ) ) { return; } if ( callback && ! removeAll ) { // Try to find specified callback to remove - handlers = HOOKS[ type ][ hook ]; + handlers = hooksArray[ hook ]; for ( i = handlers.length - 1; i >= 0; i-- ) { if ( handlers[ i ].callback === callback ) { handlers.splice( i, 1 ); @@ -94,7 +92,7 @@ function createRemoveHookByType( type, removeAll ) { } } else { // Reset hooks to empty - delete HOOKS[ type ][ hook ]; + delete hooksArray[ hook ]; } }; } @@ -104,11 +102,10 @@ function createRemoveHookByType( type, removeAll ) { * hooks of the specified type by calling upon runner with its hook name * and arguments. * - * @param {string} type Type for which hooks are to be run, one of 'action' or 'filter'. * @param {Function} runner Function to invoke for each hook callback * @return {Function} Hook runner */ -function createRunHookByType( type, runner ) { +function createRunHook( runner ) { /** * Runs the specified hook. * @@ -152,6 +149,7 @@ function runDoAction( action, args ) { handlers[ i ].callback.apply( null, args ); HOOKS.actions[ action ].runs = HOOKS.actions[ action ].runs ? HOOKS.actions[ action ].runs + 1 : 1; } + } /** @@ -211,13 +209,21 @@ function sortHooks( hooks ) { /** * See what action is currently being executed. * - * @param {string} type Type of hooks to check, one of 'action' or 'filter'. - * @param {string} action The name of the action to check for. + * @param {string} hooksArray Hooks array of hooks to check. + * @param {string} action The name of the action to check for. * - * @return {[type]} [description] + * @return {Function} A function that gets the currently executing filter, */ -function createCurrentHookByType( type ) { - return function( action ) { +function createCurrentHook( hooksArray ) { + + /** + * Get the current active hook. + * + * @param {string} action The name of the action to check for, if omitted will check for any action being performed. + * + * @return {string} Returns the currently executing action, or false if none. + */ + return function() { // If the action was not passed, check for any current hook. if ( 'undefined' === typeof action ) { @@ -225,8 +231,8 @@ function createCurrentHookByType( type ) { } // Return the current hook. - return HOOKS[ type ] && HOOKS[ type ].current ? - HOOKS[ type ].current : + return hooksArray && hooksArray.current ? + hooksArray.current : false; }; } @@ -236,22 +242,22 @@ function createCurrentHookByType( type ) { /** * Checks to see if an action is currently being executed. * - * @param {string} type Type of hooks to check, one of 'action' or 'filter'. + * @param {string} type Type of hooks to check. * @param {string} action The name of the action to check for, if omitted will check for any action being performed. * * @return {[type]} [description] */ -function createDoingHookByType( type ) { +function createDoingHook( hooksArray ) { return function( action ) { // If the action was not passed, check for any current hook. if ( 'undefined' === typeof action ) { - return 'undefined' !== typeof HOOKS[ type ].current; + return 'undefined' !== typeof hooksArray.current; } // Return the current hook. - return HOOKS[ type ] && HOOKS[ type ].current ? - action === HOOKS[ type ].current : + return hooksArray && hooksArray.current ? + action === hooksArray.current : false; }; } @@ -259,15 +265,15 @@ function createDoingHookByType( type ) { /** * Retrieve the number of times an action is fired. * - * @param {string} type Type for which hooks to check, one of 'action' or 'filter'. - * @param {string} action The action to check. + * @param {string} hooksArray Hooks array of hooks to check. + * @param {string} action The action to check. * * @return {[type]} [description] */ -function createDidHookByType( type ) { +function createDidHook( hooksArray ) { return function( action ) { - return HOOKS[ type ] && HOOKS[ type ][ action ] && HOOKS[ type ][ action ].runs ? - HOOKS[ type ][ action ].runs : + return hooksArray && hooksArray[ action ] && hooksArray[ action ].runs ? + hooksArray[ action ].runs : 0; }; } @@ -275,55 +281,61 @@ function createDidHookByType( type ) { /** * Check to see if an action is registered for a hook. * - * @param {string} type Type for which hooks to check, one of 'action' or 'filter'. - * @param {string} action The action to check. + * @param {string} hooksArray Hooks array of hooks to check. + * @param {string} action The action to check. * * @return {bool} Whether an action has been registered for a hook. */ -function createHasHookByType( type ) { +function createHasHook( hooksArray ) { return function( action ) { - return HOOKS[ type ] && HOOKS[ type ][ action ] ? - !! HOOKS[ type ][ action ] : + return hooksArray && hooksArray[ action ] ? + !! hooksArray[ action ] : false; }; } /** * Remove all the actions registered to a hook. + * + * @param {string} hooksArray Hooks array of hooks to check. + * + * @return {Function} All hook remover. */ -function createRemoveAllByType( type ) { - return createRemoveHookByType( type, true ); +function createRemoveAllHook( hooksArray ) { + return createRemoveHook( hooksArray, true ); } // Remove functions. -export removeFilter = createRemoveHookByType( 'filters' ); -export removeAction = createRemoveHookByType( 'actions' ); +export const removeFilter = createRemoveHook( HOOKS.filters ); +export const removeAction = createRemoveHook( HOOKS.actions ); + // Do action/apply filter functions. -export doAction = createRunHookByType( 'actions', runDoAction ); -export applyFilters = createRunHookByType( 'filters', runApplyFilters ); +export const doAction = createRunHook( runDoAction ); +export const applyFilters = createRunHook( runApplyFilters ); // Add functions. -export addAction = createAddHookByType( 'actions' ); -export addFilter = createAddHookByType( 'filters' ); +export const addAction = createAddHook( HOOKS.actions ); +export const addFilter = createAddHook( HOOKS.filters ); // Doing action: true until next action fired. -export doingAction = createDoingHookByType( 'actions' ), +export const doingAction = createDoingHook( HOOKS.actions ); // Doing filter: true while filter is being applied. -export doingFilter = createDoingHookByType( 'filters' ), +export const doingFilter = createDoingHook( HOOKS.filters ); // Did functions. -export didAction = createDidHookByType( 'actions' ); -export didFilter = createDidHookByType( 'filters' ); +export const didAction = createDidHook( HOOKS.actions ); +export const didFilter = createDidHook( HOOKS.filters ); // Has functions. -export hasAction = createHasHookByType( 'actions' ); -export hasFilter = createHasHookByType( 'filters' ); +export const hasAction = createHasHook( HOOKS.actions ); +export const hasFilter = createHasHook( HOOKS.filters ); // Remove all functions. -export removeAllActions = createRemoveAllByType( 'actions' ); -export removeAllFilters = createRemoveAllByType( 'filters' ); +export const removeAllActions = createRemoveAllHook( HOOKS.actions ); +export const removeAllFilters = createRemoveAllHook( HOOKS.filters ); // Current filter. -export currentFilter = createCurrentHookByType( 'filters' ); +export const currentFilter = createCurrentHook( HOOKS.filters ); + diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 247e922d73bde..09c1dbd02a817 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -2,18 +2,18 @@ * Internal Dependencies. */ import { - doAction - applyFilters - addAction - addFilter - doingAction - doingFilter - didAction - didFilter - hasAction - hasFilter - removeAllActions - removeAllFilters + doAction, + applyFilters, + addAction, + addFilter, + doingAction, + doingFilter, + didAction, + didFilter, + hasAction, + hasFilter, + removeAllActions, + removeAllFilters, currentFilter } from '../'; From 632c98a066e7e900e6a9146d9aecfe1d0e95f36e Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Wed, 19 Jul 2017 23:57:11 -0400 Subject: [PATCH 054/393] First pass, jest tests --- packages/hooks/src/test/index.test.js | 73 ++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 09c1dbd02a817..bf067cfa71686 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -12,9 +12,80 @@ import { didFilter, hasAction, hasFilter, + removeFilter, + removeAction, removeAllActions, removeAllFilters, currentFilter } from '../'; -// @todo port over qunit tests from core. +function filter_a( str ) { + return str + 'a'; +} +function filter_b( str ) { + return str + 'b'; +} +function filter_c( str ) { + return str + 'c'; +} +function action_a() { + window.actionValue += 'a'; +} +function action_b() { + window.actionValue += 'b'; +} +function action_c() { + window.actionValue += 'c'; +} +function filter_check() { + ok( doingFilter( 'runtest.filter' ), 'The runtest.filter is running.' ); +} +window.actionValue = ''; + +describe( 'add and remove a filter', () => { + it( 'should leave the value unfiltered', () => { + addFilter( 'test.filter', filter_a ); + removeFilter( 'test.filter' ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); + } ); +} ); + +describe( 'add a filter and run it', () => { + it( 'should filter the value', () => { + addFilter( 'test.filter', filter_a ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testa' ); + removeFilter( 'test.filter' ); + } ); +} ); + +describe( 'add 2 filters in a row and run them', () => { + it( 'both filters should apply', () => { + addFilter( 'test.filter', filter_a ); + addFilter( 'test.filter', filter_b ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); + removeFilter( 'test.filter' ); + } ); +} ); + +describe( 'add 3 filters with different priorities and run them', () => { + it( 'should run in order', () => { + addFilter( 'test.filter', filter_a ); + addFilter( 'test.filter', filter_b, 2 ); + addFilter( 'test.filter', filter_c, 8 ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testbca' ); + removeFilter( 'test.filter' ); + } ); +} ); + +describe( 'add and remove an action', () => { + it( 'should leave the action unhooked', () => { + window.actionValue = ''; + addAction( 'test.action', action_a ); + removeAction( 'test.action' ); + doAction( 'test.action' ); + expect( window.actionValue ).toBe( '' ); + } ); +} ); + + + From 77c9906273791f394607abff4a92af95063c7d0c Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 20 Jul 2017 08:01:37 -0400 Subject: [PATCH 055/393] add remainder of tests --- packages/hooks/src/test/index.test.js | 179 +++++++++++++++++++++++++- 1 file changed, 178 insertions(+), 1 deletion(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index bf067cfa71686..2ef6986ed0d20 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -38,7 +38,7 @@ function action_c() { window.actionValue += 'c'; } function filter_check() { - ok( doingFilter( 'runtest.filter' ), 'The runtest.filter is running.' ); + expect( doingFilter( 'runtest.filter' ) ).toBeTruthy(); } window.actionValue = ''; @@ -87,5 +87,182 @@ describe( 'add and remove an action', () => { } ); } ); +describe( 'add an action and run it', function() { + it( 'should', () => { + window.actionValue = ''; + addAction( 'test.action', action_a ); + doAction( 'test.action' ); + expect( window.actionValue ).toBe( 'a' ); + removeAction( 'test.action' ); + } ); +} ); + +describe( 'add 2 actions in a row and then run them', function() { + it( 'should', () => { + window.actionValue = ''; + addAction( 'test.action', action_a ); + addAction( 'test.action', action_b ); + doAction( 'test.action' ); + expect( window.actionValue ).toBe( 'ab' ); + removeAction( 'test.action' ); + } ); +} ); + +describe( 'add 3 actions with different priorities and run them', function() { + it( 'should', () => { + window.actionValue = ''; + addAction( 'test.action', action_a ); + addAction( 'test.action', action_b, 2 ); + addAction( 'test.action', action_c, 8 ); + doAction( 'test.action' ); + expect( window.actionValue ).toBe( 'bca' ); + removeAction( 'test.action' ); + } ); +} ); + +describe( 'pass in two arguments to an action', function() { + it( 'should', () => { + var arg1 = 10, + arg2 = 20; + + addAction( 'test.action', function( a, b ) { + expect( arg1 ).toBe( a ); + expect( arg2 ).toBe( b ); + } ); + doAction( 'test.action', arg1, arg2 ); + removeAction( 'test.action' ); + + expect( arg1 ).toBe( 10 ); + expect( arg2 ).toBe( 20 ); + } ); +} ); + +describe( 'fire action multiple times', function() { + it( 'should', () => { + var func; + expect.assertions(2); + + func = function() { + expect( true ).toBe( true ); + }; + + addAction( 'test.action', func ); + doAction( 'test.action' ); + doAction( 'test.action' ); + removeAction( 'test.action' ); + } ); +} ); + +describe( 'remove specific action callback', function() { + it( 'should', () => { + window.actionValue = ''; + addAction( 'test.action', action_a ); + addAction( 'test.action', action_b, 2 ); + addAction( 'test.action', action_c, 8 ); + + removeAction( 'test.action', action_b ); + doAction( 'test.action' ); + expect( window.actionValue ).toBe( 'ca' ); + removeAction( 'test.action' ); + } ); +} ); + +describe( 'remove all action callbacks', function() { + it( 'should', () => { + window.actionValue = ''; + addAction( 'test.action', action_a ); + addAction( 'test.action', action_b, 2 ); + addAction( 'test.action', action_c, 8 ); + + removeAllActions( 'test.action' ); + doAction( 'test.action' ); + expect( window.actionValue ).toBe( '' ); + } ); +} ); + +describe( 'remove specific filter callback', function() { + it( 'should', () => { + addFilter( 'test.filter', filter_a ); + addFilter( 'test.filter', filter_b, 2 ); + addFilter( 'test.filter', filter_c, 8 ); + + removeFilter( 'test.filter', filter_b ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testca' ); + removeFilter( 'test.filter' ); + } ); +} ); + +describe( 'remove all filter callbacks', function() { + it( 'should', () => { + addFilter( 'test.filter', filter_a ); + addFilter( 'test.filter', filter_b, 2 ); + addFilter( 'test.filter', filter_c, 8 ); + + removeAllFilters( 'test.filter' ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); + } ); +} ); + +// Test doingAction, didAction, hasAction. +describe( 'Test doingAction, didAction and hasAction.', function() { + it( 'should', () => { + + // Reset state for testing. + removeAction( 'test.action' ); + addAction( 'another.action', function(){} ); + doAction( 'another.action' ); + + // Verify no action is running yet. + expect( ! doingAction( 'test.action' ) ).toBeTruthy(); + + expect( didAction( 'test.action' ) ).toBe( 0 ); + expect( ! hasAction( 'test.action' ) ).toBeTruthy(); + + addAction( 'test.action', action_a ); + + // Verify action added, not running yet. + expect( ! doingAction( 'test.action' ) ).toBeTruthy(); + expect( didAction( 'test.action' ) ).toBe( 0 ); + expect( hasAction( 'test.action' ) ).toBeTruthy(); + + doAction( 'test.action' ); + + // Verify action added and running. + expect( doingAction( 'test.action' ) ).toBeTruthy(); + expect( didAction( 'test.action' ) ).toBe( 1 ); + expect( hasAction( 'test.action' ) ).toBeTruthy(); + + doAction( 'test.action' ); + expect( didAction( 'test.action' ) ).toBe( 2 ); + + removeAction( 'test.action' ); + + // Verify state is reset appropriately. + expect( doingAction( 'test.action' ) ).toBeTruthy(); + expect( didAction( 'test.action' ) ).toBe( 0 ); + expect( ! hasAction( 'test.action' ) ).toBeTruthy(); + + doAction( 'another.action' ); + expect( ! doingAction( 'test.action' ) ).toBeTruthy(); + + // Verify hasAction returns false when no matching action. + expect( ! hasAction( 'notatest.action' ) ).toBeTruthy(); + + } ); +} ); + +describe( 'Verify doingFilter, didFilter and hasFilter.', function() { + it( 'should', () => { + addFilter( 'runtest.filter', filter_check ); + + // Verify filter added and running. + var test = applyFilters( 'runtest.filter', true ); + expect( didFilter( 'runtest.filter' ), 1, 'The runtest.filter has run once.' ); + expect( hasFilter( 'runtest.filter' ), 'The runtest.filter is registered.' ); + expect( ! hasFilter( 'notatest.filter' ), 'The notatest.filter is not registered.' ); + + removeFilter( 'runtest.filter' ); + } ); +} ); From b4b713d02a910b4a3c7a933debac0e962914b204 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 20 Jul 2017 08:06:25 -0400 Subject: [PATCH 056/393] Docs refinements --- packages/hooks/src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index f5544c1549f7c..18fa61033d968 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -245,7 +245,7 @@ function createCurrentHook( hooksArray ) { * @param {string} type Type of hooks to check. * @param {string} action The name of the action to check for, if omitted will check for any action being performed. * - * @return {[type]} [description] + * @return {bool} Whether the hook is being executed. */ function createDoingHook( hooksArray ) { return function( action ) { @@ -268,7 +268,7 @@ function createDoingHook( hooksArray ) { * @param {string} hooksArray Hooks array of hooks to check. * @param {string} action The action to check. * - * @return {[type]} [description] + * @return {number} The number of times the hook has run. */ function createDidHook( hooksArray ) { return function( action ) { From 9d24e77cb9f0877c048e1298e000136a58bd177d Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 20 Jul 2017 08:32:59 -0400 Subject: [PATCH 057/393] Break out code into one file per funciton --- packages/hooks/src/createAddHook.js | 54 ++++ packages/hooks/src/createCurrentHook.js | 32 +++ packages/hooks/src/createDidHook.js | 17 ++ packages/hooks/src/createDoingHook.js | 24 ++ packages/hooks/src/createHasHook.js | 17 ++ packages/hooks/src/createRemoveAllHook.js | 14 + packages/hooks/src/createRemoveHook.js | 40 +++ packages/hooks/src/createRunHook.js | 30 ++ packages/hooks/src/hooks.js | 10 + packages/hooks/src/index.js | 316 +--------------------- packages/hooks/src/runApplyFilters.js | 32 +++ packages/hooks/src/runDoAction.js | 28 ++ packages/hooks/src/sortHooks.js | 25 ++ 13 files changed, 334 insertions(+), 305 deletions(-) create mode 100644 packages/hooks/src/createAddHook.js create mode 100644 packages/hooks/src/createCurrentHook.js create mode 100644 packages/hooks/src/createDidHook.js create mode 100644 packages/hooks/src/createDoingHook.js create mode 100644 packages/hooks/src/createHasHook.js create mode 100644 packages/hooks/src/createRemoveAllHook.js create mode 100644 packages/hooks/src/createRemoveHook.js create mode 100644 packages/hooks/src/createRunHook.js create mode 100644 packages/hooks/src/hooks.js create mode 100644 packages/hooks/src/runApplyFilters.js create mode 100644 packages/hooks/src/runDoAction.js create mode 100644 packages/hooks/src/sortHooks.js diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js new file mode 100644 index 0000000000000..2d48450471974 --- /dev/null +++ b/packages/hooks/src/createAddHook.js @@ -0,0 +1,54 @@ +import sortHooks from './sortHooks'; + +/** + * Returns a function which, when invoked, will add a hook. + * + * @param {string} hooksArray Hooks array to which hooks are to be added + * @return {Function} Hook added. + */ +const createAddHook = function( hooksArray ) { + /** + * Adds the hook to the appropriate hooks container + * + * @param {string} hook Name of hook to add + * @param {Function} callback Function to call when the hook is run + * @param {?number} priority Priority of this hook (default=10) + */ + return function( hook, callback, priority ) { + var hookObject, hooks; + if ( typeof hook !== 'string' || typeof callback !== 'function' ) { + return; + } + + // Assign default priority + if ( 'undefined' === typeof priority ) { + priority = 10; + } else { + priority = parseInt( priority, 10 ); + } + + // Validate numeric priority + if ( isNaN( priority ) ) { + return; + } + + hookObject = { + callback: callback, + priority: priority + }; + + if ( hooksArray.hasOwnProperty( hook ) ) { + // Append and re-sort amongst existing + hooks = hooksArray[ hook ]; + hooks.push( hookObject ); + hooks = sortHooks( hooks ); + } else { + // First of its type needs no sort + hooks = [ hookObject ]; + } + + hooksArray[ hook ] = hooks; + }; +} + +export default createAddHook; diff --git a/packages/hooks/src/createCurrentHook.js b/packages/hooks/src/createCurrentHook.js new file mode 100644 index 0000000000000..351808a04aa51 --- /dev/null +++ b/packages/hooks/src/createCurrentHook.js @@ -0,0 +1,32 @@ +/** + * See what action is currently being executed. + * + * @param {string} hooksArray Hooks array of hooks to check. + * @param {string} action The name of the action to check for. + * + * @return {Function} A function that gets the currently executing filter, + */ +const createCurrentHook = function( hooksArray ) { + + /** + * Get the current active hook. + * + * @param {string} action The name of the action to check for, if omitted will check for any action being performed. + * + * @return {string} Returns the currently executing action, or false if none. + */ + return function() { + + // If the action was not passed, check for any current hook. + if ( 'undefined' === typeof action ) { + return false; + } + + // Return the current hook. + return hooksArray && hooksArray.current ? + hooksArray.current : + false; + }; +} + +export default createCurrentHook; diff --git a/packages/hooks/src/createDidHook.js b/packages/hooks/src/createDidHook.js new file mode 100644 index 0000000000000..a7223ae8f33f7 --- /dev/null +++ b/packages/hooks/src/createDidHook.js @@ -0,0 +1,17 @@ +/** + * Retrieve the number of times an action is fired. + * + * @param {string} hooksArray Hooks array of hooks to check. + * @param {string} action The action to check. + * + * @return {number} The number of times the hook has run. + */ +const createDidHook = function( hooksArray ) { + return function( action ) { + return hooksArray && hooksArray[ action ] && hooksArray[ action ].runs ? + hooksArray[ action ].runs : + 0; + }; +} + +export default createDidHook; diff --git a/packages/hooks/src/createDoingHook.js b/packages/hooks/src/createDoingHook.js new file mode 100644 index 0000000000000..95932c1b5e341 --- /dev/null +++ b/packages/hooks/src/createDoingHook.js @@ -0,0 +1,24 @@ +/** + * Checks to see if an action is currently being executed. + * + * @param {string} type Type of hooks to check. + * @param {string} action The name of the action to check for, if omitted will check for any action being performed. + * + * @return {bool} Whether the hook is being executed. + */ +const createDoingHook = function( hooksArray ) { + return function( action ) { + + // If the action was not passed, check for any current hook. + if ( 'undefined' === typeof action ) { + return 'undefined' !== typeof hooksArray.current; + } + + // Return the current hook. + return hooksArray && hooksArray.current ? + action === hooksArray.current : + false; + }; +} + +export default createDoingHook; diff --git a/packages/hooks/src/createHasHook.js b/packages/hooks/src/createHasHook.js new file mode 100644 index 0000000000000..6419cb55e4b65 --- /dev/null +++ b/packages/hooks/src/createHasHook.js @@ -0,0 +1,17 @@ +/** + * Check to see if an action is registered for a hook. + * + * @param {string} hooksArray Hooks array of hooks to check. + * @param {string} action The action to check. + * + * @return {bool} Whether an action has been registered for a hook. + */ +const createHasHook = function( hooksArray ) { + return function( action ) { + return hooksArray && hooksArray[ action ] ? + !! hooksArray[ action ] : + false; + }; +} + +export default createHasHook; diff --git a/packages/hooks/src/createRemoveAllHook.js b/packages/hooks/src/createRemoveAllHook.js new file mode 100644 index 0000000000000..b4bfd9c9c7111 --- /dev/null +++ b/packages/hooks/src/createRemoveAllHook.js @@ -0,0 +1,14 @@ +import createRemoveHook from './createRemoveHook'; + +/** + * Remove all the actions registered to a hook. + * + * @param {string} hooksArray Hooks array of hooks to check. + * + * @return {Function} All hook remover. + */ +const createRemoveAllHook = function( hooksArray ) { + return createRemoveHook( hooksArray, true ); +} + +export default createRemoveAllHook; diff --git a/packages/hooks/src/createRemoveHook.js b/packages/hooks/src/createRemoveHook.js new file mode 100644 index 0000000000000..e0c3c0acd2f12 --- /dev/null +++ b/packages/hooks/src/createRemoveHook.js @@ -0,0 +1,40 @@ +/** + * Returns a function which, when invoked, will remove a specified hook. + * + * @param {string} hooksArray Hooks array from which hooks are to be removed. + * @param {bool} removeAll Whether to always remove all hooked callbacks. + * + * @return {Function} Hook remover. + */ +const createRemoveHook = function ( hooksArray, removeAll ) { + /** + * Removes the specified hook by resetting its value. + * + * @param {string} hook Name of hook to remove + * @param {?Function} callback The specific callback to be removed. Optional, if + * omitted, clears all callbacks. + */ + return function( hook, callback ) { + var handlers, i; + + // Baily early if no hooks exist by this name + if ( ! hooksArray || ! hooksArray.hasOwnProperty( hook ) ) { + return; + } + + if ( callback && ! removeAll ) { + // Try to find specified callback to remove + handlers = hooksArray[ hook ]; + for ( i = handlers.length - 1; i >= 0; i-- ) { + if ( handlers[ i ].callback === callback ) { + handlers.splice( i, 1 ); + } + } + } else { + // Reset hooks to empty + delete hooksArray[ hook ]; + } + }; +} + +export default createRemoveHook; \ No newline at end of file diff --git a/packages/hooks/src/createRunHook.js b/packages/hooks/src/createRunHook.js new file mode 100644 index 0000000000000..7d678b237a3ea --- /dev/null +++ b/packages/hooks/src/createRunHook.js @@ -0,0 +1,30 @@ +/** + * Returns a function which, when invoked, will execute all registered + * hooks of the specified type by calling upon runner with its hook name + * and arguments. + * + * @param {Function} runner Function to invoke for each hook callback + * @return {Function} Hook runner + */ +const createRunHook = function( runner ) { + /** + * Runs the specified hook. + * + * @param {string} hook The hook to run + * @param {...*} args Arguments to pass to the action/filter + * @return {*} Return value of runner, if applicable + * @private + */ + return function( /* hook, ...args */ ) { + var args, hook; + + args = Array.prototype.slice.call( arguments ); + hook = args.shift(); + + if ( typeof hook === 'string' ) { + return runner( hook, args ); + } + }; +} + +export default createRunHook; diff --git a/packages/hooks/src/hooks.js b/packages/hooks/src/hooks.js new file mode 100644 index 0000000000000..e5017949edbc5 --- /dev/null +++ b/packages/hooks/src/hooks.js @@ -0,0 +1,10 @@ +/** + * Contains the registered hooks, keyed by hook type. Each hook type is an + * array of objects with priority and callback of each registered hook. + */ +var HOOKS = { + actions: [], + filters: [] +}; + +export default HOOKS; diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index 18fa61033d968..0b5975b07dee6 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -1,309 +1,15 @@ -/** - * Contains the registered hooks, keyed by hook type. Each hook type is an - * array of objects with priority and callback of each registered hook. - */ -var HOOKS = { - actions: [], - filters: [] -}; +import HOOKS from './hooks'; +import createAddHook from './createAddHook'; +import createRemoveHook from './createRemoveHook'; +import createRunHook from './createRunHook'; +import runDoAction from './runDoAction'; +import runApplyFilters from './runApplyFilters'; +import createCurrentHook from './createCurrentHook'; +import createDoingHook from './createDoingHook'; +import createDidHook from './createDidHook'; +import createHasHook from './createHasHook'; +import createRemoveAllHook from './createRemoveAllHook'; -/** - * Returns a function which, when invoked, will add a hook. - * - * @param {string} hooksArray Hooks array to which hooks are to be added - * @return {Function} Hook added. - */ -function createAddHook( hooksArray ) { - /** - * Adds the hook to the appropriate hooks container - * - * @param {string} hook Name of hook to add - * @param {Function} callback Function to call when the hook is run - * @param {?number} priority Priority of this hook (default=10) - */ - return function( hook, callback, priority ) { - var hookObject, hooks; - if ( typeof hook !== 'string' || typeof callback !== 'function' ) { - return; - } - - // Assign default priority - if ( 'undefined' === typeof priority ) { - priority = 10; - } else { - priority = parseInt( priority, 10 ); - } - - // Validate numeric priority - if ( isNaN( priority ) ) { - return; - } - - hookObject = { - callback: callback, - priority: priority - }; - - if ( hooksArray.hasOwnProperty( hook ) ) { - // Append and re-sort amongst existing - hooks = hooksArray[ hook ]; - hooks.push( hookObject ); - hooks = sortHooks( hooks ); - } else { - // First of its type needs no sort - hooks = [ hookObject ]; - } - - hooksArray[ hook ] = hooks; - }; -} - -/** - * Returns a function which, when invoked, will remove a specified hook. - * - * @param {string} hooksArray Hooks array from which hooks are to be removed. - * @param {bool} removeAll Whether to always remove all hooked callbacks. - * - * @return {Function} Hook remover. - */ -function createRemoveHook( hooksArray, removeAll ) { - /** - * Removes the specified hook by resetting its value. - * - * @param {string} hook Name of hook to remove - * @param {?Function} callback The specific callback to be removed. Optional, if - * omitted, clears all callbacks. - */ - return function( hook, callback ) { - var handlers, i; - - // Baily early if no hooks exist by this name - if ( ! hooksArray || ! hooksArray.hasOwnProperty( hook ) ) { - return; - } - - if ( callback && ! removeAll ) { - // Try to find specified callback to remove - handlers = hooksArray[ hook ]; - for ( i = handlers.length - 1; i >= 0; i-- ) { - if ( handlers[ i ].callback === callback ) { - handlers.splice( i, 1 ); - } - } - } else { - // Reset hooks to empty - delete hooksArray[ hook ]; - } - }; -} - -/** - * Returns a function which, when invoked, will execute all registered - * hooks of the specified type by calling upon runner with its hook name - * and arguments. - * - * @param {Function} runner Function to invoke for each hook callback - * @return {Function} Hook runner - */ -function createRunHook( runner ) { - /** - * Runs the specified hook. - * - * @param {string} hook The hook to run - * @param {...*} args Arguments to pass to the action/filter - * @return {*} Return value of runner, if applicable - * @private - */ - return function( /* hook, ...args */ ) { - var args, hook; - - args = Array.prototype.slice.call( arguments ); - hook = args.shift(); - - if ( typeof hook === 'string' ) { - return runner( hook, args ); - } - }; -} - -/** - * Performs an action if it exists. - * - * @param {string} action The action to perform. - * @param {...*} args Optional args to pass to the action. - * @private - */ -function runDoAction( action, args ) { - var handlers, i; - if ( HOOKS.actions ) { - handlers = HOOKS.actions[ action ]; - } - - if ( ! handlers ) { - return; - } - - HOOKS.actions.current = action; - - for ( i = 0; i < handlers.length; i++ ) { - handlers[ i ].callback.apply( null, args ); - HOOKS.actions[ action ].runs = HOOKS.actions[ action ].runs ? HOOKS.actions[ action ].runs + 1 : 1; - } - -} - -/** - * Performs a filter if it exists. - * - * @param {string} filter The filter to apply. - * @param {...*} args Optional args to pass to the filter. - * @return {*} The filtered value - * @private - */ -function runApplyFilters( filter, args ) { - var handlers, i; - if ( HOOKS.filters ) { - handlers = HOOKS.filters[ filter ]; - } - - if ( ! handlers ) { - return args[ 0 ]; - } - - HOOKS.filters.current = filter; - HOOKS.filters[ filter ].runs = HOOKS.filters[ filter ].runs ? HOOKS.filters[ filter ].runs + 1 : 1; - - for ( i = 0; i < handlers.length; i++ ) { - args[ 0 ] = handlers[ i ].callback.apply( null, args ); - } - delete( HOOKS.filters.current ); - - return args[ 0 ]; -} - -/** - * Use an insert sort for keeping our hooks organized based on priority. - * - * @see http://jsperf.com/javascript-sort - * - * @param {Array} hooks Array of the hooks to sort - * @return {Array} The sorted array - * @private - */ -function sortHooks( hooks ) { - var i, tmpHook, j, prevHook; - for ( i = 1; i < hooks.length; i++ ) { - tmpHook = hooks[ i ]; - j = i; - while ( ( prevHook = hooks[ j - 1 ] ) && prevHook.priority > tmpHook.priority ) { - hooks[ j ] = hooks[ j - 1 ]; - --j; - } - hooks[ j ] = tmpHook; - } - - return hooks; -} - - -/** - * See what action is currently being executed. - * - * @param {string} hooksArray Hooks array of hooks to check. - * @param {string} action The name of the action to check for. - * - * @return {Function} A function that gets the currently executing filter, - */ -function createCurrentHook( hooksArray ) { - - /** - * Get the current active hook. - * - * @param {string} action The name of the action to check for, if omitted will check for any action being performed. - * - * @return {string} Returns the currently executing action, or false if none. - */ - return function() { - - // If the action was not passed, check for any current hook. - if ( 'undefined' === typeof action ) { - return false; - } - - // Return the current hook. - return hooksArray && hooksArray.current ? - hooksArray.current : - false; - }; -} - - - -/** - * Checks to see if an action is currently being executed. - * - * @param {string} type Type of hooks to check. - * @param {string} action The name of the action to check for, if omitted will check for any action being performed. - * - * @return {bool} Whether the hook is being executed. - */ -function createDoingHook( hooksArray ) { - return function( action ) { - - // If the action was not passed, check for any current hook. - if ( 'undefined' === typeof action ) { - return 'undefined' !== typeof hooksArray.current; - } - - // Return the current hook. - return hooksArray && hooksArray.current ? - action === hooksArray.current : - false; - }; -} - -/** - * Retrieve the number of times an action is fired. - * - * @param {string} hooksArray Hooks array of hooks to check. - * @param {string} action The action to check. - * - * @return {number} The number of times the hook has run. - */ -function createDidHook( hooksArray ) { - return function( action ) { - return hooksArray && hooksArray[ action ] && hooksArray[ action ].runs ? - hooksArray[ action ].runs : - 0; - }; -} - -/** - * Check to see if an action is registered for a hook. - * - * @param {string} hooksArray Hooks array of hooks to check. - * @param {string} action The action to check. - * - * @return {bool} Whether an action has been registered for a hook. - */ -function createHasHook( hooksArray ) { - return function( action ) { - return hooksArray && hooksArray[ action ] ? - !! hooksArray[ action ] : - false; - }; -} - -/** - * Remove all the actions registered to a hook. - * - * @param {string} hooksArray Hooks array of hooks to check. - * - * @return {Function} All hook remover. - */ -function createRemoveAllHook( hooksArray ) { - return createRemoveHook( hooksArray, true ); -} // Remove functions. export const removeFilter = createRemoveHook( HOOKS.filters ); diff --git a/packages/hooks/src/runApplyFilters.js b/packages/hooks/src/runApplyFilters.js new file mode 100644 index 0000000000000..b584cbe3f138f --- /dev/null +++ b/packages/hooks/src/runApplyFilters.js @@ -0,0 +1,32 @@ +import HOOKS from './hooks'; + +/** + * Performs a filter if it exists. + * + * @param {string} filter The filter to apply. + * @param {...*} args Optional args to pass to the filter. + * @return {*} The filtered value + * @private + */ +const runApplyFilters = function( filter, args ) { + var handlers, i; + if ( HOOKS.filters ) { + handlers = HOOKS.filters[ filter ]; + } + + if ( ! handlers ) { + return args[ 0 ]; + } + + HOOKS.filters.current = filter; + HOOKS.filters[ filter ].runs = HOOKS.filters[ filter ].runs ? HOOKS.filters[ filter ].runs + 1 : 1; + + for ( i = 0; i < handlers.length; i++ ) { + args[ 0 ] = handlers[ i ].callback.apply( null, args ); + } + delete( HOOKS.filters.current ); + + return args[ 0 ]; +} + +export default runApplyFilters; diff --git a/packages/hooks/src/runDoAction.js b/packages/hooks/src/runDoAction.js new file mode 100644 index 0000000000000..0688e73631d60 --- /dev/null +++ b/packages/hooks/src/runDoAction.js @@ -0,0 +1,28 @@ +import HOOKS from './hooks'; + +/** + * Performs an action if it exists. + * + * @param {string} action The action to perform. + * @param {...*} args Optional args to pass to the action. + * @private + */ +const runDoAction = function( action, args ) { + var handlers, i; + if ( HOOKS.actions ) { + handlers = HOOKS.actions[ action ]; + } + + if ( ! handlers ) { + return; + } + + HOOKS.actions.current = action; + + for ( i = 0; i < handlers.length; i++ ) { + handlers[ i ].callback.apply( null, args ); + HOOKS.actions[ action ].runs = HOOKS.actions[ action ].runs ? HOOKS.actions[ action ].runs + 1 : 1; + } +} + +export default runDoAction; diff --git a/packages/hooks/src/sortHooks.js b/packages/hooks/src/sortHooks.js new file mode 100644 index 0000000000000..1b1b16ba2a229 --- /dev/null +++ b/packages/hooks/src/sortHooks.js @@ -0,0 +1,25 @@ +/** + * Use an insert sort for keeping our hooks organized based on priority. + * + * @see http://jsperf.com/javascript-sort + * + * @param {Array} hooks Array of the hooks to sort + * @return {Array} The sorted array + * @private + */ +const sortHooks = function( hooks ) { + var i, tmpHook, j, prevHook; + for ( i = 1; i < hooks.length; i++ ) { + tmpHook = hooks[ i ]; + j = i; + while ( ( prevHook = hooks[ j - 1 ] ) && prevHook.priority > tmpHook.priority ) { + hooks[ j ] = hooks[ j - 1 ]; + --j; + } + hooks[ j ] = tmpHook; + } + + return hooks; +} + +export default sortHooks; From 57f6038c9e895b960649a11ef4eceab2907a574b Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 16:44:31 +0200 Subject: [PATCH 058/393] Centralize all run logic into `createRunHook` Also fixes a bug that `doingAction` would remain true after its action was completed. Effectively it would always be true. --- packages/hooks/src/createRunHook.js | 38 +++++++++++++++++++-------- packages/hooks/src/index.js | 11 +++----- packages/hooks/src/runApplyFilters.js | 32 ---------------------- packages/hooks/src/runDoAction.js | 28 -------------------- packages/hooks/src/test/index.test.js | 30 ++++++++++++--------- 5 files changed, 48 insertions(+), 91 deletions(-) delete mode 100644 packages/hooks/src/runApplyFilters.js delete mode 100644 packages/hooks/src/runDoAction.js diff --git a/packages/hooks/src/createRunHook.js b/packages/hooks/src/createRunHook.js index 7d678b237a3ea..af248e96055b3 100644 --- a/packages/hooks/src/createRunHook.js +++ b/packages/hooks/src/createRunHook.js @@ -3,26 +3,42 @@ * hooks of the specified type by calling upon runner with its hook name * and arguments. * - * @param {Function} runner Function to invoke for each hook callback + * @param {Function} hooks Object that contains the hooks to run. + * @param {bool} returnFirstArg Whether each hook callback is expected to + * return its first argument. * @return {Function} Hook runner */ -const createRunHook = function( runner ) { +const createRunHook = function( hooks, returnFirstArg ) { /** * Runs the specified hook. * - * @param {string} hook The hook to run - * @param {...*} args Arguments to pass to the action/filter - * @return {*} Return value of runner, if applicable + * @param {string} hookName The hook to run + * @param {...*} args Arguments to pass to the hook callbacks + * @return {*} Return value of runner, if applicable * @private */ - return function( /* hook, ...args */ ) { - var args, hook; + return function runner( hookName, ...args ) { + const handlers = hooks[ hookName ]; + let maybeReturnValue = args[ 0 ]; - args = Array.prototype.slice.call( arguments ); - hook = args.shift(); + if ( ! handlers ) { + return ( returnFirstArg ? maybeReturnValue : undefined ); + } + + hooks.current = hookName; + handlers.runs = ( handlers.runs || 0 ) + 1; + + handlers.forEach( handler => { + maybeReturnValue = handler.callback.apply( null, args ); + if ( returnFirstArg ) { + args[ 0 ] = maybeReturnValue; + } + } ); + + delete hooks.current; - if ( typeof hook === 'string' ) { - return runner( hook, args ); + if ( returnFirstArg ) { + return maybeReturnValue; } }; } diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index 0b5975b07dee6..18e94a580eba8 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -2,8 +2,6 @@ import HOOKS from './hooks'; import createAddHook from './createAddHook'; import createRemoveHook from './createRemoveHook'; import createRunHook from './createRunHook'; -import runDoAction from './runDoAction'; -import runApplyFilters from './runApplyFilters'; import createCurrentHook from './createCurrentHook'; import createDoingHook from './createDoingHook'; import createDidHook from './createDidHook'; @@ -15,19 +13,16 @@ import createRemoveAllHook from './createRemoveAllHook'; export const removeFilter = createRemoveHook( HOOKS.filters ); export const removeAction = createRemoveHook( HOOKS.actions ); - // Do action/apply filter functions. -export const doAction = createRunHook( runDoAction ); -export const applyFilters = createRunHook( runApplyFilters ); +export const doAction = createRunHook( HOOKS.actions ); +export const applyFilters = createRunHook( HOOKS.filters, true ); // Add functions. export const addAction = createAddHook( HOOKS.actions ); export const addFilter = createAddHook( HOOKS.filters ); -// Doing action: true until next action fired. +// Doing action/filter: true while a hook is being run. export const doingAction = createDoingHook( HOOKS.actions ); - -// Doing filter: true while filter is being applied. export const doingFilter = createDoingHook( HOOKS.filters ); // Did functions. diff --git a/packages/hooks/src/runApplyFilters.js b/packages/hooks/src/runApplyFilters.js deleted file mode 100644 index b584cbe3f138f..0000000000000 --- a/packages/hooks/src/runApplyFilters.js +++ /dev/null @@ -1,32 +0,0 @@ -import HOOKS from './hooks'; - -/** - * Performs a filter if it exists. - * - * @param {string} filter The filter to apply. - * @param {...*} args Optional args to pass to the filter. - * @return {*} The filtered value - * @private - */ -const runApplyFilters = function( filter, args ) { - var handlers, i; - if ( HOOKS.filters ) { - handlers = HOOKS.filters[ filter ]; - } - - if ( ! handlers ) { - return args[ 0 ]; - } - - HOOKS.filters.current = filter; - HOOKS.filters[ filter ].runs = HOOKS.filters[ filter ].runs ? HOOKS.filters[ filter ].runs + 1 : 1; - - for ( i = 0; i < handlers.length; i++ ) { - args[ 0 ] = handlers[ i ].callback.apply( null, args ); - } - delete( HOOKS.filters.current ); - - return args[ 0 ]; -} - -export default runApplyFilters; diff --git a/packages/hooks/src/runDoAction.js b/packages/hooks/src/runDoAction.js deleted file mode 100644 index 0688e73631d60..0000000000000 --- a/packages/hooks/src/runDoAction.js +++ /dev/null @@ -1,28 +0,0 @@ -import HOOKS from './hooks'; - -/** - * Performs an action if it exists. - * - * @param {string} action The action to perform. - * @param {...*} args Optional args to pass to the action. - * @private - */ -const runDoAction = function( action, args ) { - var handlers, i; - if ( HOOKS.actions ) { - handlers = HOOKS.actions[ action ]; - } - - if ( ! handlers ) { - return; - } - - HOOKS.actions.current = action; - - for ( i = 0; i < handlers.length; i++ ) { - handlers[ i ].callback.apply( null, args ); - HOOKS.actions[ action ].runs = HOOKS.actions[ action ].runs ? HOOKS.actions[ action ].runs + 1 : 1; - } -} - -export default runDoAction; diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 2ef6986ed0d20..40266b75955fc 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -206,47 +206,53 @@ describe( 'remove all filter callbacks', function() { // Test doingAction, didAction, hasAction. describe( 'Test doingAction, didAction and hasAction.', function() { it( 'should', () => { + let actionCalls = 0; // Reset state for testing. removeAction( 'test.action' ); - addAction( 'another.action', function(){} ); + addAction( 'another.action', () => {} ); doAction( 'another.action' ); // Verify no action is running yet. - expect( ! doingAction( 'test.action' ) ).toBeTruthy(); + expect( doingAction( 'test.action' ) ).toBe( false ); expect( didAction( 'test.action' ) ).toBe( 0 ); - expect( ! hasAction( 'test.action' ) ).toBeTruthy(); + expect( hasAction( 'test.action' ) ).toBe( false ); - addAction( 'test.action', action_a ); + addAction( 'test.action', () => { + actionCalls++; + expect( doingAction( 'test.action' ) ).toBe( true ); + } ); // Verify action added, not running yet. - expect( ! doingAction( 'test.action' ) ).toBeTruthy(); + expect( doingAction( 'test.action' ) ).toBe( false ); expect( didAction( 'test.action' ) ).toBe( 0 ); - expect( hasAction( 'test.action' ) ).toBeTruthy(); + expect( hasAction( 'test.action' ) ).toBe( true ); doAction( 'test.action' ); // Verify action added and running. - expect( doingAction( 'test.action' ) ).toBeTruthy(); + expect( actionCalls ).toBe( 1 ); + expect( doingAction( 'test.action' ) ).toBe( false ); expect( didAction( 'test.action' ) ).toBe( 1 ); - expect( hasAction( 'test.action' ) ).toBeTruthy(); + expect( hasAction( 'test.action' ) ).toBe( true ); doAction( 'test.action' ); + expect( actionCalls ).toBe( 2 ); expect( didAction( 'test.action' ) ).toBe( 2 ); removeAction( 'test.action' ); // Verify state is reset appropriately. - expect( doingAction( 'test.action' ) ).toBeTruthy(); + expect( doingAction( 'test.action' ) ).toBe( false ); expect( didAction( 'test.action' ) ).toBe( 0 ); - expect( ! hasAction( 'test.action' ) ).toBeTruthy(); + expect( hasAction( 'test.action' ) ).toBe( false ); doAction( 'another.action' ); - expect( ! doingAction( 'test.action' ) ).toBeTruthy(); + expect( doingAction( 'test.action' ) ).toBe( false ); // Verify hasAction returns false when no matching action. - expect( ! hasAction( 'notatest.action' ) ).toBeTruthy(); + expect( hasAction( 'notatest.action' ) ).toBe( false ); } ); } ); From 1901b435371fa9020c7b8a83f1b596a4d1310ef1 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 16:54:24 +0200 Subject: [PATCH 059/393] Use a consistent order for functions --- packages/hooks/src/index.js | 42 +++++++++++++-------------- packages/hooks/src/test/index.test.js | 18 ++++++------ 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index 18e94a580eba8..3b71ace685706 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -1,42 +1,40 @@ import HOOKS from './hooks'; import createAddHook from './createAddHook'; import createRemoveHook from './createRemoveHook'; +import createRemoveAllHook from './createRemoveAllHook'; +import createHasHook from './createHasHook'; import createRunHook from './createRunHook'; import createCurrentHook from './createCurrentHook'; import createDoingHook from './createDoingHook'; import createDidHook from './createDidHook'; -import createHasHook from './createHasHook'; -import createRemoveAllHook from './createRemoveAllHook'; - -// Remove functions. -export const removeFilter = createRemoveHook( HOOKS.filters ); -export const removeAction = createRemoveHook( HOOKS.actions ); - -// Do action/apply filter functions. -export const doAction = createRunHook( HOOKS.actions ); -export const applyFilters = createRunHook( HOOKS.filters, true ); - -// Add functions. +// Add action/filter functions. export const addAction = createAddHook( HOOKS.actions ); export const addFilter = createAddHook( HOOKS.filters ); -// Doing action/filter: true while a hook is being run. -export const doingAction = createDoingHook( HOOKS.actions ); -export const doingFilter = createDoingHook( HOOKS.filters ); - -// Did functions. -export const didAction = createDidHook( HOOKS.actions ); -export const didFilter = createDidHook( HOOKS.filters ); +// Remove action/filter functions. +export const removeAction = createRemoveHook( HOOKS.actions ); +export const removeFilter = createRemoveHook( HOOKS.filters ); -// Has functions. +// Has action/filter functions. export const hasAction = createHasHook( HOOKS.actions ); export const hasFilter = createHasHook( HOOKS.filters ); -// Remove all functions. +// Remove all actions/filters functions. export const removeAllActions = createRemoveAllHook( HOOKS.actions ); export const removeAllFilters = createRemoveAllHook( HOOKS.filters ); -// Current filter. +// Do action/apply filters functions. +export const doAction = createRunHook( HOOKS.actions ); +export const applyFilters = createRunHook( HOOKS.filters, true ); + +// Current action/filter functions. export const currentFilter = createCurrentHook( HOOKS.filters ); +// Doing action/filter: true while a hook is being run. +export const doingAction = createDoingHook( HOOKS.actions ); +export const doingFilter = createDoingHook( HOOKS.filters ); + +// Did action/filter functions. +export const didAction = createDidHook( HOOKS.actions ); +export const didFilter = createDidHook( HOOKS.filters ); diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 40266b75955fc..66509774176c3 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -2,21 +2,21 @@ * Internal Dependencies. */ import { - doAction, - applyFilters, addAction, addFilter, + removeAction, + removeFilter, + removeAllActions, + removeAllFilters, + hasAction, + hasFilter, + doAction, + applyFilters, + currentFilter, doingAction, doingFilter, didAction, didFilter, - hasAction, - hasFilter, - removeFilter, - removeAction, - removeAllActions, - removeAllFilters, - currentFilter } from '../'; function filter_a( str ) { From f6c2b45765968ab93bc134369fcb1183fe5afe76 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 17:00:40 +0200 Subject: [PATCH 060/393] Fix `currentFilter` and unit-test it --- packages/hooks/src/createCurrentHook.js | 32 ------------------------- packages/hooks/src/index.js | 3 +-- packages/hooks/src/test/index.test.js | 26 +++++++++++++------- 3 files changed, 19 insertions(+), 42 deletions(-) delete mode 100644 packages/hooks/src/createCurrentHook.js diff --git a/packages/hooks/src/createCurrentHook.js b/packages/hooks/src/createCurrentHook.js deleted file mode 100644 index 351808a04aa51..0000000000000 --- a/packages/hooks/src/createCurrentHook.js +++ /dev/null @@ -1,32 +0,0 @@ -/** - * See what action is currently being executed. - * - * @param {string} hooksArray Hooks array of hooks to check. - * @param {string} action The name of the action to check for. - * - * @return {Function} A function that gets the currently executing filter, - */ -const createCurrentHook = function( hooksArray ) { - - /** - * Get the current active hook. - * - * @param {string} action The name of the action to check for, if omitted will check for any action being performed. - * - * @return {string} Returns the currently executing action, or false if none. - */ - return function() { - - // If the action was not passed, check for any current hook. - if ( 'undefined' === typeof action ) { - return false; - } - - // Return the current hook. - return hooksArray && hooksArray.current ? - hooksArray.current : - false; - }; -} - -export default createCurrentHook; diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index 3b71ace685706..af4870ef3ae53 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -4,7 +4,6 @@ import createRemoveHook from './createRemoveHook'; import createRemoveAllHook from './createRemoveAllHook'; import createHasHook from './createHasHook'; import createRunHook from './createRunHook'; -import createCurrentHook from './createCurrentHook'; import createDoingHook from './createDoingHook'; import createDidHook from './createDidHook'; @@ -29,7 +28,7 @@ export const doAction = createRunHook( HOOKS.actions ); export const applyFilters = createRunHook( HOOKS.filters, true ); // Current action/filter functions. -export const currentFilter = createCurrentHook( HOOKS.filters ); +export const currentFilter = () => HOOKS.filters.current || null; // Doing action/filter: true while a hook is being run. export const doingAction = createDoingHook( HOOKS.actions ); diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 66509774176c3..33a36f233b17c 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -37,9 +37,6 @@ function action_b() { function action_c() { window.actionValue += 'c'; } -function filter_check() { - expect( doingFilter( 'runtest.filter' ) ).toBeTruthy(); -} window.actionValue = ''; describe( 'add and remove a filter', () => { @@ -259,13 +256,26 @@ describe( 'Test doingAction, didAction and hasAction.', function() { describe( 'Verify doingFilter, didFilter and hasFilter.', function() { it( 'should', () => { - addFilter( 'runtest.filter', filter_check ); + let filterCalls = 0; + + addFilter( 'runtest.filter', arg => { + filterCalls++; + expect( currentFilter() ).toBe( 'runtest.filter' ); + expect( doingFilter( 'runtest.filter' ) ).toBeTruthy(); + return arg; + } ); // Verify filter added and running. - var test = applyFilters( 'runtest.filter', true ); - expect( didFilter( 'runtest.filter' ), 1, 'The runtest.filter has run once.' ); - expect( hasFilter( 'runtest.filter' ), 'The runtest.filter is registered.' ); - expect( ! hasFilter( 'notatest.filter' ), 'The notatest.filter is not registered.' ); + const test = applyFilters( 'runtest.filter', 'someValue' ); + expect( test ).toBe( 'someValue' ); + expect( filterCalls ).toBe( 1 ); + expect( didFilter( 'runtest.filter' ) ).toBe( 1 ); + expect( hasFilter( 'runtest.filter' ) ).toBe( true ); + expect( hasFilter( 'notatest.filter' ) ).toBe( false ); + expect( doingFilter() ).toBe( false ); + expect( doingFilter( 'runtest.filter' ) ).toBe( false ); + expect( doingFilter( 'notatest.filter' ) ).toBe( false ); + expect( currentFilter() ).toBe( null ); removeFilter( 'runtest.filter' ); } ); From f50aadb4a41441d68759d88e26ca62445a94c5f9 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 17:09:40 +0200 Subject: [PATCH 061/393] Add `currentAction` and unit-test it --- packages/hooks/src/index.js | 1 + packages/hooks/src/test/index.test.js | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index af4870ef3ae53..c6714cc2403bb 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -28,6 +28,7 @@ export const doAction = createRunHook( HOOKS.actions ); export const applyFilters = createRunHook( HOOKS.filters, true ); // Current action/filter functions. +export const currentAction = () => HOOKS.actions.current || null; export const currentFilter = () => HOOKS.filters.current || null; // Doing action/filter: true while a hook is being run. diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 33a36f233b17c..36e578134f934 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -12,6 +12,7 @@ import { hasFilter, doAction, applyFilters, + currentAction, currentFilter, doingAction, doingFilter, @@ -218,6 +219,7 @@ describe( 'Test doingAction, didAction and hasAction.', function() { addAction( 'test.action', () => { actionCalls++; + expect( currentAction() ).toBe( 'test.action' ); expect( doingAction( 'test.action' ) ).toBe( true ); } ); @@ -233,6 +235,10 @@ describe( 'Test doingAction, didAction and hasAction.', function() { expect( doingAction( 'test.action' ) ).toBe( false ); expect( didAction( 'test.action' ) ).toBe( 1 ); expect( hasAction( 'test.action' ) ).toBe( true ); + expect( doingAction() ).toBe( false ); + expect( doingAction( 'test.action' ) ).toBe( false ); + expect( doingAction( 'notatest.action' ) ).toBe( false ); + expect( currentAction() ).toBe( null ); doAction( 'test.action' ); expect( actionCalls ).toBe( 2 ); From bee29d7df6c7708bb6444b93becf1be86fd54f23 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 17:09:50 +0200 Subject: [PATCH 062/393] Declare base hooks objects as objects, not arrays --- packages/hooks/src/hooks.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/hooks/src/hooks.js b/packages/hooks/src/hooks.js index e5017949edbc5..a133b768d2788 100644 --- a/packages/hooks/src/hooks.js +++ b/packages/hooks/src/hooks.js @@ -3,8 +3,8 @@ * array of objects with priority and callback of each registered hook. */ var HOOKS = { - actions: [], - filters: [] + actions: {}, + filters: {}, }; export default HOOKS; From b02296c847a8675c5ab7ef037584371634fe035e Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 17:30:46 +0200 Subject: [PATCH 063/393] Several fixes to hook removal behavior - Calling `removeAction` and `removeFilter` without a callback should not remove all hooks. This operation should be explicitly requested. - Calling `removeAllActions` and `removeAllFilters` should not reset `didAction` and `didFilter` counts. Also correctly reset state (clear all hooks and all hook call counts) before each test. --- packages/hooks/src/createDidHook.js | 6 +-- packages/hooks/src/createRemoveHook.js | 24 +++++++----- packages/hooks/src/hooks.js | 2 +- packages/hooks/src/index.js | 5 +-- packages/hooks/src/test/index.test.js | 52 ++++++++++++++++---------- 5 files changed, 52 insertions(+), 37 deletions(-) diff --git a/packages/hooks/src/createDidHook.js b/packages/hooks/src/createDidHook.js index a7223ae8f33f7..2607a54dd86fa 100644 --- a/packages/hooks/src/createDidHook.js +++ b/packages/hooks/src/createDidHook.js @@ -8,9 +8,9 @@ */ const createDidHook = function( hooksArray ) { return function( action ) { - return hooksArray && hooksArray[ action ] && hooksArray[ action ].runs ? - hooksArray[ action ].runs : - 0; + return hooksArray[ action ] && hooksArray[ action ].runs + ? hooksArray[ action ].runs + : 0; }; } diff --git a/packages/hooks/src/createRemoveHook.js b/packages/hooks/src/createRemoveHook.js index e0c3c0acd2f12..88eab2d6095ea 100644 --- a/packages/hooks/src/createRemoveHook.js +++ b/packages/hooks/src/createRemoveHook.js @@ -2,27 +2,34 @@ * Returns a function which, when invoked, will remove a specified hook. * * @param {string} hooksArray Hooks array from which hooks are to be removed. - * @param {bool} removeAll Whether to always remove all hooked callbacks. + * @param {bool} removeAll Whether to remove all hooked callbacks. * * @return {Function} Hook remover. */ -const createRemoveHook = function ( hooksArray, removeAll ) { +const createRemoveHook = function( hooksArray, removeAll ) { /** * Removes the specified hook by resetting its value. * * @param {string} hook Name of hook to remove - * @param {?Function} callback The specific callback to be removed. Optional, if - * omitted, clears all callbacks. + * @param {?Function} callback The specific callback to be removed. If + * omitted (and `removeAll` is truthy), clears + * all callbacks. */ return function( hook, callback ) { var handlers, i; - // Baily early if no hooks exist by this name + // Bail early if no hooks exist by this name if ( ! hooksArray || ! hooksArray.hasOwnProperty( hook ) ) { return; } - if ( callback && ! removeAll ) { + if ( removeAll ) { + const runs = hooksArray[ hook ].runs; + hooksArray[ hook ] = []; + if ( runs ) { + hooksArray[ hook ].runs = runs; + } + } else if ( callback ) { // Try to find specified callback to remove handlers = hooksArray[ hook ]; for ( i = handlers.length - 1; i >= 0; i-- ) { @@ -30,11 +37,8 @@ const createRemoveHook = function ( hooksArray, removeAll ) { handlers.splice( i, 1 ); } } - } else { - // Reset hooks to empty - delete hooksArray[ hook ]; } }; } -export default createRemoveHook; \ No newline at end of file +export default createRemoveHook; diff --git a/packages/hooks/src/hooks.js b/packages/hooks/src/hooks.js index a133b768d2788..2fa576f48eb26 100644 --- a/packages/hooks/src/hooks.js +++ b/packages/hooks/src/hooks.js @@ -2,7 +2,7 @@ * Contains the registered hooks, keyed by hook type. Each hook type is an * array of objects with priority and callback of each registered hook. */ -var HOOKS = { +const HOOKS = { actions: {}, filters: {}, }; diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index c6714cc2403bb..992930edd77ee 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -1,7 +1,6 @@ import HOOKS from './hooks'; import createAddHook from './createAddHook'; import createRemoveHook from './createRemoveHook'; -import createRemoveAllHook from './createRemoveAllHook'; import createHasHook from './createHasHook'; import createRunHook from './createRunHook'; import createDoingHook from './createDoingHook'; @@ -20,8 +19,8 @@ export const hasAction = createHasHook( HOOKS.actions ); export const hasFilter = createHasHook( HOOKS.filters ); // Remove all actions/filters functions. -export const removeAllActions = createRemoveAllHook( HOOKS.actions ); -export const removeAllFilters = createRemoveAllHook( HOOKS.filters ); +export const removeAllActions = createRemoveHook( HOOKS.actions, true ); +export const removeAllFilters = createRemoveHook( HOOKS.filters, true ); // Do action/apply filters functions. export const doAction = createRunHook( HOOKS.actions ); diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 36e578134f934..073702752a299 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -1,6 +1,7 @@ /** - * Internal Dependencies. + * Internal dependencies */ +import HOOKS from '../hooks'; import { addAction, addFilter, @@ -38,12 +39,23 @@ function action_b() { function action_c() { window.actionValue += 'c'; } -window.actionValue = ''; + +beforeEach( () => { + window.actionValue = ''; + // Reset state in between tests (clear all callbacks, `didAction` counts, + // etc.) Just reseting HOOKS.actions and HOOKS.filters is not enough + // because the internal functions have references to the original objects. + [ HOOKS.actions, HOOKS.filters ].forEach( hooks => { + for ( const k in hooks ) { + delete hooks[ k ]; + } + } ); +} ); describe( 'add and remove a filter', () => { it( 'should leave the value unfiltered', () => { addFilter( 'test.filter', filter_a ); - removeFilter( 'test.filter' ); + removeAllFilters( 'test.filter' ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); } ); } ); @@ -52,7 +64,7 @@ describe( 'add a filter and run it', () => { it( 'should filter the value', () => { addFilter( 'test.filter', filter_a ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testa' ); - removeFilter( 'test.filter' ); + removeAllFilters( 'test.filter' ); } ); } ); @@ -61,7 +73,7 @@ describe( 'add 2 filters in a row and run them', () => { addFilter( 'test.filter', filter_a ); addFilter( 'test.filter', filter_b ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); - removeFilter( 'test.filter' ); + removeAllFilters( 'test.filter' ); } ); } ); @@ -71,7 +83,7 @@ describe( 'add 3 filters with different priorities and run them', () => { addFilter( 'test.filter', filter_b, 2 ); addFilter( 'test.filter', filter_c, 8 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testbca' ); - removeFilter( 'test.filter' ); + removeAllFilters( 'test.filter' ); } ); } ); @@ -79,7 +91,7 @@ describe( 'add and remove an action', () => { it( 'should leave the action unhooked', () => { window.actionValue = ''; addAction( 'test.action', action_a ); - removeAction( 'test.action' ); + removeAllActions( 'test.action' ); doAction( 'test.action' ); expect( window.actionValue ).toBe( '' ); } ); @@ -91,7 +103,7 @@ describe( 'add an action and run it', function() { addAction( 'test.action', action_a ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'a' ); - removeAction( 'test.action' ); + removeAllActions( 'test.action' ); } ); } ); @@ -102,7 +114,7 @@ describe( 'add 2 actions in a row and then run them', function() { addAction( 'test.action', action_b ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'ab' ); - removeAction( 'test.action' ); + removeAllActions( 'test.action' ); } ); } ); @@ -114,7 +126,7 @@ describe( 'add 3 actions with different priorities and run them', function() { addAction( 'test.action', action_c, 8 ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'bca' ); - removeAction( 'test.action' ); + removeAllActions( 'test.action' ); } ); } ); @@ -128,7 +140,7 @@ describe( 'pass in two arguments to an action', function() { expect( arg2 ).toBe( b ); } ); doAction( 'test.action', arg1, arg2 ); - removeAction( 'test.action' ); + removeAllActions( 'test.action' ); expect( arg1 ).toBe( 10 ); expect( arg2 ).toBe( 20 ); @@ -147,7 +159,7 @@ describe( 'fire action multiple times', function() { addAction( 'test.action', func ); doAction( 'test.action' ); doAction( 'test.action' ); - removeAction( 'test.action' ); + removeAllActions( 'test.action' ); } ); } ); @@ -161,7 +173,7 @@ describe( 'remove specific action callback', function() { removeAction( 'test.action', action_b ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'ca' ); - removeAction( 'test.action' ); + removeAllActions( 'test.action' ); } ); } ); @@ -186,7 +198,7 @@ describe( 'remove specific filter callback', function() { removeFilter( 'test.filter', filter_b ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testca' ); - removeFilter( 'test.filter' ); + removeAllFilters( 'test.filter' ); } ); } ); @@ -206,8 +218,6 @@ describe( 'Test doingAction, didAction and hasAction.', function() { it( 'should', () => { let actionCalls = 0; - // Reset state for testing. - removeAction( 'test.action' ); addAction( 'another.action', () => {} ); doAction( 'another.action' ); @@ -244,11 +254,11 @@ describe( 'Test doingAction, didAction and hasAction.', function() { expect( actionCalls ).toBe( 2 ); expect( didAction( 'test.action' ) ).toBe( 2 ); - removeAction( 'test.action' ); + removeAllActions( 'test.action' ); // Verify state is reset appropriately. expect( doingAction( 'test.action' ) ).toBe( false ); - expect( didAction( 'test.action' ) ).toBe( 0 ); + expect( didAction( 'test.action' ) ).toBe( 2 ); expect( hasAction( 'test.action' ) ).toBe( false ); doAction( 'another.action' ); @@ -256,7 +266,6 @@ describe( 'Test doingAction, didAction and hasAction.', function() { // Verify hasAction returns false when no matching action. expect( hasAction( 'notatest.action' ) ).toBe( false ); - } ); } ); @@ -283,7 +292,10 @@ describe( 'Verify doingFilter, didFilter and hasFilter.', function() { expect( doingFilter( 'notatest.filter' ) ).toBe( false ); expect( currentFilter() ).toBe( null ); - removeFilter( 'runtest.filter' ); + removeAllFilters( 'runtest.filter' ); + + expect( hasFilter( 'runtest.filter' ) ).toBe( false ); + expect( didFilter( 'runtest.filter' ) ).toBe( 1 ); } ); } ); From aeca7dfe1ffa530ca060ff7608c1a22ee1c0bb61 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 17:33:24 +0200 Subject: [PATCH 064/393] Fix `hasAction` and `hasFilter` if all hooks have been removed --- packages/hooks/src/createHasHook.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/hooks/src/createHasHook.js b/packages/hooks/src/createHasHook.js index 6419cb55e4b65..0811847bdac07 100644 --- a/packages/hooks/src/createHasHook.js +++ b/packages/hooks/src/createHasHook.js @@ -8,9 +8,9 @@ */ const createHasHook = function( hooksArray ) { return function( action ) { - return hooksArray && hooksArray[ action ] ? - !! hooksArray[ action ] : - false; + return hooksArray && hooksArray[ action ] + ? hooksArray[ action ].length > 0 + : false; }; } From 678f79037b940770b6fca3845529e5adbb62d412 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 17:42:43 +0200 Subject: [PATCH 065/393] Remove now-unused `createRemoveAllHook` --- packages/hooks/src/createRemoveAllHook.js | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 packages/hooks/src/createRemoveAllHook.js diff --git a/packages/hooks/src/createRemoveAllHook.js b/packages/hooks/src/createRemoveAllHook.js deleted file mode 100644 index b4bfd9c9c7111..0000000000000 --- a/packages/hooks/src/createRemoveAllHook.js +++ /dev/null @@ -1,14 +0,0 @@ -import createRemoveHook from './createRemoveHook'; - -/** - * Remove all the actions registered to a hook. - * - * @param {string} hooksArray Hooks array of hooks to check. - * - * @return {Function} All hook remover. - */ -const createRemoveAllHook = function( hooksArray ) { - return createRemoveHook( hooksArray, true ); -} - -export default createRemoveAllHook; From 78acfe185aae0dc467ac106ca9a6cc748914bfa4 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 18:06:55 +0200 Subject: [PATCH 066/393] Naming and documentation cleanup - `hooks`: A hooks object, keyed by hook name - `hookName`: A hook name - `handlers`: The handlers for a single hook - All top-level and inner (returned) functions have names. --- packages/hooks/src/createAddHook.js | 37 +++++++++++++------------- packages/hooks/src/createDidHook.js | 23 ++++++++++------ packages/hooks/src/createDoingHook.js | 34 ++++++++++++++--------- packages/hooks/src/createHasHook.js | 25 +++++++++++------ packages/hooks/src/createRemoveHook.js | 34 +++++++++++------------ packages/hooks/src/createRunHook.js | 25 ++++++++--------- packages/hooks/src/sortHooks.js | 23 +++++++++------- packages/hooks/src/test/index.test.js | 4 ++- 8 files changed, 118 insertions(+), 87 deletions(-) diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index 2d48450471974..2672b596ad93f 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -3,20 +3,20 @@ import sortHooks from './sortHooks'; /** * Returns a function which, when invoked, will add a hook. * - * @param {string} hooksArray Hooks array to which hooks are to be added - * @return {Function} Hook added. + * @param {Object} hooks Stored hooks, keyed by hook name. + * + * @return {Function} Function that adds a new hook. */ -const createAddHook = function( hooksArray ) { +function createAddHook( hooks ) { /** - * Adds the hook to the appropriate hooks container + * Adds the hook to the appropriate hooks container. * - * @param {string} hook Name of hook to add + * @param {string} hookName Name of hook to add * @param {Function} callback Function to call when the hook is run * @param {?number} priority Priority of this hook (default=10) */ - return function( hook, callback, priority ) { - var hookObject, hooks; - if ( typeof hook !== 'string' || typeof callback !== 'function' ) { + return function addHook( hookName, callback, priority ) { + if ( typeof hookName !== 'string' || typeof callback !== 'function' ) { return; } @@ -32,22 +32,23 @@ const createAddHook = function( hooksArray ) { return; } - hookObject = { + const handler = { callback: callback, - priority: priority + priority: priority, }; + let handlers; - if ( hooksArray.hasOwnProperty( hook ) ) { - // Append and re-sort amongst existing - hooks = hooksArray[ hook ]; - hooks.push( hookObject ); - hooks = sortHooks( hooks ); + if ( hooks.hasOwnProperty( hookName ) ) { + // Append and re-sort amongst the existing callbacks. + handlers = hooks[ hookName ]; + handlers.push( handler ); + handlers = sortHooks( handlers ); } else { - // First of its type needs no sort - hooks = [ hookObject ]; + // This is the first hook of its type. + handlers = [ handler ]; } - hooksArray[ hook ] = hooks; + hooks[ hookName ] = handlers; }; } diff --git a/packages/hooks/src/createDidHook.js b/packages/hooks/src/createDidHook.js index 2607a54dd86fa..cdbcee8d50eb2 100644 --- a/packages/hooks/src/createDidHook.js +++ b/packages/hooks/src/createDidHook.js @@ -1,15 +1,22 @@ /** - * Retrieve the number of times an action is fired. + * Returns a function which, when invoked, will return the number of times a + * hook has been called. * - * @param {string} hooksArray Hooks array of hooks to check. - * @param {string} action The action to check. + * @param {Object} hooks Stored hooks, keyed by hook name. * - * @return {number} The number of times the hook has run. + * @return {Function} Function that returns a hook's call count. */ -const createDidHook = function( hooksArray ) { - return function( action ) { - return hooksArray[ action ] && hooksArray[ action ].runs - ? hooksArray[ action ].runs +function createDidHook( hooks ) { + /** + * Returns the number of times an action has been fired. + * + * @param {string} hookName The hook name to check. + * + * @return {number} The number of times the hook has run. + */ + return function didHook( hookName ) { + return hooks.hasOwnProperty( hookName ) && hooks[ hookName ].runs + ? hooks[ hookName ].runs : 0; }; } diff --git a/packages/hooks/src/createDoingHook.js b/packages/hooks/src/createDoingHook.js index 95932c1b5e341..ba7aa02874497 100644 --- a/packages/hooks/src/createDoingHook.js +++ b/packages/hooks/src/createDoingHook.js @@ -1,23 +1,31 @@ /** - * Checks to see if an action is currently being executed. + * Returns a function which, when invoked, will return whether a hook is + * currently being executed. * - * @param {string} type Type of hooks to check. - * @param {string} action The name of the action to check for, if omitted will check for any action being performed. + * @param {Object} hooks Stored hooks, keyed by hook name. * - * @return {bool} Whether the hook is being executed. + * @return {Function} Function that returns whether a hook is currently + * being executed. */ -const createDoingHook = function( hooksArray ) { - return function( action ) { - - // If the action was not passed, check for any current hook. - if ( 'undefined' === typeof action ) { - return 'undefined' !== typeof hooksArray.current; +function createDoingHook( hooks ) { + /** + * Returns whether a hook is currently being executed. + * + * @param {?string} hookName The name of the hook to check for. If + * omitted, will check for any hook being executed. + * + * @return {bool} Whether the hook is being executed. + */ + return function doingHook( hookName ) { + // If the hookName was not passed, check for any current hook. + if ( 'undefined' === typeof hookName ) { + return 'undefined' !== typeof hooks.current; } // Return the current hook. - return hooksArray && hooksArray.current ? - action === hooksArray.current : - false; + return hooks.current + ? hookName === hooks.current + : false; }; } diff --git a/packages/hooks/src/createHasHook.js b/packages/hooks/src/createHasHook.js index 0811847bdac07..4b3567eaa4393 100644 --- a/packages/hooks/src/createHasHook.js +++ b/packages/hooks/src/createHasHook.js @@ -1,15 +1,24 @@ /** - * Check to see if an action is registered for a hook. + * Returns a function which, when invoked, will return whether any handlers are + * attached to a particular hook. * - * @param {string} hooksArray Hooks array of hooks to check. - * @param {string} action The action to check. + * @param {Object} hooks Stored hooks, keyed by hook name. * - * @return {bool} Whether an action has been registered for a hook. + * @return {Function} Function that returns whether any handlers are + * attached to a particular hook. */ -const createHasHook = function( hooksArray ) { - return function( action ) { - return hooksArray && hooksArray[ action ] - ? hooksArray[ action ].length > 0 +function createHasHook( hooks ) { + /** + * Returns how many handlers are attached for the given hook. + * + * @param {string} hookName The name of the hook to check for. + * + * @return {bool} Whether any handlers are attached to the + * given hook. + */ + return function hasHook( hookName ) { + return hooks && hooks.hasOwnProperty( hookName ) + ? hooks[ hookName ].length > 0 : false; }; } diff --git a/packages/hooks/src/createRemoveHook.js b/packages/hooks/src/createRemoveHook.js index 88eab2d6095ea..ab6e3cec39722 100644 --- a/packages/hooks/src/createRemoveHook.js +++ b/packages/hooks/src/createRemoveHook.js @@ -1,38 +1,38 @@ /** - * Returns a function which, when invoked, will remove a specified hook. + * Returns a function which, when invoked, will remove a specified hook or all + * hooks by the given name. * - * @param {string} hooksArray Hooks array from which hooks are to be removed. + * @param {Object} hooks Stored hooks, keyed by hook name. * @param {bool} removeAll Whether to remove all hooked callbacks. * - * @return {Function} Hook remover. + * @return {Function} Function that removes hooks. */ -const createRemoveHook = function( hooksArray, removeAll ) { +const createRemoveHook = function( hooks, removeAll ) { /** - * Removes the specified hook by resetting its value. + * Removes the specified callback (or all callbacks) from the hook with a + * given name. * - * @param {string} hook Name of hook to remove + * @param {string} hookName The name of the hook to modify. * @param {?Function} callback The specific callback to be removed. If * omitted (and `removeAll` is truthy), clears * all callbacks. */ - return function( hook, callback ) { - var handlers, i; - - // Bail early if no hooks exist by this name - if ( ! hooksArray || ! hooksArray.hasOwnProperty( hook ) ) { + return function removeHook( hookName, callback ) { + // Bail if no hooks exist by this name + if ( ! hooks.hasOwnProperty( hookName ) ) { return; } if ( removeAll ) { - const runs = hooksArray[ hook ].runs; - hooksArray[ hook ] = []; + const runs = hooks[ hookName ].runs; + hooks[ hookName ] = []; if ( runs ) { - hooksArray[ hook ].runs = runs; + hooks[ hookName ].runs = runs; } } else if ( callback ) { - // Try to find specified callback to remove - handlers = hooksArray[ hook ]; - for ( i = handlers.length - 1; i >= 0; i-- ) { + // Try to find the specified callback to remove. + const handlers = hooks[ hookName ]; + for ( let i = handlers.length - 1; i >= 0; i-- ) { if ( handlers[ i ].callback === callback ) { handlers.splice( i, 1 ); } diff --git a/packages/hooks/src/createRunHook.js b/packages/hooks/src/createRunHook.js index af248e96055b3..ca07b64564c59 100644 --- a/packages/hooks/src/createRunHook.js +++ b/packages/hooks/src/createRunHook.js @@ -1,23 +1,24 @@ /** - * Returns a function which, when invoked, will execute all registered - * hooks of the specified type by calling upon runner with its hook name - * and arguments. + * Returns a function which, when invoked, will execute all callbacks + * registered to a hook of the specified type, optionally returning the final + * value of the call chain. * - * @param {Function} hooks Object that contains the hooks to run. - * @param {bool} returnFirstArg Whether each hook callback is expected to + * @param {Object} hooks Stored hooks, keyed by hook name. + * @param {?bool} returnFirstArg Whether each hook callback is expected to * return its first argument. - * @return {Function} Hook runner + * + * @return {Function} Function that runs hook callbacks. */ const createRunHook = function( hooks, returnFirstArg ) { /** - * Runs the specified hook. + * Runs all callbacks for the specified hook. + * + * @param {string} hookName The name of the hook to run. + * @param {...*} args Arguments to pass to the hook callbacks. * - * @param {string} hookName The hook to run - * @param {...*} args Arguments to pass to the hook callbacks - * @return {*} Return value of runner, if applicable - * @private + * @return {*} Return value of runner, if applicable. */ - return function runner( hookName, ...args ) { + return function runHooks( hookName, ...args ) { const handlers = hooks[ hookName ]; let maybeReturnValue = args[ 0 ]; diff --git a/packages/hooks/src/sortHooks.js b/packages/hooks/src/sortHooks.js index 1b1b16ba2a229..8e6ed0015be3c 100644 --- a/packages/hooks/src/sortHooks.js +++ b/packages/hooks/src/sortHooks.js @@ -1,25 +1,28 @@ /** - * Use an insert sort for keeping our hooks organized based on priority. + * Use an insert sort to keep hook handlers organized based on priority. * * @see http://jsperf.com/javascript-sort * - * @param {Array} hooks Array of the hooks to sort - * @return {Array} The sorted array + * @param {Array} handlers Array of the handlers to sort + * @return {Array} The sorted array * @private */ -const sortHooks = function( hooks ) { +const sortHooks = function( handlers ) { var i, tmpHook, j, prevHook; - for ( i = 1; i < hooks.length; i++ ) { - tmpHook = hooks[ i ]; + for ( i = 1; i < handlers.length; i++ ) { + tmpHook = handlers[ i ]; j = i; - while ( ( prevHook = hooks[ j - 1 ] ) && prevHook.priority > tmpHook.priority ) { - hooks[ j ] = hooks[ j - 1 ]; + while ( + ( prevHook = handlers[ j - 1 ] ) && + prevHook.priority > tmpHook.priority + ) { + handlers[ j ] = handlers[ j - 1 ]; --j; } - hooks[ j ] = tmpHook; + handlers[ j ] = tmpHook; } - return hooks; + return handlers; } export default sortHooks; diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 073702752a299..7fbe4d6e094fb 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -230,6 +230,7 @@ describe( 'Test doingAction, didAction and hasAction.', function() { addAction( 'test.action', () => { actionCalls++; expect( currentAction() ).toBe( 'test.action' ); + expect( doingAction() ).toBe( true ); expect( doingAction( 'test.action' ) ).toBe( true ); } ); @@ -276,7 +277,8 @@ describe( 'Verify doingFilter, didFilter and hasFilter.', function() { addFilter( 'runtest.filter', arg => { filterCalls++; expect( currentFilter() ).toBe( 'runtest.filter' ); - expect( doingFilter( 'runtest.filter' ) ).toBeTruthy(); + expect( doingFilter() ).toBe( true ); + expect( doingFilter( 'runtest.filter' ) ).toBe( true ); return arg; } ); From 637af4d4fc28252fa0fc56c1583ac7e8de908f5c Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 18:10:43 +0200 Subject: [PATCH 067/393] Make `hasAction` and `hasFilter` return the number of registered hooks This is different than PHP, because the existing PHP API that these functions accept a callback and return its priority won't work well in JavaScript. Instead, when we implement namespaced hooks, these functions should work the same way: return the number of handlers registered under the given hook and namespace. --- packages/hooks/src/createHasHook.js | 10 +++++----- packages/hooks/src/test/index.test.js | 18 +++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/hooks/src/createHasHook.js b/packages/hooks/src/createHasHook.js index 4b3567eaa4393..6d9cd107146d5 100644 --- a/packages/hooks/src/createHasHook.js +++ b/packages/hooks/src/createHasHook.js @@ -13,13 +13,13 @@ function createHasHook( hooks ) { * * @param {string} hookName The name of the hook to check for. * - * @return {bool} Whether any handlers are attached to the - * given hook. + * @return {number} The number of handlers that are attached to + * the given hook. */ return function hasHook( hookName ) { - return hooks && hooks.hasOwnProperty( hookName ) - ? hooks[ hookName ].length > 0 - : false; + return hooks.hasOwnProperty( hookName ) + ? hooks[ hookName ].length + : 0; }; } diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 7fbe4d6e094fb..c5ae0a9c615a4 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -225,7 +225,7 @@ describe( 'Test doingAction, didAction and hasAction.', function() { expect( doingAction( 'test.action' ) ).toBe( false ); expect( didAction( 'test.action' ) ).toBe( 0 ); - expect( hasAction( 'test.action' ) ).toBe( false ); + expect( hasAction( 'test.action' ) ).toBe( 0 ); addAction( 'test.action', () => { actionCalls++; @@ -237,7 +237,7 @@ describe( 'Test doingAction, didAction and hasAction.', function() { // Verify action added, not running yet. expect( doingAction( 'test.action' ) ).toBe( false ); expect( didAction( 'test.action' ) ).toBe( 0 ); - expect( hasAction( 'test.action' ) ).toBe( true ); + expect( hasAction( 'test.action' ) ).toBe( 1 ); doAction( 'test.action' ); @@ -245,7 +245,7 @@ describe( 'Test doingAction, didAction and hasAction.', function() { expect( actionCalls ).toBe( 1 ); expect( doingAction( 'test.action' ) ).toBe( false ); expect( didAction( 'test.action' ) ).toBe( 1 ); - expect( hasAction( 'test.action' ) ).toBe( true ); + expect( hasAction( 'test.action' ) ).toBe( 1 ); expect( doingAction() ).toBe( false ); expect( doingAction( 'test.action' ) ).toBe( false ); expect( doingAction( 'notatest.action' ) ).toBe( false ); @@ -260,13 +260,13 @@ describe( 'Test doingAction, didAction and hasAction.', function() { // Verify state is reset appropriately. expect( doingAction( 'test.action' ) ).toBe( false ); expect( didAction( 'test.action' ) ).toBe( 2 ); - expect( hasAction( 'test.action' ) ).toBe( false ); + expect( hasAction( 'test.action' ) ).toBe( 0 ); doAction( 'another.action' ); expect( doingAction( 'test.action' ) ).toBe( false ); - // Verify hasAction returns false when no matching action. - expect( hasAction( 'notatest.action' ) ).toBe( false ); + // Verify hasAction returns 0 when no matching action. + expect( hasAction( 'notatest.action' ) ).toBe( 0 ); } ); } ); @@ -287,8 +287,8 @@ describe( 'Verify doingFilter, didFilter and hasFilter.', function() { expect( test ).toBe( 'someValue' ); expect( filterCalls ).toBe( 1 ); expect( didFilter( 'runtest.filter' ) ).toBe( 1 ); - expect( hasFilter( 'runtest.filter' ) ).toBe( true ); - expect( hasFilter( 'notatest.filter' ) ).toBe( false ); + expect( hasFilter( 'runtest.filter' ) ).toBe( 1 ); + expect( hasFilter( 'notatest.filter' ) ).toBe( 0 ); expect( doingFilter() ).toBe( false ); expect( doingFilter( 'runtest.filter' ) ).toBe( false ); expect( doingFilter( 'notatest.filter' ) ).toBe( false ); @@ -296,7 +296,7 @@ describe( 'Verify doingFilter, didFilter and hasFilter.', function() { removeAllFilters( 'runtest.filter' ); - expect( hasFilter( 'runtest.filter' ) ).toBe( false ); + expect( hasFilter( 'runtest.filter' ) ).toBe( 0 ); expect( didFilter( 'runtest.filter' ) ).toBe( 1 ); } ); } ); From b7b30f4a01388be6fe45c2fca69f396be3847d92 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 18:15:12 +0200 Subject: [PATCH 068/393] Remove unnecessary `describe`/`it` pairs Just replace them with `test` instead, per the Jest examples. --- packages/hooks/src/test/index.test.js | 384 ++++++++++++-------------- 1 file changed, 175 insertions(+), 209 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index c5ae0a9c615a4..5d624b02b6442 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -52,253 +52,219 @@ beforeEach( () => { } ); } ); -describe( 'add and remove a filter', () => { - it( 'should leave the value unfiltered', () => { - addFilter( 'test.filter', filter_a ); - removeAllFilters( 'test.filter' ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); - } ); +test( 'add and remove a filter', () => { + addFilter( 'test.filter', filter_a ); + removeAllFilters( 'test.filter' ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); } ); -describe( 'add a filter and run it', () => { - it( 'should filter the value', () => { - addFilter( 'test.filter', filter_a ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testa' ); - removeAllFilters( 'test.filter' ); - } ); +test( 'add a filter and run it', () => { + addFilter( 'test.filter', filter_a ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testa' ); + removeAllFilters( 'test.filter' ); } ); -describe( 'add 2 filters in a row and run them', () => { - it( 'both filters should apply', () => { - addFilter( 'test.filter', filter_a ); - addFilter( 'test.filter', filter_b ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); - removeAllFilters( 'test.filter' ); - } ); +test( 'add 2 filters in a row and run them', () => { + addFilter( 'test.filter', filter_a ); + addFilter( 'test.filter', filter_b ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); + removeAllFilters( 'test.filter' ); } ); -describe( 'add 3 filters with different priorities and run them', () => { - it( 'should run in order', () => { - addFilter( 'test.filter', filter_a ); - addFilter( 'test.filter', filter_b, 2 ); - addFilter( 'test.filter', filter_c, 8 ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testbca' ); - removeAllFilters( 'test.filter' ); - } ); +test( 'add 3 filters with different priorities and run them', () => { + addFilter( 'test.filter', filter_a ); + addFilter( 'test.filter', filter_b, 2 ); + addFilter( 'test.filter', filter_c, 8 ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testbca' ); + removeAllFilters( 'test.filter' ); } ); -describe( 'add and remove an action', () => { - it( 'should leave the action unhooked', () => { - window.actionValue = ''; - addAction( 'test.action', action_a ); - removeAllActions( 'test.action' ); - doAction( 'test.action' ); - expect( window.actionValue ).toBe( '' ); - } ); +test( 'add and remove an action', () => { + window.actionValue = ''; + addAction( 'test.action', action_a ); + removeAllActions( 'test.action' ); + doAction( 'test.action' ); + expect( window.actionValue ).toBe( '' ); } ); -describe( 'add an action and run it', function() { - it( 'should', () => { - window.actionValue = ''; - addAction( 'test.action', action_a ); - doAction( 'test.action' ); - expect( window.actionValue ).toBe( 'a' ); - removeAllActions( 'test.action' ); - } ); +test( 'add an action and run it', function() { + window.actionValue = ''; + addAction( 'test.action', action_a ); + doAction( 'test.action' ); + expect( window.actionValue ).toBe( 'a' ); + removeAllActions( 'test.action' ); } ); -describe( 'add 2 actions in a row and then run them', function() { - it( 'should', () => { - window.actionValue = ''; - addAction( 'test.action', action_a ); - addAction( 'test.action', action_b ); - doAction( 'test.action' ); - expect( window.actionValue ).toBe( 'ab' ); - removeAllActions( 'test.action' ); - } ); +test( 'add 2 actions in a row and then run them', function() { + window.actionValue = ''; + addAction( 'test.action', action_a ); + addAction( 'test.action', action_b ); + doAction( 'test.action' ); + expect( window.actionValue ).toBe( 'ab' ); + removeAllActions( 'test.action' ); } ); -describe( 'add 3 actions with different priorities and run them', function() { - it( 'should', () => { - window.actionValue = ''; - addAction( 'test.action', action_a ); - addAction( 'test.action', action_b, 2 ); - addAction( 'test.action', action_c, 8 ); - doAction( 'test.action' ); - expect( window.actionValue ).toBe( 'bca' ); - removeAllActions( 'test.action' ); - } ); +test( 'add 3 actions with different priorities and run them', function() { + window.actionValue = ''; + addAction( 'test.action', action_a ); + addAction( 'test.action', action_b, 2 ); + addAction( 'test.action', action_c, 8 ); + doAction( 'test.action' ); + expect( window.actionValue ).toBe( 'bca' ); + removeAllActions( 'test.action' ); } ); -describe( 'pass in two arguments to an action', function() { - it( 'should', () => { - var arg1 = 10, - arg2 = 20; - - addAction( 'test.action', function( a, b ) { - expect( arg1 ).toBe( a ); - expect( arg2 ).toBe( b ); - } ); - doAction( 'test.action', arg1, arg2 ); - removeAllActions( 'test.action' ); +test( 'pass in two arguments to an action', function() { + var arg1 = 10, + arg2 = 20; - expect( arg1 ).toBe( 10 ); - expect( arg2 ).toBe( 20 ); + addAction( 'test.action', function( a, b ) { + expect( arg1 ).toBe( a ); + expect( arg2 ).toBe( b ); } ); + doAction( 'test.action', arg1, arg2 ); + removeAllActions( 'test.action' ); + + expect( arg1 ).toBe( 10 ); + expect( arg2 ).toBe( 20 ); } ); -describe( 'fire action multiple times', function() { - it( 'should', () => { - var func; - expect.assertions(2); +test( 'fire action multiple times', function() { + var func; + expect.assertions(2); - func = function() { - expect( true ).toBe( true ); - }; + func = function() { + expect( true ).toBe( true ); + }; - addAction( 'test.action', func ); - doAction( 'test.action' ); - doAction( 'test.action' ); - removeAllActions( 'test.action' ); - } ); + addAction( 'test.action', func ); + doAction( 'test.action' ); + doAction( 'test.action' ); + removeAllActions( 'test.action' ); } ); -describe( 'remove specific action callback', function() { - it( 'should', () => { - window.actionValue = ''; - addAction( 'test.action', action_a ); - addAction( 'test.action', action_b, 2 ); - addAction( 'test.action', action_c, 8 ); - - removeAction( 'test.action', action_b ); - doAction( 'test.action' ); - expect( window.actionValue ).toBe( 'ca' ); - removeAllActions( 'test.action' ); - } ); +test( 'remove specific action callback', function() { + window.actionValue = ''; + addAction( 'test.action', action_a ); + addAction( 'test.action', action_b, 2 ); + addAction( 'test.action', action_c, 8 ); + + removeAction( 'test.action', action_b ); + doAction( 'test.action' ); + expect( window.actionValue ).toBe( 'ca' ); + removeAllActions( 'test.action' ); } ); -describe( 'remove all action callbacks', function() { - it( 'should', () => { - window.actionValue = ''; - addAction( 'test.action', action_a ); - addAction( 'test.action', action_b, 2 ); - addAction( 'test.action', action_c, 8 ); +test( 'remove all action callbacks', function() { + window.actionValue = ''; + addAction( 'test.action', action_a ); + addAction( 'test.action', action_b, 2 ); + addAction( 'test.action', action_c, 8 ); - removeAllActions( 'test.action' ); - doAction( 'test.action' ); - expect( window.actionValue ).toBe( '' ); - } ); + removeAllActions( 'test.action' ); + doAction( 'test.action' ); + expect( window.actionValue ).toBe( '' ); } ); -describe( 'remove specific filter callback', function() { - it( 'should', () => { - addFilter( 'test.filter', filter_a ); - addFilter( 'test.filter', filter_b, 2 ); - addFilter( 'test.filter', filter_c, 8 ); +test( 'remove specific filter callback', function() { + addFilter( 'test.filter', filter_a ); + addFilter( 'test.filter', filter_b, 2 ); + addFilter( 'test.filter', filter_c, 8 ); - removeFilter( 'test.filter', filter_b ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testca' ); - removeAllFilters( 'test.filter' ); - } ); + removeFilter( 'test.filter', filter_b ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testca' ); + removeAllFilters( 'test.filter' ); } ); -describe( 'remove all filter callbacks', function() { - it( 'should', () => { - addFilter( 'test.filter', filter_a ); - addFilter( 'test.filter', filter_b, 2 ); - addFilter( 'test.filter', filter_c, 8 ); +test( 'remove all filter callbacks', function() { + addFilter( 'test.filter', filter_a ); + addFilter( 'test.filter', filter_b, 2 ); + addFilter( 'test.filter', filter_c, 8 ); - removeAllFilters( 'test.filter' ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); - } ); + removeAllFilters( 'test.filter' ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); } ); // Test doingAction, didAction, hasAction. -describe( 'Test doingAction, didAction and hasAction.', function() { - it( 'should', () => { - let actionCalls = 0; - - addAction( 'another.action', () => {} ); - doAction( 'another.action' ); - - // Verify no action is running yet. - expect( doingAction( 'test.action' ) ).toBe( false ); - - expect( didAction( 'test.action' ) ).toBe( 0 ); - expect( hasAction( 'test.action' ) ).toBe( 0 ); - - addAction( 'test.action', () => { - actionCalls++; - expect( currentAction() ).toBe( 'test.action' ); - expect( doingAction() ).toBe( true ); - expect( doingAction( 'test.action' ) ).toBe( true ); - } ); - - // Verify action added, not running yet. - expect( doingAction( 'test.action' ) ).toBe( false ); - expect( didAction( 'test.action' ) ).toBe( 0 ); - expect( hasAction( 'test.action' ) ).toBe( 1 ); - - doAction( 'test.action' ); - - // Verify action added and running. - expect( actionCalls ).toBe( 1 ); - expect( doingAction( 'test.action' ) ).toBe( false ); - expect( didAction( 'test.action' ) ).toBe( 1 ); - expect( hasAction( 'test.action' ) ).toBe( 1 ); - expect( doingAction() ).toBe( false ); - expect( doingAction( 'test.action' ) ).toBe( false ); - expect( doingAction( 'notatest.action' ) ).toBe( false ); - expect( currentAction() ).toBe( null ); - - doAction( 'test.action' ); - expect( actionCalls ).toBe( 2 ); - expect( didAction( 'test.action' ) ).toBe( 2 ); - - removeAllActions( 'test.action' ); - - // Verify state is reset appropriately. - expect( doingAction( 'test.action' ) ).toBe( false ); - expect( didAction( 'test.action' ) ).toBe( 2 ); - expect( hasAction( 'test.action' ) ).toBe( 0 ); - - doAction( 'another.action' ); - expect( doingAction( 'test.action' ) ).toBe( false ); - - // Verify hasAction returns 0 when no matching action. - expect( hasAction( 'notatest.action' ) ).toBe( 0 ); - } ); -} ); +test( 'Test doingAction, didAction and hasAction.', function() { + let actionCalls = 0; + + addAction( 'another.action', () => {} ); + doAction( 'another.action' ); -describe( 'Verify doingFilter, didFilter and hasFilter.', function() { - it( 'should', () => { - let filterCalls = 0; - - addFilter( 'runtest.filter', arg => { - filterCalls++; - expect( currentFilter() ).toBe( 'runtest.filter' ); - expect( doingFilter() ).toBe( true ); - expect( doingFilter( 'runtest.filter' ) ).toBe( true ); - return arg; - } ); - - // Verify filter added and running. - const test = applyFilters( 'runtest.filter', 'someValue' ); - expect( test ).toBe( 'someValue' ); - expect( filterCalls ).toBe( 1 ); - expect( didFilter( 'runtest.filter' ) ).toBe( 1 ); - expect( hasFilter( 'runtest.filter' ) ).toBe( 1 ); - expect( hasFilter( 'notatest.filter' ) ).toBe( 0 ); - expect( doingFilter() ).toBe( false ); - expect( doingFilter( 'runtest.filter' ) ).toBe( false ); - expect( doingFilter( 'notatest.filter' ) ).toBe( false ); - expect( currentFilter() ).toBe( null ); - - removeAllFilters( 'runtest.filter' ); - - expect( hasFilter( 'runtest.filter' ) ).toBe( 0 ); - expect( didFilter( 'runtest.filter' ) ).toBe( 1 ); + // Verify no action is running yet. + expect( doingAction( 'test.action' ) ).toBe( false ); + + expect( didAction( 'test.action' ) ).toBe( 0 ); + expect( hasAction( 'test.action' ) ).toBe( 0 ); + + addAction( 'test.action', () => { + actionCalls++; + expect( currentAction() ).toBe( 'test.action' ); + expect( doingAction() ).toBe( true ); + expect( doingAction( 'test.action' ) ).toBe( true ); } ); + + // Verify action added, not running yet. + expect( doingAction( 'test.action' ) ).toBe( false ); + expect( didAction( 'test.action' ) ).toBe( 0 ); + expect( hasAction( 'test.action' ) ).toBe( 1 ); + + doAction( 'test.action' ); + + // Verify action added and running. + expect( actionCalls ).toBe( 1 ); + expect( doingAction( 'test.action' ) ).toBe( false ); + expect( didAction( 'test.action' ) ).toBe( 1 ); + expect( hasAction( 'test.action' ) ).toBe( 1 ); + expect( doingAction() ).toBe( false ); + expect( doingAction( 'test.action' ) ).toBe( false ); + expect( doingAction( 'notatest.action' ) ).toBe( false ); + expect( currentAction() ).toBe( null ); + + doAction( 'test.action' ); + expect( actionCalls ).toBe( 2 ); + expect( didAction( 'test.action' ) ).toBe( 2 ); + + removeAllActions( 'test.action' ); + + // Verify state is reset appropriately. + expect( doingAction( 'test.action' ) ).toBe( false ); + expect( didAction( 'test.action' ) ).toBe( 2 ); + expect( hasAction( 'test.action' ) ).toBe( 0 ); + + doAction( 'another.action' ); + expect( doingAction( 'test.action' ) ).toBe( false ); + + // Verify hasAction returns 0 when no matching action. + expect( hasAction( 'notatest.action' ) ).toBe( 0 ); } ); +test( 'Verify doingFilter, didFilter and hasFilter.', function() { + let filterCalls = 0; + + addFilter( 'runtest.filter', arg => { + filterCalls++; + expect( currentFilter() ).toBe( 'runtest.filter' ); + expect( doingFilter() ).toBe( true ); + expect( doingFilter( 'runtest.filter' ) ).toBe( true ); + return arg; + } ); + // Verify filter added and running. + const test = applyFilters( 'runtest.filter', 'someValue' ); + expect( test ).toBe( 'someValue' ); + expect( filterCalls ).toBe( 1 ); + expect( didFilter( 'runtest.filter' ) ).toBe( 1 ); + expect( hasFilter( 'runtest.filter' ) ).toBe( 1 ); + expect( hasFilter( 'notatest.filter' ) ).toBe( 0 ); + expect( doingFilter() ).toBe( false ); + expect( doingFilter( 'runtest.filter' ) ).toBe( false ); + expect( doingFilter( 'notatest.filter' ) ).toBe( false ); + expect( currentFilter() ).toBe( null ); + + removeAllFilters( 'runtest.filter' ); + + expect( hasFilter( 'runtest.filter' ) ).toBe( 0 ); + expect( didFilter( 'runtest.filter' ) ).toBe( 1 ); +} ); From b351db4abf1a9ad24b1fa419e6c65b5c8f79063e Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 18:53:52 +0200 Subject: [PATCH 069/393] A bit more function declaration cleanup --- packages/hooks/src/createRemoveHook.js | 2 +- packages/hooks/src/createRunHook.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/hooks/src/createRemoveHook.js b/packages/hooks/src/createRemoveHook.js index ab6e3cec39722..33d1bd5622dda 100644 --- a/packages/hooks/src/createRemoveHook.js +++ b/packages/hooks/src/createRemoveHook.js @@ -7,7 +7,7 @@ * * @return {Function} Function that removes hooks. */ -const createRemoveHook = function( hooks, removeAll ) { +function createRemoveHook( hooks, removeAll ) { /** * Removes the specified callback (or all callbacks) from the hook with a * given name. diff --git a/packages/hooks/src/createRunHook.js b/packages/hooks/src/createRunHook.js index ca07b64564c59..e9ab4eb42e7d0 100644 --- a/packages/hooks/src/createRunHook.js +++ b/packages/hooks/src/createRunHook.js @@ -9,7 +9,7 @@ * * @return {Function} Function that runs hook callbacks. */ -const createRunHook = function( hooks, returnFirstArg ) { +function createRunHook( hooks, returnFirstArg ) { /** * Runs all callbacks for the specified hook. * From 498e15be0f9d0d2cabd4994f6bb6c741af2c6bfc Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 18:56:07 +0200 Subject: [PATCH 070/393] Use ES6 object shorthand --- packages/hooks/src/createAddHook.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index 2672b596ad93f..298b11292f477 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -32,10 +32,7 @@ function createAddHook( hooks ) { return; } - const handler = { - callback: callback, - priority: priority, - }; + const handler = { callback, priority }; let handlers; if ( hooks.hasOwnProperty( hookName ) ) { From e3392c3d65916d3379c09ba976451edcfc7d84d9 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 19:09:58 +0200 Subject: [PATCH 071/393] Add explicit error reporting --- packages/hooks/src/createAddHook.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index 298b11292f477..f172e84f0824c 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -16,7 +16,13 @@ function createAddHook( hooks ) { * @param {?number} priority Priority of this hook (default=10) */ return function addHook( hookName, callback, priority ) { - if ( typeof hookName !== 'string' || typeof callback !== 'function' ) { + if ( typeof hookName !== 'string' ) { + console.error( 'The hook name must be a string.' ); + return; + } + + if ( typeof callback !== 'function' ) { + console.error( 'The hook callback must be a function.' ); return; } @@ -29,6 +35,7 @@ function createAddHook( hooks ) { // Validate numeric priority if ( isNaN( priority ) ) { + console.error( 'The hook priority must be omitted or a number.' ); return; } From 53294fd0f0df33d13e7284382a2f09db25bc991d Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 19:16:26 +0200 Subject: [PATCH 072/393] Test adding and removing multiple filters at the same priority --- packages/hooks/src/test/index.test.js | 49 +++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 5d624b02b6442..9a7645130669d 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -79,6 +79,55 @@ test( 'add 3 filters with different priorities and run them', () => { removeAllFilters( 'test.filter' ); } ); +test( 'filters with the same and different priorities', () => { + const callbacks = {}; + + [ 1, 2, 3, 4 ].forEach( priority => { + [ 'a', 'b', 'c', 'd' ].forEach( string => { + callbacks[ 'fn_' + priority + string ] = value => { + return value.concat( priority + string ); + }; + } ); + } ); + + addFilter( 'test_order', callbacks.fn_3a, 3 ); + addFilter( 'test_order', callbacks.fn_3b, 3 ); + addFilter( 'test_order', callbacks.fn_3c, 3 ); + addFilter( 'test_order', callbacks.fn_2a, 2 ); + addFilter( 'test_order', callbacks.fn_2b, 2 ); + addFilter( 'test_order', callbacks.fn_2c, 2 ); + + expect( applyFilters( 'test_order', [] ) ).toEqual( + [ '2a', '2b', '2c', '3a', '3b', '3c' ] + ); + + removeFilter( 'test_order', callbacks.fn_2b ); + removeFilter( 'test_order', callbacks.fn_3a ); + + expect( applyFilters( 'test_order', [] ) ).toEqual( + [ '2a', '2c', '3b', '3c' ] + ); + + addFilter( 'test_order', callbacks.fn_4a, 4 ); + addFilter( 'test_order', callbacks.fn_4b, 4 ); + addFilter( 'test_order', callbacks.fn_1a, 1 ); + addFilter( 'test_order', callbacks.fn_4c, 4 ); + addFilter( 'test_order', callbacks.fn_1b, 1 ); + addFilter( 'test_order', callbacks.fn_3d, 3 ); + addFilter( 'test_order', callbacks.fn_4d, 4 ); + addFilter( 'test_order', callbacks.fn_1c, 1 ); + addFilter( 'test_order', callbacks.fn_2d, 2 ); + addFilter( 'test_order', callbacks.fn_1d, 1 ); + + expect( applyFilters( 'test_order', [] ) ).toEqual( [ + // all except 2b and 3a, which we removed earlier + '1a', '1b', '1c', '1d', + '2a', '2c', '2d', + '3b', '3c', '3d', + '4a', '4b', '4c', '4d', + ] ); +} ); + test( 'add and remove an action', () => { window.actionValue = ''; addAction( 'test.action', action_a ); From 07b61a08ea22026cafe20f3eba0548daecfef8f6 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 19:25:46 +0200 Subject: [PATCH 073/393] Keep the hooks list always sorted instead of explicitly sorting it --- packages/hooks/src/createAddHook.js | 15 ++++++++++----- packages/hooks/src/sortHooks.js | 28 ---------------------------- 2 files changed, 10 insertions(+), 33 deletions(-) delete mode 100644 packages/hooks/src/sortHooks.js diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index f172e84f0824c..71febb849a125 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -1,5 +1,3 @@ -import sortHooks from './sortHooks'; - /** * Returns a function which, when invoked, will add a hook. * @@ -43,10 +41,17 @@ function createAddHook( hooks ) { let handlers; if ( hooks.hasOwnProperty( hookName ) ) { - // Append and re-sort amongst the existing callbacks. + // Find the correct insert index of the new hook. handlers = hooks[ hookName ]; - handlers.push( handler ); - handlers = sortHooks( handlers ); + let i = 0; + while ( i < handlers.length ) { + if ( handlers[ i ].priority > priority ) { + break; + } + i++; + } + // Insert (or append) the new hook. + handlers.splice( i, 0, handler ); } else { // This is the first hook of its type. handlers = [ handler ]; diff --git a/packages/hooks/src/sortHooks.js b/packages/hooks/src/sortHooks.js deleted file mode 100644 index 8e6ed0015be3c..0000000000000 --- a/packages/hooks/src/sortHooks.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Use an insert sort to keep hook handlers organized based on priority. - * - * @see http://jsperf.com/javascript-sort - * - * @param {Array} handlers Array of the handlers to sort - * @return {Array} The sorted array - * @private - */ -const sortHooks = function( handlers ) { - var i, tmpHook, j, prevHook; - for ( i = 1; i < handlers.length; i++ ) { - tmpHook = handlers[ i ]; - j = i; - while ( - ( prevHook = handlers[ j - 1 ] ) && - prevHook.priority > tmpHook.priority - ) { - handlers[ j ] = handlers[ j - 1 ]; - --j; - } - handlers[ j ] = tmpHook; - } - - return handlers; -} - -export default sortHooks; From ee303e6795f924f003e044893e3ce0802b45b205 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 19:29:40 +0200 Subject: [PATCH 074/393] Remove remaining `var` statements --- packages/hooks/src/test/index.test.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 9a7645130669d..06c9ee4ce0f04 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -164,25 +164,21 @@ test( 'add 3 actions with different priorities and run them', function() { } ); test( 'pass in two arguments to an action', function() { - var arg1 = 10, - arg2 = 20; + const arg1 = { a: 10 }; + const arg2 = { b: 20 }; addAction( 'test.action', function( a, b ) { - expect( arg1 ).toBe( a ); - expect( arg2 ).toBe( b ); + expect( a ).toBe( arg1 ); + expect( b ).toBe( arg2 ); } ); doAction( 'test.action', arg1, arg2 ); removeAllActions( 'test.action' ); - - expect( arg1 ).toBe( 10 ); - expect( arg2 ).toBe( 20 ); } ); test( 'fire action multiple times', function() { - var func; - expect.assertions(2); + expect.assertions( 2 ); - func = function() { + function func() { expect( true ).toBe( true ); }; From b1251e33baad0900552cf1aef34b20ac6c375fa9 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 19:31:29 +0200 Subject: [PATCH 075/393] Remove remaining per-test cleanup logic This is all handled in `beforeEach` now. --- packages/hooks/src/test/index.test.js | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 06c9ee4ce0f04..c2f2d60388801 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -61,14 +61,12 @@ test( 'add and remove a filter', () => { test( 'add a filter and run it', () => { addFilter( 'test.filter', filter_a ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testa' ); - removeAllFilters( 'test.filter' ); } ); test( 'add 2 filters in a row and run them', () => { addFilter( 'test.filter', filter_a ); addFilter( 'test.filter', filter_b ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); - removeAllFilters( 'test.filter' ); } ); test( 'add 3 filters with different priorities and run them', () => { @@ -76,7 +74,6 @@ test( 'add 3 filters with different priorities and run them', () => { addFilter( 'test.filter', filter_b, 2 ); addFilter( 'test.filter', filter_c, 8 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testbca' ); - removeAllFilters( 'test.filter' ); } ); test( 'filters with the same and different priorities', () => { @@ -129,7 +126,6 @@ test( 'filters with the same and different priorities', () => { } ); test( 'add and remove an action', () => { - window.actionValue = ''; addAction( 'test.action', action_a ); removeAllActions( 'test.action' ); doAction( 'test.action' ); @@ -137,30 +133,24 @@ test( 'add and remove an action', () => { } ); test( 'add an action and run it', function() { - window.actionValue = ''; addAction( 'test.action', action_a ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'a' ); - removeAllActions( 'test.action' ); } ); test( 'add 2 actions in a row and then run them', function() { - window.actionValue = ''; addAction( 'test.action', action_a ); addAction( 'test.action', action_b ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'ab' ); - removeAllActions( 'test.action' ); } ); test( 'add 3 actions with different priorities and run them', function() { - window.actionValue = ''; addAction( 'test.action', action_a ); addAction( 'test.action', action_b, 2 ); addAction( 'test.action', action_c, 8 ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'bca' ); - removeAllActions( 'test.action' ); } ); test( 'pass in two arguments to an action', function() { @@ -172,7 +162,6 @@ test( 'pass in two arguments to an action', function() { expect( b ).toBe( arg2 ); } ); doAction( 'test.action', arg1, arg2 ); - removeAllActions( 'test.action' ); } ); test( 'fire action multiple times', function() { @@ -185,11 +174,9 @@ test( 'fire action multiple times', function() { addAction( 'test.action', func ); doAction( 'test.action' ); doAction( 'test.action' ); - removeAllActions( 'test.action' ); } ); test( 'remove specific action callback', function() { - window.actionValue = ''; addAction( 'test.action', action_a ); addAction( 'test.action', action_b, 2 ); addAction( 'test.action', action_c, 8 ); @@ -197,11 +184,9 @@ test( 'remove specific action callback', function() { removeAction( 'test.action', action_b ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'ca' ); - removeAllActions( 'test.action' ); } ); test( 'remove all action callbacks', function() { - window.actionValue = ''; addAction( 'test.action', action_a ); addAction( 'test.action', action_b, 2 ); addAction( 'test.action', action_c, 8 ); @@ -218,7 +203,6 @@ test( 'remove specific filter callback', function() { removeFilter( 'test.filter', filter_b ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testca' ); - removeAllFilters( 'test.filter' ); } ); test( 'remove all filter callbacks', function() { From 7eda5e29948388001d06eaa1ed8e3bf977c47656 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 20 Jul 2017 15:47:11 -0400 Subject: [PATCH 076/393] Add webpack and build wp-hooks for core --- package.json | 3 +- packages/hooks/src/wp-hooks.js | 41 +++ packages/hooks/wp-hooks.js | 482 +++++++++++++++++++++++++++++++++ webpack.config.js | 6 + 4 files changed, 531 insertions(+), 1 deletion(-) create mode 100644 packages/hooks/src/wp-hooks.js create mode 100644 packages/hooks/wp-hooks.js create mode 100644 webpack.config.js diff --git a/package.json b/package.json index ebc1c5328ff61..f044ec1886663 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "jest": "^20.0.4", "lerna": "^2.0.0-rc.5", "mkdirp": "^0.5.1", - "rimraf": "^2.6.1" + "rimraf": "^2.6.1", + "webpack": "^3.3.0" }, "scripts": { "build-clean": "rimraf ./packages/*/build ./packages/*/build-browser ./packages/*/build-module", diff --git a/packages/hooks/src/wp-hooks.js b/packages/hooks/src/wp-hooks.js new file mode 100644 index 0000000000000..3f0461d2efca8 --- /dev/null +++ b/packages/hooks/src/wp-hooks.js @@ -0,0 +1,41 @@ +import HOOKS from './hooks'; +import { + addAction, + addFilter, + removeAction, + removeFilter, + removeAllActions, + removeAllFilters, + hasAction, + hasFilter, + doAction, + applyFilters, + currentAction, + currentFilter, + doingAction, + doingFilter, + didAction, + didFilter +} from './'; + +const hooks = { + addAction, + addFilter, + removeAction, + removeFilter, + removeAllActions, + removeAllFilters, + hasAction, + hasFilter, + doAction, + applyFilters, + currentAction, + currentFilter, + doingAction, + doingFilter, + didAction, + didFilter +} + +window.wp = window.wp || {}; +window.wp.hooks = hooks; diff --git a/packages/hooks/wp-hooks.js b/packages/hooks/wp-hooks.js new file mode 100644 index 0000000000000..3e196b049d1a7 --- /dev/null +++ b/packages/hooks/wp-hooks.js @@ -0,0 +1,482 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 1); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/** + * Contains the registered hooks, keyed by hook type. Each hook type is an + * array of objects with priority and callback of each registered hook. + */ +const HOOKS = { + actions: {}, + filters: {}, +}; + +/* harmony default export */ __webpack_exports__["a"] = (HOOKS); + + +/***/ }), +/* 1 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__hooks__ = __webpack_require__(0); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1____ = __webpack_require__(2); + + + +const hooks = { + addAction: __WEBPACK_IMPORTED_MODULE_1____["a" /* addAction */], + addFilter: __WEBPACK_IMPORTED_MODULE_1____["b" /* addFilter */], + removeAction: __WEBPACK_IMPORTED_MODULE_1____["m" /* removeAction */], + removeFilter: __WEBPACK_IMPORTED_MODULE_1____["p" /* removeFilter */], + removeAllActions: __WEBPACK_IMPORTED_MODULE_1____["n" /* removeAllActions */], + removeAllFilters: __WEBPACK_IMPORTED_MODULE_1____["o" /* removeAllFilters */], + hasAction: __WEBPACK_IMPORTED_MODULE_1____["k" /* hasAction */], + hasFilter: __WEBPACK_IMPORTED_MODULE_1____["l" /* hasFilter */], + doAction: __WEBPACK_IMPORTED_MODULE_1____["h" /* doAction */], + applyFilters: __WEBPACK_IMPORTED_MODULE_1____["c" /* applyFilters */], + currentAction: __WEBPACK_IMPORTED_MODULE_1____["d" /* currentAction */], + currentFilter: __WEBPACK_IMPORTED_MODULE_1____["e" /* currentFilter */], + doingAction: __WEBPACK_IMPORTED_MODULE_1____["i" /* doingAction */], + doingFilter: __WEBPACK_IMPORTED_MODULE_1____["j" /* doingFilter */], + didAction: __WEBPACK_IMPORTED_MODULE_1____["f" /* didAction */], + didFilter: __WEBPACK_IMPORTED_MODULE_1____["g" /* didFilter */] +} + +window.wp = window.wp || {}; +window.wp.hooks = hooks; + + +/***/ }), +/* 2 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__hooks__ = __webpack_require__(0); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__createAddHook__ = __webpack_require__(3); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__createRemoveHook__ = __webpack_require__(4); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__createHasHook__ = __webpack_require__(5); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__createRunHook__ = __webpack_require__(6); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__createDoingHook__ = __webpack_require__(7); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__createDidHook__ = __webpack_require__(8); + + + + + + + + +// Add action/filter functions. +const addAction = Object(__WEBPACK_IMPORTED_MODULE_1__createAddHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].actions ); +/* harmony export (immutable) */ __webpack_exports__["a"] = addAction; + +const addFilter = Object(__WEBPACK_IMPORTED_MODULE_1__createAddHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].filters ); +/* harmony export (immutable) */ __webpack_exports__["b"] = addFilter; + + +// Remove action/filter functions. +const removeAction = Object(__WEBPACK_IMPORTED_MODULE_2__createRemoveHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].actions ); +/* harmony export (immutable) */ __webpack_exports__["m"] = removeAction; + +const removeFilter = Object(__WEBPACK_IMPORTED_MODULE_2__createRemoveHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].filters ); +/* harmony export (immutable) */ __webpack_exports__["p"] = removeFilter; + + +// Has action/filter functions. +const hasAction = Object(__WEBPACK_IMPORTED_MODULE_3__createHasHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].actions ); +/* harmony export (immutable) */ __webpack_exports__["k"] = hasAction; + +const hasFilter = Object(__WEBPACK_IMPORTED_MODULE_3__createHasHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].filters ); +/* harmony export (immutable) */ __webpack_exports__["l"] = hasFilter; + + +// Remove all actions/filters functions. +const removeAllActions = Object(__WEBPACK_IMPORTED_MODULE_2__createRemoveHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].actions, true ); +/* harmony export (immutable) */ __webpack_exports__["n"] = removeAllActions; + +const removeAllFilters = Object(__WEBPACK_IMPORTED_MODULE_2__createRemoveHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].filters, true ); +/* harmony export (immutable) */ __webpack_exports__["o"] = removeAllFilters; + + +// Do action/apply filters functions. +const doAction = Object(__WEBPACK_IMPORTED_MODULE_4__createRunHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].actions ); +/* harmony export (immutable) */ __webpack_exports__["h"] = doAction; + +const applyFilters = Object(__WEBPACK_IMPORTED_MODULE_4__createRunHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].filters, true ); +/* harmony export (immutable) */ __webpack_exports__["c"] = applyFilters; + + +// Current action/filter functions. +const currentAction = () => __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].actions.current || null; +/* harmony export (immutable) */ __webpack_exports__["d"] = currentAction; + +const currentFilter = () => __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].filters.current || null; +/* harmony export (immutable) */ __webpack_exports__["e"] = currentFilter; + + +// Doing action/filter: true while a hook is being run. +const doingAction = Object(__WEBPACK_IMPORTED_MODULE_5__createDoingHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].actions ); +/* harmony export (immutable) */ __webpack_exports__["i"] = doingAction; + +const doingFilter = Object(__WEBPACK_IMPORTED_MODULE_5__createDoingHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].filters ); +/* harmony export (immutable) */ __webpack_exports__["j"] = doingFilter; + + +// Did action/filter functions. +const didAction = Object(__WEBPACK_IMPORTED_MODULE_6__createDidHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].actions ); +/* harmony export (immutable) */ __webpack_exports__["f"] = didAction; + +const didFilter = Object(__WEBPACK_IMPORTED_MODULE_6__createDidHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].filters ); +/* harmony export (immutable) */ __webpack_exports__["g"] = didFilter; + + + +/***/ }), +/* 3 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/** + * Returns a function which, when invoked, will add a hook. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * + * @return {Function} Function that adds a new hook. + */ +function createAddHook( hooks ) { + /** + * Adds the hook to the appropriate hooks container. + * + * @param {string} hookName Name of hook to add + * @param {Function} callback Function to call when the hook is run + * @param {?number} priority Priority of this hook (default=10) + */ + return function addHook( hookName, callback, priority ) { + if ( typeof hookName !== 'string' ) { + console.error( 'The hook name must be a string.' ); + return; + } + + if ( typeof callback !== 'function' ) { + console.error( 'The hook callback must be a function.' ); + return; + } + + // Assign default priority + if ( 'undefined' === typeof priority ) { + priority = 10; + } else { + priority = parseInt( priority, 10 ); + } + + // Validate numeric priority + if ( isNaN( priority ) ) { + console.error( 'The hook priority must be omitted or a number.' ); + return; + } + + const handler = { callback, priority }; + let handlers; + + if ( hooks.hasOwnProperty( hookName ) ) { + // Find the correct insert index of the new hook. + handlers = hooks[ hookName ]; + let i = 0; + while ( i < handlers.length ) { + if ( handlers[ i ].priority > priority ) { + break; + } + i++; + } + // Insert (or append) the new hook. + handlers.splice( i, 0, handler ); + } else { + // This is the first hook of its type. + handlers = [ handler ]; + } + + hooks[ hookName ] = handlers; + }; +} + +/* harmony default export */ __webpack_exports__["a"] = (createAddHook); + + +/***/ }), +/* 4 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/** + * Returns a function which, when invoked, will remove a specified hook or all + * hooks by the given name. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * @param {bool} removeAll Whether to remove all hooked callbacks. + * + * @return {Function} Function that removes hooks. + */ +function createRemoveHook( hooks, removeAll ) { + /** + * Removes the specified callback (or all callbacks) from the hook with a + * given name. + * + * @param {string} hookName The name of the hook to modify. + * @param {?Function} callback The specific callback to be removed. If + * omitted (and `removeAll` is truthy), clears + * all callbacks. + */ + return function removeHook( hookName, callback ) { + // Bail if no hooks exist by this name + if ( ! hooks.hasOwnProperty( hookName ) ) { + return; + } + + if ( removeAll ) { + const runs = hooks[ hookName ].runs; + hooks[ hookName ] = []; + if ( runs ) { + hooks[ hookName ].runs = runs; + } + } else if ( callback ) { + // Try to find the specified callback to remove. + const handlers = hooks[ hookName ]; + for ( let i = handlers.length - 1; i >= 0; i-- ) { + if ( handlers[ i ].callback === callback ) { + handlers.splice( i, 1 ); + } + } + } + }; +} + +/* harmony default export */ __webpack_exports__["a"] = (createRemoveHook); + + +/***/ }), +/* 5 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/** + * Returns a function which, when invoked, will return whether any handlers are + * attached to a particular hook. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * + * @return {Function} Function that returns whether any handlers are + * attached to a particular hook. + */ +function createHasHook( hooks ) { + /** + * Returns how many handlers are attached for the given hook. + * + * @param {string} hookName The name of the hook to check for. + * + * @return {number} The number of handlers that are attached to + * the given hook. + */ + return function hasHook( hookName ) { + return hooks.hasOwnProperty( hookName ) + ? hooks[ hookName ].length + : 0; + }; +} + +/* harmony default export */ __webpack_exports__["a"] = (createHasHook); + + +/***/ }), +/* 6 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/** + * Returns a function which, when invoked, will execute all callbacks + * registered to a hook of the specified type, optionally returning the final + * value of the call chain. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * @param {?bool} returnFirstArg Whether each hook callback is expected to + * return its first argument. + * + * @return {Function} Function that runs hook callbacks. + */ +function createRunHook( hooks, returnFirstArg ) { + /** + * Runs all callbacks for the specified hook. + * + * @param {string} hookName The name of the hook to run. + * @param {...*} args Arguments to pass to the hook callbacks. + * + * @return {*} Return value of runner, if applicable. + */ + return function runHooks( hookName, ...args ) { + const handlers = hooks[ hookName ]; + let maybeReturnValue = args[ 0 ]; + + if ( ! handlers ) { + return ( returnFirstArg ? maybeReturnValue : undefined ); + } + + hooks.current = hookName; + handlers.runs = ( handlers.runs || 0 ) + 1; + + handlers.forEach( handler => { + maybeReturnValue = handler.callback.apply( null, args ); + if ( returnFirstArg ) { + args[ 0 ] = maybeReturnValue; + } + } ); + + delete hooks.current; + + if ( returnFirstArg ) { + return maybeReturnValue; + } + }; +} + +/* harmony default export */ __webpack_exports__["a"] = (createRunHook); + + +/***/ }), +/* 7 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/** + * Returns a function which, when invoked, will return whether a hook is + * currently being executed. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * + * @return {Function} Function that returns whether a hook is currently + * being executed. + */ +function createDoingHook( hooks ) { + /** + * Returns whether a hook is currently being executed. + * + * @param {?string} hookName The name of the hook to check for. If + * omitted, will check for any hook being executed. + * + * @return {bool} Whether the hook is being executed. + */ + return function doingHook( hookName ) { + // If the hookName was not passed, check for any current hook. + if ( 'undefined' === typeof hookName ) { + return 'undefined' !== typeof hooks.current; + } + + // Return the current hook. + return hooks.current + ? hookName === hooks.current + : false; + }; +} + +/* harmony default export */ __webpack_exports__["a"] = (createDoingHook); + + +/***/ }), +/* 8 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/** + * Returns a function which, when invoked, will return the number of times a + * hook has been called. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * + * @return {Function} Function that returns a hook's call count. + */ +function createDidHook( hooks ) { + /** + * Returns the number of times an action has been fired. + * + * @param {string} hookName The hook name to check. + * + * @return {number} The number of times the hook has run. + */ + return function didHook( hookName ) { + return hooks.hasOwnProperty( hookName ) && hooks[ hookName ].runs + ? hooks[ hookName ].runs + : 0; + }; +} + +/* harmony default export */ __webpack_exports__["a"] = (createDidHook); + + +/***/ }) +/******/ ]); \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000000000..0244e911453ef --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,6 @@ +module.exports = { + entry: './packages/hooks/src/wp-hooks.js', + output: { + filename: './packages/hooks/wp-hooks.js' + } +} From 0e9986a2a863e8ba8692010f2d034f43e29299ec Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 20 Jul 2017 15:51:38 -0400 Subject: [PATCH 077/393] remove built file and adjust build path --- packages/hooks/wp-hooks.js | 482 ------------------------------------- webpack.config.js | 2 +- 2 files changed, 1 insertion(+), 483 deletions(-) delete mode 100644 packages/hooks/wp-hooks.js diff --git a/packages/hooks/wp-hooks.js b/packages/hooks/wp-hooks.js deleted file mode 100644 index 3e196b049d1a7..0000000000000 --- a/packages/hooks/wp-hooks.js +++ /dev/null @@ -1,482 +0,0 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 1); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -/** - * Contains the registered hooks, keyed by hook type. Each hook type is an - * array of objects with priority and callback of each registered hook. - */ -const HOOKS = { - actions: {}, - filters: {}, -}; - -/* harmony default export */ __webpack_exports__["a"] = (HOOKS); - - -/***/ }), -/* 1 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__hooks__ = __webpack_require__(0); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1____ = __webpack_require__(2); - - - -const hooks = { - addAction: __WEBPACK_IMPORTED_MODULE_1____["a" /* addAction */], - addFilter: __WEBPACK_IMPORTED_MODULE_1____["b" /* addFilter */], - removeAction: __WEBPACK_IMPORTED_MODULE_1____["m" /* removeAction */], - removeFilter: __WEBPACK_IMPORTED_MODULE_1____["p" /* removeFilter */], - removeAllActions: __WEBPACK_IMPORTED_MODULE_1____["n" /* removeAllActions */], - removeAllFilters: __WEBPACK_IMPORTED_MODULE_1____["o" /* removeAllFilters */], - hasAction: __WEBPACK_IMPORTED_MODULE_1____["k" /* hasAction */], - hasFilter: __WEBPACK_IMPORTED_MODULE_1____["l" /* hasFilter */], - doAction: __WEBPACK_IMPORTED_MODULE_1____["h" /* doAction */], - applyFilters: __WEBPACK_IMPORTED_MODULE_1____["c" /* applyFilters */], - currentAction: __WEBPACK_IMPORTED_MODULE_1____["d" /* currentAction */], - currentFilter: __WEBPACK_IMPORTED_MODULE_1____["e" /* currentFilter */], - doingAction: __WEBPACK_IMPORTED_MODULE_1____["i" /* doingAction */], - doingFilter: __WEBPACK_IMPORTED_MODULE_1____["j" /* doingFilter */], - didAction: __WEBPACK_IMPORTED_MODULE_1____["f" /* didAction */], - didFilter: __WEBPACK_IMPORTED_MODULE_1____["g" /* didFilter */] -} - -window.wp = window.wp || {}; -window.wp.hooks = hooks; - - -/***/ }), -/* 2 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__hooks__ = __webpack_require__(0); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__createAddHook__ = __webpack_require__(3); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__createRemoveHook__ = __webpack_require__(4); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__createHasHook__ = __webpack_require__(5); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__createRunHook__ = __webpack_require__(6); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__createDoingHook__ = __webpack_require__(7); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__createDidHook__ = __webpack_require__(8); - - - - - - - - -// Add action/filter functions. -const addAction = Object(__WEBPACK_IMPORTED_MODULE_1__createAddHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].actions ); -/* harmony export (immutable) */ __webpack_exports__["a"] = addAction; - -const addFilter = Object(__WEBPACK_IMPORTED_MODULE_1__createAddHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].filters ); -/* harmony export (immutable) */ __webpack_exports__["b"] = addFilter; - - -// Remove action/filter functions. -const removeAction = Object(__WEBPACK_IMPORTED_MODULE_2__createRemoveHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].actions ); -/* harmony export (immutable) */ __webpack_exports__["m"] = removeAction; - -const removeFilter = Object(__WEBPACK_IMPORTED_MODULE_2__createRemoveHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].filters ); -/* harmony export (immutable) */ __webpack_exports__["p"] = removeFilter; - - -// Has action/filter functions. -const hasAction = Object(__WEBPACK_IMPORTED_MODULE_3__createHasHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].actions ); -/* harmony export (immutable) */ __webpack_exports__["k"] = hasAction; - -const hasFilter = Object(__WEBPACK_IMPORTED_MODULE_3__createHasHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].filters ); -/* harmony export (immutable) */ __webpack_exports__["l"] = hasFilter; - - -// Remove all actions/filters functions. -const removeAllActions = Object(__WEBPACK_IMPORTED_MODULE_2__createRemoveHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].actions, true ); -/* harmony export (immutable) */ __webpack_exports__["n"] = removeAllActions; - -const removeAllFilters = Object(__WEBPACK_IMPORTED_MODULE_2__createRemoveHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].filters, true ); -/* harmony export (immutable) */ __webpack_exports__["o"] = removeAllFilters; - - -// Do action/apply filters functions. -const doAction = Object(__WEBPACK_IMPORTED_MODULE_4__createRunHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].actions ); -/* harmony export (immutable) */ __webpack_exports__["h"] = doAction; - -const applyFilters = Object(__WEBPACK_IMPORTED_MODULE_4__createRunHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].filters, true ); -/* harmony export (immutable) */ __webpack_exports__["c"] = applyFilters; - - -// Current action/filter functions. -const currentAction = () => __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].actions.current || null; -/* harmony export (immutable) */ __webpack_exports__["d"] = currentAction; - -const currentFilter = () => __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].filters.current || null; -/* harmony export (immutable) */ __webpack_exports__["e"] = currentFilter; - - -// Doing action/filter: true while a hook is being run. -const doingAction = Object(__WEBPACK_IMPORTED_MODULE_5__createDoingHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].actions ); -/* harmony export (immutable) */ __webpack_exports__["i"] = doingAction; - -const doingFilter = Object(__WEBPACK_IMPORTED_MODULE_5__createDoingHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].filters ); -/* harmony export (immutable) */ __webpack_exports__["j"] = doingFilter; - - -// Did action/filter functions. -const didAction = Object(__WEBPACK_IMPORTED_MODULE_6__createDidHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].actions ); -/* harmony export (immutable) */ __webpack_exports__["f"] = didAction; - -const didFilter = Object(__WEBPACK_IMPORTED_MODULE_6__createDidHook__["a" /* default */])( __WEBPACK_IMPORTED_MODULE_0__hooks__["a" /* default */].filters ); -/* harmony export (immutable) */ __webpack_exports__["g"] = didFilter; - - - -/***/ }), -/* 3 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -/** - * Returns a function which, when invoked, will add a hook. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * - * @return {Function} Function that adds a new hook. - */ -function createAddHook( hooks ) { - /** - * Adds the hook to the appropriate hooks container. - * - * @param {string} hookName Name of hook to add - * @param {Function} callback Function to call when the hook is run - * @param {?number} priority Priority of this hook (default=10) - */ - return function addHook( hookName, callback, priority ) { - if ( typeof hookName !== 'string' ) { - console.error( 'The hook name must be a string.' ); - return; - } - - if ( typeof callback !== 'function' ) { - console.error( 'The hook callback must be a function.' ); - return; - } - - // Assign default priority - if ( 'undefined' === typeof priority ) { - priority = 10; - } else { - priority = parseInt( priority, 10 ); - } - - // Validate numeric priority - if ( isNaN( priority ) ) { - console.error( 'The hook priority must be omitted or a number.' ); - return; - } - - const handler = { callback, priority }; - let handlers; - - if ( hooks.hasOwnProperty( hookName ) ) { - // Find the correct insert index of the new hook. - handlers = hooks[ hookName ]; - let i = 0; - while ( i < handlers.length ) { - if ( handlers[ i ].priority > priority ) { - break; - } - i++; - } - // Insert (or append) the new hook. - handlers.splice( i, 0, handler ); - } else { - // This is the first hook of its type. - handlers = [ handler ]; - } - - hooks[ hookName ] = handlers; - }; -} - -/* harmony default export */ __webpack_exports__["a"] = (createAddHook); - - -/***/ }), -/* 4 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -/** - * Returns a function which, when invoked, will remove a specified hook or all - * hooks by the given name. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * @param {bool} removeAll Whether to remove all hooked callbacks. - * - * @return {Function} Function that removes hooks. - */ -function createRemoveHook( hooks, removeAll ) { - /** - * Removes the specified callback (or all callbacks) from the hook with a - * given name. - * - * @param {string} hookName The name of the hook to modify. - * @param {?Function} callback The specific callback to be removed. If - * omitted (and `removeAll` is truthy), clears - * all callbacks. - */ - return function removeHook( hookName, callback ) { - // Bail if no hooks exist by this name - if ( ! hooks.hasOwnProperty( hookName ) ) { - return; - } - - if ( removeAll ) { - const runs = hooks[ hookName ].runs; - hooks[ hookName ] = []; - if ( runs ) { - hooks[ hookName ].runs = runs; - } - } else if ( callback ) { - // Try to find the specified callback to remove. - const handlers = hooks[ hookName ]; - for ( let i = handlers.length - 1; i >= 0; i-- ) { - if ( handlers[ i ].callback === callback ) { - handlers.splice( i, 1 ); - } - } - } - }; -} - -/* harmony default export */ __webpack_exports__["a"] = (createRemoveHook); - - -/***/ }), -/* 5 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -/** - * Returns a function which, when invoked, will return whether any handlers are - * attached to a particular hook. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * - * @return {Function} Function that returns whether any handlers are - * attached to a particular hook. - */ -function createHasHook( hooks ) { - /** - * Returns how many handlers are attached for the given hook. - * - * @param {string} hookName The name of the hook to check for. - * - * @return {number} The number of handlers that are attached to - * the given hook. - */ - return function hasHook( hookName ) { - return hooks.hasOwnProperty( hookName ) - ? hooks[ hookName ].length - : 0; - }; -} - -/* harmony default export */ __webpack_exports__["a"] = (createHasHook); - - -/***/ }), -/* 6 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -/** - * Returns a function which, when invoked, will execute all callbacks - * registered to a hook of the specified type, optionally returning the final - * value of the call chain. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * @param {?bool} returnFirstArg Whether each hook callback is expected to - * return its first argument. - * - * @return {Function} Function that runs hook callbacks. - */ -function createRunHook( hooks, returnFirstArg ) { - /** - * Runs all callbacks for the specified hook. - * - * @param {string} hookName The name of the hook to run. - * @param {...*} args Arguments to pass to the hook callbacks. - * - * @return {*} Return value of runner, if applicable. - */ - return function runHooks( hookName, ...args ) { - const handlers = hooks[ hookName ]; - let maybeReturnValue = args[ 0 ]; - - if ( ! handlers ) { - return ( returnFirstArg ? maybeReturnValue : undefined ); - } - - hooks.current = hookName; - handlers.runs = ( handlers.runs || 0 ) + 1; - - handlers.forEach( handler => { - maybeReturnValue = handler.callback.apply( null, args ); - if ( returnFirstArg ) { - args[ 0 ] = maybeReturnValue; - } - } ); - - delete hooks.current; - - if ( returnFirstArg ) { - return maybeReturnValue; - } - }; -} - -/* harmony default export */ __webpack_exports__["a"] = (createRunHook); - - -/***/ }), -/* 7 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -/** - * Returns a function which, when invoked, will return whether a hook is - * currently being executed. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * - * @return {Function} Function that returns whether a hook is currently - * being executed. - */ -function createDoingHook( hooks ) { - /** - * Returns whether a hook is currently being executed. - * - * @param {?string} hookName The name of the hook to check for. If - * omitted, will check for any hook being executed. - * - * @return {bool} Whether the hook is being executed. - */ - return function doingHook( hookName ) { - // If the hookName was not passed, check for any current hook. - if ( 'undefined' === typeof hookName ) { - return 'undefined' !== typeof hooks.current; - } - - // Return the current hook. - return hooks.current - ? hookName === hooks.current - : false; - }; -} - -/* harmony default export */ __webpack_exports__["a"] = (createDoingHook); - - -/***/ }), -/* 8 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -/** - * Returns a function which, when invoked, will return the number of times a - * hook has been called. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * - * @return {Function} Function that returns a hook's call count. - */ -function createDidHook( hooks ) { - /** - * Returns the number of times an action has been fired. - * - * @param {string} hookName The hook name to check. - * - * @return {number} The number of times the hook has run. - */ - return function didHook( hookName ) { - return hooks.hasOwnProperty( hookName ) && hooks[ hookName ].runs - ? hooks[ hookName ].runs - : 0; - }; -} - -/* harmony default export */ __webpack_exports__["a"] = (createDidHook); - - -/***/ }) -/******/ ]); \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js index 0244e911453ef..036556a60e62f 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,6 +1,6 @@ module.exports = { entry: './packages/hooks/src/wp-hooks.js', output: { - filename: './packages/hooks/wp-hooks.js' + filename: './packages/hooks/build/wp-core/wp-hooks.js' } } From c9890db6e925bc6144b37e446ef129332433e816 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 23:46:07 +0200 Subject: [PATCH 078/393] Remove unused dependencies --- packages/hooks/package.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/hooks/package.json b/packages/hooks/package.json index 4724aff1efadf..94ec11ada4e92 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -10,9 +10,5 @@ "module": "build-module/index.js", "browser": "build-browser/index.js", "author": "WordPress", - "license": "GPL-2.0+", - "dependencies": { - "querystring": "^0.2.0", - "url": "^0.11.0" - } + "license": "GPL-2.0+" } From de6efd77cf0b1de0b58e2d9e03f52b0f672635cb Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 23:46:26 +0200 Subject: [PATCH 079/393] Use an ES6 default argument to set the default hook priority --- packages/hooks/src/createAddHook.js | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index 71febb849a125..59b2139dc57f6 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -13,7 +13,7 @@ function createAddHook( hooks ) { * @param {Function} callback Function to call when the hook is run * @param {?number} priority Priority of this hook (default=10) */ - return function addHook( hookName, callback, priority ) { + return function addHook( hookName, callback, priority = 10 ) { if ( typeof hookName !== 'string' ) { console.error( 'The hook name must be a string.' ); return; @@ -24,16 +24,9 @@ function createAddHook( hooks ) { return; } - // Assign default priority - if ( 'undefined' === typeof priority ) { - priority = 10; - } else { - priority = parseInt( priority, 10 ); - } - // Validate numeric priority - if ( isNaN( priority ) ) { - console.error( 'The hook priority must be omitted or a number.' ); + if ( typeof priority !== 'number' ) { + console.error( 'If specified, the hook priority must be a number.' ); return; } From ad479985757fd39ee32ff772f733db9f017ecba3 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 20 Jul 2017 23:52:20 +0200 Subject: [PATCH 080/393] Refactor handlers objects: don't assign extra properties on arrays --- packages/hooks/src/createAddHook.js | 10 +++++----- packages/hooks/src/createHasHook.js | 2 +- packages/hooks/src/createRemoveHook.js | 11 +++++------ packages/hooks/src/createRunHook.js | 19 ++++++++++++++----- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index 59b2139dc57f6..30ceda75c2540 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -31,11 +31,10 @@ function createAddHook( hooks ) { } const handler = { callback, priority }; - let handlers; if ( hooks.hasOwnProperty( hookName ) ) { // Find the correct insert index of the new hook. - handlers = hooks[ hookName ]; + const handlers = hooks[ hookName ].handlers; let i = 0; while ( i < handlers.length ) { if ( handlers[ i ].priority > priority ) { @@ -47,10 +46,11 @@ function createAddHook( hooks ) { handlers.splice( i, 0, handler ); } else { // This is the first hook of its type. - handlers = [ handler ]; + hooks[ hookName ] = { + handlers: [ handler ], + runs: 0, + }; } - - hooks[ hookName ] = handlers; }; } diff --git a/packages/hooks/src/createHasHook.js b/packages/hooks/src/createHasHook.js index 6d9cd107146d5..46cd61a1eb0e4 100644 --- a/packages/hooks/src/createHasHook.js +++ b/packages/hooks/src/createHasHook.js @@ -18,7 +18,7 @@ function createHasHook( hooks ) { */ return function hasHook( hookName ) { return hooks.hasOwnProperty( hookName ) - ? hooks[ hookName ].length + ? hooks[ hookName ].handlers.length : 0; }; } diff --git a/packages/hooks/src/createRemoveHook.js b/packages/hooks/src/createRemoveHook.js index 33d1bd5622dda..a136ca299171f 100644 --- a/packages/hooks/src/createRemoveHook.js +++ b/packages/hooks/src/createRemoveHook.js @@ -24,14 +24,13 @@ function createRemoveHook( hooks, removeAll ) { } if ( removeAll ) { - const runs = hooks[ hookName ].runs; - hooks[ hookName ] = []; - if ( runs ) { - hooks[ hookName ].runs = runs; - } + hooks[ hookName ] = { + runs: hooks[ hookName ].runs, + handlers: [], + }; } else if ( callback ) { // Try to find the specified callback to remove. - const handlers = hooks[ hookName ]; + const handlers = hooks[ hookName ].handlers; for ( let i = handlers.length - 1; i >= 0; i-- ) { if ( handlers[ i ].callback === callback ) { handlers.splice( i, 1 ); diff --git a/packages/hooks/src/createRunHook.js b/packages/hooks/src/createRunHook.js index e9ab4eb42e7d0..3d0da3b945f77 100644 --- a/packages/hooks/src/createRunHook.js +++ b/packages/hooks/src/createRunHook.js @@ -19,16 +19,25 @@ function createRunHook( hooks, returnFirstArg ) { * @return {*} Return value of runner, if applicable. */ return function runHooks( hookName, ...args ) { - const handlers = hooks[ hookName ]; - let maybeReturnValue = args[ 0 ]; + if ( ! hooks.hasOwnProperty( hookName ) ) { + hooks[ hookName ] = { + runs: 0, + handlers: [], + }; + } - if ( ! handlers ) { - return ( returnFirstArg ? maybeReturnValue : undefined ); + const handlers = hooks[ hookName ].handlers; + + if ( ! handlers.length ) { + return returnFirstArg + ? args[ 0 ] + : undefined; } hooks.current = hookName; - handlers.runs = ( handlers.runs || 0 ) + 1; + hooks[ hookName ].runs++; + let maybeReturnValue = args[ 0 ]; handlers.forEach( handler => { maybeReturnValue = handler.callback.apply( null, args ); if ( returnFirstArg ) { From 562cf377ccfe55d2d0bc3e2886c8d508a4dc80a6 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 20 Jul 2017 18:23:36 -0400 Subject: [PATCH 081/393] Run core build JS thru babel --- package.json | 3 ++- webpack.config.js | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index f044ec1886663..e62872fefbbc4 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "lerna": "^2.0.0-rc.5", "mkdirp": "^0.5.1", "rimraf": "^2.6.1", - "webpack": "^3.3.0" + "webpack": "^3.3.0", + "babel-loader": "^7.1.1" }, "scripts": { "build-clean": "rimraf ./packages/*/build ./packages/*/build-browser ./packages/*/build-module", diff --git a/webpack.config.js b/webpack.config.js index 036556a60e62f..ca6d3a000efd6 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,5 +2,17 @@ module.exports = { entry: './packages/hooks/src/wp-hooks.js', output: { filename: './packages/hooks/build/wp-core/wp-hooks.js' + }, + module: { + rules: [ + { + test: /\.js$/, + exclude: /(node_modules)/, + use: { + loader: 'babel-loader' + } + } + ] } + } From e780e22bdfc261c5bfe96462449c9d824d62ee0a Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Thu, 20 Jul 2017 00:00:31 +1000 Subject: [PATCH 082/393] chore: Update chalk to 2.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2ed94f7f2f5ac..4e58084adbd1b 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "babel-plugin-transform-object-rest-spread": "^6.23.0", "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-env": "^1.5.2", - "chalk": "^1.1.3", + "chalk": "^2.0.1", "glob": "^7.1.2", "jest": "^20.0.4", "lerna": "^2.0.0", From f882313d9bf80a490c330d8d22ad02f90f7eafe6 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 21 Jul 2017 12:00:26 -0400 Subject: [PATCH 083/393] remove babel-loader for now --- package.json | 3 +-- webpack.config.js | 12 ------------ 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/package.json b/package.json index e62872fefbbc4..f044ec1886663 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,7 @@ "lerna": "^2.0.0-rc.5", "mkdirp": "^0.5.1", "rimraf": "^2.6.1", - "webpack": "^3.3.0", - "babel-loader": "^7.1.1" + "webpack": "^3.3.0" }, "scripts": { "build-clean": "rimraf ./packages/*/build ./packages/*/build-browser ./packages/*/build-module", diff --git a/webpack.config.js b/webpack.config.js index ca6d3a000efd6..036556a60e62f 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,17 +2,5 @@ module.exports = { entry: './packages/hooks/src/wp-hooks.js', output: { filename: './packages/hooks/build/wp-core/wp-hooks.js' - }, - module: { - rules: [ - { - test: /\.js$/, - exclude: /(node_modules)/, - use: { - loader: 'babel-loader' - } - } - ] } - } From 9eeb1987044a97a997e11a907449518e4c8e8860 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 21 Jul 2017 15:30:32 -0400 Subject: [PATCH 084/393] =?UTF-8?q?rename=20=E2=80=98current=E2=80=99=20?= =?UTF-8?q?=3D>=20=E2=80=98=5F=5Fcurrent=E2=80=99=20and=20make=20it=20a=20?= =?UTF-8?q?stack?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/hooks/src/createDoingHook.js | 8 ++++---- packages/hooks/src/createRunHook.js | 7 +++++-- packages/hooks/src/index.js | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/hooks/src/createDoingHook.js b/packages/hooks/src/createDoingHook.js index ba7aa02874497..860b657c9a469 100644 --- a/packages/hooks/src/createDoingHook.js +++ b/packages/hooks/src/createDoingHook.js @@ -19,12 +19,12 @@ function createDoingHook( hooks ) { return function doingHook( hookName ) { // If the hookName was not passed, check for any current hook. if ( 'undefined' === typeof hookName ) { - return 'undefined' !== typeof hooks.current; + return 'undefined' !== typeof hooks.__current[0]; } - // Return the current hook. - return hooks.current - ? hookName === hooks.current + // Return the __current hook. + return hooks.__current[0] + ? hookName === hooks.__current[0] : false; }; } diff --git a/packages/hooks/src/createRunHook.js b/packages/hooks/src/createRunHook.js index 3d0da3b945f77..911e2a0382e52 100644 --- a/packages/hooks/src/createRunHook.js +++ b/packages/hooks/src/createRunHook.js @@ -34,7 +34,8 @@ function createRunHook( hooks, returnFirstArg ) { : undefined; } - hooks.current = hookName; + hooks.__current = hooks.__current || []; + hooks.__current.push( hookName ); hooks[ hookName ].runs++; let maybeReturnValue = args[ 0 ]; @@ -45,10 +46,12 @@ function createRunHook( hooks, returnFirstArg ) { } } ); - delete hooks.current; + hooks.__current.pop(); if ( returnFirstArg ) { return maybeReturnValue; + } else { + return false; } }; } diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index 992930edd77ee..732aa09ce91f7 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -27,8 +27,8 @@ export const doAction = createRunHook( HOOKS.actions ); export const applyFilters = createRunHook( HOOKS.filters, true ); // Current action/filter functions. -export const currentAction = () => HOOKS.actions.current || null; -export const currentFilter = () => HOOKS.filters.current || null; +export const currentAction = () => HOOKS.actions.__current[0] || null; +export const currentFilter = () => HOOKS.filters.__current[0] || null; // Doing action/filter: true while a hook is being run. export const doingAction = createDoingHook( HOOKS.actions ); From fd0ccd3b884d27263ef06d5e4db638657dd10d93 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 21 Jul 2017 15:38:17 -0400 Subject: [PATCH 085/393] Add initial readme based on https://github.com/adamsilverstein/WP-JS-Hooks --- packages/hooks/README.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 packages/hooks/README.md diff --git a/packages/hooks/README.md b/packages/hooks/README.md new file mode 100644 index 0000000000000..1174727feffc6 --- /dev/null +++ b/packages/hooks/README.md @@ -0,0 +1,34 @@ +# WP-JS-Hooks + +A lightweight & efficient EventManager for JavaScript in WordPress. + + +### API Usage +API functions can be called via the global `wp.hooks` like this `wp.hooks.addAction()`, etc. + +* `addAction( 'namespace.identifier', callback, priority )` +* `addFilter( 'namespace.identifier', callback, priority )` +* `removeAction( 'namespace.identifier', callback )` +* `removeFilter( 'namespace.identifier', callback )` +* `removeAllActions( 'namespace.identifier' )` +* `removeAllFilters( 'namespace.identifier' )` +* `doAction( 'namespace.identifier', arg1, arg2, moreArgs, finalArg )` +* `applyFilters( 'namespace.identifier', content )` +* `doingAction( 'namespace.identifier' )` +* `doingFilter( 'namespace.identifier' )` +* `didAction( 'namespace.identifier' )` +* `didFilter( 'namespace.identifier' )` +* `hasAction( 'namespace.identifier' )` +* `hasFilter( 'namespace.identifier' )` + + +### Background +See ticket [#21170](http://core.trac.wordpress.org/ticket/21170) for more information. + + +### Features + +* Fast and lightweight. +* Priorities system ensures hooks with lower integer priority are fired first. +* Uses native object hash lookup for finding hook callbacks. +* Utilizes insertion sort for keeping priorities correct. Best Case: O(n), worst case: O(n^2) From fc48fbfb2b29a545b0e5474a02729f38230d376c Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 21 Jul 2017 15:53:55 -0400 Subject: [PATCH 086/393] test remove a filter callback of lower priority when running hook --- packages/hooks/src/test/index.test.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index c2f2d60388801..8e15d9d8af5ec 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -205,6 +205,16 @@ test( 'remove specific filter callback', function() { expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testca' ); } ); +test( 'remove a filter callback of lower priority when running hook', function() { + + addFilter( 'test.filter', filter_a, 1 ); + addFilter( 'test.filter', filter_b, 3 ); + addFilter( 'test.filter', filter_c, 4 ); + addFilter( 'test.filter', filter_a_removesb, 2 ); + + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); +} ); + test( 'remove all filter callbacks', function() { addFilter( 'test.filter', filter_a ); addFilter( 'test.filter', filter_b, 2 ); From 566af31749c47bac813269f1fc6497517c40a1fd Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 21 Jul 2017 15:54:11 -0400 Subject: [PATCH 087/393] test remove a filter callback of same priority when running hook --- packages/hooks/src/test/index.test.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 8e15d9d8af5ec..a1c55150e725e 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -39,6 +39,10 @@ function action_b() { function action_c() { window.actionValue += 'c'; } +function filter_a_removesb( str ) { + removeFilter( 'test.filter', filter_b ); + return str; +} beforeEach( () => { window.actionValue = ''; @@ -215,6 +219,16 @@ test( 'remove a filter callback of lower priority when running hook', function() expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); } ); +test( 'remove a filter callback of same priority when running hook', function() { + + addFilter( 'test.filter', filter_a, 1 ); + addFilter( 'test.filter', filter_a_removesb, 2 ); + addFilter( 'test.filter', filter_b, 2 ); + addFilter( 'test.filter', filter_c, 4 ); + + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); +} ); + test( 'remove all filter callbacks', function() { addFilter( 'test.filter', filter_a ); addFilter( 'test.filter', filter_b, 2 ); From 6ce626857615312e3f47f17193c1c9bc61aea583 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 21 Jul 2017 16:15:50 -0400 Subject: [PATCH 088/393] prevent and test for (dingle level) hook recursion --- packages/hooks/src/createRunHook.js | 14 +++++++++++--- packages/hooks/src/test/index.test.js | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/packages/hooks/src/createRunHook.js b/packages/hooks/src/createRunHook.js index 911e2a0382e52..d7af0eb62d1f3 100644 --- a/packages/hooks/src/createRunHook.js +++ b/packages/hooks/src/createRunHook.js @@ -39,10 +39,18 @@ function createRunHook( hooks, returnFirstArg ) { hooks[ hookName ].runs++; let maybeReturnValue = args[ 0 ]; + handlers.forEach( handler => { - maybeReturnValue = handler.callback.apply( null, args ); - if ( returnFirstArg ) { - args[ 0 ] = maybeReturnValue; + if ( handler.callback !== hooks.currentCallback ) { + + // Prevent hook recursion. + hooks.currentCallback = handler.callback; + maybeReturnValue = handler.callback.apply( null, args ); + hooks.currentCallback = false; + + if ( returnFirstArg ) { + args[ 0 ] = maybeReturnValue; + } } } ); diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index a1c55150e725e..83557225ec965 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -24,26 +24,37 @@ import { function filter_a( str ) { return str + 'a'; } + function filter_b( str ) { return str + 'b'; } + function filter_c( str ) { return str + 'c'; } + function action_a() { window.actionValue += 'a'; } + function action_b() { window.actionValue += 'b'; } + function action_c() { window.actionValue += 'c'; } + function filter_a_removesb( str ) { removeFilter( 'test.filter', filter_b ); return str; } +function filter_that_applies_recursively( str ) { + applyFilters( 'test.filter', str ); + return str; +} + beforeEach( () => { window.actionValue = ''; // Reset state in between tests (clear all callbacks, `didAction` counts, @@ -321,3 +332,11 @@ test( 'Verify doingFilter, didFilter and hasFilter.', function() { expect( hasFilter( 'runtest.filter' ) ).toBe( 0 ); expect( didFilter( 'runtest.filter' ) ).toBe( 1 ); } ); + +test( 'recursively calling a filter', function() { + + addFilter( 'test.filter', filter_that_applies_recursively, 10 ); + + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); +} ); + From 83dffa47ec0f121e066a88928fb467af0307dbca Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 21 Jul 2017 16:20:12 -0400 Subject: [PATCH 089/393] test remove a filter callback of higher priority when running hook --- packages/hooks/src/test/index.test.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 83557225ec965..9a1f1deaa17c5 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -230,9 +230,20 @@ test( 'remove a filter callback of lower priority when running hook', function() expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); } ); +test( 'remove a filter callback of higher priority when running hook', function() { + + addFilter( 'test.filter', filter_a, 1 ); + addFilter( 'test.filter', filter_b, 3 ); + addFilter( 'test.filter', filter_c, 5 ); + addFilter( 'test.filter', filter_a_removesb, 6 ); + + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); +} ); + test( 'remove a filter callback of same priority when running hook', function() { addFilter( 'test.filter', filter_a, 1 ); + // Note: works if added first, adding after may need fixing. addFilter( 'test.filter', filter_a_removesb, 2 ); addFilter( 'test.filter', filter_b, 2 ); addFilter( 'test.filter', filter_c, 4 ); From 2a60b9f237ec34050535f326255da1624bceab65 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 21 Jul 2017 16:25:02 -0400 Subject: [PATCH 090/393] Failing recursive test: remove one hook in a callback before adding another --- packages/hooks/src/test/index.test.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 9a1f1deaa17c5..acef761147495 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -239,6 +239,15 @@ test( 'remove a filter callback of higher priority when running hook', function( expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); +test( 'remove one hook in a callback before adding another', function() { + addFilter( 'test.filter', filter_a, 1 ); + addFilter( 'test.filter', filter_b, 3 ); + addFilter( 'test.filter', filter_c, 5 ); + addFilter( 'test.filter', filter_a_removesb, 4 ); + + // Fails!!! only a & b run, not c. + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); +} ); test( 'remove a filter callback of same priority when running hook', function() { From 79ef421b7debc0070aa352652089b713f12b482d Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 21 Jul 2017 17:04:04 -0400 Subject: [PATCH 091/393] Add babel-loader for core build --- package.json | 3 ++- webpack.config.js | 13 ++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index f044ec1886663..e62872fefbbc4 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "lerna": "^2.0.0-rc.5", "mkdirp": "^0.5.1", "rimraf": "^2.6.1", - "webpack": "^3.3.0" + "webpack": "^3.3.0", + "babel-loader": "^7.1.1" }, "scripts": { "build-clean": "rimraf ./packages/*/build ./packages/*/build-browser ./packages/*/build-module", diff --git a/webpack.config.js b/webpack.config.js index 036556a60e62f..5faefb963d7a3 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,6 +1,17 @@ module.exports = { entry: './packages/hooks/src/wp-hooks.js', output: { - filename: './packages/hooks/build/wp-core/wp-hooks.js' + filename: './packages/hooks/wp-core/wp-hooks.js' + }, + module: { + rules: [ + { + test: /\.js$/, + exclude: /(node_modules)/, + use: { + loader: 'babel-loader' + } + } + ] } } From 0b62dd44de21dabf59157013d672a1842146876a Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Fri, 21 Jul 2017 11:28:05 +1000 Subject: [PATCH 092/393] chore: Remove `version` from `lerna.json` --- lerna.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lerna.json b/lerna.json index 14b21512a980c..020530655ac46 100644 --- a/lerna.json +++ b/lerna.json @@ -2,6 +2,5 @@ "lerna": "2.0.0-rc.5", "packages": [ "packages/*" - ], - "version": "0.0.0" + ] } From 24aaba9d4ec382774db9864fa2e6321080b529fb Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 13:45:41 +0200 Subject: [PATCH 093/393] Add test coverage and run tests during Travis build (#18) --- .travis.yml | 4 +++- README.md | 4 ++++ package.json | 14 +++++++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1790f9d00c73c..c50f49f6d2e00 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,9 @@ language: node_js node_js: - '8' - '6' -script: true + +script: npm run test:coverage-ci + notifications: slack: rooms: diff --git a/README.md b/README.md index 4e060a73692ac..86f0f892a2659 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,6 @@ # packages + +[![Build Status](https://img.shields.io/travis/WordPress/packages/master.svg)](https://travis-ci.org/WordPress/packages) +[![Coverage](https://img.shields.io/coveralls/WordPress/packages/master.svg)](https://coveralls.io/github/WordPress/packages) + Collection of JS modules and tools for WordPress development diff --git a/package.json b/package.json index 4e58084adbd1b..1539a667031f7 100644 --- a/package.json +++ b/package.json @@ -5,16 +5,28 @@ "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-env": "^1.5.2", "chalk": "^2.0.1", + "coveralls": "^2.13.1", "glob": "^7.1.2", "jest": "^20.0.4", "lerna": "^2.0.0", "mkdirp": "^0.5.1", "rimraf": "^2.6.1" }, + "jest": { + "collectCoverageFrom": [ + "packages/*/**/*.js" + ], + "coveragePathIgnorePatterns": [ + "/.*/build.*" + ], + "coverageDirectory": "coverage" + }, "scripts": { "build-clean": "rimraf ./packages/*/build ./packages/*/build-browser ./packages/*/build-module", "build": "node ./scripts/build.js", "test": "jest", - "watch": "jest --watch" + "test:coverage": "jest --coverage", + "test:coverage-ci": "jest --coverage && coveralls < coverage/lcov.info", + "test:watch": "jest --watch" } } From bf69f8927de3569d88a6e1adeff753e69fa825f4 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 14:06:16 +0200 Subject: [PATCH 094/393] Clean up tests for removing a filter while filters are running --- packages/hooks/src/test/index.test.js | 63 ++++++++++++++++++--------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index acef761147495..0f29f782791a6 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -33,6 +33,21 @@ function filter_c( str ) { return str + 'c'; } +function filter_b_removes_self( str ) { + removeFilter( 'test.filter', filter_b_removes_self ); + return str + 'b'; +} + +function filter_removes_b( str ) { + removeFilter( 'test.filter', filter_b ); + return str; +} + +function filter_removes_c( str ) { + removeFilter( 'test.filter', filter_c ); + return str; +} + function action_a() { window.actionValue += 'a'; } @@ -45,11 +60,6 @@ function action_c() { window.actionValue += 'c'; } -function filter_a_removesb( str ) { - removeFilter( 'test.filter', filter_b ); - return str; -} - function filter_that_applies_recursively( str ) { applyFilters( 'test.filter', str ); return str; @@ -220,40 +230,53 @@ test( 'remove specific filter callback', function() { expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testca' ); } ); -test( 'remove a filter callback of lower priority when running hook', function() { - +test( 'filter removes a callback that has already executed', function() { addFilter( 'test.filter', filter_a, 1 ); addFilter( 'test.filter', filter_b, 3 ); - addFilter( 'test.filter', filter_c, 4 ); - addFilter( 'test.filter', filter_a_removesb, 2 ); + addFilter( 'test.filter', filter_c, 5 ); + addFilter( 'test.filter', filter_removes_b, 4 ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); -test( 'remove a filter callback of higher priority when running hook', function() { +test( 'filter removes a callback that has already executed (same priority)', function() { + addFilter( 'test.filter', filter_a, 1 ); + addFilter( 'test.filter', filter_b, 2 ); + addFilter( 'test.filter', filter_removes_b, 2 ); + addFilter( 'test.filter', filter_c, 4 ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); +} ); + +test( 'filter removes the current callback', function() { addFilter( 'test.filter', filter_a, 1 ); - addFilter( 'test.filter', filter_b, 3 ); + addFilter( 'test.filter', filter_b_removes_self, 3 ); addFilter( 'test.filter', filter_c, 5 ); - addFilter( 'test.filter', filter_a_removesb, 6 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); -test( 'remove one hook in a callback before adding another', function() { + +test( 'filter removes a callback that has not yet executed (last)', function() { addFilter( 'test.filter', filter_a, 1 ); addFilter( 'test.filter', filter_b, 3 ); addFilter( 'test.filter', filter_c, 5 ); - addFilter( 'test.filter', filter_a_removesb, 4 ); + addFilter( 'test.filter', filter_removes_c, 4 ); - // Fails!!! only a & b run, not c. - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); } ); -test( 'remove a filter callback of same priority when running hook', function() { +test( 'filter removes a callback that has not yet executed (middle)', function() { + addFilter( 'test.filter', filter_a, 1 ); + addFilter( 'test.filter', filter_b, 3 ); + addFilter( 'test.filter', filter_c, 4 ); + addFilter( 'test.filter', filter_removes_b, 2 ); + + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); +} ); +test( 'filter removes a callback that has not yet executed (same priority)', function() { addFilter( 'test.filter', filter_a, 1 ); - // Note: works if added first, adding after may need fixing. - addFilter( 'test.filter', filter_a_removesb, 2 ); + addFilter( 'test.filter', filter_removes_b, 2 ); addFilter( 'test.filter', filter_b, 2 ); addFilter( 'test.filter', filter_c, 4 ); From bd911d075eadff234b10b97f0bc44f6f587bbdc5 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 14:44:56 +0200 Subject: [PATCH 095/393] Add test demonstrating desired recursion behavior --- packages/hooks/src/test/index.test.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 0f29f782791a6..f8e049ff62517 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -60,11 +60,6 @@ function action_c() { window.actionValue += 'c'; } -function filter_that_applies_recursively( str ) { - applyFilters( 'test.filter', str ); - return str; -} - beforeEach( () => { window.actionValue = ''; // Reset state in between tests (clear all callbacks, `didAction` counts, @@ -377,9 +372,13 @@ test( 'Verify doingFilter, didFilter and hasFilter.', function() { } ); test( 'recursively calling a filter', function() { + addFilter( 'test.filter', value => { + if ( value.length === 7 ) { + return value; + } + return applyFilters( 'test.filter', value + 'X' ); + } ); - addFilter( 'test.filter', filter_that_applies_recursively, 10 ); - - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testXXX' ); } ); From b802c1d954c371aa2f9c86021e672427e3623d9f Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 14:51:34 +0200 Subject: [PATCH 096/393] Convert most functions in tests to arrow functions (for consistency) --- packages/hooks/src/test/index.test.js | 38 +++++++++++++-------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index f8e049ff62517..8adc2fec03b0a 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -152,20 +152,20 @@ test( 'add and remove an action', () => { expect( window.actionValue ).toBe( '' ); } ); -test( 'add an action and run it', function() { +test( 'add an action and run it', () => { addAction( 'test.action', action_a ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'a' ); } ); -test( 'add 2 actions in a row and then run them', function() { +test( 'add 2 actions in a row and then run them', () => { addAction( 'test.action', action_a ); addAction( 'test.action', action_b ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'ab' ); } ); -test( 'add 3 actions with different priorities and run them', function() { +test( 'add 3 actions with different priorities and run them', () => { addAction( 'test.action', action_a ); addAction( 'test.action', action_b, 2 ); addAction( 'test.action', action_c, 8 ); @@ -173,18 +173,18 @@ test( 'add 3 actions with different priorities and run them', function() { expect( window.actionValue ).toBe( 'bca' ); } ); -test( 'pass in two arguments to an action', function() { +test( 'pass in two arguments to an action', () => { const arg1 = { a: 10 }; const arg2 = { b: 20 }; - addAction( 'test.action', function( a, b ) { + addAction( 'test.action', ( a, b ) => { expect( a ).toBe( arg1 ); expect( b ).toBe( arg2 ); } ); doAction( 'test.action', arg1, arg2 ); } ); -test( 'fire action multiple times', function() { +test( 'fire action multiple times', () => { expect.assertions( 2 ); function func() { @@ -196,7 +196,7 @@ test( 'fire action multiple times', function() { doAction( 'test.action' ); } ); -test( 'remove specific action callback', function() { +test( 'remove specific action callback', () => { addAction( 'test.action', action_a ); addAction( 'test.action', action_b, 2 ); addAction( 'test.action', action_c, 8 ); @@ -206,7 +206,7 @@ test( 'remove specific action callback', function() { expect( window.actionValue ).toBe( 'ca' ); } ); -test( 'remove all action callbacks', function() { +test( 'remove all action callbacks', () => { addAction( 'test.action', action_a ); addAction( 'test.action', action_b, 2 ); addAction( 'test.action', action_c, 8 ); @@ -216,7 +216,7 @@ test( 'remove all action callbacks', function() { expect( window.actionValue ).toBe( '' ); } ); -test( 'remove specific filter callback', function() { +test( 'remove specific filter callback', () => { addFilter( 'test.filter', filter_a ); addFilter( 'test.filter', filter_b, 2 ); addFilter( 'test.filter', filter_c, 8 ); @@ -225,7 +225,7 @@ test( 'remove specific filter callback', function() { expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testca' ); } ); -test( 'filter removes a callback that has already executed', function() { +test( 'filter removes a callback that has already executed', () => { addFilter( 'test.filter', filter_a, 1 ); addFilter( 'test.filter', filter_b, 3 ); addFilter( 'test.filter', filter_c, 5 ); @@ -234,7 +234,7 @@ test( 'filter removes a callback that has already executed', function() { expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); -test( 'filter removes a callback that has already executed (same priority)', function() { +test( 'filter removes a callback that has already executed (same priority)', () => { addFilter( 'test.filter', filter_a, 1 ); addFilter( 'test.filter', filter_b, 2 ); addFilter( 'test.filter', filter_removes_b, 2 ); @@ -243,7 +243,7 @@ test( 'filter removes a callback that has already executed (same priority)', fun expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); -test( 'filter removes the current callback', function() { +test( 'filter removes the current callback', () => { addFilter( 'test.filter', filter_a, 1 ); addFilter( 'test.filter', filter_b_removes_self, 3 ); addFilter( 'test.filter', filter_c, 5 ); @@ -251,7 +251,7 @@ test( 'filter removes the current callback', function() { expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); -test( 'filter removes a callback that has not yet executed (last)', function() { +test( 'filter removes a callback that has not yet executed (last)', () => { addFilter( 'test.filter', filter_a, 1 ); addFilter( 'test.filter', filter_b, 3 ); addFilter( 'test.filter', filter_c, 5 ); @@ -260,7 +260,7 @@ test( 'filter removes a callback that has not yet executed (last)', function() { expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); } ); -test( 'filter removes a callback that has not yet executed (middle)', function() { +test( 'filter removes a callback that has not yet executed (middle)', () => { addFilter( 'test.filter', filter_a, 1 ); addFilter( 'test.filter', filter_b, 3 ); addFilter( 'test.filter', filter_c, 4 ); @@ -269,7 +269,7 @@ test( 'filter removes a callback that has not yet executed (middle)', function() expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); } ); -test( 'filter removes a callback that has not yet executed (same priority)', function() { +test( 'filter removes a callback that has not yet executed (same priority)', () => { addFilter( 'test.filter', filter_a, 1 ); addFilter( 'test.filter', filter_removes_b, 2 ); addFilter( 'test.filter', filter_b, 2 ); @@ -278,7 +278,7 @@ test( 'filter removes a callback that has not yet executed (same priority)', fun expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); } ); -test( 'remove all filter callbacks', function() { +test( 'remove all filter callbacks', () => { addFilter( 'test.filter', filter_a ); addFilter( 'test.filter', filter_b, 2 ); addFilter( 'test.filter', filter_c, 8 ); @@ -288,7 +288,7 @@ test( 'remove all filter callbacks', function() { } ); // Test doingAction, didAction, hasAction. -test( 'Test doingAction, didAction and hasAction.', function() { +test( 'Test doingAction, didAction and hasAction.', () => { let actionCalls = 0; addAction( 'another.action', () => {} ); @@ -342,7 +342,7 @@ test( 'Test doingAction, didAction and hasAction.', function() { expect( hasAction( 'notatest.action' ) ).toBe( 0 ); } ); -test( 'Verify doingFilter, didFilter and hasFilter.', function() { +test( 'Verify doingFilter, didFilter and hasFilter.', () => { let filterCalls = 0; addFilter( 'runtest.filter', arg => { @@ -371,7 +371,7 @@ test( 'Verify doingFilter, didFilter and hasFilter.', function() { expect( didFilter( 'runtest.filter' ) ).toBe( 1 ); } ); -test( 'recursively calling a filter', function() { +test( 'recursively calling a filter', () => { addFilter( 'test.filter', value => { if ( value.length === 7 ) { return value; From 4e393d663db61cedcff4392f9d1e3a02f4798887 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 14:53:41 +0200 Subject: [PATCH 097/393] Add failing test for `currentFilter` with multiple filters running --- packages/hooks/src/test/index.test.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 8adc2fec03b0a..6c6289b3bced4 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -382,3 +382,16 @@ test( 'recursively calling a filter', () => { expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testXXX' ); } ); +test( 'current filter when multiple filters are running', () => { + addFilter( 'test.filter1', value => { + return applyFilters( 'test.filter2', value.concat( currentFilter() ) ); + } ); + + addFilter( 'test.filter2', value => { + return value.concat( currentFilter() ); + } ); + + expect( applyFilters( 'test.filter1', [ 'test' ] ) ).toBe( + [ 'test', 'test.filter1', 'test.filter2' ] + ); +} ); From 5d0513c7f2ea1b3f60b79959c91e537f50d12a1a Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 17:22:14 +0200 Subject: [PATCH 098/393] Fix `currentFilter` behavior --- packages/hooks/src/createCurrentHook.js | 27 +++++++++++++++++++++++++ packages/hooks/src/index.js | 5 +++-- packages/hooks/src/test/index.test.js | 2 +- 3 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 packages/hooks/src/createCurrentHook.js diff --git a/packages/hooks/src/createCurrentHook.js b/packages/hooks/src/createCurrentHook.js new file mode 100644 index 0000000000000..e5ff3519f370f --- /dev/null +++ b/packages/hooks/src/createCurrentHook.js @@ -0,0 +1,27 @@ +/** + * Returns a function which, when invoked, will return the name of the + * currently running hook, or `null` if no hook of the given type is currently + * running. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * + * @return {Function} Function that returns the current hook. + */ +function createCurrentHook( hooks, returnFirstArg ) { + /** + * Returns the name of the currently running hook, or `null` if no hook of + * the given type is currently running. + * + * @return {?string} The name of the currently running hook, or + * `null` if no hook is currently running. + */ + return function currentHook() { + if ( ! hooks.__current || ! hooks.__current.length ) { + return null; + } + + return hooks.__current[ hooks.__current.length - 1 ]; + }; +} + +export default createCurrentHook; diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index 732aa09ce91f7..93801c5bfc7c8 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -3,6 +3,7 @@ import createAddHook from './createAddHook'; import createRemoveHook from './createRemoveHook'; import createHasHook from './createHasHook'; import createRunHook from './createRunHook'; +import createCurrentHook from './createCurrentHook'; import createDoingHook from './createDoingHook'; import createDidHook from './createDidHook'; @@ -27,8 +28,8 @@ export const doAction = createRunHook( HOOKS.actions ); export const applyFilters = createRunHook( HOOKS.filters, true ); // Current action/filter functions. -export const currentAction = () => HOOKS.actions.__current[0] || null; -export const currentFilter = () => HOOKS.filters.__current[0] || null; +export const currentAction = createCurrentHook( HOOKS.actions ); +export const currentFilter = createCurrentHook( HOOKS.filters ); // Doing action/filter: true while a hook is being run. export const doingAction = createDoingHook( HOOKS.actions ); diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 6c6289b3bced4..e2ebcd2d99bdd 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -391,7 +391,7 @@ test( 'current filter when multiple filters are running', () => { return value.concat( currentFilter() ); } ); - expect( applyFilters( 'test.filter1', [ 'test' ] ) ).toBe( + expect( applyFilters( 'test.filter1', [ 'test' ] ) ).toEqual( [ 'test', 'test.filter1', 'test.filter2' ] ); } ); From c11003c73d84a3b1c7fadafbd385ba997d5a16ba Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 17:23:06 +0200 Subject: [PATCH 099/393] Add more `currentFilter` test assertions --- packages/hooks/src/test/index.test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index e2ebcd2d99bdd..9d1da8c00f4c7 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -391,7 +391,11 @@ test( 'current filter when multiple filters are running', () => { return value.concat( currentFilter() ); } ); + expect( currentFilter() ).toBe( null ); + expect( applyFilters( 'test.filter1', [ 'test' ] ) ).toEqual( [ 'test', 'test.filter1', 'test.filter2' ] ); + + expect( currentFilter() ).toBe( null ); } ); From ad098726b206f68ae08defd74c3b077276f15828 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 17:24:15 +0200 Subject: [PATCH 100/393] Remove `wp-hooks.js` entry point This logic needs to be generated by Webpack instead. Otherwise something like it will end up being duplicated and manually maintained for every module in this repo. --- packages/hooks/src/wp-hooks.js | 41 ---------------------------------- 1 file changed, 41 deletions(-) delete mode 100644 packages/hooks/src/wp-hooks.js diff --git a/packages/hooks/src/wp-hooks.js b/packages/hooks/src/wp-hooks.js deleted file mode 100644 index 3f0461d2efca8..0000000000000 --- a/packages/hooks/src/wp-hooks.js +++ /dev/null @@ -1,41 +0,0 @@ -import HOOKS from './hooks'; -import { - addAction, - addFilter, - removeAction, - removeFilter, - removeAllActions, - removeAllFilters, - hasAction, - hasFilter, - doAction, - applyFilters, - currentAction, - currentFilter, - doingAction, - doingFilter, - didAction, - didFilter -} from './'; - -const hooks = { - addAction, - addFilter, - removeAction, - removeFilter, - removeAllActions, - removeAllFilters, - hasAction, - hasFilter, - doAction, - applyFilters, - currentAction, - currentFilter, - doingAction, - doingFilter, - didAction, - didFilter -} - -window.wp = window.wp || {}; -window.wp.hooks = hooks; From a80a4dfa43e5b30edf1a40304cbde213ee2abc0e Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 17:26:18 +0200 Subject: [PATCH 101/393] Disable Travis Slack notifications for PR builds (#19) --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index c50f49f6d2e00..83891f417bd9c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,3 +13,4 @@ notifications: on_start: never on_success: change on_failure: always + on_pull_requests: false From 0498ee8a0b2256c3fb9c87036f6555491579ce5b Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 17:42:29 +0200 Subject: [PATCH 102/393] Prevent hook names from starting with `__` This would break some of the library's internal functionality. --- packages/hooks/src/createAddHook.js | 5 +++++ packages/hooks/src/test/index.test.js | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index 30ceda75c2540..42bffcab8db62 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -19,6 +19,11 @@ function createAddHook( hooks ) { return; } + if ( /^__/.test( hookName ) ) { + console.error( 'The hook name cannot begin with `__`.' ); + return; + } + if ( typeof callback !== 'function' ) { console.error( 'The hook callback must be a function.' ); return; diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 9d1da8c00f4c7..9c54c2701593f 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -1,3 +1,5 @@ +/* eslint-disable no-console */ + /** * Internal dependencies */ @@ -60,6 +62,8 @@ function action_c() { window.actionValue += 'c'; } +const consoleErrorOriginal = console.error; + beforeEach( () => { window.actionValue = ''; // Reset state in between tests (clear all callbacks, `didAction` counts, @@ -70,6 +74,11 @@ beforeEach( () => { delete hooks[ k ]; } } ); + console.error = jest.fn(); +} ); + +afterEach( () => { + console.error = consoleErrorOriginal; } ); test( 'add and remove a filter', () => { @@ -89,6 +98,14 @@ test( 'add 2 filters in a row and run them', () => { expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); } ); +test( 'cannot add filters named with __ prefix' , () => { + addFilter( '__test', () => null ); + expect( console.error ).toHaveBeenCalledWith( + 'The hook name cannot begin with `__`.' + ); + expect( applyFilters( '__test', 42 ) ).toBe( 42 ); +} ); + test( 'add 3 filters with different priorities and run them', () => { addFilter( 'test.filter', filter_a ); addFilter( 'test.filter', filter_b, 2 ); From 5b8c5f30fce4bf6d8ec0b2897d4ddd1b825b534d Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 17:45:10 +0200 Subject: [PATCH 103/393] Prevent running hooks with invalid names --- packages/hooks/src/createRunHook.js | 10 ++++++++++ packages/hooks/src/test/index.test.js | 10 ++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/hooks/src/createRunHook.js b/packages/hooks/src/createRunHook.js index d7af0eb62d1f3..81f1ea6525702 100644 --- a/packages/hooks/src/createRunHook.js +++ b/packages/hooks/src/createRunHook.js @@ -19,6 +19,16 @@ function createRunHook( hooks, returnFirstArg ) { * @return {*} Return value of runner, if applicable. */ return function runHooks( hookName, ...args ) { + if ( typeof hookName !== 'string' ) { + console.error( 'The hook name must be a string.' ); + return; + } + + if ( /^__/.test( hookName ) ) { + console.error( 'The hook name cannot begin with `__`.' ); + return; + } + if ( ! hooks.hasOwnProperty( hookName ) ) { hooks[ hookName ] = { runs: 0, diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 9c54c2701593f..d0a309733670c 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -98,12 +98,18 @@ test( 'add 2 filters in a row and run them', () => { expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); } ); -test( 'cannot add filters named with __ prefix' , () => { +test( 'cannot add filters named with __ prefix', () => { addFilter( '__test', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The hook name cannot begin with `__`.' ); - expect( applyFilters( '__test', 42 ) ).toBe( 42 ); +} ); + +test( 'cannot run filters named with __ prefix', () => { + expect( applyFilters( '__test', 42 ) ).toBe( undefined ); + expect( console.error ).toHaveBeenCalledWith( + 'The hook name cannot begin with `__`.' + ); } ); test( 'add 3 filters with different priorities and run them', () => { From 6327a542be626cad9d6e6ed97a2f0d15b8df7f5a Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 17:52:51 +0200 Subject: [PATCH 104/393] Add missing tests for error conditions --- packages/hooks/src/test/index.test.js | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index d0a309733670c..0c77bb1be00c9 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -98,6 +98,13 @@ test( 'add 2 filters in a row and run them', () => { expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); } ); +test( 'cannot add filters with non-string names', () => { + addFilter( 42, () => null ); + expect( console.error ).toHaveBeenCalledWith( + 'The hook name must be a string.' + ); +} ); + test( 'cannot add filters named with __ prefix', () => { addFilter( '__test', () => null ); expect( console.error ).toHaveBeenCalledWith( @@ -105,6 +112,27 @@ test( 'cannot add filters named with __ prefix', () => { ); } ); +test( 'cannot add filters with non-function callbacks', () => { + addFilter( 'test', '42' ); + expect( console.error ).toHaveBeenCalledWith( + 'The hook callback must be a function.' + ); +} ); + +test( 'cannot add filters with non-numeric priorities', () => { + addFilter( 'test', () => null, '42' ); + expect( console.error ).toHaveBeenCalledWith( + 'If specified, the hook priority must be a number.' + ); +} ); + +test( 'cannot run filters with non-string names', () => { + expect( applyFilters( () => {}, 42 ) ).toBe( undefined ); + expect( console.error ).toHaveBeenCalledWith( + 'The hook name must be a string.' + ); +} ); + test( 'cannot run filters named with __ prefix', () => { expect( applyFilters( '__test', 42 ) ).toBe( undefined ); expect( console.error ).toHaveBeenCalledWith( From dd10eab04e9a66ba6289b9ce021f3625bfd346d8 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 18:02:18 +0200 Subject: [PATCH 105/393] Make hook removal functions return the number of hooks removed --- packages/hooks/src/createRemoveHook.js | 10 +++++++++- packages/hooks/src/test/index.test.js | 22 ++++++++++++++-------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/packages/hooks/src/createRemoveHook.js b/packages/hooks/src/createRemoveHook.js index a136ca299171f..245e9e0fc0887 100644 --- a/packages/hooks/src/createRemoveHook.js +++ b/packages/hooks/src/createRemoveHook.js @@ -16,14 +16,19 @@ function createRemoveHook( hooks, removeAll ) { * @param {?Function} callback The specific callback to be removed. If * omitted (and `removeAll` is truthy), clears * all callbacks. + * + * @return {number} The number of callbacks removed. */ return function removeHook( hookName, callback ) { // Bail if no hooks exist by this name if ( ! hooks.hasOwnProperty( hookName ) ) { - return; + return 0; } + let handlersRemoved = 0; + if ( removeAll ) { + handlersRemoved = hooks[ hookName ].handlers.length; hooks[ hookName ] = { runs: hooks[ hookName ].runs, handlers: [], @@ -34,9 +39,12 @@ function createRemoveHook( hooks, removeAll ) { for ( let i = handlers.length - 1; i >= 0; i-- ) { if ( handlers[ i ].callback === callback ) { handlers.splice( i, 1 ); + handlersRemoved++; } } } + + return handlersRemoved; }; } diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 0c77bb1be00c9..3939eb04f5159 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -83,8 +83,9 @@ afterEach( () => { test( 'add and remove a filter', () => { addFilter( 'test.filter', filter_a ); - removeAllFilters( 'test.filter' ); + expect( removeAllFilters( 'test.filter' ) ).toEqual( 1 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); + expect( removeAllFilters( 'test.filter' ) ).toEqual( 0 ); } ); test( 'add a filter and run it', () => { @@ -98,6 +99,11 @@ test( 'add 2 filters in a row and run them', () => { expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); } ); +test( 'remove a non-existent filter', () => { + expect( removeFilter( 'test.filter', filter_a ) ).toEqual( 0 ); + expect( removeAllFilters( 'test.filter' ) ).toEqual( 0 ); +} ); + test( 'cannot add filters with non-string names', () => { addFilter( 42, () => null ); expect( console.error ).toHaveBeenCalledWith( @@ -198,7 +204,7 @@ test( 'filters with the same and different priorities', () => { test( 'add and remove an action', () => { addAction( 'test.action', action_a ); - removeAllActions( 'test.action' ); + expect( removeAllActions( 'test.action' ) ).toEqual( 1 ); doAction( 'test.action' ); expect( window.actionValue ).toBe( '' ); } ); @@ -252,7 +258,7 @@ test( 'remove specific action callback', () => { addAction( 'test.action', action_b, 2 ); addAction( 'test.action', action_c, 8 ); - removeAction( 'test.action', action_b ); + expect( removeAction( 'test.action', action_b ) ).toEqual( 1 ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'ca' ); } ); @@ -262,7 +268,7 @@ test( 'remove all action callbacks', () => { addAction( 'test.action', action_b, 2 ); addAction( 'test.action', action_c, 8 ); - removeAllActions( 'test.action' ); + expect( removeAllActions( 'test.action' ) ).toEqual( 3 ); doAction( 'test.action' ); expect( window.actionValue ).toBe( '' ); } ); @@ -272,7 +278,7 @@ test( 'remove specific filter callback', () => { addFilter( 'test.filter', filter_b, 2 ); addFilter( 'test.filter', filter_c, 8 ); - removeFilter( 'test.filter', filter_b ); + expect( removeFilter( 'test.filter', filter_b ) ).toEqual( 1 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testca' ); } ); @@ -334,7 +340,7 @@ test( 'remove all filter callbacks', () => { addFilter( 'test.filter', filter_b, 2 ); addFilter( 'test.filter', filter_c, 8 ); - removeAllFilters( 'test.filter' ); + expect( removeAllFilters( 'test.filter' ) ).toEqual( 3 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); } ); @@ -379,7 +385,7 @@ test( 'Test doingAction, didAction and hasAction.', () => { expect( actionCalls ).toBe( 2 ); expect( didAction( 'test.action' ) ).toBe( 2 ); - removeAllActions( 'test.action' ); + expect( removeAllActions( 'test.action' ) ).toEqual( 1 ); // Verify state is reset appropriately. expect( doingAction( 'test.action' ) ).toBe( false ); @@ -416,7 +422,7 @@ test( 'Verify doingFilter, didFilter and hasFilter.', () => { expect( doingFilter( 'notatest.filter' ) ).toBe( false ); expect( currentFilter() ).toBe( null ); - removeAllFilters( 'runtest.filter' ); + expect( removeAllFilters( 'runtest.filter' ) ).toEqual( 1 ); expect( hasFilter( 'runtest.filter' ) ).toBe( 0 ); expect( didFilter( 'runtest.filter' ) ).toBe( 1 ); From 8be21e550b486e9d5650c972e9c3d9d8a27f28ab Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 18:05:15 +0200 Subject: [PATCH 106/393] Ensure that hook callbacks to remove are functions This will need to change later, but for now we should still make sure we validate our expected inputs strictly. --- packages/hooks/src/createRemoveHook.js | 7 ++++++- packages/hooks/src/test/index.test.js | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/hooks/src/createRemoveHook.js b/packages/hooks/src/createRemoveHook.js index 245e9e0fc0887..6e0a3cc73b003 100644 --- a/packages/hooks/src/createRemoveHook.js +++ b/packages/hooks/src/createRemoveHook.js @@ -20,6 +20,11 @@ function createRemoveHook( hooks, removeAll ) { * @return {number} The number of callbacks removed. */ return function removeHook( hookName, callback ) { + if ( ! removeAll && typeof callback !== 'function' ) { + console.error( 'The hook callback to remove must be a function.' ); + return; + } + // Bail if no hooks exist by this name if ( ! hooks.hasOwnProperty( hookName ) ) { return 0; @@ -33,7 +38,7 @@ function createRemoveHook( hooks, removeAll ) { runs: hooks[ hookName ].runs, handlers: [], }; - } else if ( callback ) { + } else { // Try to find the specified callback to remove. const handlers = hooks[ hookName ].handlers; for ( let i = handlers.length - 1; i >= 0; i-- ) { diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 3939eb04f5159..060f4f5adc511 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -104,6 +104,13 @@ test( 'remove a non-existent filter', () => { expect( removeAllFilters( 'test.filter' ) ).toEqual( 0 ); } ); +test( 'remove an invalid callback from a filter', () => { + expect( removeFilter( 'test.filter', 42 ) ).toEqual( undefined ); + expect( console.error ).toHaveBeenCalledWith( + 'The hook callback to remove must be a function.' + ); +} ); + test( 'cannot add filters with non-string names', () => { addFilter( 42, () => null ); expect( console.error ).toHaveBeenCalledWith( From 70b3ebc3c417cddc6f718cbb6047e820ae4eabef Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 18:06:47 +0200 Subject: [PATCH 107/393] Test running a filter with no callbacks --- packages/hooks/src/test/index.test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 060f4f5adc511..5f4ef3c79b5b0 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -81,6 +81,10 @@ afterEach( () => { console.error = consoleErrorOriginal; } ); +test( 'run a filter with no callbacks', () => { + expect( applyFilters( 'test.filter', 42 ) ).toEqual( 42 ); +} ); + test( 'add and remove a filter', () => { addFilter( 'test.filter', filter_a ); expect( removeAllFilters( 'test.filter' ) ).toEqual( 1 ); From a3b49019a14aa7849bc178ef60471239d072eab4 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 18:40:09 +0200 Subject: [PATCH 108/393] `doAction` should return `undefined` --- packages/hooks/src/createRunHook.js | 2 -- packages/hooks/src/test/index.test.js | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/hooks/src/createRunHook.js b/packages/hooks/src/createRunHook.js index 81f1ea6525702..74a12f7e257e9 100644 --- a/packages/hooks/src/createRunHook.js +++ b/packages/hooks/src/createRunHook.js @@ -68,8 +68,6 @@ function createRunHook( hooks, returnFirstArg ) { if ( returnFirstArg ) { return maybeReturnValue; - } else { - return false; } }; } diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 5f4ef3c79b5b0..c56cf059e93e8 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -216,7 +216,7 @@ test( 'filters with the same and different priorities', () => { test( 'add and remove an action', () => { addAction( 'test.action', action_a ); expect( removeAllActions( 'test.action' ) ).toEqual( 1 ); - doAction( 'test.action' ); + expect( doAction( 'test.action' ) ).toBe( undefined ); expect( window.actionValue ).toBe( '' ); } ); From 6653227ec4ce9b4f8087e8b81d3c5283d9e46d3c Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 19:05:45 +0200 Subject: [PATCH 109/393] Add failing test for recursive filters --- packages/hooks/src/test/index.test.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index c56cf059e93e8..bd9c3e799ca5d 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -467,3 +467,19 @@ test( 'current filter when multiple filters are running', () => { expect( currentFilter() ).toBe( null ); } ); + +test( 'adding and removing filters with recursion', () => { + function removeRecurseAndAdd2( val ) { + expect( removeFilter( 'remove_and_add', removeRecurseAndAdd2 ) ).toEqual( 1 ); + val += '-' + applyFilters( 'remove_and_add', '' ) + '-'; + addFilter( 'remove_and_add', removeRecurseAndAdd2, 11 ); + return val + '2'; + } + + addFilter( 'remove_and_add', val => val + '1', 11 ); + addFilter( 'remove_and_add', removeRecurseAndAdd2, 11 ); + addFilter( 'remove_and_add', val => val + '3', 11 ); + addFilter( 'remove_and_add', val => val + '4', 12 ); + + expect( applyFilters( 'remove_and_add', '' ) ).toEqual( '1-134-234' ); +} ); From 2e9b96ea166fe4ee00704efa93d0951197b89437 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 19:56:55 +0200 Subject: [PATCH 110/393] First attempt at handling adding/removing callbacks during execution Also allows recursion. --- packages/hooks/src/createAddHook.js | 11 +++++++++++ packages/hooks/src/createCurrentHook.js | 2 +- packages/hooks/src/createDoingHook.js | 2 +- packages/hooks/src/createRemoveHook.js | 12 ++++++++++++ packages/hooks/src/createRunHook.js | 26 ++++++++++++------------- 5 files changed, 38 insertions(+), 15 deletions(-) diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index 42bffcab8db62..c5aceaafdf392 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -49,6 +49,17 @@ function createAddHook( hooks ) { } // Insert (or append) the new hook. handlers.splice( i, 0, handler ); + // We may also be currently executing this hook. If the callback + // we're adding would come after the current callback, there's no + // problem; otherwise we need to increase the execution index of + // any other runs by 1 to account for the added element. + ( hooks.__current || [] ) + .filter( hookInfo => hookInfo.name === hookName ) + .forEach( hookInfo => { + if ( hookInfo.currentIndex >= i ) { + hookInfo.currentIndex++; + } + } ); } else { // This is the first hook of its type. hooks[ hookName ] = { diff --git a/packages/hooks/src/createCurrentHook.js b/packages/hooks/src/createCurrentHook.js index e5ff3519f370f..2df265f44cf6f 100644 --- a/packages/hooks/src/createCurrentHook.js +++ b/packages/hooks/src/createCurrentHook.js @@ -20,7 +20,7 @@ function createCurrentHook( hooks, returnFirstArg ) { return null; } - return hooks.__current[ hooks.__current.length - 1 ]; + return hooks.__current[ hooks.__current.length - 1 ].name; }; } diff --git a/packages/hooks/src/createDoingHook.js b/packages/hooks/src/createDoingHook.js index 860b657c9a469..d27f2faa9ead1 100644 --- a/packages/hooks/src/createDoingHook.js +++ b/packages/hooks/src/createDoingHook.js @@ -24,7 +24,7 @@ function createDoingHook( hooks ) { // Return the __current hook. return hooks.__current[0] - ? hookName === hooks.__current[0] + ? hookName === hooks.__current[0].name : false; }; } diff --git a/packages/hooks/src/createRemoveHook.js b/packages/hooks/src/createRemoveHook.js index 6e0a3cc73b003..8e92b94eddb94 100644 --- a/packages/hooks/src/createRemoveHook.js +++ b/packages/hooks/src/createRemoveHook.js @@ -45,6 +45,18 @@ function createRemoveHook( hooks, removeAll ) { if ( handlers[ i ].callback === callback ) { handlers.splice( i, 1 ); handlersRemoved++; + // This callback may also be part of a hook that is + // currently executing. If the callback we're removing + // comes after the current callback, there's no problem; + // otherwise we need to decrease the execution index of any + // other runs by 1 to account for the removed element. + ( hooks.__current || [] ) + .filter( hookInfo => hookInfo.name === hookName ) + .forEach( hookInfo => { + if ( hookInfo.currentIndex >= i ) { + hookInfo.currentIndex--; + } + } ); } } } diff --git a/packages/hooks/src/createRunHook.js b/packages/hooks/src/createRunHook.js index 74a12f7e257e9..31dccd30a5475 100644 --- a/packages/hooks/src/createRunHook.js +++ b/packages/hooks/src/createRunHook.js @@ -44,25 +44,25 @@ function createRunHook( hooks, returnFirstArg ) { : undefined; } + const hookInfo = { + name: hookName, + currentIndex: 0, + }; + hooks.__current = hooks.__current || []; - hooks.__current.push( hookName ); + hooks.__current.push( hookInfo ); hooks[ hookName ].runs++; let maybeReturnValue = args[ 0 ]; - handlers.forEach( handler => { - if ( handler.callback !== hooks.currentCallback ) { - - // Prevent hook recursion. - hooks.currentCallback = handler.callback; - maybeReturnValue = handler.callback.apply( null, args ); - hooks.currentCallback = false; - - if ( returnFirstArg ) { - args[ 0 ] = maybeReturnValue; - } + while ( hookInfo.currentIndex < handlers.length ) { + const handler = handlers[ hookInfo.currentIndex ]; + maybeReturnValue = handler.callback.apply( null, args ); + if ( returnFirstArg ) { + args[ 0 ] = maybeReturnValue; } - } ); + hookInfo.currentIndex++; + } hooks.__current.pop(); From 54f70c1e3787a675253a59ff554e93bb4fe276ac Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 19:57:35 +0200 Subject: [PATCH 111/393] Make the filter adding/removing/recursion test pass --- packages/hooks/src/test/index.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index bd9c3e799ca5d..e26d90dd40ea5 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -472,14 +472,14 @@ test( 'adding and removing filters with recursion', () => { function removeRecurseAndAdd2( val ) { expect( removeFilter( 'remove_and_add', removeRecurseAndAdd2 ) ).toEqual( 1 ); val += '-' + applyFilters( 'remove_and_add', '' ) + '-'; - addFilter( 'remove_and_add', removeRecurseAndAdd2, 11 ); + addFilter( 'remove_and_add', removeRecurseAndAdd2, 10 ); return val + '2'; } addFilter( 'remove_and_add', val => val + '1', 11 ); - addFilter( 'remove_and_add', removeRecurseAndAdd2, 11 ); - addFilter( 'remove_and_add', val => val + '3', 11 ); - addFilter( 'remove_and_add', val => val + '4', 12 ); + addFilter( 'remove_and_add', removeRecurseAndAdd2, 12 ); + addFilter( 'remove_and_add', val => val + '3', 13 ); + addFilter( 'remove_and_add', val => val + '4', 14 ); expect( applyFilters( 'remove_and_add', '' ) ).toEqual( '1-134-234' ); } ); From afa92ea9a97876be19140b4e0c5515048d681830 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 20:36:08 +0200 Subject: [PATCH 112/393] Minor style and speed improvement --- packages/hooks/src/createAddHook.js | 12 +++++------- packages/hooks/src/createRemoveHook.js | 12 +++++------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index c5aceaafdf392..36ec8a6709a36 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -53,13 +53,11 @@ function createAddHook( hooks ) { // we're adding would come after the current callback, there's no // problem; otherwise we need to increase the execution index of // any other runs by 1 to account for the added element. - ( hooks.__current || [] ) - .filter( hookInfo => hookInfo.name === hookName ) - .forEach( hookInfo => { - if ( hookInfo.currentIndex >= i ) { - hookInfo.currentIndex++; - } - } ); + ( hooks.__current || [] ).forEach( hookInfo => { + if ( hookInfo.name === hookName && hookInfo.currentIndex >= i ) { + hookInfo.currentIndex++; + } + } ); } else { // This is the first hook of its type. hooks[ hookName ] = { diff --git a/packages/hooks/src/createRemoveHook.js b/packages/hooks/src/createRemoveHook.js index 8e92b94eddb94..6cb8d47c1b9aa 100644 --- a/packages/hooks/src/createRemoveHook.js +++ b/packages/hooks/src/createRemoveHook.js @@ -50,13 +50,11 @@ function createRemoveHook( hooks, removeAll ) { // comes after the current callback, there's no problem; // otherwise we need to decrease the execution index of any // other runs by 1 to account for the removed element. - ( hooks.__current || [] ) - .filter( hookInfo => hookInfo.name === hookName ) - .forEach( hookInfo => { - if ( hookInfo.currentIndex >= i ) { - hookInfo.currentIndex--; - } - } ); + ( hooks.__current || [] ).forEach( hookInfo => { + if ( hookInfo.name === hookName && hookInfo.currentIndex >= i ) { + hookInfo.currentIndex--; + } + } ); } } } From 0919ab9eef6bdb7d8cdaf6f7d6c44b4c12e67960 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Mon, 24 Jul 2017 20:50:30 +0200 Subject: [PATCH 113/393] Add missing tests --- packages/hooks/src/test/index.test.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index e26d90dd40ea5..7b3cafcebd6b1 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -264,6 +264,33 @@ test( 'fire action multiple times', () => { doAction( 'test.action' ); } ); +test( 'add a filter before the one currently executing', () => { + addFilter( 'test.filter', val => { + addFilter( 'test.filter', val => val + 'a', 1 ); + return val + 'b'; + }, 2 ); + + expect( applyFilters( 'test.filter', 'test_' ) ).toEqual( 'test_b' ); +} ); + +test( 'add a filter after the one currently executing', () => { + addFilter( 'test.filter', val => { + addFilter( 'test.filter', val => val + 'b', 2 ); + return val + 'a'; + }, 1 ); + + expect( applyFilters( 'test.filter', 'test_' ) ).toEqual( 'test_ab' ); +} ); + +test( 'add a filter immediately after the one currently executing', () => { + addFilter( 'test.filter', val => { + addFilter( 'test.filter', val => val + 'b', 1 ); + return val + 'a'; + }, 1 ); + + expect( applyFilters( 'test.filter', 'test_' ) ).toEqual( 'test_ab' ); +} ); + test( 'remove specific action callback', () => { addAction( 'test.action', action_a ); addAction( 'test.action', action_b, 2 ); From b9961a4c9889d4ca27fed33d00f003e5ee460c66 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 25 Jul 2017 15:13:51 +0100 Subject: [PATCH 114/393] URL: Adding a README for the URL Package --- packages/url/README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 packages/url/README.md diff --git a/packages/url/README.md b/packages/url/README.md new file mode 100644 index 0000000000000..59f5faa93cb2c --- /dev/null +++ b/packages/url/README.md @@ -0,0 +1,20 @@ +# WordPress URL Package + +A collection of utilities to manipulate URLs + +## Installation + +Install the module + +```bash +npm install @wordpress/url --save +``` + +## Usage + +```JS +import { addQueryArgs } from '@wordpress/url'; + +// Appends arguments to the query string of a given url +const newUrl = addQueryArgs( 'https://google.com', { q: 'test' } ); // https://google.com/?q=test +``` From b5cf4a19d3f4c16b1dfc53a9a89d5c160ea71b78 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Tue, 25 Jul 2017 17:07:17 +0200 Subject: [PATCH 115/393] Update readme --- packages/a11y-speak/README.md | 46 ++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/packages/a11y-speak/README.md b/packages/a11y-speak/README.md index 6c4497e67e276..74485819d6515 100644 --- a/packages/a11y-speak/README.md +++ b/packages/a11y-speak/README.md @@ -1,37 +1,43 @@ -# a11y-speak -Allows you to easily announce dynamic interface updates to screen readers using ARIA live regions. This module is inspired by wp-a11y.js +# @wordpress/a11y +Collection of JS modules for enhancing accessibility. + +## speak + +Allows you to easily announce dynamic interface updates to screen readers using ARIA live regions. This module is inspired by the `speak` function in wp-a11y.js + +### Usage + +To make the `wp.a11y.speak` functionality more universally available, we've decided to create a dedicated JS module for it, called `speak`. Usage is very simple: + +```JS +import { speak } from '@wordpress/a11y'; + +// For polite messages that shouldn't interrupt what screen readers are currently announcing. +speak( 'The message you want to send to the ARIA live region' ); + +// For assertive messages that should interrupt what screen readers are currently announcing. +speak( 'The message you want to send to the ARIA live region', 'assertive' ); +``` + +### Background For context I'll quote [this article on WordPress.org](https://make.wordpress.org/accessibility/2015/04/15/let-wordpress-speak-new-in-wordpress-4-2/) by [@joedolson](https://github.com/joedolson): -> ## Why. +> #### Why. > In modern web development, updating discrete regions of a screen with JavaScript is common. The use of AJAX responses in modern JavaScript-based User Interfaces allows web developers to create beautiful interfaces similar to Desktop applications that don’t require pages to reload or refresh. > JavaScript can create great usability improvements for most users – but when content is updated dynamically, it has the potential to introduce accessibility issues. This is one of the steps you can take to handle that problem. -> ## What. +> #### What. > When a portion of a page is updated with JavaScript, the update is usually highlighted with animation and bright colors, and is easy to see. But if you don’t have the ability to see the screen, you don’t know this has happened, unless the updated region is marked as an ARIA-live region. > If this isn’t marked, there’s no notification for screen readers. But it’s also possible that all the region content will be announced after an update, if the ARIA live region is too large. You want to provide users with just a simple, concise message. -> ## How. +> #### How. > That’s what `wp.a11y.speak()` is meant for. It’s a simple tool that creates and appends an ARIA live notifications area to the element where developers can dispatch text messages. Assistive technologies will automatically announce any text change in this area. This ARIA live region has an ARIA role of “status” so it has an implicit aria-live value of polite and an implicit aria-atomic value of true. > This means assistive technologies will notify users of updates but generally do not interrupt the current task, and updates take low priority. If you’re creating an application with higher priority updates (such as a notification that their current session is about to expire, for example), then you’ll want to create your own method with an aria-live value of assertive. -## Usage - -To make the `wp.a11y.speak` functionality more universally available, we've decided to create a dedicated JS module for it, called `A11ySpeak`. Usage is very simple: - -```JS -var A11ySpeak = require('A11ySpeak'); - -// For polite messages that shouldn't interrupt what screen readers are currently announcing. -A11ySpeak( 'The message you want to send to the ARIA live region' ); - -// For assertive messages that should interrupt what screen readers are currently announcing. -A11ySpeak( 'The message you want to send to the ARIA live region', 'assertive' ); -``` - ## Browser support -IE9+ and all modern browsers. +See https://make.wordpress.org/design/handbook/design-guide/browser-support/ From 9e676f9fbdff5a9b428e621bf8c67662e7b6f287 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Tue, 25 Jul 2017 17:11:19 +0200 Subject: [PATCH 116/393] rename module to a11y --- packages/{a11y-speak => a11y}/README.md | 0 packages/{a11y-speak => a11y}/package.json | 7 +++---- packages/{a11y-speak => a11y}/src/addContainer.js | 0 packages/{a11y-speak => a11y}/src/clear.js | 0 packages/{a11y-speak => a11y}/src/domReady.js | 0 packages/{a11y-speak => a11y}/src/filterMessage.js | 0 packages/{a11y-speak => a11y}/src/index.js | 4 +--- .../{a11y-speak => a11y}/src/test/addContainer.test.js | 0 packages/{a11y-speak => a11y}/src/test/clear.test.js | 0 packages/{a11y-speak => a11y}/src/test/domReady.test.js | 0 .../{a11y-speak => a11y}/src/test/filterMessage.test.js | 0 packages/{a11y-speak => a11y}/src/test/index.test.js | 0 12 files changed, 4 insertions(+), 7 deletions(-) rename packages/{a11y-speak => a11y}/README.md (100%) rename packages/{a11y-speak => a11y}/package.json (60%) rename packages/{a11y-speak => a11y}/src/addContainer.js (100%) rename packages/{a11y-speak => a11y}/src/clear.js (100%) rename packages/{a11y-speak => a11y}/src/domReady.js (100%) rename packages/{a11y-speak => a11y}/src/filterMessage.js (100%) rename packages/{a11y-speak => a11y}/src/index.js (94%) rename packages/{a11y-speak => a11y}/src/test/addContainer.test.js (100%) rename packages/{a11y-speak => a11y}/src/test/clear.test.js (100%) rename packages/{a11y-speak => a11y}/src/test/domReady.test.js (100%) rename packages/{a11y-speak => a11y}/src/test/filterMessage.test.js (100%) rename packages/{a11y-speak => a11y}/src/test/index.test.js (100%) diff --git a/packages/a11y-speak/README.md b/packages/a11y/README.md similarity index 100% rename from packages/a11y-speak/README.md rename to packages/a11y/README.md diff --git a/packages/a11y-speak/package.json b/packages/a11y/package.json similarity index 60% rename from packages/a11y-speak/package.json rename to packages/a11y/package.json index c7b837e1b64f3..2b948d75477b4 100644 --- a/packages/a11y-speak/package.json +++ b/packages/a11y/package.json @@ -1,8 +1,8 @@ { - "name": "@wordpress/a11y-speak", + "name": "@wordpress/a11y", "version": "0.0.1", - "description": "Easily announce dynamic interface updates to screen readers using ARIA live regions.", - "homepage": "https://github.com/WordPress/packages/packages/a11y-speak/README.md", + "description": "Collection of JS modules and tools for WordPress development", + "homepage": "https://github.com/WordPress/packages/tree/master/packages/a11y/README.md", "author": "WordPress", "keywords": [ "a11y", @@ -11,7 +11,6 @@ "main": "build/index.js", "module": "build-module/index.js", "browser": "build-browser/index.js", - "license": "GPL-2.0+", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" diff --git a/packages/a11y-speak/src/addContainer.js b/packages/a11y/src/addContainer.js similarity index 100% rename from packages/a11y-speak/src/addContainer.js rename to packages/a11y/src/addContainer.js diff --git a/packages/a11y-speak/src/clear.js b/packages/a11y/src/clear.js similarity index 100% rename from packages/a11y-speak/src/clear.js rename to packages/a11y/src/clear.js diff --git a/packages/a11y-speak/src/domReady.js b/packages/a11y/src/domReady.js similarity index 100% rename from packages/a11y-speak/src/domReady.js rename to packages/a11y/src/domReady.js diff --git a/packages/a11y-speak/src/filterMessage.js b/packages/a11y/src/filterMessage.js similarity index 100% rename from packages/a11y-speak/src/filterMessage.js rename to packages/a11y/src/filterMessage.js diff --git a/packages/a11y-speak/src/index.js b/packages/a11y/src/index.js similarity index 94% rename from packages/a11y-speak/src/index.js rename to packages/a11y/src/index.js index c0152cf6c9e19..59cf1b9bc9618 100644 --- a/packages/a11y-speak/src/index.js +++ b/packages/a11y/src/index.js @@ -32,7 +32,7 @@ domReady( setup ); * @param {String} ariaLive Optional. The politeness level for aria-live. Possible values: * polite or assertive. Default polite. */ -const A11ySpeak = function( message, ariaLive ) { +export const speak = function( message, ariaLive ) { // Clear previous messages to allow repeated strings being read out. clear(); @@ -44,5 +44,3 @@ const A11ySpeak = function( message, ariaLive ) { containerPolite.textContent = message; } }; - -export default A11ySpeak; diff --git a/packages/a11y-speak/src/test/addContainer.test.js b/packages/a11y/src/test/addContainer.test.js similarity index 100% rename from packages/a11y-speak/src/test/addContainer.test.js rename to packages/a11y/src/test/addContainer.test.js diff --git a/packages/a11y-speak/src/test/clear.test.js b/packages/a11y/src/test/clear.test.js similarity index 100% rename from packages/a11y-speak/src/test/clear.test.js rename to packages/a11y/src/test/clear.test.js diff --git a/packages/a11y-speak/src/test/domReady.test.js b/packages/a11y/src/test/domReady.test.js similarity index 100% rename from packages/a11y-speak/src/test/domReady.test.js rename to packages/a11y/src/test/domReady.test.js diff --git a/packages/a11y-speak/src/test/filterMessage.test.js b/packages/a11y/src/test/filterMessage.test.js similarity index 100% rename from packages/a11y-speak/src/test/filterMessage.test.js rename to packages/a11y/src/test/filterMessage.test.js diff --git a/packages/a11y-speak/src/test/index.test.js b/packages/a11y/src/test/index.test.js similarity index 100% rename from packages/a11y-speak/src/test/index.test.js rename to packages/a11y/src/test/index.test.js From 6dbcd630ce97efae40ea5d759603b0bba9694a09 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Tue, 25 Jul 2017 17:12:40 +0200 Subject: [PATCH 117/393] Fix unit tests --- packages/a11y/src/test/index.test.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/a11y/src/test/index.test.js b/packages/a11y/src/test/index.test.js index 291aca0e9f269..60b8f77ba40ab 100644 --- a/packages/a11y/src/test/index.test.js +++ b/packages/a11y/src/test/index.test.js @@ -1,4 +1,4 @@ -import A11ySpeak from '../'; +import { speak } from '../'; jest.mock( '../clear', () => { return jest.fn(); @@ -14,7 +14,7 @@ import clear from '../clear'; import domReady from '../domReady'; import filterMessage from '../filterMessage'; -describe( 'A11ySpeak', () => { +describe( 'speak', () => { let containerPolite = document.getElementById( 'a11y-speak-polite' ); let containerAssertive = document.getElementById( 'a11y-speak-assertive' ); @@ -31,7 +31,7 @@ describe( 'A11ySpeak', () => { describe( 'in default mode', () => { it( 'should set the textcontent of the polite aria-live region', () => { - A11ySpeak( 'default message' ); + speak( 'default message' ); expect( containerPolite.textContent ).toBe( 'default message' ); expect( containerAssertive.textContent ).toBe( '' ); expect( clear ).toHaveBeenCalled(); @@ -41,7 +41,7 @@ describe( 'A11ySpeak', () => { describe( 'in assertive mode', () => { it( 'should set the textcontent of the assertive aria-live region', () => { - A11ySpeak( 'assertive message', 'assertive' ); + speak( 'assertive message', 'assertive' ); expect( containerPolite.textContent ).toBe( '' ); expect( containerAssertive.textContent ).toBe( 'assertive message' ); } ); @@ -49,7 +49,7 @@ describe( 'A11ySpeak', () => { describe( 'in explicit polite mode', () => { it( 'should set the textcontent of the polite aria-live region', () => { - A11ySpeak( 'polite message', 'polite' ); + speak( 'polite message', 'polite' ); expect( containerPolite.textContent ).toBe( 'polite message' ); expect( containerAssertive.textContent ).toBe( '' ); } ); From ac798cf0b261fb34f4a0d03f2dfd04f47a750941 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Wed, 26 Jul 2017 18:06:24 +0200 Subject: [PATCH 118/393] Move domReady module to its own package. --- packages/a11y/src/index.js | 2 +- packages/a11y/src/test/index.test.js | 4 +-- packages/domReady/README.md | 25 +++++++++++++++++++ packages/domReady/package.json | 21 ++++++++++++++++ .../src/domReady.js => domReady/src/index.js} | 0 .../src/test/domReady.test.js | 2 +- 6 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 packages/domReady/README.md create mode 100644 packages/domReady/package.json rename packages/{a11y/src/domReady.js => domReady/src/index.js} (100%) rename packages/{a11y => domReady}/src/test/domReady.test.js (88%) diff --git a/packages/a11y/src/index.js b/packages/a11y/src/index.js index 59cf1b9bc9618..9e4135a124c19 100644 --- a/packages/a11y/src/index.js +++ b/packages/a11y/src/index.js @@ -1,6 +1,6 @@ import addContainer from './addContainer'; import clear from './clear'; -import domReady from './domReady'; +import domReady from '../../domReady/src/'; import filterMessage from './filterMessage'; let containerPolite, containerAssertive = ''; diff --git a/packages/a11y/src/test/index.test.js b/packages/a11y/src/test/index.test.js index 60b8f77ba40ab..425526648c734 100644 --- a/packages/a11y/src/test/index.test.js +++ b/packages/a11y/src/test/index.test.js @@ -3,7 +3,7 @@ import { speak } from '../'; jest.mock( '../clear', () => { return jest.fn(); } ); -jest.mock( '../domReady', () => { +jest.mock( '../../../domReady/src/', () => { return jest.fn( ( callback ) => { callback(); } ); } ); jest.mock( '../filterMessage', () => { @@ -11,7 +11,7 @@ jest.mock( '../filterMessage', () => { } ); import clear from '../clear'; -import domReady from '../domReady'; +import domReady from '../../../domReady/src/'; import filterMessage from '../filterMessage'; describe( 'speak', () => { diff --git a/packages/domReady/README.md b/packages/domReady/README.md new file mode 100644 index 0000000000000..3e132701d3bbf --- /dev/null +++ b/packages/domReady/README.md @@ -0,0 +1,25 @@ +# @wordpress/domReady + +Executes a function after the DOM has loaded. + +## Installation + +Install the module + +```bash +npm install @wordpress/domReady --save +``` + +### Usage + +```JS +import domReady from '@wordpress/domReady'; + +domReady( function() { + //do something after DOM loads. +} ); +``` + +## Browser support + +See https://make.wordpress.org/design/handbook/design-guide/browser-support/ diff --git a/packages/domReady/package.json b/packages/domReady/package.json new file mode 100644 index 0000000000000..256ba47923b0f --- /dev/null +++ b/packages/domReady/package.json @@ -0,0 +1,21 @@ +{ + "name": "@wordpress/domReady", + "version": "0.0.1", + "description": "Execute callback after the DOM is loaded.", + "homepage": "https://github.com/WordPress/packages/tree/master/packages/domReady/README.md", + "author": "WordPress", + "keywords": [ + "DOM", + "Readystate" + ], + "main": "build/index.js", + "module": "build-module/index.js", + "browser": "build-browser/index.js", + "repository": { + "type": "git", + "url": "https://github.com/WordPress/packages.git" + }, + "bugs": { + "url": "https://github.com/WordPress/packages/issues" + } +} diff --git a/packages/a11y/src/domReady.js b/packages/domReady/src/index.js similarity index 100% rename from packages/a11y/src/domReady.js rename to packages/domReady/src/index.js diff --git a/packages/a11y/src/test/domReady.test.js b/packages/domReady/src/test/domReady.test.js similarity index 88% rename from packages/a11y/src/test/domReady.test.js rename to packages/domReady/src/test/domReady.test.js index 10fbe31aaf30e..70a6e6b517641 100644 --- a/packages/a11y/src/test/domReady.test.js +++ b/packages/domReady/src/test/domReady.test.js @@ -1,4 +1,4 @@ -import domReady from '../domReady'; +import domReady from '../'; let callback = jest.fn( () => {} ); From 173604f7c4291f2373d77cdf66782fa969afa52e Mon Sep 17 00:00:00 2001 From: omarreiss Date: Wed, 26 Jul 2017 18:06:39 +0200 Subject: [PATCH 119/393] Add installation section to a11y package. --- packages/a11y/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/a11y/README.md b/packages/a11y/README.md index 74485819d6515..45a4c0aa2bfcc 100644 --- a/packages/a11y/README.md +++ b/packages/a11y/README.md @@ -2,6 +2,14 @@ Collection of JS modules for enhancing accessibility. +## Installation + +Install the module + +```bash +npm install @wordpress/a11y --save +``` + ## speak Allows you to easily announce dynamic interface updates to screen readers using ARIA live regions. This module is inspired by the `speak` function in wp-a11y.js From a60dc7093b2348fd7d8cd8935d2bc1bad03c5fb5 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Wed, 26 Jul 2017 19:55:50 +0200 Subject: [PATCH 120/393] Just depend on domReady already. Lerna will do the magic :heart_eyes_cat: --- packages/a11y/package.json | 5 ++++- packages/a11y/src/index.js | 2 +- packages/a11y/src/test/index.test.js | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/a11y/package.json b/packages/a11y/package.json index 2b948d75477b4..4b8ea72ed1342 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -17,5 +17,8 @@ }, "bugs": { "url": "https://github.com/WordPress/packages/issues" - } + }, + "dependencies": { + "@wordpress/domReady": "^0.0.1" + } } diff --git a/packages/a11y/src/index.js b/packages/a11y/src/index.js index 9e4135a124c19..982acfb7a0549 100644 --- a/packages/a11y/src/index.js +++ b/packages/a11y/src/index.js @@ -1,6 +1,6 @@ import addContainer from './addContainer'; import clear from './clear'; -import domReady from '../../domReady/src/'; +import domReady from '@wordpress/domReady'; import filterMessage from './filterMessage'; let containerPolite, containerAssertive = ''; diff --git a/packages/a11y/src/test/index.test.js b/packages/a11y/src/test/index.test.js index 425526648c734..258a8b0f2239c 100644 --- a/packages/a11y/src/test/index.test.js +++ b/packages/a11y/src/test/index.test.js @@ -3,7 +3,7 @@ import { speak } from '../'; jest.mock( '../clear', () => { return jest.fn(); } ); -jest.mock( '../../../domReady/src/', () => { +jest.mock( '@wordpress/domReady', () => { return jest.fn( ( callback ) => { callback(); } ); } ); jest.mock( '../filterMessage', () => { @@ -11,7 +11,7 @@ jest.mock( '../filterMessage', () => { } ); import clear from '../clear'; -import domReady from '../../../domReady/src/'; +import domReady from '@wordpress/domReady'; import filterMessage from '../filterMessage'; describe( 'speak', () => { From afe05d52063765b506f58145a3882d2ff603c430 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Wed, 26 Jul 2017 20:11:33 +0200 Subject: [PATCH 121/393] rename domReady.test.js to index.test.js --- packages/domReady/src/test/{domReady.test.js => index.test.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/domReady/src/test/{domReady.test.js => index.test.js} (100%) diff --git a/packages/domReady/src/test/domReady.test.js b/packages/domReady/src/test/index.test.js similarity index 100% rename from packages/domReady/src/test/domReady.test.js rename to packages/domReady/src/test/index.test.js From 9d42f85a25560524d5ede92e4ab04765877b54db Mon Sep 17 00:00:00 2001 From: omarreiss Date: Wed, 26 Jul 2017 21:12:06 +0200 Subject: [PATCH 122/393] Add testcase for domReady package that tests the loading readystate --- packages/domReady/src/test/index.test.js | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/domReady/src/test/index.test.js b/packages/domReady/src/test/index.test.js index 70a6e6b517641..ad090522d3fc6 100644 --- a/packages/domReady/src/test/index.test.js +++ b/packages/domReady/src/test/index.test.js @@ -1,12 +1,30 @@ import domReady from '../'; -let callback = jest.fn( () => {} ); - describe( 'domReady', () => { describe( 'when document readystate is complete', () => { it( 'should call the callback.', () => { + let callback = jest.fn( () => {} ); + domReady( callback ); expect( callback ).toHaveBeenCalled(); } ); } ); + + describe( 'when document readystate is still loading', () => { + it( 'should add the callback as an event listener to the DOMContentLoaded event.', () => { + let addEventListener = jest.fn( () => {} ); + + Object.defineProperty(document, 'readyState', { + value: 'loading' + } ); + Object.defineProperty(document, 'addEventListener', { + value: addEventListener + } ); + + let callback = jest.fn( () => {} ); + domReady( callback ); + expect( callback ).not.toHaveBeenCalled(); + expect( addEventListener ).toHaveBeenCalledWith( 'DOMContentLoaded', callback ); + } ); + } ); } ); From ebd25627a7c29f85e90a3e407842db087b6cdfbc Mon Sep 17 00:00:00 2001 From: omarreiss Date: Thu, 27 Jul 2017 09:57:39 +0200 Subject: [PATCH 123/393] package name should not contain uppercase letter --- packages/{domReady => dom-ready}/README.md | 0 packages/{domReady => dom-ready}/package.json | 2 +- packages/{domReady => dom-ready}/src/index.js | 0 packages/{domReady => dom-ready}/src/test/index.test.js | 0 4 files changed, 1 insertion(+), 1 deletion(-) rename packages/{domReady => dom-ready}/README.md (100%) rename packages/{domReady => dom-ready}/package.json (93%) rename packages/{domReady => dom-ready}/src/index.js (100%) rename packages/{domReady => dom-ready}/src/test/index.test.js (100%) diff --git a/packages/domReady/README.md b/packages/dom-ready/README.md similarity index 100% rename from packages/domReady/README.md rename to packages/dom-ready/README.md diff --git a/packages/domReady/package.json b/packages/dom-ready/package.json similarity index 93% rename from packages/domReady/package.json rename to packages/dom-ready/package.json index 256ba47923b0f..abb8531615a82 100644 --- a/packages/domReady/package.json +++ b/packages/dom-ready/package.json @@ -1,5 +1,5 @@ { - "name": "@wordpress/domReady", + "name": "@wordpress/dom-ready", "version": "0.0.1", "description": "Execute callback after the DOM is loaded.", "homepage": "https://github.com/WordPress/packages/tree/master/packages/domReady/README.md", diff --git a/packages/domReady/src/index.js b/packages/dom-ready/src/index.js similarity index 100% rename from packages/domReady/src/index.js rename to packages/dom-ready/src/index.js diff --git a/packages/domReady/src/test/index.test.js b/packages/dom-ready/src/test/index.test.js similarity index 100% rename from packages/domReady/src/test/index.test.js rename to packages/dom-ready/src/test/index.test.js From 1eb07eca2324fc776ea1a34d7f6a61127137512a Mon Sep 17 00:00:00 2001 From: omarreiss Date: Thu, 27 Jul 2017 11:50:23 +0200 Subject: [PATCH 124/393] bootstrap and build packages before running the tests. --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 83891f417bd9c..411cc075760fe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,9 @@ node_js: - '8' - '6' -script: npm run test:coverage-ci +script: + - lerna bootstrap && npm run build + - npm run test:coverage-ci notifications: slack: From 8c8b21fce22ceed7635a684e2ce41469024df937 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Thu, 27 Jul 2017 11:55:09 +0200 Subject: [PATCH 125/393] Make sure a11y package requires the renamed domReady module. --- packages/a11y/package.json | 2 +- packages/a11y/src/index.js | 2 +- packages/a11y/src/test/index.test.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/a11y/package.json b/packages/a11y/package.json index 4b8ea72ed1342..3e57dbbab4db0 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -19,6 +19,6 @@ "url": "https://github.com/WordPress/packages/issues" }, "dependencies": { - "@wordpress/domReady": "^0.0.1" + "@wordpress/dom-ready": "^0.0.1" } } diff --git a/packages/a11y/src/index.js b/packages/a11y/src/index.js index 982acfb7a0549..6473df4d97c67 100644 --- a/packages/a11y/src/index.js +++ b/packages/a11y/src/index.js @@ -1,6 +1,6 @@ import addContainer from './addContainer'; import clear from './clear'; -import domReady from '@wordpress/domReady'; +import domReady from '@wordpress/dom-ready'; import filterMessage from './filterMessage'; let containerPolite, containerAssertive = ''; diff --git a/packages/a11y/src/test/index.test.js b/packages/a11y/src/test/index.test.js index 258a8b0f2239c..991b870410210 100644 --- a/packages/a11y/src/test/index.test.js +++ b/packages/a11y/src/test/index.test.js @@ -3,7 +3,7 @@ import { speak } from '../'; jest.mock( '../clear', () => { return jest.fn(); } ); -jest.mock( '@wordpress/domReady', () => { +jest.mock( '@wordpress/dom-ready', () => { return jest.fn( ( callback ) => { callback(); } ); } ); jest.mock( '../filterMessage', () => { @@ -11,7 +11,7 @@ jest.mock( '../filterMessage', () => { } ); import clear from '../clear'; -import domReady from '@wordpress/domReady'; +import domReady from '@wordpress/dom-ready'; import filterMessage from '../filterMessage'; describe( 'speak', () => { From 7afeaa39e7bde8c464568c826c597d50316a223e Mon Sep 17 00:00:00 2001 From: omarreiss Date: Thu, 27 Jul 2017 13:39:49 +0200 Subject: [PATCH 126/393] No need to support low ie versions. --- packages/dom-ready/src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dom-ready/src/index.js b/packages/dom-ready/src/index.js index 20afbeb8b9d97..329f9ebf26d99 100644 --- a/packages/dom-ready/src/index.js +++ b/packages/dom-ready/src/index.js @@ -6,7 +6,7 @@ * @returns {void} */ const domReady = function( callback ) { - if ( document.readyState === 'complete' || ( document.readyState !== 'loading' && !document.documentElement.doScroll ) ) { + if ( document.readyState === 'complete' ) { return callback(); } From 96df82774b3e3d34fd6f85565c2648659f6034ef Mon Sep 17 00:00:00 2001 From: omarreiss Date: Thu, 27 Jul 2017 14:53:47 +0200 Subject: [PATCH 127/393] improve coverage take 1 --- packages/a11y/src/index.js | 11 ++-- packages/a11y/src/test/addContainer.test.js | 58 ++++++++++++++------- packages/a11y/src/test/index.test.js | 47 ++++++++++++++++- 3 files changed, 92 insertions(+), 24 deletions(-) diff --git a/packages/a11y/src/index.js b/packages/a11y/src/index.js index 6473df4d97c67..de1788119eb3f 100644 --- a/packages/a11y/src/index.js +++ b/packages/a11y/src/index.js @@ -3,14 +3,12 @@ import clear from './clear'; import domReady from '@wordpress/dom-ready'; import filterMessage from './filterMessage'; -let containerPolite, containerAssertive = ''; - /** * Create the live regions. */ -const setup = function() { - containerPolite = document.getElementById( 'a11y-speak-polite' ); - containerAssertive = document.getElementById( 'a11y-speak-assertive' ); +export const setup = function() { + let containerPolite = document.getElementById( 'a11y-speak-polite' ); + let containerAssertive = document.getElementById( 'a11y-speak-assertive' ); if ( containerPolite === null ) { containerPolite = addContainer( 'polite' ); @@ -38,6 +36,9 @@ export const speak = function( message, ariaLive ) { message = filterMessage( message ); + let containerPolite = document.getElementById( 'a11y-speak-polite' ); + let containerAssertive = document.getElementById( 'a11y-speak-assertive' ); + if ( containerAssertive && 'assertive' === ariaLive ) { containerAssertive.textContent = message; } else if ( containerPolite ) { diff --git a/packages/a11y/src/test/addContainer.test.js b/packages/a11y/src/test/addContainer.test.js index 476a7ef191e0a..ccd0b845312bc 100644 --- a/packages/a11y/src/test/addContainer.test.js +++ b/packages/a11y/src/test/addContainer.test.js @@ -1,23 +1,45 @@ import addContainer from '../addContainer'; describe( 'addContainer', () => { - it( 'should create an aria-live element', () => { - let containerPolite = addContainer( 'polite' ); - let containerAssertive = addContainer( 'assertive' ); + describe( 'with polite param', () => { + it( 'should create an aria-live element with aria-live attr set to polite', () => { + let container = addContainer( 'polite' ); - expect( containerPolite ).not.toBe( null ); - expect( containerAssertive ).not.toBe( null ); - expect( containerPolite.className ).toBe( 'a11y-speak-region' ); - expect( containerAssertive.className ).toBe( 'a11y-speak-region' ); - expect( containerPolite.id ).toBe( 'a11y-speak-polite' ); - expect( containerAssertive.id ).toBe( 'a11y-speak-assertive' ); - expect( containerPolite.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); - expect( containerAssertive.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); - expect( containerPolite.getAttribute( 'aria-live' ) ).toBe( 'polite' ); - expect( containerAssertive.getAttribute( 'aria-live' ) ).toBe( 'assertive' ); - expect( containerPolite.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); - expect( containerAssertive.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); - expect( containerPolite.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); - expect( containerAssertive.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); - } ); + expect( container ).not.toBe( null ); + expect( container.className ).toBe( 'a11y-speak-region' ); + expect( container.id ).toBe( 'a11y-speak-polite' ); + expect( container.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); + expect( container.getAttribute( 'aria-live' ) ).toBe( 'polite' ); + expect( container.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); + expect( container.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); + } ); + } ); + + describe( 'with assertive param', () => { + it( 'should create an aria-live element with aria-live attr set to assertive', () => { + let container = addContainer( 'assertive' ); + + expect( container ).not.toBe( null ); + expect( container.className ).toBe( 'a11y-speak-region' ); + expect( container.id ).toBe( 'a11y-speak-assertive' ); + expect( container.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); + expect( container.getAttribute( 'aria-live' ) ).toBe( 'assertive' ); + expect( container.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); + expect( container.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); + } ); + } ); + + describe( 'without param', () => { + it( 'should default to creating an aria-live element with aria-live attr set to polite', () => { + let container = addContainer( 'polite' ); + + expect( container ).not.toBe( null ); + expect( container.className ).toBe( 'a11y-speak-region' ); + expect( container.id ).toBe( 'a11y-speak-polite' ); + expect( container.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); + expect( container.getAttribute( 'aria-live' ) ).toBe( 'polite' ); + expect( container.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); + expect( container.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); + } ); + } ); } ); diff --git a/packages/a11y/src/test/index.test.js b/packages/a11y/src/test/index.test.js index 991b870410210..03704c336debe 100644 --- a/packages/a11y/src/test/index.test.js +++ b/packages/a11y/src/test/index.test.js @@ -1,4 +1,4 @@ -import { speak } from '../'; +import { setup, speak } from '../'; jest.mock( '../clear', () => { return jest.fn(); @@ -54,4 +54,49 @@ describe( 'speak', () => { expect( containerAssertive.textContent ).toBe( '' ); } ); } ); + + describe( 'when somehow the assertive container is not present', () => { + beforeEach( () => { + document.getElementById( 'a11y-speak-assertive' ).remove(); + } ); + + afterEach( () => { + setup(); + containerAssertive = document.getElementById( 'a11y-speak-assertive' ); + } ); + + it( 'should set the textcontent of the polite aria-live region', () => { + speak( 'message', 'assertive' ); + expect( containerPolite.textContent ).toBe( 'message' ); + expect( document.getElementById( 'a11y-speak-assertive' ) ).toBe( null ); + } ); + } ); + + describe( 'when somehow the both containers are not present', () => { + beforeEach( () => { + containerAssertive.remove(); + containerPolite.remove(); + } ); + + afterEach( () => { + setup(); + containerPolite = document.getElementById( 'a11y-speak-polite' ); + containerAssertive = document.getElementById( 'a11y-speak-assertive' ); + } ); + + it( 'should set the textcontent of the polite aria-live region', () => { + expect( document.getElementById( 'a11y-speak-polite' ) ).toBe( null ); + expect( document.getElementById( 'a11y-speak-assertive' ) ).toBe( null ); + } ); + } ); + + describe( 'setup when the elements already exist', () => { + it( 'should not create the aria live regions again', () => { + let before = document.getElementsByClassName( 'a11y-speak-region' ).length; + setup(); + let after = document.getElementsByClassName( 'a11y-speak-region' ).length; + + expect( before ).toBe( after ); + } ); + } ); } ); From 64fed30dbc1b6f7434b4afff6d28ecc5e6e65be3 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 27 Jul 2017 15:50:38 +0100 Subject: [PATCH 128/393] Switch code coverage from coveralls to codecov (#22) --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1539a667031f7..099698d670ab4 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-env": "^1.5.2", "chalk": "^2.0.1", - "coveralls": "^2.13.1", + "codecov": "^2.2.0", "glob": "^7.1.2", "jest": "^20.0.4", "lerna": "^2.0.0", @@ -26,7 +26,7 @@ "build": "node ./scripts/build.js", "test": "jest", "test:coverage": "jest --coverage", - "test:coverage-ci": "jest --coverage && coveralls < coverage/lcov.info", + "test:coverage-ci": "jest --coverage && codecov", "test:watch": "jest --watch" } } From e195bc1df38d1cf9c1b0a24f69122977f360abb0 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 27 Jul 2017 16:05:49 +0100 Subject: [PATCH 129/393] Fix initialization from a fresh repo clone (#16) --- .nvmrc | 1 + package-lock.json | 5262 ++++++++++++++++++++++++++++++++ packages/url/package-lock.json | 27 + scripts/build.js | 8 +- 4 files changed, 5294 insertions(+), 4 deletions(-) create mode 100644 .nvmrc create mode 100644 package-lock.json create mode 100644 packages/url/package-lock.json diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000000000..a00f43e3090a7 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v8 diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000000..3cff4d2562f62 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,5262 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "abab": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.3.tgz", + "integrity": "sha1-uB3l9ydOxOdW15fNg08wNkJyTl0=", + "dev": true + }, + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + }, + "acorn-globals": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", + "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", + "dev": true, + "requires": { + "acorn": "4.0.13" + } + }, + "add-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", + "integrity": "sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=", + "dev": true + }, + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "anymatch": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz", + "integrity": "sha1-o+Uvo5FoyCX/V7AkgSbOWo/5VQc=", + "dev": true, + "requires": { + "arrify": "1.0.1", + "micromatch": "2.3.11" + } + }, + "append-transform": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", + "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", + "dev": true, + "requires": { + "default-require-extensions": "1.0.0" + } + }, + "aproba": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.2.tgz", + "integrity": "sha512-ZpYajIfO0j2cOFTO955KUMIKNmj6zhX8kVztMAxFsDaMwz+9Z9SV0uou2pC9HJqcfpffOsjnbrDMvkNy+9RXPw==", + "dev": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", + "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", + "dev": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.3.3" + } + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", + "dev": true + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "dev": true + }, + "async": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", + "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", + "dev": true, + "requires": { + "lodash": "4.17.4" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "dev": true + }, + "aws4": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", + "dev": true + }, + "babel-code-frame": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", + "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + } + } + }, + "babel-core": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.25.0.tgz", + "integrity": "sha1-fdQrBGPHQunVKW3rPsZ6kyLa1yk=", + "dev": true, + "requires": { + "babel-code-frame": "6.22.0", + "babel-generator": "6.25.0", + "babel-helpers": "6.24.1", + "babel-messages": "6.23.0", + "babel-register": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "babylon": "6.17.4", + "convert-source-map": "1.5.0", + "debug": "2.6.8", + "json5": "0.5.1", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "path-is-absolute": "1.0.1", + "private": "0.1.7", + "slash": "1.0.0", + "source-map": "0.5.6" + } + }, + "babel-generator": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.25.0.tgz", + "integrity": "sha1-M6GvcNXyiQrrRlpKd5PB32qeqfw=", + "dev": true, + "requires": { + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "detect-indent": "4.0.0", + "jsesc": "1.3.0", + "lodash": "4.17.4", + "source-map": "0.5.6", + "trim-right": "1.0.1" + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "dev": true, + "requires": { + "babel-helper-explode-assignable-expression": "6.24.1", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.23.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-helper-define-map": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.24.1.tgz", + "integrity": "sha1-epdH8ljYlH0y1RX2qhx70CIEoIA=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "lodash": "4.17.4" + } + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "dev": true, + "requires": { + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } + }, + "babel-helper-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz", + "integrity": "sha1-024i+rEAjXnYhkjjIRaGgShFbOg=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "lodash": "4.17.4" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "dev": true, + "requires": { + "babel-helper-optimise-call-expression": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } + }, + "babel-jest": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-20.0.3.tgz", + "integrity": "sha1-5KA7E9wQOJ4UD8ZF0J/8TO0wFnE=", + "dev": true, + "requires": { + "babel-core": "6.25.0", + "babel-plugin-istanbul": "4.1.4", + "babel-preset-jest": "20.0.3" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.4.tgz", + "integrity": "sha1-GN3oS/POMp/d8/QQP66SFFbY5Yc=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "istanbul-lib-instrument": "1.7.4", + "test-exclude": "4.1.1" + } + }, + "babel-plugin-jest-hoist": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-20.0.3.tgz", + "integrity": "sha1-r+3IU70/jcNUjqZx++adA8wsF2c=", + "dev": true + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", + "dev": true + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", + "dev": true + }, + "babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", + "dev": true + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "dev": true + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "6.24.1", + "babel-plugin-syntax-async-functions": "6.13.0", + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz", + "integrity": "sha1-dsKV3DpHQbFmWt/TFnIV3P8ypXY=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "lodash": "4.17.4" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "dev": true, + "requires": { + "babel-helper-define-map": "6.24.1", + "babel-helper-function-name": "6.24.1", + "babel-helper-optimise-call-expression": "6.24.1", + "babel-helper-replace-supers": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz", + "integrity": "sha1-0+MQtA72ZKNmIiAAl8bUQCmPK/4=", + "dev": true, + "requires": { + "babel-plugin-transform-strict-mode": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "dev": true, + "requires": { + "babel-helper-replace-supers": "6.24.1", + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "dev": true, + "requires": { + "babel-helper-call-delegate": "6.24.1", + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "dev": true, + "requires": { + "babel-helper-regex": "6.24.1", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "dev": true, + "requires": { + "babel-helper-regex": "6.24.1", + "babel-runtime": "6.23.0", + "regexpu-core": "2.0.0" + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "dev": true, + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", + "babel-plugin-syntax-exponentiation-operator": "6.13.0", + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.23.0.tgz", + "integrity": "sha1-h11ryb52HFiirj/u5dxIldjH+SE=", + "dev": true, + "requires": { + "babel-plugin-syntax-object-rest-spread": "6.13.0", + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz", + "integrity": "sha1-uNowWtQ8PJm0hI5P5AN7dw0jxBg=", + "dev": true, + "requires": { + "regenerator-transform": "0.9.11" + } + }, + "babel-plugin-transform-runtime": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz", + "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } + }, + "babel-preset-env": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.0.tgz", + "integrity": "sha512-OVgtQRuOZKckrILgMA5rvctvFZPv72Gua9Rt006AiPoB0DJKGN07UmaQA+qRrYgK71MVct8fFhT0EyNWYorVew==", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-syntax-trailing-function-commas": "6.22.0", + "babel-plugin-transform-async-to-generator": "6.24.1", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.24.1", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-exponentiation-operator": "6.24.1", + "babel-plugin-transform-regenerator": "6.24.1", + "browserslist": "2.2.0", + "invariant": "2.2.2", + "semver": "5.3.0" + } + }, + "babel-preset-jest": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-20.0.3.tgz", + "integrity": "sha1-y6yq3stdaJyh4d4TYOv8ZoYsF4o=", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "20.0.3" + } + }, + "babel-register": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.24.1.tgz", + "integrity": "sha1-fhDhOi9xBlvfrVoXh7pFvKbe118=", + "dev": true, + "requires": { + "babel-core": "6.25.0", + "babel-runtime": "6.23.0", + "core-js": "2.4.1", + "home-or-tmp": "2.0.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "source-map-support": "0.4.15" + } + }, + "babel-runtime": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", + "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=", + "dev": true, + "requires": { + "core-js": "2.4.1", + "regenerator-runtime": "0.10.5" + } + }, + "babel-template": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.25.0.tgz", + "integrity": "sha1-ZlJBFmt8KqTGGdceGSlpVSsQwHE=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "babylon": "6.17.4", + "lodash": "4.17.4" + } + }, + "babel-traverse": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.25.0.tgz", + "integrity": "sha1-IldJfi/NGbie3BPEyROB+VEklvE=", + "dev": true, + "requires": { + "babel-code-frame": "6.22.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "babylon": "6.17.4", + "debug": "2.6.8", + "globals": "9.18.0", + "invariant": "2.2.2", + "lodash": "4.17.4" + } + }, + "babel-types": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.25.0.tgz", + "integrity": "sha1-cK+ySNVmDl0Y+BHZHIMDtUE0oY4=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "esutils": "2.0.2", + "lodash": "4.17.4", + "to-fast-properties": "1.0.3" + } + }, + "babylon": { + "version": "6.17.4", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.17.4.tgz", + "integrity": "sha512-kChlV+0SXkjE0vUn9OZ7pBMWRFd8uq3mZe8x1K6jhuNcAFAtEnjchFAqB+dYEXKyd+JpT6eppRR78QAr5gTsUw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "browser-resolve": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", + "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browserslist": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.2.0.tgz", + "integrity": "sha512-t09UuOv/4/hrL1y4wZ871+kKE6E2bkdMD6duZtV7FZIHFpsmdQfW63BH3bAjkfpkbP/eFKyenUbDUKigV/VmRw==", + "dev": true, + "requires": { + "caniuse-lite": "1.0.30000704", + "electron-to-chromium": "1.3.16" + } + }, + "bser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", + "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", + "dev": true, + "requires": { + "node-int64": "0.4.0" + } + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "byline": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", + "integrity": "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=", + "dev": true + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true, + "optional": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + } + } + }, + "caniuse-lite": { + "version": "1.0.30000704", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000704.tgz", + "integrity": "sha1-rbbqARNFFWY2gtuTq6spHUwClGs=", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "optional": true, + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } + }, + "chalk": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.0.1.tgz", + "integrity": "sha512-Mp+FXEI+FrwY/XYV45b2YD3E8i3HwnEAoFcM0qlZzq/RZ9RwWitt2Y/c7cqRAz70U7hfekqx6qNYthuKFO6K0g==", + "dev": true, + "requires": { + "ansi-styles": "3.1.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.1.0.tgz", + "integrity": "sha1-CcIC1ckX7CMYjKpcnLkXnNlUd1A=", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "supports-color": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.0.tgz", + "integrity": "sha512-Ts0Mu/A1S1aZxEJNG88I4Oc9rcZSBFNac5e27yh4j2mqbhZSSzR1Ah79EYwSn9Zuh7lrlGD2cVGzw1RKGzyLSg==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "ci-info": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.0.0.tgz", + "integrity": "sha1-3FKF8rTiUYIWg2gcOBwziPRuxTQ=", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "2.0.0" + } + }, + "cli-width": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", + "integrity": "sha1-sjTKIJsp72b8UY2bmNWEewDt8Ao=", + "dev": true + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "optional": true, + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true, + "optional": true + } + } + }, + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "dev": true + }, + "cmd-shim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-2.0.2.tgz", + "integrity": "sha1-b8vamUg6j9FdfTChlspp1oii79s=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "mkdirp": "0.5.1" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "color-convert": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", + "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "columnify": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz", + "integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=", + "dev": true, + "requires": { + "strip-ansi": "3.0.1", + "wcwidth": "1.0.1" + } + }, + "combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "dev": true, + "requires": { + "delayed-stream": "1.0.0" + } + }, + "command-join": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/command-join/-/command-join-2.0.0.tgz", + "integrity": "sha1-Uui5hPSHLZUv8b3IuYOX0nxxRM8=", + "dev": true + }, + "compare-func": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.2.tgz", + "integrity": "sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg=", + "dev": true, + "requires": { + "array-ify": "1.0.0", + "dot-prop": "3.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "content-type-parser": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.1.tgz", + "integrity": "sha1-w+VpiMU8ZRJ/tG1AMqOpACRv3JQ=", + "dev": true + }, + "conventional-changelog": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-1.1.4.tgz", + "integrity": "sha1-EIvHUMKjF+IA4vm0E8qqH4x++js=", + "dev": true, + "requires": { + "conventional-changelog-angular": "1.4.0", + "conventional-changelog-atom": "0.1.1", + "conventional-changelog-codemirror": "0.1.0", + "conventional-changelog-core": "1.9.0", + "conventional-changelog-ember": "0.2.6", + "conventional-changelog-eslint": "0.1.0", + "conventional-changelog-express": "0.1.0", + "conventional-changelog-jquery": "0.1.0", + "conventional-changelog-jscs": "0.1.0", + "conventional-changelog-jshint": "0.1.0" + } + }, + "conventional-changelog-angular": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-1.4.0.tgz", + "integrity": "sha512-ukKX22lJl9ewogze1hKbBuff/dGMG2uyGpOhhw0ehhlv6GtdeCxj51YfGOZ5qC89WwsHT7SDXFzBKidwH3pwmQ==", + "dev": true, + "requires": { + "compare-func": "1.3.2", + "github-url-from-git": "1.5.0", + "q": "1.5.0", + "read-pkg-up": "2.0.0" + }, + "dependencies": { + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "2.3.0" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "read-pkg": "2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "conventional-changelog-atom": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-0.1.1.tgz", + "integrity": "sha512-6Nlu/+MiD4gi7k3Z+N1vMJWpaPSdvFPWzPGnH4OXewHAxiAl0L/TT9CGgA01fosPxmYr4hMNtD7kyN0tkg8vIA==", + "dev": true, + "requires": { + "q": "1.5.0" + } + }, + "conventional-changelog-cli": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/conventional-changelog-cli/-/conventional-changelog-cli-1.3.2.tgz", + "integrity": "sha512-Z89mXKV0IIB0q8tNvIIZtNNrun3MUuQC0YJPzsF2t5UyaqmqnOpLNLHX28+Pwi+aHI2LQjEar1OmEoZgYP+6Kw==", + "dev": true, + "requires": { + "add-stream": "1.0.0", + "conventional-changelog": "1.1.4", + "lodash": "4.17.4", + "meow": "3.7.0", + "tempfile": "1.1.1" + } + }, + "conventional-changelog-codemirror": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-0.1.0.tgz", + "integrity": "sha1-dXelkdv5tTjnoVCn7mL2WihyszQ=", + "dev": true, + "requires": { + "q": "1.5.0" + } + }, + "conventional-changelog-core": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-1.9.0.tgz", + "integrity": "sha1-3l37wJGEdlZQjUo4njXJobxJ5/Q=", + "dev": true, + "requires": { + "conventional-changelog-writer": "1.4.1", + "conventional-commits-parser": "1.3.0", + "dateformat": "1.0.12", + "get-pkg-repo": "1.4.0", + "git-raw-commits": "1.2.0", + "git-remote-origin-url": "2.0.0", + "git-semver-tags": "1.2.1", + "lodash": "4.17.4", + "normalize-package-data": "2.4.0", + "q": "1.5.0", + "read-pkg": "1.1.0", + "read-pkg-up": "1.0.1", + "through2": "2.0.3" + } + }, + "conventional-changelog-ember": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-0.2.6.tgz", + "integrity": "sha1-i3NVQZ9RJ0k8TFYkc6svx5LxwrY=", + "dev": true, + "requires": { + "q": "1.5.0" + } + }, + "conventional-changelog-eslint": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-0.1.0.tgz", + "integrity": "sha1-pSQR6ZngUBzlALhWsKZD0DMJB+I=", + "dev": true, + "requires": { + "q": "1.5.0" + } + }, + "conventional-changelog-express": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-0.1.0.tgz", + "integrity": "sha1-VcbIQcgRliA2wDe9vZZKVK4xD84=", + "dev": true, + "requires": { + "q": "1.5.0" + } + }, + "conventional-changelog-jquery": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-0.1.0.tgz", + "integrity": "sha1-Agg5cWLjhGmG5xJztsecW1+A9RA=", + "dev": true, + "requires": { + "q": "1.5.0" + } + }, + "conventional-changelog-jscs": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-jscs/-/conventional-changelog-jscs-0.1.0.tgz", + "integrity": "sha1-BHnrRDzH1yxYvwvPDvHURKkvDlw=", + "dev": true, + "requires": { + "q": "1.5.0" + } + }, + "conventional-changelog-jshint": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-0.1.0.tgz", + "integrity": "sha1-AMq46aMxdIer2UxNhGcTQpGNKgc=", + "dev": true, + "requires": { + "compare-func": "1.3.2", + "q": "1.5.0" + } + }, + "conventional-changelog-writer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-1.4.1.tgz", + "integrity": "sha1-P0y00APrtWmJ0w00WJO1KkNjnI4=", + "dev": true, + "requires": { + "compare-func": "1.3.2", + "conventional-commits-filter": "1.0.0", + "dateformat": "1.0.12", + "handlebars": "4.0.10", + "json-stringify-safe": "5.0.1", + "lodash": "4.17.4", + "meow": "3.7.0", + "semver": "5.3.0", + "split": "1.0.0", + "through2": "2.0.3" + } + }, + "conventional-commits-filter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-1.0.0.tgz", + "integrity": "sha1-b8KmWTcrw/IznPn//34bA0S5MDk=", + "dev": true, + "requires": { + "is-subset": "0.1.1", + "modify-values": "1.0.0" + } + }, + "conventional-commits-parser": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-1.3.0.tgz", + "integrity": "sha1-4ye1MZThp61dxjR57pCZpSsCSGU=", + "dev": true, + "requires": { + "is-text-path": "1.0.1", + "JSONStream": "1.3.1", + "lodash": "4.17.4", + "meow": "3.7.0", + "split2": "2.1.1", + "through2": "2.0.3", + "trim-off-newlines": "1.0.1" + } + }, + "conventional-recommended-bump": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-1.0.1.tgz", + "integrity": "sha512-2FrE8UJwt2EKpICi/E7P+xqyYUysdfMnFYiGV+7ANzJsixkBOrBKrKlCEV2NllCjR0XOmNfnA/mgozC5jAhhGQ==", + "dev": true, + "requires": { + "concat-stream": "1.6.0", + "conventional-commits-filter": "1.0.0", + "conventional-commits-parser": "2.0.0", + "git-raw-commits": "1.2.0", + "git-semver-tags": "1.2.1", + "meow": "3.7.0", + "object-assign": "4.1.1" + }, + "dependencies": { + "conventional-commits-parser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-2.0.0.tgz", + "integrity": "sha512-8od6g684Fhi5Vpp4ABRv/RBsW1AY6wSHbJHEK6FGTv+8jvAAnlABniZu/FVmX9TcirkHepaEsa1QGkRvbg0CKw==", + "dev": true, + "requires": { + "is-text-path": "1.0.1", + "JSONStream": "1.3.1", + "lodash": "4.17.4", + "meow": "3.7.0", + "split2": "2.1.1", + "through2": "2.0.3", + "trim-off-newlines": "1.0.1" + } + } + } + }, + "convert-source-map": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", + "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=", + "dev": true + }, + "core-js": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", + "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.2.14" + } + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dev": true, + "requires": { + "boom": "2.10.1" + } + }, + "cssom": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", + "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=", + "dev": true + }, + "cssstyle": { + "version": "0.2.37", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", + "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", + "dev": true, + "requires": { + "cssom": "0.3.2" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "1.0.2" + } + }, + "dargs": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-4.1.0.tgz", + "integrity": "sha1-A6nbtLXC8Tm/FK5T8LiipqhvThc=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "dateformat": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", + "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", + "dev": true, + "requires": { + "get-stdin": "4.0.1", + "meow": "3.7.0" + } + }, + "debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "default-require-extensions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", + "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", + "dev": true, + "requires": { + "strip-bom": "2.0.0" + } + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "1.0.2" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "diff": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.0.tgz", + "integrity": "sha512-w0XZubFWn0Adlsapj9EAWX0FqWdO4tz8kc3RiYdWLh4k/V8PTb6i0SMgXt0vRM3zyKnT8tKO7mUlieRQHIjMNg==", + "dev": true + }, + "dot-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", + "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", + "dev": true, + "requires": { + "is-obj": "1.0.1" + } + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "dev": true + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "electron-to-chromium": { + "version": "1.3.16", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.16.tgz", + "integrity": "sha1-0OAmc1dUdwkBrjAaIWZMukXZL30=", + "dev": true + }, + "errno": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", + "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=", + "dev": true, + "requires": { + "prr": "0.0.0" + } + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "dev": true, + "requires": { + "esprima": "2.7.3", + "estraverse": "1.9.3", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.2.0" + }, + "dependencies": { + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "exec-sh": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.0.tgz", + "integrity": "sha1-FPdd4/INKG75MwmbLOUKkDWc7xA=", + "dev": true, + "requires": { + "merge": "1.2.0" + } + }, + "execa": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.6.3.tgz", + "integrity": "sha1-V7aaWU8IF1nGnlNw8NF7nLEWWP4=", + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "2.2.3" + } + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true + }, + "external-editor": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.4.tgz", + "integrity": "sha1-HtkZnanL/i7y96MbL96LDRI2iXI=", + "dev": true, + "requires": { + "iconv-lite": "0.4.18", + "jschardet": "1.5.0", + "tmp": "0.0.31" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz", + "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==", + "dev": true + } + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "extsprintf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", + "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fb-watchman": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", + "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", + "dev": true, + "requires": { + "bser": "2.0.0" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fileset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", + "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "dev": true, + "requires": { + "glob": "7.1.2", + "minimatch": "3.0.4" + } + }, + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "1.0.2" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "dev": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.15" + } + }, + "fs-extra": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", + "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "3.0.1", + "universalify": "0.1.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "requires": { + "aproba": "1.1.2", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" + } + }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "dev": true + }, + "get-pkg-repo": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz", + "integrity": "sha1-xztInAbYDMVTbCyFP54FIyBWly0=", + "dev": true, + "requires": { + "hosted-git-info": "2.5.0", + "meow": "3.7.0", + "normalize-package-data": "2.4.0", + "parse-github-repo-url": "1.4.0", + "through2": "2.0.3" + } + }, + "get-port": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.1.0.tgz", + "integrity": "sha1-7wGxioTKZIaXD/meVERhQac//T4=", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "git-raw-commits": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-1.2.0.tgz", + "integrity": "sha1-DzqL/ZmuDy2LkiTViJKXXppS0Dw=", + "dev": true, + "requires": { + "dargs": "4.1.0", + "lodash.template": "4.4.0", + "meow": "3.7.0", + "split2": "2.1.1", + "through2": "2.0.3" + } + }, + "git-remote-origin-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", + "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=", + "dev": true, + "requires": { + "gitconfiglocal": "1.0.0", + "pify": "2.3.0" + } + }, + "git-semver-tags": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-1.2.1.tgz", + "integrity": "sha512-fFyxtzTHCTQKwB4clA2AInVrlflBbVbbJD4NWwmxKXHUgsU/K9kmHNlkPLqFiuy9xu9q3lNopghR4VXeQwZbTQ==", + "dev": true, + "requires": { + "meow": "3.7.0", + "semver": "5.3.0" + } + }, + "gitconfiglocal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", + "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=", + "dev": true, + "requires": { + "ini": "1.3.4" + } + }, + "github-url-from-git": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/github-url-from-git/-/github-url-from-git-1.5.0.tgz", + "integrity": "sha1-+YX+3MCpqledyI16/waNVcxiUaA=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true + }, + "handlebars": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz", + "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=", + "dev": true, + "requires": { + "async": "1.5.2", + "optimist": "0.6.1", + "source-map": "0.4.4", + "uglify-js": "2.8.29" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "har-schema": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", + "dev": true + }, + "har-validator": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "dev": true, + "requires": { + "ajv": "4.11.8", + "har-schema": "1.0.5" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dev": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "dev": true + }, + "html-encoding-sniffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.1.tgz", + "integrity": "sha1-eb96eF6klf5mFl5zQVPzY/9UN9o=", + "dev": true, + "requires": { + "whatwg-encoding": "1.0.1" + } + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "dev": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.0", + "sshpk": "1.13.1" + } + }, + "iconv-lite": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ini": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", + "dev": true + }, + "inquirer": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.2.0.tgz", + "integrity": "sha512-4CyUYMP7lOBkiUU1rR24WGrfRX6SucwbY2Mqb1PdApU24wnTIk4TsnkQwV72dDdIKZ2ycLP+fWCV+tA7wwgoew==", + "dev": true, + "requires": { + "ansi-escapes": "2.0.0", + "chalk": "2.0.1", + "cli-cursor": "2.1.0", + "cli-width": "2.1.0", + "external-editor": "2.0.4", + "figures": "2.0.0", + "lodash": "4.17.4", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rx-lite": "4.0.8", + "rx-lite-aggregates": "4.0.8", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "through": "2.3.8" + }, + "dependencies": { + "ansi-escapes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-2.0.0.tgz", + "integrity": "sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs=", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "invariant": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "dev": true, + "requires": { + "loose-envify": "1.3.1" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-ci": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", + "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", + "dev": true, + "requires": { + "ci-info": "1.0.0" + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-subset": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz", + "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=", + "dev": true + }, + "is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", + "dev": true, + "requires": { + "text-extensions": "1.5.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul-api": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.1.11.tgz", + "integrity": "sha1-/MC0YeKzvaceMFFVE4I4doJX2d4=", + "dev": true, + "requires": { + "async": "2.5.0", + "fileset": "2.0.3", + "istanbul-lib-coverage": "1.1.1", + "istanbul-lib-hook": "1.0.7", + "istanbul-lib-instrument": "1.7.4", + "istanbul-lib-report": "1.1.1", + "istanbul-lib-source-maps": "1.2.1", + "istanbul-reports": "1.1.1", + "js-yaml": "3.9.0", + "mkdirp": "0.5.1", + "once": "1.4.0" + } + }, + "istanbul-lib-coverage": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz", + "integrity": "sha512-0+1vDkmzxqJIn5rcoEqapSB4DmPxE31EtI2dF2aCkV5esN9EWHxZ0dwgDClivMXJqE7zaYQxq30hj5L0nlTN5Q==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz", + "integrity": "sha512-3U2HB9y1ZV9UmFlE12Fx+nPtFqIymzrqCksrXujm3NVbAZIJg/RfYgO1XiIa0mbmxTjWpVEVlkIZJ25xVIAfkQ==", + "dev": true, + "requires": { + "append-transform": "0.4.0" + } + }, + "istanbul-lib-instrument": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.4.tgz", + "integrity": "sha1-6f2SDkdn89Ge3HZeLWs/XMvQ7qg=", + "dev": true, + "requires": { + "babel-generator": "6.25.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "babylon": "6.17.4", + "istanbul-lib-coverage": "1.1.1", + "semver": "5.3.0" + } + }, + "istanbul-lib-report": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz", + "integrity": "sha512-tvF+YmCmH4thnez6JFX06ujIA19WPa9YUiwjc1uALF2cv5dmE3It8b5I8Ob7FHJ70H9Y5yF+TDkVa/mcADuw1Q==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "1.1.1", + "mkdirp": "0.5.1", + "path-parse": "1.0.5", + "supports-color": "3.2.3" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz", + "integrity": "sha512-mukVvSXCn9JQvdJl8wP/iPhqig0MRtuWuD4ZNKo6vB2Ik//AmhAKe3QnPN02dmkRe3lTudFk3rzoHhwU4hb94w==", + "dev": true, + "requires": { + "debug": "2.6.8", + "istanbul-lib-coverage": "1.1.1", + "mkdirp": "0.5.1", + "rimraf": "2.6.1", + "source-map": "0.5.6" + } + }, + "istanbul-reports": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.1.1.tgz", + "integrity": "sha512-P8G873A0kW24XRlxHVGhMJBhQ8gWAec+dae7ZxOBzxT4w+a9ATSPvRVK3LB1RAJ9S8bg2tOyWHAGW40Zd2dKfw==", + "dev": true, + "requires": { + "handlebars": "4.0.10" + } + }, + "jest": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest/-/jest-20.0.4.tgz", + "integrity": "sha1-PdJgwpidba1nix6cxNkZRPbWAqw=", + "dev": true, + "requires": { + "jest-cli": "20.0.4" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "jest-cli": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-20.0.4.tgz", + "integrity": "sha1-5TKxnYiuW8bEF+iwWTpv6VSx3JM=", + "dev": true, + "requires": { + "ansi-escapes": "1.4.0", + "callsites": "2.0.0", + "chalk": "1.1.3", + "graceful-fs": "4.1.11", + "is-ci": "1.0.10", + "istanbul-api": "1.1.11", + "istanbul-lib-coverage": "1.1.1", + "istanbul-lib-instrument": "1.7.4", + "istanbul-lib-source-maps": "1.2.1", + "jest-changed-files": "20.0.3", + "jest-config": "20.0.4", + "jest-docblock": "20.0.3", + "jest-environment-jsdom": "20.0.3", + "jest-haste-map": "20.0.4", + "jest-jasmine2": "20.0.4", + "jest-message-util": "20.0.3", + "jest-regex-util": "20.0.3", + "jest-resolve-dependencies": "20.0.3", + "jest-runtime": "20.0.4", + "jest-snapshot": "20.0.3", + "jest-util": "20.0.3", + "micromatch": "2.3.11", + "node-notifier": "5.1.2", + "pify": "2.3.0", + "slash": "1.0.0", + "string-length": "1.0.1", + "throat": "3.2.0", + "which": "1.2.14", + "worker-farm": "1.4.1", + "yargs": "7.1.0" + } + } + } + }, + "jest-changed-files": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-20.0.3.tgz", + "integrity": "sha1-k5TVzGXEOEBhSb7xv01Sto4D4/g=", + "dev": true + }, + "jest-config": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-20.0.4.tgz", + "integrity": "sha1-43kwqyIXyRNgXv8T5712PsSPruo=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "glob": "7.1.2", + "jest-environment-jsdom": "20.0.3", + "jest-environment-node": "20.0.3", + "jest-jasmine2": "20.0.4", + "jest-matcher-utils": "20.0.3", + "jest-regex-util": "20.0.3", + "jest-resolve": "20.0.4", + "jest-validate": "20.0.3", + "pretty-format": "20.0.3" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + } + } + }, + "jest-diff": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-20.0.3.tgz", + "integrity": "sha1-gfKI/Z5nXw+yPHXxwrGURf5YZhc=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "diff": "3.3.0", + "jest-matcher-utils": "20.0.3", + "pretty-format": "20.0.3" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + } + } + }, + "jest-docblock": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-20.0.3.tgz", + "integrity": "sha1-F76phDQswz2DxQ++FUXqDvqkRxI=", + "dev": true + }, + "jest-environment-jsdom": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-20.0.3.tgz", + "integrity": "sha1-BIqKwS7iJfcZBBdxODS7mZeH3pk=", + "dev": true, + "requires": { + "jest-mock": "20.0.3", + "jest-util": "20.0.3", + "jsdom": "9.12.0" + } + }, + "jest-environment-node": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-20.0.3.tgz", + "integrity": "sha1-1Ii8RhKvLCRumG6K52caCZFj1AM=", + "dev": true, + "requires": { + "jest-mock": "20.0.3", + "jest-util": "20.0.3" + } + }, + "jest-haste-map": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-20.0.4.tgz", + "integrity": "sha1-ZT61XIic48Ah97lGk/IKQVm63wM=", + "dev": true, + "requires": { + "fb-watchman": "2.0.0", + "graceful-fs": "4.1.11", + "jest-docblock": "20.0.3", + "micromatch": "2.3.11", + "sane": "1.6.0", + "worker-farm": "1.4.1" + } + }, + "jest-jasmine2": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-20.0.4.tgz", + "integrity": "sha1-/MWxQReA2RHQQpAu8YWehS5g1eE=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "graceful-fs": "4.1.11", + "jest-diff": "20.0.3", + "jest-matcher-utils": "20.0.3", + "jest-matchers": "20.0.3", + "jest-message-util": "20.0.3", + "jest-snapshot": "20.0.3", + "once": "1.4.0", + "p-map": "1.1.1" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + } + } + }, + "jest-matcher-utils": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-20.0.3.tgz", + "integrity": "sha1-s6a443yld4A7CDKpixZPRLeBVhI=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "pretty-format": "20.0.3" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + } + } + }, + "jest-matchers": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-matchers/-/jest-matchers-20.0.3.tgz", + "integrity": "sha1-ymnbHDLbWm9wf6XgQBq7VXAN/WA=", + "dev": true, + "requires": { + "jest-diff": "20.0.3", + "jest-matcher-utils": "20.0.3", + "jest-message-util": "20.0.3", + "jest-regex-util": "20.0.3" + } + }, + "jest-message-util": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-20.0.3.tgz", + "integrity": "sha1-auwoRDBvyw5udNV5bBAG2W/dgxw=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "micromatch": "2.3.11", + "slash": "1.0.0" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + } + } + }, + "jest-mock": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-20.0.3.tgz", + "integrity": "sha1-i8Bw6QQUqhVcEajWTIaaDVxx2lk=", + "dev": true + }, + "jest-regex-util": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-20.0.3.tgz", + "integrity": "sha1-hburXRM+RGJbGfr4xqpRItCF12I=", + "dev": true + }, + "jest-resolve": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-20.0.4.tgz", + "integrity": "sha1-lEiz6La6/BVHlETGSZBFt//ll6U=", + "dev": true, + "requires": { + "browser-resolve": "1.11.2", + "is-builtin-module": "1.0.0", + "resolve": "1.3.3" + } + }, + "jest-resolve-dependencies": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-20.0.3.tgz", + "integrity": "sha1-bhSntxevDyyzZnxUneQK8Bexcjo=", + "dev": true, + "requires": { + "jest-regex-util": "20.0.3" + } + }, + "jest-runtime": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-20.0.4.tgz", + "integrity": "sha1-osgCIZxCA/dU3xQE5JAYYWnRJNg=", + "dev": true, + "requires": { + "babel-core": "6.25.0", + "babel-jest": "20.0.3", + "babel-plugin-istanbul": "4.1.4", + "chalk": "1.1.3", + "convert-source-map": "1.5.0", + "graceful-fs": "4.1.11", + "jest-config": "20.0.4", + "jest-haste-map": "20.0.4", + "jest-regex-util": "20.0.3", + "jest-resolve": "20.0.4", + "jest-util": "20.0.3", + "json-stable-stringify": "1.0.1", + "micromatch": "2.3.11", + "strip-bom": "3.0.0", + "yargs": "7.1.0" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "jest-snapshot": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-20.0.3.tgz", + "integrity": "sha1-W4R+GtsaTZCFKn+fElCG4YfHZWY=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "jest-diff": "20.0.3", + "jest-matcher-utils": "20.0.3", + "jest-util": "20.0.3", + "natural-compare": "1.4.0", + "pretty-format": "20.0.3" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + } + } + }, + "jest-util": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-20.0.3.tgz", + "integrity": "sha1-DAf32A2C9OWmfG+LnD/n9lz9Mq0=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "graceful-fs": "4.1.11", + "jest-message-util": "20.0.3", + "jest-mock": "20.0.3", + "jest-validate": "20.0.3", + "leven": "2.1.0", + "mkdirp": "0.5.1" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + } + } + }, + "jest-validate": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-20.0.3.tgz", + "integrity": "sha1-0M/R3k9XnymEhJJcKA+PHZTsPKs=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "jest-matcher-utils": "20.0.3", + "leven": "2.1.0", + "pretty-format": "20.0.3" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + } + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.0.tgz", + "integrity": "sha512-0LoUNELX4S+iofCT8f4uEHIiRBR+c2AINyC8qRWfC6QNruLtxVZRJaPcu/xwMgFIgDxF25tGHaDjvxzJCNE9yw==", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, + "jschardet": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.5.0.tgz", + "integrity": "sha512-+Q8JsoEQbrdE+a/gg1F9XO92gcKXgpE5UACqr0sIubjDmBEkd+OOWPGzQeMrWSLxd73r4dHxBeRW7edHu5LmJQ==", + "dev": true + }, + "jsdom": { + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-9.12.0.tgz", + "integrity": "sha1-6MVG//ywbADUgzyoRBD+1/igl9Q=", + "dev": true, + "requires": { + "abab": "1.0.3", + "acorn": "4.0.13", + "acorn-globals": "3.1.0", + "array-equal": "1.0.0", + "content-type-parser": "1.0.1", + "cssom": "0.3.2", + "cssstyle": "0.2.37", + "escodegen": "1.8.1", + "html-encoding-sniffer": "1.0.1", + "nwmatcher": "1.4.1", + "parse5": "1.5.1", + "request": "2.81.0", + "sax": "1.2.4", + "symbol-tree": "3.2.2", + "tough-cookie": "2.3.2", + "webidl-conversions": "4.0.1", + "whatwg-encoding": "1.0.1", + "whatwg-url": "4.8.0", + "xml-name-validator": "2.0.1" + } + }, + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "JSONStream": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz", + "integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=", + "dev": true, + "requires": { + "jsonparse": "1.3.1", + "through": "2.3.8" + } + }, + "jsprim": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", + "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.0.2", + "json-schema": "0.2.3", + "verror": "1.3.6" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true, + "optional": true + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "1.0.0" + } + }, + "lerna": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lerna/-/lerna-2.0.0.tgz", + "integrity": "sha1-Sacv5w4Grr/X6iPvsqtBq+YOvuo=", + "dev": true, + "requires": { + "async": "1.5.2", + "chalk": "1.1.3", + "cmd-shim": "2.0.2", + "columnify": "1.5.4", + "command-join": "2.0.0", + "conventional-changelog-cli": "1.3.2", + "conventional-recommended-bump": "1.0.1", + "dedent": "0.7.0", + "execa": "0.6.3", + "find-up": "2.1.0", + "fs-extra": "3.0.1", + "get-port": "3.1.0", + "glob": "7.1.2", + "globby": "6.1.0", + "graceful-fs": "4.1.11", + "inquirer": "3.2.0", + "is-ci": "1.0.10", + "load-json-file": "2.0.0", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "npmlog": "4.1.2", + "p-finally": "1.0.0", + "path-exists": "3.0.0", + "read-cmd-shim": "1.0.1", + "read-pkg": "2.0.0", + "rimraf": "2.6.1", + "safe-buffer": "5.1.1", + "semver": "5.3.0", + "signal-exit": "3.0.2", + "strong-log-transformer": "1.0.6", + "temp-write": "3.3.0", + "write-file-atomic": "2.1.0", + "write-json-file": "2.2.0", + "write-pkg": "3.1.0", + "yargs": "8.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "which": "1.2.14" + } + }, + "get-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "pinkie-promise": "2.0.1" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + } + }, + "os-locale": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.0.0.tgz", + "integrity": "sha1-FZGN7VEFIrge565aMJ1U9jn8OaQ=", + "dev": true, + "requires": { + "execa": "0.5.1", + "lcid": "1.0.0", + "mem": "1.1.0" + }, + "dependencies": { + "execa": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.5.1.tgz", + "integrity": "sha1-3j+4XLjW6RyFvLzrFkWBeFy1ezY=", + "dev": true, + "requires": { + "cross-spawn": "4.0.2", + "get-stream": "2.3.1", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + } + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "2.3.0" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "read-pkg": "2.0.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "yargs": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", + "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", + "dev": true, + "requires": { + "camelcase": "4.1.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "2.0.0", + "read-pkg-up": "2.0.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "7.0.0" + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "dev": true, + "requires": { + "camelcase": "4.1.0" + } + } + } + }, + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.template": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", + "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0", + "lodash.templatesettings": "4.1.0" + } + }, + "lodash.templatesettings": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", + "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0" + } + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "dev": true, + "requires": { + "js-tokens": "3.0.2" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" + } + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "make-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.0.0.tgz", + "integrity": "sha1-l6ARdR6R3YfPre9Ygy67BJNt6Xg=", + "dev": true, + "requires": { + "pify": "2.3.0" + } + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.4" + } + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "1.1.0" + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.4.0", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "merge": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz", + "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=", + "dev": true + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.3" + } + }, + "mime-db": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz", + "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=", + "dev": true + }, + "mime-types": { + "version": "2.1.15", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz", + "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=", + "dev": true, + "requires": { + "mime-db": "1.27.0" + } + }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "modify-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.0.tgz", + "integrity": "sha1-4rbN65zhn5kxelNyLz2/XfXqqrI=", + "dev": true + }, + "moment": { + "version": "2.18.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz", + "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-notifier": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.1.2.tgz", + "integrity": "sha1-L6nhJgX6EACdRFSdb82KY93g5P8=", + "dev": true, + "requires": { + "growly": "1.3.0", + "semver": "5.3.0", + "shellwords": "0.1.0", + "which": "1.2.14" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "5.3.0", + "validate-npm-package-license": "3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "1.0.2" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "2.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "nwmatcher": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.1.tgz", + "integrity": "sha1-eumwew6oBNt+JfBctf5Al9TklJ8=", + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "1.1.0" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "0.0.8", + "wordwrap": "0.0.3" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + }, + "dependencies": { + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", + "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", + "dev": true + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "1.1.0" + } + }, + "p-map": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.1.1.tgz", + "integrity": "sha1-BfXkrpegaDcbwqXMhr+9vBnErno=", + "dev": true + }, + "parse-github-repo-url": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.0.tgz", + "integrity": "sha1-KGxT4smWLgZBZJ7jrJUI/KTdlZw=", + "dev": true + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + }, + "parse5": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", + "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "pretty-format": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-20.0.3.tgz", + "integrity": "sha1-Ag41ClYKH+GpjcO+tsz/s4beixQ=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1", + "ansi-styles": "3.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.1.0.tgz", + "integrity": "sha1-CcIC1ckX7CMYjKpcnLkXnNlUd1A=", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + } + } + }, + "private": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", + "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "prr": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", + "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "q": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz", + "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=", + "dev": true + }, + "qs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", + "dev": true + }, + "randomatic": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + } + } + }, + "read-cmd-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz", + "integrity": "sha1-LV0Vd4ajfAVdIgd8MsU/gynpHHs=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } + } + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + } + }, + "regenerate": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz", + "integrity": "sha1-0ZQcZ7rUN+G+dkM63Vs4X5WxkmA=", + "dev": true + }, + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", + "dev": true + }, + "regenerator-transform": { + "version": "0.9.11", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.9.11.tgz", + "integrity": "sha1-On0GdSDLe3F2dp61/4aGkb7+EoM=", + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "private": "0.1.7" + } + }, + "regex-cache": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz", + "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=", + "dev": true, + "requires": { + "is-equal-shallow": "0.1.3", + "is-primitive": "2.0.0" + } + }, + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "dev": true, + "requires": { + "regenerate": "1.3.2", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "requires": { + "jsesc": "0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remove-trailing-separator": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz", + "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "1.0.2" + } + }, + "request": { + "version": "2.81.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "dev": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.15", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.6.0", + "uuid": "3.1.0" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "resolve": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.3.3.tgz", + "integrity": "sha1-ZVkHw0aahoDcLeOidaj91paR8OU=", + "dev": true, + "requires": { + "path-parse": "1.0.5" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "2.0.1", + "signal-exit": "3.0.2" + } + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "optional": true, + "requires": { + "align-text": "0.1.4" + } + }, + "rimraf": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "2.1.0" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", + "dev": true + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dev": true, + "requires": { + "rx-lite": "4.0.8" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "sane": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-1.6.0.tgz", + "integrity": "sha1-lhDEUjB6E10pwf3+JUcDQYDEZ3U=", + "dev": true, + "requires": { + "anymatch": "1.3.0", + "exec-sh": "0.2.0", + "fb-watchman": "1.9.2", + "minimatch": "3.0.4", + "minimist": "1.2.0", + "walker": "1.0.7", + "watch": "0.10.0" + }, + "dependencies": { + "bser": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bser/-/bser-1.0.2.tgz", + "integrity": "sha1-OBEWlwsqbe6lZG3RXdcnhES1YWk=", + "dev": true, + "requires": { + "node-int64": "0.4.0" + } + }, + "fb-watchman": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-1.9.2.tgz", + "integrity": "sha1-okz0eCf4LTj7Waaa1wt247auc4M=", + "dev": true, + "requires": { + "bser": "1.0.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shellwords": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.0.tgz", + "integrity": "sha1-Zq/Ue2oSky2Qccv9mKUueFzQuhQ=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", + "dev": true + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true, + "requires": { + "is-plain-obj": "1.1.0" + } + }, + "source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", + "dev": true + }, + "source-map-support": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.15.tgz", + "integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=", + "dev": true, + "requires": { + "source-map": "0.5.6" + } + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "split": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.0.tgz", + "integrity": "sha1-xDlc5oOrzSVLwo/h2rtuXCfc/64=", + "dev": true, + "requires": { + "through": "2.3.8" + } + }, + "split2": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/split2/-/split2-2.1.1.tgz", + "integrity": "sha1-eh9VHhdqkOzTNF9yRqDP4XXvT9A=", + "dev": true, + "requires": { + "through2": "2.0.3" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", + "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "dev": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "string-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", + "integrity": "sha1-VpcPscOFWOnnC3KL894mmsRa36w=", + "dev": true, + "requires": { + "strip-ansi": "3.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "4.0.1" + } + }, + "strong-log-transformer": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-1.0.6.tgz", + "integrity": "sha1-9/uTdYpppXEUAYEnfuoMLrEwH6M=", + "dev": true, + "requires": { + "byline": "5.0.0", + "duplexer": "0.1.1", + "minimist": "0.1.0", + "moment": "2.18.1", + "through": "2.3.8" + }, + "dependencies": { + "minimist": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.1.0.tgz", + "integrity": "sha1-md9lelJXTCHJBXSX33QnkLK0wN4=", + "dev": true + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "symbol-tree": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", + "dev": true + }, + "temp-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", + "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=", + "dev": true + }, + "temp-write": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/temp-write/-/temp-write-3.3.0.tgz", + "integrity": "sha1-walt4rNgYTQuroH0T/ABrsj2Fak=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "is-stream": "1.1.0", + "make-dir": "1.0.0", + "pify": "2.3.0", + "temp-dir": "1.0.0", + "uuid": "3.1.0" + } + }, + "tempfile": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-1.1.1.tgz", + "integrity": "sha1-W8xOrsxKsscH2LwR2ZzMmiyyh/I=", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2", + "uuid": "2.0.3" + }, + "dependencies": { + "uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", + "dev": true + } + } + }, + "test-exclude": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.1.1.tgz", + "integrity": "sha512-35+Asrsk3XHJDBgf/VRFexPgh3UyETv8IAn/LRTiZjVy6rjPVqdEk8dJcJYBzl1w0XCJM48lvTy8SfEsCWS4nA==", + "dev": true, + "requires": { + "arrify": "1.0.1", + "micromatch": "2.3.11", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "require-main-filename": "1.0.1" + } + }, + "text-extensions": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.5.0.tgz", + "integrity": "sha1-0cstFLXQvEW/3Kigikc/aMfrDLw=", + "dev": true + }, + "throat": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-3.2.0.tgz", + "integrity": "sha512-/EY8VpvlqJ+sFtLPeOgc8Pl7kQVOWv0woD87KTXVHPIAE842FGT+rokxIhe8xIUP1cfgrkt0as0vDLjDiMtr8w==", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "2.3.3", + "xtend": "4.0.1" + } + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2" + } + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + }, + "tough-cookie": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", + "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", + "dev": true, + "requires": { + "punycode": "1.4.1" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "trim-off-newlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", + "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, + "optional": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "optional": true, + "requires": { + "source-map": "0.5.6", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, + "dependencies": { + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "optional": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true, + "optional": true + }, + "universalify": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", + "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, + "verror": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", + "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", + "dev": true, + "requires": { + "extsprintf": "1.0.2" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.11" + } + }, + "watch": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/watch/-/watch-0.10.0.tgz", + "integrity": "sha1-d3mLLaD5kQ1ZXxrOWwwiWFIfIdw=", + "dev": true + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "1.0.3" + } + }, + "webidl-conversions": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.1.tgz", + "integrity": "sha1-gBWherg+fhsxFjhIas6B2mziBqA=", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.1.tgz", + "integrity": "sha1-PGxFGhmO567FWx7GHQkgxngBpfQ=", + "dev": true, + "requires": { + "iconv-lite": "0.4.13" + } + }, + "whatwg-url": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz", + "integrity": "sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA=", + "dev": true, + "requires": { + "tr46": "0.0.3", + "webidl-conversions": "3.0.1" + }, + "dependencies": { + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + } + } + }, + "which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "wide-align": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", + "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", + "dev": true, + "requires": { + "string-width": "1.0.2" + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true, + "optional": true + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + }, + "worker-farm": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.4.1.tgz", + "integrity": "sha512-tgFAtgOYLPutkAyzgpS6VJFL5HY+0ui1Tvua+fITgz8ByaJTMFGtazR6xxQfwfiAcbwE+2fLG/K49wc2TfwCNw==", + "dev": true, + "requires": { + "errno": "0.1.4", + "xtend": "4.0.1" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write-file-atomic": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.1.0.tgz", + "integrity": "sha512-0TZ20a+xcIl4u0+Mj5xDH2yOWdmQiXlKf9Hm+TgDXjTMsEYb+gDrmb8e8UNAzMCitX8NBqG4Z/FUQIyzv/R1JQ==", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "imurmurhash": "0.1.4", + "slide": "1.1.6" + } + }, + "write-json-file": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-2.2.0.tgz", + "integrity": "sha1-UYYlBruzthnu+reFnx/WxtBTCHY=", + "dev": true, + "requires": { + "detect-indent": "5.0.0", + "graceful-fs": "4.1.11", + "make-dir": "1.0.0", + "pify": "2.3.0", + "sort-keys": "1.1.2", + "write-file-atomic": "2.1.0" + }, + "dependencies": { + "detect-indent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", + "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=", + "dev": true + } + } + }, + "write-pkg": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/write-pkg/-/write-pkg-3.1.0.tgz", + "integrity": "sha1-AwqZlMyZk9JbTnWp8aGSNgcpHOk=", + "dev": true, + "requires": { + "sort-keys": "2.0.0", + "write-json-file": "2.2.0" + }, + "dependencies": { + "sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", + "dev": true, + "requires": { + "is-plain-obj": "1.1.0" + } + } + } + }, + "xml-name-validator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", + "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", + "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "dev": true, + "requires": { + "camelcase": "3.0.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "1.4.0", + "read-pkg-up": "1.0.1", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "1.0.2", + "which-module": "1.0.0", + "y18n": "3.2.1", + "yargs-parser": "5.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + } + } + } + }, + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "dev": true, + "requires": { + "camelcase": "3.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + } + } + } + } +} diff --git a/packages/url/package-lock.json b/packages/url/package-lock.json new file mode 100644 index 0000000000000..3e824d7b10197 --- /dev/null +++ b/packages/url/package-lock.json @@ -0,0 +1,27 @@ +{ + "name": "@wordpress/url", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + } + } +} diff --git a/scripts/build.js b/scripts/build.js index e19761780d50d..4b5374401d366 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -25,7 +25,7 @@ const BUILD_DIR = { module: 'build-module', browser: 'build-browser', }; -const OK = chalk.reset.inverse.bold.green( ' DONE ' ); +const DONE = chalk.reset.inverse.bold.green( ' DONE ' ); /** * Babel Configuration @@ -136,13 +136,13 @@ function buildFileFor( file, silent, environment ) { */ function buildPackage( packagePath ) { const srcDir = path.resolve( packagePath, SRC_DIR ); - const pattern = path.resolve( srcDir, '**/*' ); - const files = glob.sync( pattern, { nodir: true } ); + const files = glob.sync( srcDir + '/**/*.js', { nodir: true } ) + .filter( file => ! /\.test\.js/.test( file ) ); process.stdout.write( `${ path.basename( packagePath ) }\n` ); files.forEach( file => buildFile( file, true ) ); - process.stdout.write( `${ OK }\n` ); + process.stdout.write( `${ DONE }\n` ); } process.stdout.write( chalk.inverse( '>> Building packages \n' ) ); From d60f97c64d4c5af78c1fd4a71ed407a471047504 Mon Sep 17 00:00:00 2001 From: James Nylen Date: Thu, 27 Jul 2017 18:58:53 +0200 Subject: [PATCH 130/393] Update coverage badge in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 86f0f892a2659..9104cfa169a18 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # packages [![Build Status](https://img.shields.io/travis/WordPress/packages/master.svg)](https://travis-ci.org/WordPress/packages) -[![Coverage](https://img.shields.io/coveralls/WordPress/packages/master.svg)](https://coveralls.io/github/WordPress/packages) +[![Coverage](https://img.shields.io/codecov/c/github/WordPress/packages/master.svg)](https://codecov.io/gh/WordPress/packages) Collection of JS modules and tools for WordPress development From ffbfa1ec1263ccb5d3ea8018a61cd3285d88a3fe Mon Sep 17 00:00:00 2001 From: omarreiss Date: Fri, 28 Jul 2017 14:10:57 +0200 Subject: [PATCH 131/393] Codestyle --- packages/a11y/src/addContainer.js | 22 +-- packages/a11y/src/clear.js | 8 +- packages/a11y/src/filterMessage.js | 28 +-- packages/a11y/src/index.js | 36 ++-- packages/a11y/src/test/addContainer.test.js | 56 +++--- packages/a11y/src/test/clear.test.js | 28 +-- packages/a11y/src/test/filterMessage.test.js | 40 ++-- packages/a11y/src/test/index.test.js | 182 +++++++++---------- packages/dom-ready/src/index.js | 8 +- packages/dom-ready/src/test/index.test.js | 46 ++--- 10 files changed, 227 insertions(+), 227 deletions(-) diff --git a/packages/a11y/src/addContainer.js b/packages/a11y/src/addContainer.js index c4b830717762c..d478ffcf887f3 100644 --- a/packages/a11y/src/addContainer.js +++ b/packages/a11y/src/addContainer.js @@ -6,20 +6,20 @@ * @returns {Object} $container The ARIA live region jQuery object. */ const addContainer = function( ariaLive ) { - ariaLive = ariaLive || 'polite'; + ariaLive = ariaLive || 'polite'; - let container = document.createElement( 'div' ); - container.id = 'a11y-speak-' + ariaLive; - container.className = 'a11y-speak-region'; + let container = document.createElement( 'div' ); + container.id = 'a11y-speak-' + ariaLive; + container.className = 'a11y-speak-region'; - let screenReaderTextStyle = 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;'; - container.setAttribute( 'style', screenReaderTextStyle ); - container.setAttribute( 'aria-live', ariaLive ); - container.setAttribute( 'aria-relevant', 'additions text' ); - container.setAttribute( 'aria-atomic', 'true' ); + let screenReaderTextStyle = 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;'; + container.setAttribute( 'style', screenReaderTextStyle ); + container.setAttribute( 'aria-live', ariaLive ); + container.setAttribute( 'aria-relevant', 'additions text' ); + container.setAttribute( 'aria-atomic', 'true' ); - document.querySelector( 'body' ).appendChild( container ); - return container; + document.querySelector( 'body' ).appendChild( container ); + return container; }; export default addContainer; diff --git a/packages/a11y/src/clear.js b/packages/a11y/src/clear.js index eb05020c9a9ec..b2226f0210806 100644 --- a/packages/a11y/src/clear.js +++ b/packages/a11y/src/clear.js @@ -2,10 +2,10 @@ * Clear the a11y-speak-region elements. */ const clear = function() { - let regions = document.querySelectorAll( '.a11y-speak-region' ); - for ( let i = 0; i < regions.length; i++ ) { - regions[ i ].textContent = ''; - } + let regions = document.querySelectorAll( '.a11y-speak-region' ); + for ( let i = 0; i < regions.length; i++ ) { + regions[i].textContent = ''; + } }; export default clear; diff --git a/packages/a11y/src/filterMessage.js b/packages/a11y/src/filterMessage.js index aa0e2c16bdef7..dc68bc6064117 100644 --- a/packages/a11y/src/filterMessage.js +++ b/packages/a11y/src/filterMessage.js @@ -1,4 +1,4 @@ -let previousMessage = '' +let previousMessage = ''; /** * Filter the message to be announced to the screenreader. @@ -9,22 +9,22 @@ let previousMessage = '' */ const filterMessage = function( message ) { - /* - * Strip HTML tags (if any) from the message string. Ideally, messages should - * be simple strings, carefully crafted for specific use with A11ySpeak. - * When re-using already existing strings this will ensure simple HTML to be - * stripped out and replaced with a space. Browsers will collapse multiple - * spaces natively. - */ - message = message.replace( /<[^<>]+>/g, ' ' ); + /* + * Strip HTML tags (if any) from the message string. Ideally, messages should + * be simple strings, carefully crafted for specific use with A11ySpeak. + * When re-using already existing strings this will ensure simple HTML to be + * stripped out and replaced with a space. Browsers will collapse multiple + * spaces natively. + */ + message = message.replace( /<[^<>]+>/g, ' ' ); - if ( previousMessage === message ) { - message = message + '\u00A0'; - } + if ( previousMessage === message ) { + message += '\u00A0'; + } - previousMessage = message; + previousMessage = message; - return message; + return message; }; export default filterMessage; diff --git a/packages/a11y/src/index.js b/packages/a11y/src/index.js index de1788119eb3f..b6eb15aeb2f9a 100644 --- a/packages/a11y/src/index.js +++ b/packages/a11y/src/index.js @@ -7,15 +7,15 @@ import filterMessage from './filterMessage'; * Create the live regions. */ export const setup = function() { - let containerPolite = document.getElementById( 'a11y-speak-polite' ); - let containerAssertive = document.getElementById( 'a11y-speak-assertive' ); + let containerPolite = document.getElementById( 'a11y-speak-polite' ); + let containerAssertive = document.getElementById( 'a11y-speak-assertive' ); - if ( containerPolite === null ) { - containerPolite = addContainer( 'polite' ); - } - if ( containerAssertive === null ) { - containerAssertive = addContainer( 'assertive' ); - } + if ( containerPolite === null ) { + containerPolite = addContainer( 'polite' ); + } + if ( containerAssertive === null ) { + containerAssertive = addContainer( 'assertive' ); + } }; /** @@ -31,17 +31,17 @@ domReady( setup ); * polite or assertive. Default polite. */ export const speak = function( message, ariaLive ) { - // Clear previous messages to allow repeated strings being read out. - clear(); + // Clear previous messages to allow repeated strings being read out. + clear(); - message = filterMessage( message ); + message = filterMessage( message ); - let containerPolite = document.getElementById( 'a11y-speak-polite' ); - let containerAssertive = document.getElementById( 'a11y-speak-assertive' ); + let containerPolite = document.getElementById( 'a11y-speak-polite' ); + let containerAssertive = document.getElementById( 'a11y-speak-assertive' ); - if ( containerAssertive && 'assertive' === ariaLive ) { - containerAssertive.textContent = message; - } else if ( containerPolite ) { - containerPolite.textContent = message; - } + if ( containerAssertive && 'assertive' === ariaLive ) { + containerAssertive.textContent = message; + } else if ( containerPolite ) { + containerPolite.textContent = message; + } }; diff --git a/packages/a11y/src/test/addContainer.test.js b/packages/a11y/src/test/addContainer.test.js index ccd0b845312bc..8bde66e6711b2 100644 --- a/packages/a11y/src/test/addContainer.test.js +++ b/packages/a11y/src/test/addContainer.test.js @@ -3,43 +3,43 @@ import addContainer from '../addContainer'; describe( 'addContainer', () => { describe( 'with polite param', () => { it( 'should create an aria-live element with aria-live attr set to polite', () => { - let container = addContainer( 'polite' ); + let container = addContainer( 'polite' ); expect( container ).not.toBe( null ); - expect( container.className ).toBe( 'a11y-speak-region' ); - expect( container.id ).toBe( 'a11y-speak-polite' ); - expect( container.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); - expect( container.getAttribute( 'aria-live' ) ).toBe( 'polite' ); - expect( container.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); - expect( container.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); - } ); - } ); + expect( container.className ).toBe( 'a11y-speak-region' ); + expect( container.id ).toBe( 'a11y-speak-polite' ); + expect( container.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); + expect( container.getAttribute( 'aria-live' ) ).toBe( 'polite' ); + expect( container.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); + expect( container.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); + }); + }); describe( 'with assertive param', () => { it( 'should create an aria-live element with aria-live attr set to assertive', () => { - let container = addContainer( 'assertive' ); + let container = addContainer( 'assertive' ); expect( container ).not.toBe( null ); - expect( container.className ).toBe( 'a11y-speak-region' ); - expect( container.id ).toBe( 'a11y-speak-assertive' ); - expect( container.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); - expect( container.getAttribute( 'aria-live' ) ).toBe( 'assertive' ); - expect( container.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); - expect( container.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); - } ); - } ); + expect( container.className ).toBe( 'a11y-speak-region' ); + expect( container.id ).toBe( 'a11y-speak-assertive' ); + expect( container.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); + expect( container.getAttribute( 'aria-live' ) ).toBe( 'assertive' ); + expect( container.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); + expect( container.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); + }); + }); describe( 'without param', () => { it( 'should default to creating an aria-live element with aria-live attr set to polite', () => { - let container = addContainer( 'polite' ); + let container = addContainer( 'polite' ); expect( container ).not.toBe( null ); - expect( container.className ).toBe( 'a11y-speak-region' ); - expect( container.id ).toBe( 'a11y-speak-polite' ); - expect( container.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); - expect( container.getAttribute( 'aria-live' ) ).toBe( 'polite' ); - expect( container.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); - expect( container.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); - } ); - } ); -} ); + expect( container.className ).toBe( 'a11y-speak-region' ); + expect( container.id ).toBe( 'a11y-speak-polite' ); + expect( container.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); + expect( container.getAttribute( 'aria-live' ) ).toBe( 'polite' ); + expect( container.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); + expect( container.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); + }); + }); +}); diff --git a/packages/a11y/src/test/clear.test.js b/packages/a11y/src/test/clear.test.js index b6a07ce06b98d..70655bfc748b0 100644 --- a/packages/a11y/src/test/clear.test.js +++ b/packages/a11y/src/test/clear.test.js @@ -1,19 +1,19 @@ import clear from '../clear'; describe( 'clear', () => { - it( 'should clear all a11y-speak-region elements', () => { - let container1 = document.createElement( 'div' ); - container1.className = 'a11y-speak-region'; - container1.textContent = 'not empty'; - document.querySelector( 'body' ).appendChild( container1 ); + it( 'should clear all a11y-speak-region elements', () => { + let container1 = document.createElement( 'div' ); + container1.className = 'a11y-speak-region'; + container1.textContent = 'not empty'; + document.querySelector( 'body' ).appendChild( container1 ); - let container2 = document.createElement( 'div' ); - container2.className = 'a11y-speak-region'; - container2.textContent = 'not empty'; - document.querySelector( 'body' ).appendChild( container2 ); + let container2 = document.createElement( 'div' ); + container2.className = 'a11y-speak-region'; + container2.textContent = 'not empty'; + document.querySelector( 'body' ).appendChild( container2 ); - clear(); - expect( container1.textContent ).toBe( '' ); - expect( container2.textContent ).toBe( '' ); - } ); -} ); + clear(); + expect( container1.textContent ).toBe( '' ); + expect( container2.textContent ).toBe( '' ); + }); +}); diff --git a/packages/a11y/src/test/filterMessage.test.js b/packages/a11y/src/test/filterMessage.test.js index 4ff90e71931e6..575dd11c6bd7e 100644 --- a/packages/a11y/src/test/filterMessage.test.js +++ b/packages/a11y/src/test/filterMessage.test.js @@ -1,25 +1,25 @@ import filterMessage from '../filterMessage'; describe( 'filterMessage', () => { - describe( 'when a clean message is passed in', () => { - it( 'should return the message unfiltered', () => { - let actual = filterMessage( 'clean message.' ); - expect( actual ).toBe( 'clean message.' ); - } ); - } ) + describe( 'when a clean message is passed in', () => { + it( 'should return the message unfiltered', () => { + let actual = filterMessage( 'clean message.' ); + expect( actual ).toBe( 'clean message.' ); + }); + }); - describe( 'when a message is passed in twice in a row', () => { - it( 'should add a space to the message to make sure it is announced again', () => { - filterMessage( 'repeated message.' ); - let actual = filterMessage( 'repeated message.' ); - expect( actual ).toBe( 'repeated message.' + '\u00A0' ); - } ); - } ) + describe( 'when a message is passed in twice in a row', () => { + it( 'should add a space to the message to make sure it is announced again', () => { + filterMessage( 'repeated message.' ); + let actual = filterMessage( 'repeated message.' ); + expect( actual ).toBe( 'repeated message.' + '\u00A0' ); + }); + }); - describe( 'when a message contains html tags', () => { - it( 'should strip the html tags and replace them with spaces', () => { - let actual = filterMessage( '

html paragraph

' ); - expect( actual ).toBe( ' html paragraph ' ); - } ); - } ) -} ); + describe( 'when a message contains html tags', () => { + it( 'should strip the html tags and replace them with spaces', () => { + let actual = filterMessage( '

html paragraph

' ); + expect( actual ).toBe( ' html paragraph ' ); + }); + }); +}); diff --git a/packages/a11y/src/test/index.test.js b/packages/a11y/src/test/index.test.js index 03704c336debe..ce304208f93cf 100644 --- a/packages/a11y/src/test/index.test.js +++ b/packages/a11y/src/test/index.test.js @@ -1,102 +1,102 @@ import { setup, speak } from '../'; jest.mock( '../clear', () => { - return jest.fn(); -} ); + return jest.fn(); +}); jest.mock( '@wordpress/dom-ready', () => { - return jest.fn( ( callback ) => { callback(); } ); -} ); + return jest.fn( ( callback ) => { callback(); }); +}); jest.mock( '../filterMessage', () => { - return jest.fn( ( message ) => { return message; } ); -} ); + return jest.fn( ( message ) => { return message; }); +}); import clear from '../clear'; import domReady from '@wordpress/dom-ready'; import filterMessage from '../filterMessage'; describe( 'speak', () => { - let containerPolite = document.getElementById( 'a11y-speak-polite' ); - let containerAssertive = document.getElementById( 'a11y-speak-assertive' ); - - beforeEach(() => { - containerPolite.textContent = ''; - containerAssertive.textContent = ''; - }); - - describe( 'on import', () => { - it( 'should call domReady', () => { - expect( domReady ).toHaveBeenCalled(); - } ); - } ); - - describe( 'in default mode', () => { - it( 'should set the textcontent of the polite aria-live region', () => { - speak( 'default message' ); - expect( containerPolite.textContent ).toBe( 'default message' ); - expect( containerAssertive.textContent ).toBe( '' ); - expect( clear ).toHaveBeenCalled(); - expect( filterMessage ).toHaveBeenCalledWith( 'default message' ); - } ); - } ); - - describe( 'in assertive mode', () => { - it( 'should set the textcontent of the assertive aria-live region', () => { - speak( 'assertive message', 'assertive' ); - expect( containerPolite.textContent ).toBe( '' ); - expect( containerAssertive.textContent ).toBe( 'assertive message' ); - } ); - } ); - - describe( 'in explicit polite mode', () => { - it( 'should set the textcontent of the polite aria-live region', () => { - speak( 'polite message', 'polite' ); - expect( containerPolite.textContent ).toBe( 'polite message' ); - expect( containerAssertive.textContent ).toBe( '' ); - } ); - } ); - - describe( 'when somehow the assertive container is not present', () => { - beforeEach( () => { - document.getElementById( 'a11y-speak-assertive' ).remove(); - } ); - - afterEach( () => { - setup(); - containerAssertive = document.getElementById( 'a11y-speak-assertive' ); - } ); - - it( 'should set the textcontent of the polite aria-live region', () => { - speak( 'message', 'assertive' ); - expect( containerPolite.textContent ).toBe( 'message' ); - expect( document.getElementById( 'a11y-speak-assertive' ) ).toBe( null ); - } ); - } ); - - describe( 'when somehow the both containers are not present', () => { - beforeEach( () => { - containerAssertive.remove(); - containerPolite.remove(); - } ); - - afterEach( () => { - setup(); - containerPolite = document.getElementById( 'a11y-speak-polite' ); - containerAssertive = document.getElementById( 'a11y-speak-assertive' ); - } ); - - it( 'should set the textcontent of the polite aria-live region', () => { - expect( document.getElementById( 'a11y-speak-polite' ) ).toBe( null ); - expect( document.getElementById( 'a11y-speak-assertive' ) ).toBe( null ); - } ); - } ); - - describe( 'setup when the elements already exist', () => { - it( 'should not create the aria live regions again', () => { - let before = document.getElementsByClassName( 'a11y-speak-region' ).length; - setup(); - let after = document.getElementsByClassName( 'a11y-speak-region' ).length; - - expect( before ).toBe( after ); - } ); - } ); -} ); + let containerPolite = document.getElementById( 'a11y-speak-polite' ); + let containerAssertive = document.getElementById( 'a11y-speak-assertive' ); + + beforeEach( () => { + containerPolite.textContent = ''; + containerAssertive.textContent = ''; + }); + + describe( 'on import', () => { + it( 'should call domReady', () => { + expect( domReady ).toHaveBeenCalled(); + }); + }); + + describe( 'in default mode', () => { + it( 'should set the textcontent of the polite aria-live region', () => { + speak( 'default message' ); + expect( containerPolite.textContent ).toBe( 'default message' ); + expect( containerAssertive.textContent ).toBe( '' ); + expect( clear ).toHaveBeenCalled(); + expect( filterMessage ).toHaveBeenCalledWith( 'default message' ); + }); + }); + + describe( 'in assertive mode', () => { + it( 'should set the textcontent of the assertive aria-live region', () => { + speak( 'assertive message', 'assertive' ); + expect( containerPolite.textContent ).toBe( '' ); + expect( containerAssertive.textContent ).toBe( 'assertive message' ); + }); + }); + + describe( 'in explicit polite mode', () => { + it( 'should set the textcontent of the polite aria-live region', () => { + speak( 'polite message', 'polite' ); + expect( containerPolite.textContent ).toBe( 'polite message' ); + expect( containerAssertive.textContent ).toBe( '' ); + }); + }); + + describe( 'when somehow the assertive container is not present', () => { + beforeEach( () => { + document.getElementById( 'a11y-speak-assertive' ).remove(); + }); + + afterEach( () => { + setup(); + containerAssertive = document.getElementById( 'a11y-speak-assertive' ); + }); + + it( 'should set the textcontent of the polite aria-live region', () => { + speak( 'message', 'assertive' ); + expect( containerPolite.textContent ).toBe( 'message' ); + expect( document.getElementById( 'a11y-speak-assertive' ) ).toBe( null ); + }); + }); + + describe( 'when somehow the both containers are not present', () => { + beforeEach( () => { + containerAssertive.remove(); + containerPolite.remove(); + }); + + afterEach( () => { + setup(); + containerPolite = document.getElementById( 'a11y-speak-polite' ); + containerAssertive = document.getElementById( 'a11y-speak-assertive' ); + }); + + it( 'should set the textcontent of the polite aria-live region', () => { + expect( document.getElementById( 'a11y-speak-polite' ) ).toBe( null ); + expect( document.getElementById( 'a11y-speak-assertive' ) ).toBe( null ); + }); + }); + + describe( 'setup when the elements already exist', () => { + it( 'should not create the aria live regions again', () => { + let before = document.getElementsByClassName( 'a11y-speak-region' ).length; + setup(); + let after = document.getElementsByClassName( 'a11y-speak-region' ).length; + + expect( before ).toBe( after ); + }); + }); +}); diff --git a/packages/dom-ready/src/index.js b/packages/dom-ready/src/index.js index 329f9ebf26d99..4e955fe59cd28 100644 --- a/packages/dom-ready/src/index.js +++ b/packages/dom-ready/src/index.js @@ -6,11 +6,11 @@ * @returns {void} */ const domReady = function( callback ) { - if ( document.readyState === 'complete' ) { - return callback(); - } + if ( document.readyState === 'complete' ) { + return callback(); + } - document.addEventListener( 'DOMContentLoaded', callback ); + document.addEventListener( 'DOMContentLoaded', callback ); }; export default domReady; diff --git a/packages/dom-ready/src/test/index.test.js b/packages/dom-ready/src/test/index.test.js index ad090522d3fc6..146270b70add1 100644 --- a/packages/dom-ready/src/test/index.test.js +++ b/packages/dom-ready/src/test/index.test.js @@ -1,30 +1,30 @@ import domReady from '../'; describe( 'domReady', () => { - describe( 'when document readystate is complete', () => { - it( 'should call the callback.', () => { - let callback = jest.fn( () => {} ); + describe( 'when document readystate is complete', () => { + it( 'should call the callback.', () => { + let callback = jest.fn( () => {}); - domReady( callback ); - expect( callback ).toHaveBeenCalled(); - } ); - } ); + domReady( callback ); + expect( callback ).toHaveBeenCalled(); + }); + }); - describe( 'when document readystate is still loading', () => { - it( 'should add the callback as an event listener to the DOMContentLoaded event.', () => { - let addEventListener = jest.fn( () => {} ); + describe( 'when document readystate is still loading', () => { + it( 'should add the callback as an event listener to the DOMContentLoaded event.', () => { + let addEventListener = jest.fn( () => {}); - Object.defineProperty(document, 'readyState', { - value: 'loading' - } ); - Object.defineProperty(document, 'addEventListener', { - value: addEventListener - } ); + Object.defineProperty( document, 'readyState', { + value: 'loading', + }); + Object.defineProperty( document, 'addEventListener', { + value: addEventListener, + }); - let callback = jest.fn( () => {} ); - domReady( callback ); - expect( callback ).not.toHaveBeenCalled(); - expect( addEventListener ).toHaveBeenCalledWith( 'DOMContentLoaded', callback ); - } ); - } ); -} ); + let callback = jest.fn( () => {}); + domReady( callback ); + expect( callback ).not.toHaveBeenCalled(); + expect( addEventListener ).toHaveBeenCalledWith( 'DOMContentLoaded', callback ); + }); + }); +}); From 90942a7f67881100917728f0870530182d54f3a1 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 1 Aug 2017 09:18:53 -0400 Subject: [PATCH 132/393] Add a centralized webpack folder based build for packages --- webpack.config.js | 59 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/webpack.config.js b/webpack.config.js index 5faefb963d7a3..7b8e8c6c6338b 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,17 +1,46 @@ +const entryPointNames = [ + 'hooks', + 'url', +]; + +const externals = { + react: 'React', + 'react-dom': 'ReactDOM', + 'react-dom/server': 'ReactDOMServer', + tinymce: 'tinymce', + moment: 'moment', +}; + +entryPointNames.forEach( entryPointName => { + externals[ entryPointName ] = { + 'this': [ 'wp', entryPointName ], + }; +} ); + +const config = entryPointNames.reduce( ( memo, entryPointName ) => { + memo[ entryPointName ] = './packages/' + entryPointName + '/src/index.js'; + return memo; + }, {} ); + + module.exports = { - entry: './packages/hooks/src/wp-hooks.js', - output: { - filename: './packages/hooks/wp-core/wp-hooks.js' - }, - module: { - rules: [ - { - test: /\.js$/, - exclude: /(node_modules)/, - use: { - loader: 'babel-loader' - } - } - ] - } + entry: config, + externals, + output: { + filename: 'build/[name]/index.js', + path: __dirname, + library: [ 'wp', '[name]' ], + libraryTarget: 'this', + }, + module: { + rules: [ + { + test: /\.js$/, + exclude: /(node_modules)/, + use: { + loader: 'babel-loader' + } + } + ] + } } From aa952963268d8a244af4019ead3d8978ef4c8a4b Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 31 Jul 2017 11:51:35 +0100 Subject: [PATCH 133/393] Url Module: Drop the browser built file and the useless dependencies --- package-lock.json | 198 +++++++++++++++++++++++++++------ package.json | 3 +- packages/url/package-lock.json | 24 +--- packages/url/package.json | 6 +- scripts/build.js | 7 -- 5 files changed, 168 insertions(+), 70 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3cff4d2562f62..836473e8f3c86 100644 --- a/package-lock.json +++ b/package-lock.json @@ -96,7 +96,7 @@ "aproba": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.2.tgz", - "integrity": "sha512-ZpYajIfO0j2cOFTO955KUMIKNmj6zhX8kVztMAxFsDaMwz+9Z9SV0uou2pC9HJqcfpffOsjnbrDMvkNy+9RXPw==", + "integrity": "sha1-RcZikJTeTpb2k+9+q3SuB5wkD8E=", "dev": true }, "are-we-there-yet": { @@ -118,6 +118,12 @@ "sprintf-js": "1.0.3" } }, + "argv": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz", + "integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=", + "dev": true + }, "arr-diff": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", @@ -768,15 +774,6 @@ "regenerator-transform": "0.9.11" } }, - "babel-plugin-transform-runtime": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz", - "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0" - } - }, "babel-plugin-transform-strict-mode": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", @@ -904,7 +901,7 @@ "babylon": { "version": "6.17.4", "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.17.4.tgz", - "integrity": "sha512-kChlV+0SXkjE0vUn9OZ7pBMWRFd8uq3mZe8x1K6jhuNcAFAtEnjchFAqB+dYEXKyd+JpT6eppRR78QAr5gTsUw==", + "integrity": "sha1-Pot0AriNIsNCPhN6FXeIOxX/hpo=", "dev": true }, "balanced-match": { @@ -1156,6 +1153,90 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, + "codecov": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/codecov/-/codecov-2.2.0.tgz", + "integrity": "sha1-LQaBfOuIkeymNog21Ptr9swE/9E=", + "dev": true, + "requires": { + "argv": "0.0.2", + "request": "2.79.0", + "urlgrey": "0.4.4" + }, + "dependencies": { + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "commander": "2.11.0", + "is-my-json-valid": "2.16.0", + "pinkie-promise": "2.0.1" + } + }, + "qs": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", + "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=", + "dev": true + }, + "request": { + "version": "2.79.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", + "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", + "dev": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.11.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "2.0.6", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.15", + "oauth-sign": "0.8.2", + "qs": "6.3.2", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.4.3", + "uuid": "3.1.0" + } + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", + "dev": true + } + } + }, "color-convert": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", @@ -1196,6 +1277,12 @@ "integrity": "sha1-Uui5hPSHLZUv8b3IuYOX0nxxRM8=", "dev": true }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, "compare-func": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.2.tgz", @@ -1980,6 +2067,21 @@ "wide-align": "1.1.2" } }, + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "requires": { + "is-property": "1.0.2" + } + }, "get-caller-file": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", @@ -2085,7 +2187,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -2118,7 +2220,7 @@ "globals": { "version": "9.18.0", "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "integrity": "sha1-qjiWs+abSH8X4x7SFD1pqOMMLYo=", "dev": true }, "globby": { @@ -2243,7 +2345,7 @@ "hosted-git-info": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", - "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "integrity": "sha1-bWDjSzq7yDEwYsO3mO+NkBoHrzw=", "dev": true }, "html-encoding-sniffer": { @@ -2469,6 +2571,18 @@ "is-extglob": "1.0.0" } }, + "is-my-json-valid": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz", + "integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=", + "dev": true, + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" + } + }, "is-number": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", @@ -2508,6 +2622,12 @@ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -2590,13 +2710,13 @@ "istanbul-lib-coverage": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz", - "integrity": "sha512-0+1vDkmzxqJIn5rcoEqapSB4DmPxE31EtI2dF2aCkV5esN9EWHxZ0dwgDClivMXJqE7zaYQxq30hj5L0nlTN5Q==", + "integrity": "sha1-c7+5mIhSmUFck9OKPprfeEp3qdo=", "dev": true }, "istanbul-lib-hook": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz", - "integrity": "sha512-3U2HB9y1ZV9UmFlE12Fx+nPtFqIymzrqCksrXujm3NVbAZIJg/RfYgO1XiIa0mbmxTjWpVEVlkIZJ25xVIAfkQ==", + "integrity": "sha1-3WYH8DB2V4/n1vKmMM8UO0m6zdw=", "dev": true, "requires": { "append-transform": "0.4.0" @@ -2620,7 +2740,7 @@ "istanbul-lib-report": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz", - "integrity": "sha512-tvF+YmCmH4thnez6JFX06ujIA19WPa9YUiwjc1uALF2cv5dmE3It8b5I8Ob7FHJ70H9Y5yF+TDkVa/mcADuw1Q==", + "integrity": "sha1-8OVfVmVf+jQiIIC3oM1HYOFAX8k=", "dev": true, "requires": { "istanbul-lib-coverage": "1.1.1", @@ -2649,7 +2769,7 @@ "istanbul-lib-source-maps": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz", - "integrity": "sha512-mukVvSXCn9JQvdJl8wP/iPhqig0MRtuWuD4ZNKo6vB2Ik//AmhAKe3QnPN02dmkRe3lTudFk3rzoHhwU4hb94w==", + "integrity": "sha1-pv4ay6jOCO68Y45XLilNJnAIqgw=", "dev": true, "requires": { "debug": "2.6.8", @@ -2662,7 +2782,7 @@ "istanbul-reports": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.1.1.tgz", - "integrity": "sha512-P8G873A0kW24XRlxHVGhMJBhQ8gWAec+dae7ZxOBzxT4w+a9ATSPvRVK3LB1RAJ9S8bg2tOyWHAGW40Zd2dKfw==", + "integrity": "sha1-BCvlyJ4XW8P4ZSPKqynAFOd/7k4=", "dev": true, "requires": { "handlebars": "4.0.10" @@ -3204,6 +3324,12 @@ "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", "dev": true }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, "JSONStream": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz", @@ -3616,7 +3742,7 @@ "lru-cache": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "integrity": "sha1-Yi4y6CSItJJ5EUpPns9F581rulU=", "dev": true, "requires": { "pseudomap": "1.0.2", @@ -3733,7 +3859,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "dev": true, "requires": { "brace-expansion": "1.1.8" @@ -3805,7 +3931,7 @@ "normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=", "dev": true, "requires": { "hosted-git-info": "2.5.0", @@ -3835,7 +3961,7 @@ "npmlog": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "integrity": "sha1-CKfyqL9zRgR3mp76StXMcXq7lUs=", "dev": true, "requires": { "are-we-there-yet": "1.1.4", @@ -4149,7 +4275,7 @@ "randomatic": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "integrity": "sha1-x6vpzIuHwLqodrGf3oP9RkeX44w=", "dev": true, "requires": { "is-number": "3.0.0", @@ -4241,7 +4367,7 @@ "readable-stream": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "integrity": "sha1-No8lEtefnUb9/HE0mueHi7weuVw=", "dev": true, "requires": { "core-util-is": "1.0.2", @@ -4464,7 +4590,7 @@ "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=", "dev": true }, "sane": { @@ -4511,7 +4637,7 @@ "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=", "dev": true }, "semver": { @@ -4670,7 +4796,7 @@ "string_decoder": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", "dev": true, "requires": { "safe-buffer": "5.1.1" @@ -4809,7 +4935,7 @@ "test-exclude": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.1.1.tgz", - "integrity": "sha512-35+Asrsk3XHJDBgf/VRFexPgh3UyETv8IAn/LRTiZjVy6rjPVqdEk8dJcJYBzl1w0XCJM48lvTy8SfEsCWS4nA==", + "integrity": "sha1-TYSWSwlmsAh+zDNKLOAC09k0HiY=", "dev": true, "requires": { "arrify": "1.0.1", @@ -4828,7 +4954,7 @@ "throat": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/throat/-/throat-3.2.0.tgz", - "integrity": "sha512-/EY8VpvlqJ+sFtLPeOgc8Pl7kQVOWv0woD87KTXVHPIAE842FGT+rokxIhe8xIUP1cfgrkt0as0vDLjDiMtr8w==", + "integrity": "sha1-UMsGcO28QCN7njR9fh+I5GIK+DY=", "dev": true }, "through": { @@ -4972,6 +5098,12 @@ "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=", "dev": true }, + "urlgrey": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-0.4.4.tgz", + "integrity": "sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8=", + "dev": true + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -5078,7 +5210,7 @@ "wide-align": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", - "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", + "integrity": "sha1-Vx4PGwYEY268DfwhsDObvjE0FxA=", "dev": true, "requires": { "string-width": "1.0.2" @@ -5100,7 +5232,7 @@ "worker-farm": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.4.1.tgz", - "integrity": "sha512-tgFAtgOYLPutkAyzgpS6VJFL5HY+0ui1Tvua+fITgz8ByaJTMFGtazR6xxQfwfiAcbwE+2fLG/K49wc2TfwCNw==", + "integrity": "sha1-pDi8mTp6fRM7y2VHyV7KfP9Il9g=", "dev": true, "requires": { "errno": "0.1.4", @@ -5126,7 +5258,7 @@ "write-file-atomic": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.1.0.tgz", - "integrity": "sha512-0TZ20a+xcIl4u0+Mj5xDH2yOWdmQiXlKf9Hm+TgDXjTMsEYb+gDrmb8e8UNAzMCitX8NBqG4Z/FUQIyzv/R1JQ==", + "integrity": "sha1-F2n0tVHu3OQZ8FBd6uLiZ2NULTc=", "dev": true, "requires": { "graceful-fs": "4.1.11", diff --git a/package.json b/package.json index 099698d670ab4..ac238b54fe569 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,6 @@ "devDependencies": { "babel-core": "^6.25.0", "babel-plugin-transform-object-rest-spread": "^6.23.0", - "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-env": "^1.5.2", "chalk": "^2.0.1", "codecov": "^2.2.0", @@ -22,7 +21,7 @@ "coverageDirectory": "coverage" }, "scripts": { - "build-clean": "rimraf ./packages/*/build ./packages/*/build-browser ./packages/*/build-module", + "build-clean": "rimraf ./packages/*/build ./packages/*/build-module", "build": "node ./scripts/build.js", "test": "jest", "test:coverage": "jest --coverage", diff --git a/packages/url/package-lock.json b/packages/url/package-lock.json index 3e824d7b10197..09f33e59d90fe 100644 --- a/packages/url/package-lock.json +++ b/packages/url/package-lock.json @@ -1,27 +1,5 @@ { "name": "@wordpress/url", "version": "0.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - } - } + "lockfileVersion": 1 } diff --git a/packages/url/package.json b/packages/url/package.json index cd84d89347361..8682bcdcfadde 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -8,11 +8,7 @@ "description": "WordPress URL utilities", "main": "build/index.js", "module": "build-module/index.js", - "browser": "build-browser/index.js", "author": "WordPress", "license": "GPL-2.0+", - "dependencies": { - "querystring": "^0.2.0", - "url": "^0.11.0" - } + "dependencies": {} } diff --git a/scripts/build.js b/scripts/build.js index 4b5374401d366..5342ebadd4e81 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -23,7 +23,6 @@ const SRC_DIR = 'src'; const BUILD_DIR = { main: 'build', module: 'build-module', - browser: 'build-browser', }; const DONE = chalk.reset.inverse.bold.green( ' DONE ' ); @@ -47,11 +46,6 @@ const babelConfigs = { ) ], ] } ), - browser: Object.assign( - {}, - babelDefaultConfig, - { plugins: [ ...babelDefaultConfig.plugins, 'transform-runtime' ] } - ) }; /** @@ -100,7 +94,6 @@ function getBuildPath( file, buildFolder ) { function buildFile( file, silent ) { buildFileFor( file, silent, 'main' ); buildFileFor( file, silent, 'module' ); - buildFileFor( file, silent, 'browser' ); } /** From 1e35b261d756974f6ae2064580b7cf334e6f5420 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 31 Jul 2017 14:59:17 +0100 Subject: [PATCH 134/393] URl Module: Use a pre 0.1.0 release --- packages/url/package-lock.json | 2 +- packages/url/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/url/package-lock.json b/packages/url/package-lock.json index 09f33e59d90fe..4522f465e57d6 100644 --- a/packages/url/package-lock.json +++ b/packages/url/package-lock.json @@ -1,5 +1,5 @@ { "name": "@wordpress/url", - "version": "0.0.1", + "version": "0.1.0-beta.1", "lockfileVersion": 1 } diff --git a/packages/url/package.json b/packages/url/package.json index 8682bcdcfadde..350d497ab2045 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/url", - "version": "0.0.1", + "version": "0.1.0-beta.1", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" From f53051f8abe471f1a29e538aa4b853d688c17226 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Tue, 1 Aug 2017 16:20:51 +0200 Subject: [PATCH 135/393] Apply function spacing exception to arrow functions. --- packages/a11y/src/test/index.test.js | 14 +++++++------- packages/dom-ready/src/test/index.test.js | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/a11y/src/test/index.test.js b/packages/a11y/src/test/index.test.js index ce304208f93cf..211cb39d8da99 100644 --- a/packages/a11y/src/test/index.test.js +++ b/packages/a11y/src/test/index.test.js @@ -4,10 +4,10 @@ jest.mock( '../clear', () => { return jest.fn(); }); jest.mock( '@wordpress/dom-ready', () => { - return jest.fn( ( callback ) => { callback(); }); + return jest.fn(( callback ) => { callback(); }); }); jest.mock( '../filterMessage', () => { - return jest.fn( ( message ) => { return message; }); + return jest.fn(( message ) => { return message; }); }); import clear from '../clear'; @@ -18,7 +18,7 @@ describe( 'speak', () => { let containerPolite = document.getElementById( 'a11y-speak-polite' ); let containerAssertive = document.getElementById( 'a11y-speak-assertive' ); - beforeEach( () => { + beforeEach(() => { containerPolite.textContent = ''; containerAssertive.textContent = ''; }); @@ -56,11 +56,11 @@ describe( 'speak', () => { }); describe( 'when somehow the assertive container is not present', () => { - beforeEach( () => { + beforeEach(() => { document.getElementById( 'a11y-speak-assertive' ).remove(); }); - afterEach( () => { + afterEach(() => { setup(); containerAssertive = document.getElementById( 'a11y-speak-assertive' ); }); @@ -73,12 +73,12 @@ describe( 'speak', () => { }); describe( 'when somehow the both containers are not present', () => { - beforeEach( () => { + beforeEach(() => { containerAssertive.remove(); containerPolite.remove(); }); - afterEach( () => { + afterEach(() => { setup(); containerPolite = document.getElementById( 'a11y-speak-polite' ); containerAssertive = document.getElementById( 'a11y-speak-assertive' ); diff --git a/packages/dom-ready/src/test/index.test.js b/packages/dom-ready/src/test/index.test.js index 146270b70add1..556594c1ca452 100644 --- a/packages/dom-ready/src/test/index.test.js +++ b/packages/dom-ready/src/test/index.test.js @@ -3,7 +3,7 @@ import domReady from '../'; describe( 'domReady', () => { describe( 'when document readystate is complete', () => { it( 'should call the callback.', () => { - let callback = jest.fn( () => {}); + let callback = jest.fn(() => {}); domReady( callback ); expect( callback ).toHaveBeenCalled(); @@ -12,7 +12,7 @@ describe( 'domReady', () => { describe( 'when document readystate is still loading', () => { it( 'should add the callback as an event listener to the DOMContentLoaded event.', () => { - let addEventListener = jest.fn( () => {}); + let addEventListener = jest.fn(() => {}); Object.defineProperty( document, 'readyState', { value: 'loading', @@ -21,7 +21,7 @@ describe( 'domReady', () => { value: addEventListener, }); - let callback = jest.fn( () => {}); + let callback = jest.fn(() => {}); domReady( callback ); expect( callback ).not.toHaveBeenCalled(); expect( addEventListener ).toHaveBeenCalledWith( 'DOMContentLoaded', callback ); From 84d67a939312e1823e33f47c2ccda0472068b16d Mon Sep 17 00:00:00 2001 From: omarreiss Date: Tue, 1 Aug 2017 16:23:15 +0200 Subject: [PATCH 136/393] Set initial versions to 0.1.0-dev.1 --- packages/a11y/package.json | 4 ++-- packages/dom-ready/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/a11y/package.json b/packages/a11y/package.json index 3e57dbbab4db0..6cfcc2753dc1c 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/a11y", - "version": "0.0.1", + "version": "0.1.0-dev.1", "description": "Collection of JS modules and tools for WordPress development", "homepage": "https://github.com/WordPress/packages/tree/master/packages/a11y/README.md", "author": "WordPress", @@ -19,6 +19,6 @@ "url": "https://github.com/WordPress/packages/issues" }, "dependencies": { - "@wordpress/dom-ready": "^0.0.1" + "@wordpress/dom-ready": "^0.1.0" } } diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index abb8531615a82..b771670f1e375 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom-ready", - "version": "0.0.1", + "version": "0.1.0-dev.1", "description": "Execute callback after the DOM is loaded.", "homepage": "https://github.com/WordPress/packages/tree/master/packages/domReady/README.md", "author": "WordPress", From 0788dfa126570a3db28d56c4cecbc156f05588b4 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Tue, 1 Aug 2017 16:33:20 +0200 Subject: [PATCH 137/393] Browser builds have been temporarily removed --- packages/a11y/package.json | 1 - packages/dom-ready/package.json | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/a11y/package.json b/packages/a11y/package.json index 6cfcc2753dc1c..9ac93fa778af6 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -10,7 +10,6 @@ ], "main": "build/index.js", "module": "build-module/index.js", - "browser": "build-browser/index.js", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index b771670f1e375..dfc07e9092544 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -10,7 +10,6 @@ ], "main": "build/index.js", "module": "build-module/index.js", - "browser": "build-browser/index.js", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" From 9938f4776229f84d28fcb262505495bdcf556e00 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Tue, 1 Aug 2017 16:33:47 +0200 Subject: [PATCH 138/393] require dev version of dom-ready until 0.1.0 has been released. --- packages/a11y/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/a11y/package.json b/packages/a11y/package.json index 9ac93fa778af6..307516f3c13ad 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -18,6 +18,6 @@ "url": "https://github.com/WordPress/packages/issues" }, "dependencies": { - "@wordpress/dom-ready": "^0.1.0" + "@wordpress/dom-ready": "^0.1.0-dev" } } From a473f3a6aeff03bd0354cbe77fd798d9331fd957 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 3 Aug 2017 10:38:15 +0100 Subject: [PATCH 139/393] Use the independent mode for lerna --- lerna.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lerna.json b/lerna.json index 020530655ac46..1653f5ef0ab45 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,7 @@ { - "lerna": "2.0.0-rc.5", - "packages": [ - "packages/*" - ] + "lerna": "2.0.0", + "packages": [ + "packages/*" + ], + "version": "independent" } From 1e2408b4c994570d731355dcb1d5c415edbcd693 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 8 Aug 2017 15:10:36 +0100 Subject: [PATCH 140/393] Publish - @wordpress/a11y@0.1.0-beta.0 - @wordpress/dom-ready@0.1.0-beta.0 - @wordpress/url@0.1.0-beta.0 --- packages/a11y/package.json | 11 +++++++---- packages/dom-ready/package.json | 5 ++++- packages/url/package.json | 6 ++++-- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/a11y/package.json b/packages/a11y/package.json index 307516f3c13ad..4f0958146cfca 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/a11y", - "version": "0.1.0-dev.1", + "version": "0.1.0-beta.0", "description": "Collection of JS modules and tools for WordPress development", "homepage": "https://github.com/WordPress/packages/tree/master/packages/a11y/README.md", "author": "WordPress", @@ -17,7 +17,10 @@ "bugs": { "url": "https://github.com/WordPress/packages/issues" }, - "dependencies": { - "@wordpress/dom-ready": "^0.1.0-dev" - } + "dependencies": { + "@wordpress/dom-ready": "^0.1.0-beta.0" + }, + "publishConfig": { + "access": "public" + } } diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index dfc07e9092544..c871961757b22 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom-ready", - "version": "0.1.0-dev.1", + "version": "0.1.0-beta.0", "description": "Execute callback after the DOM is loaded.", "homepage": "https://github.com/WordPress/packages/tree/master/packages/domReady/README.md", "author": "WordPress", @@ -16,5 +16,8 @@ }, "bugs": { "url": "https://github.com/WordPress/packages/issues" + }, + "publishConfig": { + "access": "public" } } diff --git a/packages/url/package.json b/packages/url/package.json index 350d497ab2045..b377a0c640b2d 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/url", - "version": "0.1.0-beta.1", + "version": "0.1.0-beta.0", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" @@ -10,5 +10,7 @@ "module": "build-module/index.js", "author": "WordPress", "license": "GPL-2.0+", - "dependencies": {} + "publishConfig": { + "access": "public" + } } From 07746b67d0593ad12fff3489ce1adedf0902d702 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 8 Aug 2017 15:36:41 +0100 Subject: [PATCH 141/393] Publish - @wordpress/a11y@0.1.0-beta.1 - @wordpress/dom-ready@0.1.0-beta.1 - @wordpress/url@0.1.0-beta.1 --- packages/a11y/package.json | 4 ++-- packages/dom-ready/package.json | 2 +- packages/url/package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/a11y/package.json b/packages/a11y/package.json index 4f0958146cfca..b660e93181d41 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/a11y", - "version": "0.1.0-beta.0", + "version": "0.1.0-beta.1", "description": "Collection of JS modules and tools for WordPress development", "homepage": "https://github.com/WordPress/packages/tree/master/packages/a11y/README.md", "author": "WordPress", @@ -18,7 +18,7 @@ "url": "https://github.com/WordPress/packages/issues" }, "dependencies": { - "@wordpress/dom-ready": "^0.1.0-beta.0" + "@wordpress/dom-ready": "^0.1.0-beta.1" }, "publishConfig": { "access": "public" diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index c871961757b22..f543488fbce71 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom-ready", - "version": "0.1.0-beta.0", + "version": "0.1.0-beta.1", "description": "Execute callback after the DOM is loaded.", "homepage": "https://github.com/WordPress/packages/tree/master/packages/domReady/README.md", "author": "WordPress", diff --git a/packages/url/package.json b/packages/url/package.json index b377a0c640b2d..138e9fdd585ce 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/url", - "version": "0.1.0-beta.0", + "version": "0.1.0-beta.1", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" From e2547d9e7d16ee1a651654e9f446e6a4c537b0b0 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 8 Aug 2017 11:06:25 -0600 Subject: [PATCH 142/393] Add check: the hook name can only contain numbers, letters and underscores --- packages/hooks/src/createRunHook.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/hooks/src/createRunHook.js b/packages/hooks/src/createRunHook.js index 31dccd30a5475..3282bd466cf04 100644 --- a/packages/hooks/src/createRunHook.js +++ b/packages/hooks/src/createRunHook.js @@ -29,6 +29,11 @@ function createRunHook( hooks, returnFirstArg ) { return; } + if ( ! /^[a-z][a-z0-9_]*$/.test( hookName ) ) { + console.error( 'The hook name can only contain numbers, letters and underscores.' ); + return; + } + if ( ! hooks.hasOwnProperty( hookName ) ) { hooks[ hookName ] = { runs: 0, From cefc79a2611e6c4d1d5b4c0ee4862282d5490e56 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 8 Aug 2017 11:06:50 -0600 Subject: [PATCH 143/393] use yoda conditional as per wp coding standards --- packages/hooks/src/createRunHook.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/hooks/src/createRunHook.js b/packages/hooks/src/createRunHook.js index 3282bd466cf04..754a73e4dd89f 100644 --- a/packages/hooks/src/createRunHook.js +++ b/packages/hooks/src/createRunHook.js @@ -19,7 +19,7 @@ function createRunHook( hooks, returnFirstArg ) { * @return {*} Return value of runner, if applicable. */ return function runHooks( hookName, ...args ) { - if ( typeof hookName !== 'string' ) { + if ( 'string' !== typeof hookName ) { console.error( 'The hook name must be a string.' ); return; } From 7c01c7afca3d85ccfb1efbd2ae573fdeb0b36c53 Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Thu, 10 Aug 2017 14:55:53 +1000 Subject: [PATCH 144/393] chore: Add `package-lock.json` to a11y package --- packages/a11y/package-lock.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 packages/a11y/package-lock.json diff --git a/packages/a11y/package-lock.json b/packages/a11y/package-lock.json new file mode 100644 index 0000000000000..84e299719a1c8 --- /dev/null +++ b/packages/a11y/package-lock.json @@ -0,0 +1,13 @@ +{ + "name": "@wordpress/a11y", + "version": "0.1.0-beta.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@wordpress/dom-ready": { + "version": "0.1.0-beta.1", + "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-0.1.0-beta.1.tgz", + "integrity": "sha512-PatjEn3GbOVLQPG3K0p7aLR6A0ggCfWa2AUK+T9t6J1oPLa3d8Kt39h/zkfd7hyn9FV7DItMk4ud8VmDthHcvA==" + } + } +} From 63ad3dca373a6f4ffa73579d2b849407e605b8ee Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Thu, 10 Aug 2017 14:57:52 +1000 Subject: [PATCH 145/393] chore: Add `package-lock.json` to domready package --- packages/dom-ready/package-lock.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/dom-ready/package-lock.json diff --git a/packages/dom-ready/package-lock.json b/packages/dom-ready/package-lock.json new file mode 100644 index 0000000000000..5759c64e6097d --- /dev/null +++ b/packages/dom-ready/package-lock.json @@ -0,0 +1,5 @@ +{ + "name": "@wordpress/dom-ready", + "version": "0.1.0-beta.1", + "lockfileVersion": 1 +} From a617462269fc6234e9e33fa5b831b03f3d0eb660 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 8 Aug 2017 15:39:47 +0100 Subject: [PATCH 146/393] Documentation: Document the publishing workflow and add helper scripts --- CONTRIBUTING.md | 29 ++++++++++++++++++++++++++++- package.json | 4 +++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b8076a73114d5..3eefbe9325317 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,6 +10,33 @@ Ideally name your branches with prefixes and descriptions, like this: `[type]/[c - `try/` = experimental feature, "tentatively add" - `update/` = update an existing feature -For example, `add/foo-module` means you're working on adding a new foo module. +For example, `add/foo-module` means you're working on adding a new foo module. You can pick among all the tickets, or some of the ones labelled Good First Task. + + +## Releasing + +This repository uses [lerna](https://lernajs.io) to manage and release the packages. Lerna automatically releases all the outdated packages. To check which packages are outdated and will be released, type `lerna updated`. + +### Development release + +Run the following command to release a dev version of the outdated packages: + +```bash +npm run publish:dev +``` + +Lerna will ask you which version number you want to choose for each package. For a `dev` release, you'll more likely want to choose the "prerelease" option. Repeat the same for all the outdated packages and confirm your version updates. + +Lerna will then publish to `npm`, commit the `package.json` changes and create the git tags. + +### Production release + +To release a production version for the outdated packages, run the following command + +```bash +npm run publish:prod +``` + +Choose the correct version (minor, major or patch) and confirm your choices and let Lerna do its magic. diff --git a/package.json b/package.json index ac238b54fe569..e7b9848f77197 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,8 @@ "test": "jest", "test:coverage": "jest --coverage", "test:coverage-ci": "jest --coverage && codecov", - "test:watch": "jest --watch" + "test:watch": "jest --watch", + "publish:dev": "npm run build-clean && npm run build && lerna publish --npm-tag next", + "publish:prod": "npm run build-clean && npm run build && lerna publish" } } From 04e3babf141bbf93f33d620c46098ba4e3a16305 Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Thu, 10 Aug 2017 15:11:43 +1000 Subject: [PATCH 147/393] docs: Rename package name from `domReady` to `dom-ready` per actual npm module name --- packages/dom-ready/README.md | 6 +++--- packages/dom-ready/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/dom-ready/README.md b/packages/dom-ready/README.md index 3e132701d3bbf..a8c7bd0262877 100644 --- a/packages/dom-ready/README.md +++ b/packages/dom-ready/README.md @@ -1,4 +1,4 @@ -# @wordpress/domReady +# @wordpress/dom-ready Executes a function after the DOM has loaded. @@ -7,13 +7,13 @@ Executes a function after the DOM has loaded. Install the module ```bash -npm install @wordpress/domReady --save +npm install @wordpress/dom-ready --save ``` ### Usage ```JS -import domReady from '@wordpress/domReady'; +import domReady from '@wordpress/dom-ready'; domReady( function() { //do something after DOM loads. diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index f543488fbce71..80310c2b674e8 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -2,7 +2,7 @@ "name": "@wordpress/dom-ready", "version": "0.1.0-beta.1", "description": "Execute callback after the DOM is loaded.", - "homepage": "https://github.com/WordPress/packages/tree/master/packages/domReady/README.md", + "homepage": "https://github.com/WordPress/packages/tree/master/packages/dom-ready/README.md", "author": "WordPress", "keywords": [ "DOM", From 62b31d4a0ec1d4e0a537ac08401817fb627e7b3f Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Thu, 10 Aug 2017 15:04:35 +1000 Subject: [PATCH 148/393] Add initial `codecov.yml` configuration file Copied from https://github.com/WordPress/gutenberg/blob/master/codecov.yml --- codecov.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 codecov.yml diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000000000..a8de7bb2a0ba7 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,11 @@ +coverage: + status: + project: + default: + target: auto + threshold: 0.5% + patch: off + +comment: + require_changes: true + From a44e53a6cf9972a99dc4e5be78d14e454d4c205e Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Thu, 10 Aug 2017 15:01:54 +1000 Subject: [PATCH 149/393] Add a link to the @wordpress nom organisation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9104cfa169a18..0c9d55151dc4a 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,4 @@ [![Build Status](https://img.shields.io/travis/WordPress/packages/master.svg)](https://travis-ci.org/WordPress/packages) [![Coverage](https://img.shields.io/codecov/c/github/WordPress/packages/master.svg)](https://codecov.io/gh/WordPress/packages) -Collection of JS modules and tools for WordPress development +Collection of JS modules and tools for WordPress development available at https://www.npmjs.com/org/wordpress From 85fae753aa308f7823ac79ad1f1aaeb65f1e8034 Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Thu, 10 Aug 2017 14:47:39 +1000 Subject: [PATCH 150/393] Standardise package name format in README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See: • https://github.com/WordPress/packages/blob/master/packages/dom-ready/README.md • https://github.com/WordPress/packages/tree/master/packages/a11y --- packages/url/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/url/README.md b/packages/url/README.md index 59f5faa93cb2c..3943a364a21c1 100644 --- a/packages/url/README.md +++ b/packages/url/README.md @@ -1,4 +1,4 @@ -# WordPress URL Package +# @wordpress/url A collection of utilities to manipulate URLs From ca955004dc468aa2e2c9578616f5c4f0ad082329 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 11 Aug 2017 08:53:54 -0400 Subject: [PATCH 151/393] removeHook - accept a namespace parameter and use it to identify item for removal --- packages/hooks/src/createRemoveHook.js | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/packages/hooks/src/createRemoveHook.js b/packages/hooks/src/createRemoveHook.js index 6cb8d47c1b9aa..3eda8b130f59f 100644 --- a/packages/hooks/src/createRemoveHook.js +++ b/packages/hooks/src/createRemoveHook.js @@ -12,18 +12,12 @@ function createRemoveHook( hooks, removeAll ) { * Removes the specified callback (or all callbacks) from the hook with a * given name. * - * @param {string} hookName The name of the hook to modify. - * @param {?Function} callback The specific callback to be removed. If - * omitted (and `removeAll` is truthy), clears - * all callbacks. + * @param {string} hookName The name of the hook to modify. + * @param {string} namespace The unique namespace identifying the callback in the form `my-plugin-slug/functionDescription`. * - * @return {number} The number of callbacks removed. + * @return {number} The number of callbacks removed. */ - return function removeHook( hookName, callback ) { - if ( ! removeAll && typeof callback !== 'function' ) { - console.error( 'The hook callback to remove must be a function.' ); - return; - } + return function removeHook( hookName, namespace ) { // Bail if no hooks exist by this name if ( ! hooks.hasOwnProperty( hookName ) ) { @@ -42,7 +36,9 @@ function createRemoveHook( hooks, removeAll ) { // Try to find the specified callback to remove. const handlers = hooks[ hookName ].handlers; for ( let i = handlers.length - 1; i >= 0; i-- ) { - if ( handlers[ i ].callback === callback ) { + if ( + handlers[ i ].namespace === namespace + ) { handlers.splice( i, 1 ); handlersRemoved++; // This callback may also be part of a hook that is From cc8b852078dbd5b9fbfbfcf0f086c861fb2e0f41 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 11 Aug 2017 08:54:22 -0400 Subject: [PATCH 152/393] addHook - The hook name can only contain numbers, letters and underscores --- packages/hooks/src/createAddHook.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index 36ec8a6709a36..c466fdd1331d7 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -24,6 +24,11 @@ function createAddHook( hooks ) { return; } + if ( ! /^[a-z][a-z0-9_]*$/.test( hookName ) ) { + console.error( 'The hook name can only contain numbers, letters and underscores.' ); + return; + } + if ( typeof callback !== 'function' ) { console.error( 'The hook callback must be a function.' ); return; From 06ddd95a12f9663a0d0340479a9751f0158ee564 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 11 Aug 2017 08:58:46 -0400 Subject: [PATCH 153/393] addHook - accept a namespace parameter and store in handler data --- packages/hooks/src/createAddHook.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index c466fdd1331d7..500c20be05380 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -9,12 +9,13 @@ function createAddHook( hooks ) { /** * Adds the hook to the appropriate hooks container. * - * @param {string} hookName Name of hook to add - * @param {Function} callback Function to call when the hook is run - * @param {?number} priority Priority of this hook (default=10) + * @param {string} hookName Name of hook to add + * @param {string} namespace The unique namespace identifying the callback in the form `my-plugin-slug/functionDescription`. + * @param {Function} callback Function to call when the hook is run + * @param {?number} priority Priority of this hook (default=10) */ - return function addHook( hookName, callback, priority = 10 ) { - if ( typeof hookName !== 'string' ) { + return function addHook( hookName, namespace, callback, priority = 10 ) { + if ( 'string' !== typeof hookName ) { console.error( 'The hook name must be a string.' ); return; } @@ -40,7 +41,7 @@ function createAddHook( hooks ) { return; } - const handler = { callback, priority }; + const handler = { callback, priority, namespace }; if ( hooks.hasOwnProperty( hookName ) ) { // Find the correct insert index of the new hook. From edd46d05071fe0a47fb198c6a29ef69f62e3dade Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 11 Aug 2017 09:00:06 -0400 Subject: [PATCH 154/393] Use some Yoda conditionals --- packages/hooks/src/createAddHook.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index 500c20be05380..442db78048505 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -30,13 +30,13 @@ function createAddHook( hooks ) { return; } - if ( typeof callback !== 'function' ) { + if ( 'function' !== typeof callback ) { console.error( 'The hook callback must be a function.' ); return; } // Validate numeric priority - if ( typeof priority !== 'number' ) { + if ( 'number' !== typeof priority ) { console.error( 'If specified, the hook priority must be a number.' ); return; } From 77be5ed65b4baaa75825c2f4c0dc5e41fbebc2d1 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 11 Aug 2017 09:04:06 -0400 Subject: [PATCH 155/393] Ensure the passed namespace is a string of the form `my-plugin-slug/functionDescription --- packages/hooks/src/createAddHook.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index 442db78048505..0b3aa49c1bcf5 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -30,6 +30,16 @@ function createAddHook( hooks ) { return; } + if ( 'string' !== typeof namespace ) { + console.error( 'The namespace must be a string.' ); + return; + } + + if ( ! /^.*\/.*$/.test( namespace ) ) { + console.error( 'The namespace must take the form `my-plugin-slug/functionDescription' ); + return; + } + if ( 'function' !== typeof callback ) { console.error( 'The hook callback must be a function.' ); return; From 2c62cdc060bb366b661eb406bd58f3a3604f4030 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 11 Aug 2017 09:11:57 -0400 Subject: [PATCH 156/393] Add a build-modules command to run webpack --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 564f8a394e0cb..e7bef5d82838f 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "scripts": { "build-clean": "rimraf ./packages/*/build ./packages/*/build-browser ./packages/*/build-module", "build": "node ./scripts/build.js", + "build-modules": "webpack --progress -p", "test": "jest", "test:coverage": "jest --coverage", "test:coverage-ci": "jest --coverage && coveralls < coverage/lcov.info", From 581e7154a71de7dace1a9032330bbcb4b3b55e31 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 11 Aug 2017 10:32:42 -0400 Subject: [PATCH 157/393] Add a `validateNamespace` helper, centralizing namespace checks --- packages/hooks/src/validateNamespace.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 packages/hooks/src/validateNamespace.js diff --git a/packages/hooks/src/validateNamespace.js b/packages/hooks/src/validateNamespace.js new file mode 100644 index 0000000000000..f8d3e702ffa2a --- /dev/null +++ b/packages/hooks/src/validateNamespace.js @@ -0,0 +1,23 @@ +/** + * Validate a namespace. + * + * @param {string} namespace The namespace to validate. + * + * @return {bool} Whether the namespace is valid. + */ +function validateNamespace( namespace ) { + + if ( 'string' !== typeof namespace ) { + console.error( 'The namespace must be a string.' ); + return false; + } + + if ( ! /^.*\/.*$/.test( namespace ) ) { + console.error( 'The namespace must take the form `my-plugin-slug/functionDescription' ); + return false; + } + + return true; +} + +export default validateNamespace; From 4c7f252f998f9533217582fc065c25e73a22d0d8 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 11 Aug 2017 10:33:03 -0400 Subject: [PATCH 158/393] Add a `validateHookName` helper, centralizing hookName validation --- packages/hooks/src/validateHookName.js | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 packages/hooks/src/validateHookName.js diff --git a/packages/hooks/src/validateHookName.js b/packages/hooks/src/validateHookName.js new file mode 100644 index 0000000000000..7af1a264c705a --- /dev/null +++ b/packages/hooks/src/validateHookName.js @@ -0,0 +1,28 @@ +/** + * Validate a hook name. + * + * @param {string} hookName The hook name to validate. + * + * @return {bool} Whether the hook name is valid. + */ +function validateHookName( hookName ) { + + if ( 'string' !== typeof hookName ) { + console.error( 'The hook name must be a string.' ); + return false; + } + + if ( /^__/.test( hookName ) ) { + console.error( 'The hook name cannot begin with `__`.' ); + return false; + } + + if ( ! /^[a-z][a-z0-9_.-]*$/.test( hookName ) ) { + console.error( 'The hook name can only contain numbers, letters, dashes, periods and underscores.' ); + return false; + } + + return true; +} + +export default validateHookName; From ef069586d081b86614cf15b495b00e33afedd292 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 11 Aug 2017 10:34:25 -0400 Subject: [PATCH 159/393] Use new hookName and namespace validation helpers throughout generators for each hookName/namespace use --- packages/hooks/src/createAddHook.js | 23 +++++------------------ packages/hooks/src/createDidHook.js | 7 +++++++ packages/hooks/src/createRemoveHook.js | 15 +++++++++++++-- packages/hooks/src/createRunHook.js | 14 +++----------- 4 files changed, 28 insertions(+), 31 deletions(-) diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index 0b3aa49c1bcf5..6162d068766c9 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -1,3 +1,6 @@ +import validateNamespace from './validateNamespace.js'; +import validateHookName from './validateHookName.js'; + /** * Returns a function which, when invoked, will add a hook. * @@ -15,28 +18,12 @@ function createAddHook( hooks ) { * @param {?number} priority Priority of this hook (default=10) */ return function addHook( hookName, namespace, callback, priority = 10 ) { - if ( 'string' !== typeof hookName ) { - console.error( 'The hook name must be a string.' ); - return; - } - - if ( /^__/.test( hookName ) ) { - console.error( 'The hook name cannot begin with `__`.' ); - return; - } - - if ( ! /^[a-z][a-z0-9_]*$/.test( hookName ) ) { - console.error( 'The hook name can only contain numbers, letters and underscores.' ); - return; - } - if ( 'string' !== typeof namespace ) { - console.error( 'The namespace must be a string.' ); + if ( ! validateHookName( hookName ) ) { return; } - if ( ! /^.*\/.*$/.test( namespace ) ) { - console.error( 'The namespace must take the form `my-plugin-slug/functionDescription' ); + if ( ! validateNamespace( namespace ) ) { return; } diff --git a/packages/hooks/src/createDidHook.js b/packages/hooks/src/createDidHook.js index cdbcee8d50eb2..9871b10627756 100644 --- a/packages/hooks/src/createDidHook.js +++ b/packages/hooks/src/createDidHook.js @@ -1,3 +1,5 @@ +import validateHookName from './validateHookName.js'; + /** * Returns a function which, when invoked, will return the number of times a * hook has been called. @@ -15,6 +17,11 @@ function createDidHook( hooks ) { * @return {number} The number of times the hook has run. */ return function didHook( hookName ) { + + if ( ! validateHookName( hookName ) ) { + return; + } + return hooks.hasOwnProperty( hookName ) && hooks[ hookName ].runs ? hooks[ hookName ].runs : 0; diff --git a/packages/hooks/src/createRemoveHook.js b/packages/hooks/src/createRemoveHook.js index 3eda8b130f59f..9383cc1ec6598 100644 --- a/packages/hooks/src/createRemoveHook.js +++ b/packages/hooks/src/createRemoveHook.js @@ -1,16 +1,19 @@ +import validateNamespace from './validateNamespace.js'; +import validateHookName from './validateHookName.js'; + /** * Returns a function which, when invoked, will remove a specified hook or all * hooks by the given name. * * @param {Object} hooks Stored hooks, keyed by hook name. - * @param {bool} removeAll Whether to remove all hooked callbacks. + * @param {bool} removeAll Whether to remove all callbacks for a hookName, without regard to namespace. Used to create `removeAll*` functions. * * @return {Function} Function that removes hooks. */ function createRemoveHook( hooks, removeAll ) { /** * Removes the specified callback (or all callbacks) from the hook with a - * given name. + * given hookName and namespace. * * @param {string} hookName The name of the hook to modify. * @param {string} namespace The unique namespace identifying the callback in the form `my-plugin-slug/functionDescription`. @@ -19,6 +22,14 @@ function createRemoveHook( hooks, removeAll ) { */ return function removeHook( hookName, namespace ) { + if ( ! validateHookName( hookName ) ) { + return; + } + + if ( ! removeAll && ! validateNamespace( namespace ) ) { + return; + } + // Bail if no hooks exist by this name if ( ! hooks.hasOwnProperty( hookName ) ) { return 0; diff --git a/packages/hooks/src/createRunHook.js b/packages/hooks/src/createRunHook.js index 754a73e4dd89f..ac04fe74064e7 100644 --- a/packages/hooks/src/createRunHook.js +++ b/packages/hooks/src/createRunHook.js @@ -1,3 +1,5 @@ +import validateHookName from './validateHookName.js'; + /** * Returns a function which, when invoked, will execute all callbacks * registered to a hook of the specified type, optionally returning the final @@ -19,18 +21,8 @@ function createRunHook( hooks, returnFirstArg ) { * @return {*} Return value of runner, if applicable. */ return function runHooks( hookName, ...args ) { - if ( 'string' !== typeof hookName ) { - console.error( 'The hook name must be a string.' ); - return; - } - - if ( /^__/.test( hookName ) ) { - console.error( 'The hook name cannot begin with `__`.' ); - return; - } - if ( ! /^[a-z][a-z0-9_]*$/.test( hookName ) ) { - console.error( 'The hook name can only contain numbers, letters and underscores.' ); + if ( ! validateHookName( hookName ) ) { return; } From 319a023fe77cfefea88d69d595f777fe6053c743 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 11 Aug 2017 10:59:41 -0400 Subject: [PATCH 160/393] Update tests to use namespaces --- packages/hooks/src/test/index.test.js | 198 +++++++++++++------------- 1 file changed, 99 insertions(+), 99 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 7b3cafcebd6b1..f08fe77bc96ff 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -36,17 +36,17 @@ function filter_c( str ) { } function filter_b_removes_self( str ) { - removeFilter( 'test.filter', filter_b_removes_self ); + removeFilter( 'test.filter', 'my_plugin/my_callback_filter_b_removes_self' ); return str + 'b'; } function filter_removes_b( str ) { - removeFilter( 'test.filter', filter_b ); + removeFilter( 'test.filter', 'my_plugin/my_callback_filter_b' ); return str; } function filter_removes_c( str ) { - removeFilter( 'test.filter', filter_c ); + removeFilter( 'test.filter', 'my_plugin/my_callback_filter_c' ); return str; } @@ -86,58 +86,58 @@ test( 'run a filter with no callbacks', () => { } ); test( 'add and remove a filter', () => { - addFilter( 'test.filter', filter_a ); + addFilter( 'test.filter', 'my_plugin/my_callback', filter_a ); expect( removeAllFilters( 'test.filter' ) ).toEqual( 1 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); expect( removeAllFilters( 'test.filter' ) ).toEqual( 0 ); } ); test( 'add a filter and run it', () => { - addFilter( 'test.filter', filter_a ); + addFilter( 'test.filter', 'my_plugin/my_callback', filter_a ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testa' ); } ); test( 'add 2 filters in a row and run them', () => { - addFilter( 'test.filter', filter_a ); - addFilter( 'test.filter', filter_b ); + addFilter( 'test.filter', 'my_plugin/my_callback', filter_a ); + addFilter( 'test.filter', 'my_plugin/my_callback', filter_b ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); } ); test( 'remove a non-existent filter', () => { - expect( removeFilter( 'test.filter', filter_a ) ).toEqual( 0 ); + expect( removeFilter( 'test.filter', 'my_plugin/my_callback', filter_a ) ).toEqual( 0 ); expect( removeAllFilters( 'test.filter' ) ).toEqual( 0 ); } ); -test( 'remove an invalid callback from a filter', () => { +test( 'remove an invalid namespace from a filter', () => { expect( removeFilter( 'test.filter', 42 ) ).toEqual( undefined ); expect( console.error ).toHaveBeenCalledWith( - 'The hook callback to remove must be a function.' + 'The namespace must be a string.' ); } ); test( 'cannot add filters with non-string names', () => { - addFilter( 42, () => null ); + addFilter( 42, 'my_plugin/my_callback', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The hook name must be a string.' ); } ); test( 'cannot add filters named with __ prefix', () => { - addFilter( '__test', () => null ); + addFilter( '__test', 'my_plugin/my_callback', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The hook name cannot begin with `__`.' ); } ); test( 'cannot add filters with non-function callbacks', () => { - addFilter( 'test', '42' ); + addFilter( 'test', 'my_plugin/my_callback', '42' ); expect( console.error ).toHaveBeenCalledWith( 'The hook callback must be a function.' ); } ); test( 'cannot add filters with non-numeric priorities', () => { - addFilter( 'test', () => null, '42' ); + addFilter( 'test', 'my_plugin/my_callback', () => null, '42' ); expect( console.error ).toHaveBeenCalledWith( 'If specified, the hook priority must be a number.' ); @@ -158,9 +158,9 @@ test( 'cannot run filters named with __ prefix', () => { } ); test( 'add 3 filters with different priorities and run them', () => { - addFilter( 'test.filter', filter_a ); - addFilter( 'test.filter', filter_b, 2 ); - addFilter( 'test.filter', filter_c, 8 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_a', filter_a ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_b', filter_b, 2 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_c', filter_c, 8 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testbca' ); } ); @@ -175,34 +175,34 @@ test( 'filters with the same and different priorities', () => { } ); } ); - addFilter( 'test_order', callbacks.fn_3a, 3 ); - addFilter( 'test_order', callbacks.fn_3b, 3 ); - addFilter( 'test_order', callbacks.fn_3c, 3 ); - addFilter( 'test_order', callbacks.fn_2a, 2 ); - addFilter( 'test_order', callbacks.fn_2b, 2 ); - addFilter( 'test_order', callbacks.fn_2c, 2 ); + addFilter( 'test_order', 'my_plugin/my_callback_fn_3a', callbacks.fn_3a, 3 ); + addFilter( 'test_order', 'my_plugin/my_callback_fn_3b', callbacks.fn_3b, 3 ); + addFilter( 'test_order', 'my_plugin/my_callback_fn_3c', callbacks.fn_3c, 3 ); + addFilter( 'test_order', 'my_plugin/my_callback_fn_2a', callbacks.fn_2a, 2 ); + addFilter( 'test_order', 'my_plugin/my_callback_fn_2b', callbacks.fn_2b, 2 ); + addFilter( 'test_order', 'my_plugin/my_callback_fn_2c', callbacks.fn_2c, 2 ); expect( applyFilters( 'test_order', [] ) ).toEqual( [ '2a', '2b', '2c', '3a', '3b', '3c' ] ); - removeFilter( 'test_order', callbacks.fn_2b ); - removeFilter( 'test_order', callbacks.fn_3a ); + removeFilter( 'test_order', 'my_plugin/my_callback_fn_2b', callbacks.fn_2b ); + removeFilter( 'test_order', 'my_plugin/my_callback_fn_3a', callbacks.fn_3a ); expect( applyFilters( 'test_order', [] ) ).toEqual( [ '2a', '2c', '3b', '3c' ] ); - addFilter( 'test_order', callbacks.fn_4a, 4 ); - addFilter( 'test_order', callbacks.fn_4b, 4 ); - addFilter( 'test_order', callbacks.fn_1a, 1 ); - addFilter( 'test_order', callbacks.fn_4c, 4 ); - addFilter( 'test_order', callbacks.fn_1b, 1 ); - addFilter( 'test_order', callbacks.fn_3d, 3 ); - addFilter( 'test_order', callbacks.fn_4d, 4 ); - addFilter( 'test_order', callbacks.fn_1c, 1 ); - addFilter( 'test_order', callbacks.fn_2d, 2 ); - addFilter( 'test_order', callbacks.fn_1d, 1 ); + addFilter( 'test_order', 'my_plugin/my_callback_fn_4a', callbacks.fn_4a, 4 ); + addFilter( 'test_order', 'my_plugin/my_callback_fn_4b', callbacks.fn_4b, 4 ); + addFilter( 'test_order', 'my_plugin/my_callback_fn_1a', callbacks.fn_1a, 1 ); + addFilter( 'test_order', 'my_plugin/my_callback_fn_4c', callbacks.fn_4c, 4 ); + addFilter( 'test_order', 'my_plugin/my_callback_fn_1b', callbacks.fn_1b, 1 ); + addFilter( 'test_order', 'my_plugin/my_callback_fn_3d', callbacks.fn_3d, 3 ); + addFilter( 'test_order', 'my_plugin/my_callback_fn_4d', callbacks.fn_4d, 4 ); + addFilter( 'test_order', 'my_plugin/my_callback_fn_1c', callbacks.fn_1c, 1 ); + addFilter( 'test_order', 'my_plugin/my_callback_fn_2d', callbacks.fn_2d, 2 ); + addFilter( 'test_order', 'my_plugin/my_callback_fn_1d', callbacks.fn_1d, 1 ); expect( applyFilters( 'test_order', [] ) ).toEqual( [ // all except 2b and 3a, which we removed earlier @@ -214,29 +214,29 @@ test( 'filters with the same and different priorities', () => { } ); test( 'add and remove an action', () => { - addAction( 'test.action', action_a ); + addAction( 'test.action', 'my_plugin/my_callback', action_a ); expect( removeAllActions( 'test.action' ) ).toEqual( 1 ); expect( doAction( 'test.action' ) ).toBe( undefined ); expect( window.actionValue ).toBe( '' ); } ); test( 'add an action and run it', () => { - addAction( 'test.action', action_a ); + addAction( 'test.action', 'my_plugin/my_callback', action_a ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'a' ); } ); test( 'add 2 actions in a row and then run them', () => { - addAction( 'test.action', action_a ); - addAction( 'test.action', action_b ); + addAction( 'test.action', 'my_plugin/my_callback', action_a ); + addAction( 'test.action', 'my_plugin/my_callback', action_b ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'ab' ); } ); test( 'add 3 actions with different priorities and run them', () => { - addAction( 'test.action', action_a ); - addAction( 'test.action', action_b, 2 ); - addAction( 'test.action', action_c, 8 ); + addAction( 'test.action', 'my_plugin/my_callback', action_a ); + addAction( 'test.action', 'my_plugin/my_callback', action_b, 2 ); + addAction( 'test.action', 'my_plugin/my_callback', action_c, 8 ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'bca' ); } ); @@ -245,7 +245,7 @@ test( 'pass in two arguments to an action', () => { const arg1 = { a: 10 }; const arg2 = { b: 20 }; - addAction( 'test.action', ( a, b ) => { + addAction( 'test.action', 'my_plugin/my_callback', ( a, b ) => { expect( a ).toBe( arg1 ); expect( b ).toBe( arg2 ); } ); @@ -259,14 +259,14 @@ test( 'fire action multiple times', () => { expect( true ).toBe( true ); }; - addAction( 'test.action', func ); + addAction( 'test.action', 'my_plugin/my_callback', func ); doAction( 'test.action' ); doAction( 'test.action' ); } ); test( 'add a filter before the one currently executing', () => { - addFilter( 'test.filter', val => { - addFilter( 'test.filter', val => val + 'a', 1 ); + addFilter( 'test.filter', 'my_plugin/my_callback', val => { + addFilter( 'test.filter', 'my_plugin/my_callback', val => val + 'a', 1 ); return val + 'b'; }, 2 ); @@ -274,8 +274,8 @@ test( 'add a filter before the one currently executing', () => { } ); test( 'add a filter after the one currently executing', () => { - addFilter( 'test.filter', val => { - addFilter( 'test.filter', val => val + 'b', 2 ); + addFilter( 'test.filter', 'my_plugin/my_callback', val => { + addFilter( 'test.filter', 'my_plugin/my_callback', val => val + 'b', 2 ); return val + 'a'; }, 1 ); @@ -283,8 +283,8 @@ test( 'add a filter after the one currently executing', () => { } ); test( 'add a filter immediately after the one currently executing', () => { - addFilter( 'test.filter', val => { - addFilter( 'test.filter', val => val + 'b', 1 ); + addFilter( 'test.filter', 'my_plugin/my_callback', val => { + addFilter( 'test.filter', 'my_plugin/my_callback', val => val + 'b', 1 ); return val + 'a'; }, 1 ); @@ -292,19 +292,19 @@ test( 'add a filter immediately after the one currently executing', () => { } ); test( 'remove specific action callback', () => { - addAction( 'test.action', action_a ); - addAction( 'test.action', action_b, 2 ); - addAction( 'test.action', action_c, 8 ); + addAction( 'test.action', 'my_plugin/my_callback_action_a', action_a ); + addAction( 'test.action', 'my_plugin/my_callback_action_b', action_b, 2 ); + addAction( 'test.action', 'my_plugin/my_callback_action_c', action_c, 8 ); - expect( removeAction( 'test.action', action_b ) ).toEqual( 1 ); + expect( removeAction( 'test.action', 'my_plugin/my_callback_action_b' ) ).toEqual( 1 ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'ca' ); } ); test( 'remove all action callbacks', () => { - addAction( 'test.action', action_a ); - addAction( 'test.action', action_b, 2 ); - addAction( 'test.action', action_c, 8 ); + addAction( 'test.action', 'my_plugin/my_callback_action_a', action_a ); + addAction( 'test.action', 'my_plugin/my_callback_action_b', action_b, 2 ); + addAction( 'test.action', 'my_plugin/my_callback_action_c', action_c, 8 ); expect( removeAllActions( 'test.action' ) ).toEqual( 3 ); doAction( 'test.action' ); @@ -312,71 +312,71 @@ test( 'remove all action callbacks', () => { } ); test( 'remove specific filter callback', () => { - addFilter( 'test.filter', filter_a ); - addFilter( 'test.filter', filter_b, 2 ); - addFilter( 'test.filter', filter_c, 8 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_a', filter_a ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_b', filter_b, 2 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_c', filter_c, 8 ); - expect( removeFilter( 'test.filter', filter_b ) ).toEqual( 1 ); + expect( removeFilter( 'test.filter', 'my_plugin/my_callback_filter_b' ) ).toEqual( 1 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testca' ); } ); test( 'filter removes a callback that has already executed', () => { - addFilter( 'test.filter', filter_a, 1 ); - addFilter( 'test.filter', filter_b, 3 ); - addFilter( 'test.filter', filter_c, 5 ); - addFilter( 'test.filter', filter_removes_b, 4 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_a', filter_a, 1 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_b', filter_b, 3 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_c', filter_c, 5 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_removes_b', filter_removes_b, 4 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); test( 'filter removes a callback that has already executed (same priority)', () => { - addFilter( 'test.filter', filter_a, 1 ); - addFilter( 'test.filter', filter_b, 2 ); - addFilter( 'test.filter', filter_removes_b, 2 ); - addFilter( 'test.filter', filter_c, 4 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_a', filter_a, 1 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_b', filter_b, 2 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_removes_b', filter_removes_b, 2 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_c', filter_c, 4 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); test( 'filter removes the current callback', () => { - addFilter( 'test.filter', filter_a, 1 ); - addFilter( 'test.filter', filter_b_removes_self, 3 ); - addFilter( 'test.filter', filter_c, 5 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_a', filter_a, 1 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_b_removes_self', filter_b_removes_self, 3 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_c', filter_c, 5 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); test( 'filter removes a callback that has not yet executed (last)', () => { - addFilter( 'test.filter', filter_a, 1 ); - addFilter( 'test.filter', filter_b, 3 ); - addFilter( 'test.filter', filter_c, 5 ); - addFilter( 'test.filter', filter_removes_c, 4 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_a', filter_a, 1 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_b', filter_b, 3 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_c', filter_c, 5 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_removes_c', filter_removes_c, 4 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); } ); test( 'filter removes a callback that has not yet executed (middle)', () => { - addFilter( 'test.filter', filter_a, 1 ); - addFilter( 'test.filter', filter_b, 3 ); - addFilter( 'test.filter', filter_c, 4 ); - addFilter( 'test.filter', filter_removes_b, 2 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_a', filter_a, 1 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_b', filter_b, 3 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_c', filter_c, 4 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_removes_b', filter_removes_b, 2 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); } ); test( 'filter removes a callback that has not yet executed (same priority)', () => { - addFilter( 'test.filter', filter_a, 1 ); - addFilter( 'test.filter', filter_removes_b, 2 ); - addFilter( 'test.filter', filter_b, 2 ); - addFilter( 'test.filter', filter_c, 4 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_a', filter_a, 1 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_removes_b', filter_removes_b, 2 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_b', filter_b, 2 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_c', filter_c, 4 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); } ); test( 'remove all filter callbacks', () => { - addFilter( 'test.filter', filter_a ); - addFilter( 'test.filter', filter_b, 2 ); - addFilter( 'test.filter', filter_c, 8 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_a', filter_a ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_b', filter_b, 2 ); + addFilter( 'test.filter', 'my_plugin/my_callback_filter_c', filter_c, 8 ); expect( removeAllFilters( 'test.filter' ) ).toEqual( 3 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); @@ -386,7 +386,7 @@ test( 'remove all filter callbacks', () => { test( 'Test doingAction, didAction and hasAction.', () => { let actionCalls = 0; - addAction( 'another.action', () => {} ); + addAction( 'another.action', 'my_plugin/my_callback', () => {} ); doAction( 'another.action' ); // Verify no action is running yet. @@ -395,7 +395,7 @@ test( 'Test doingAction, didAction and hasAction.', () => { expect( didAction( 'test.action' ) ).toBe( 0 ); expect( hasAction( 'test.action' ) ).toBe( 0 ); - addAction( 'test.action', () => { + addAction( 'test.action', 'my_plugin/my_callback', () => { actionCalls++; expect( currentAction() ).toBe( 'test.action' ); expect( doingAction() ).toBe( true ); @@ -440,7 +440,7 @@ test( 'Test doingAction, didAction and hasAction.', () => { test( 'Verify doingFilter, didFilter and hasFilter.', () => { let filterCalls = 0; - addFilter( 'runtest.filter', arg => { + addFilter( 'runtest.filter', 'my_plugin/my_callback', arg => { filterCalls++; expect( currentFilter() ).toBe( 'runtest.filter' ); expect( doingFilter() ).toBe( true ); @@ -467,7 +467,7 @@ test( 'Verify doingFilter, didFilter and hasFilter.', () => { } ); test( 'recursively calling a filter', () => { - addFilter( 'test.filter', value => { + addFilter( 'test.filter', 'my_plugin/my_callback', value => { if ( value.length === 7 ) { return value; } @@ -478,11 +478,11 @@ test( 'recursively calling a filter', () => { } ); test( 'current filter when multiple filters are running', () => { - addFilter( 'test.filter1', value => { + addFilter( 'test.filter1', 'my_plugin/my_callback', value => { return applyFilters( 'test.filter2', value.concat( currentFilter() ) ); } ); - addFilter( 'test.filter2', value => { + addFilter( 'test.filter2', 'my_plugin/my_callback', value => { return value.concat( currentFilter() ); } ); @@ -497,16 +497,16 @@ test( 'current filter when multiple filters are running', () => { test( 'adding and removing filters with recursion', () => { function removeRecurseAndAdd2( val ) { - expect( removeFilter( 'remove_and_add', removeRecurseAndAdd2 ) ).toEqual( 1 ); + expect( removeFilter( 'remove_and_add', 'my_plugin/my_callback_recurse' ) ).toEqual( 1 ); val += '-' + applyFilters( 'remove_and_add', '' ) + '-'; - addFilter( 'remove_and_add', removeRecurseAndAdd2, 10 ); + addFilter( 'remove_and_add', 'my_plugin/my_callback_recurse', 10 ); return val + '2'; } - addFilter( 'remove_and_add', val => val + '1', 11 ); - addFilter( 'remove_and_add', removeRecurseAndAdd2, 12 ); - addFilter( 'remove_and_add', val => val + '3', 13 ); - addFilter( 'remove_and_add', val => val + '4', 14 ); + addFilter( 'remove_and_add', 'my_plugin/my_callback', val => val + '1', 11 ); + addFilter( 'remove_and_add', 'my_plugin/my_callback_recurse', removeRecurseAndAdd2, 12 ); + addFilter( 'remove_and_add', 'my_plugin/my_callback', val => val + '3', 13 ); + addFilter( 'remove_and_add', 'my_plugin/my_callback', val => val + '4', 14 ); expect( applyFilters( 'remove_and_add', '' ) ).toEqual( '1-134-234' ); } ); From 4ece207a8465dce14ca5f2cab9d3bcc9f0c5a06f Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 11 Aug 2017 12:48:02 -0400 Subject: [PATCH 161/393] Update readme with new hook/namespace signature --- packages/hooks/README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/hooks/README.md b/packages/hooks/README.md index 1174727feffc6..68b27163deb12 100644 --- a/packages/hooks/README.md +++ b/packages/hooks/README.md @@ -6,20 +6,20 @@ A lightweight & efficient EventManager for JavaScript in WordPress. ### API Usage API functions can be called via the global `wp.hooks` like this `wp.hooks.addAction()`, etc. -* `addAction( 'namespace.identifier', callback, priority )` -* `addFilter( 'namespace.identifier', callback, priority )` -* `removeAction( 'namespace.identifier', callback )` -* `removeFilter( 'namespace.identifier', callback )` -* `removeAllActions( 'namespace.identifier' )` -* `removeAllFilters( 'namespace.identifier' )` -* `doAction( 'namespace.identifier', arg1, arg2, moreArgs, finalArg )` -* `applyFilters( 'namespace.identifier', content )` -* `doingAction( 'namespace.identifier' )` -* `doingFilter( 'namespace.identifier' )` -* `didAction( 'namespace.identifier' )` -* `didFilter( 'namespace.identifier' )` -* `hasAction( 'namespace.identifier' )` -* `hasFilter( 'namespace.identifier' )` +* `addAction( 'hook_name', 'my_plugin/my_callback', callback, priority )` +* `addFilter( 'hook_name', 'my_plugin/my_callback', callback, priority )` +* `removeAction( 'hook_name', 'my_plugin/my_callback' )` +* `removeFilter( 'hook_name', 'my_plugin/my_callback' )` +* `removeAllActions( 'hook_name' )` +* `removeAllFilters( 'hook_name' )` +* `doAction( 'hook_name', arg1, arg2, moreArgs, finalArg )` +* `applyFilters( 'hook_name', content )` +* `doingAction( 'hook_name' )` +* `doingFilter( 'hook_name' )` +* `didAction( 'hook_name' )` +* `didFilter( 'hook_name' )` +* `hasAction( 'hook_name' )` +* `hasFilter( 'hook_name' )` ### Background From aa709ac97ceb3ecf52651c16a4fae686680abc39 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 11 Aug 2017 22:09:58 -0400 Subject: [PATCH 162/393] Improve validateNamespace and validateHookName inline docs --- packages/hooks/src/validateHookName.js | 6 ++++-- packages/hooks/src/validateNamespace.js | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/hooks/src/validateHookName.js b/packages/hooks/src/validateHookName.js index 7af1a264c705a..963f4c3cf049d 100644 --- a/packages/hooks/src/validateHookName.js +++ b/packages/hooks/src/validateHookName.js @@ -1,7 +1,9 @@ /** - * Validate a hook name. + * Validate a hookName string. * - * @param {string} hookName The hook name to validate. + * @param {string} hookName The hook name to validate. Should be a non empty string containing + * only numbers, letters, dashes, periods and underscores. Also, + * the hook name cannot begin with `__`. * * @return {bool} Whether the hook name is valid. */ diff --git a/packages/hooks/src/validateNamespace.js b/packages/hooks/src/validateNamespace.js index f8d3e702ffa2a..4d8172aedbfea 100644 --- a/packages/hooks/src/validateNamespace.js +++ b/packages/hooks/src/validateNamespace.js @@ -1,7 +1,8 @@ /** - * Validate a namespace. + * Validate a namespace string. * - * @param {string} namespace The namespace to validate. + * @param {string} namespace The namespace to validate - should take the form + * `my-plugin-slug/functionDescription`. * * @return {bool} Whether the namespace is valid. */ From a8628a0601f69d3683a03f9d799cb782ea5f1ae6 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 11 Aug 2017 22:10:31 -0400 Subject: [PATCH 163/393] require a non-empty string when validating namespace/hookName --- packages/hooks/src/validateHookName.js | 4 ++-- packages/hooks/src/validateNamespace.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/hooks/src/validateHookName.js b/packages/hooks/src/validateHookName.js index 963f4c3cf049d..62ffe5ea7e6a9 100644 --- a/packages/hooks/src/validateHookName.js +++ b/packages/hooks/src/validateHookName.js @@ -9,8 +9,8 @@ */ function validateHookName( hookName ) { - if ( 'string' !== typeof hookName ) { - console.error( 'The hook name must be a string.' ); + if ( 'string' !== typeof hookName || '' === hookName ) { + console.error( 'The hook name must be a non-empty string.' ); return false; } diff --git a/packages/hooks/src/validateNamespace.js b/packages/hooks/src/validateNamespace.js index 4d8172aedbfea..b0cfe39d297da 100644 --- a/packages/hooks/src/validateNamespace.js +++ b/packages/hooks/src/validateNamespace.js @@ -8,8 +8,8 @@ */ function validateNamespace( namespace ) { - if ( 'string' !== typeof namespace ) { - console.error( 'The namespace must be a string.' ); + if ( 'string' !== typeof namespace || '' === namespace ) { + console.error( 'The namespace must be a non-empty string.' ); return false; } From 242f351a9e7d8132081028bdedb1532b3889acca Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 11 Aug 2017 22:12:35 -0400 Subject: [PATCH 164/393] Adjust expected error language in tests. --- packages/hooks/src/test/index.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index f08fe77bc96ff..419bdb3aeb5f7 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -111,14 +111,14 @@ test( 'remove a non-existent filter', () => { test( 'remove an invalid namespace from a filter', () => { expect( removeFilter( 'test.filter', 42 ) ).toEqual( undefined ); expect( console.error ).toHaveBeenCalledWith( - 'The namespace must be a string.' + 'The namespace must be a non-empty string.' ); } ); test( 'cannot add filters with non-string names', () => { addFilter( 42, 'my_plugin/my_callback', () => null ); expect( console.error ).toHaveBeenCalledWith( - 'The hook name must be a string.' + 'The hook name must be a non-empty string.' ); } ); @@ -146,7 +146,7 @@ test( 'cannot add filters with non-numeric priorities', () => { test( 'cannot run filters with non-string names', () => { expect( applyFilters( () => {}, 42 ) ).toBe( undefined ); expect( console.error ).toHaveBeenCalledWith( - 'The hook name must be a string.' + 'The hook name must be a non-empty string.' ); } ); From d8af28fc7f67f6348ef1d4f0e3512562d4cb965c Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 11 Aug 2017 22:47:27 -0400 Subject: [PATCH 165/393] Improved regexes for hookName and namespace validation --- packages/hooks/src/validateHookName.js | 2 +- packages/hooks/src/validateNamespace.js | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/hooks/src/validateHookName.js b/packages/hooks/src/validateHookName.js index 62ffe5ea7e6a9..0059695421125 100644 --- a/packages/hooks/src/validateHookName.js +++ b/packages/hooks/src/validateHookName.js @@ -19,7 +19,7 @@ function validateHookName( hookName ) { return false; } - if ( ! /^[a-z][a-z0-9_.-]*$/.test( hookName ) ) { + if ( ! /^[a-zA-Z][a-zA-Z0-9_.-]*$/.test( hookName ) ) { console.error( 'The hook name can only contain numbers, letters, dashes, periods and underscores.' ); return false; } diff --git a/packages/hooks/src/validateNamespace.js b/packages/hooks/src/validateNamespace.js index b0cfe39d297da..b12605338b379 100644 --- a/packages/hooks/src/validateNamespace.js +++ b/packages/hooks/src/validateNamespace.js @@ -13,8 +13,13 @@ function validateNamespace( namespace ) { return false; } - if ( ! /^.*\/.*$/.test( namespace ) ) { - console.error( 'The namespace must take the form `my-plugin-slug/functionDescription' ); + if ( ! /^[a-zA-Z][a-zA-Z0-9_.-/]*$/.test( namespace ) ) { + console.error( 'The namespace can only contain numbers, letters, dashes, periods and underscores, plus the forward slash dividing slug and description in the namespace.' ); + return false; + } + + if ( ! /^[a-zA-Z][a-zA-Z0-9_.-]*\/[a-zA-Z][a-zA-Z0-9_.-]*$/.test( namespace ) ) { + console.error( 'The namespace must take the form `my-plugin-slug/functionDescription`.' ); return false; } From 650e9e23570d20f50d37556223585a32ce94d927 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 11 Aug 2017 22:47:47 -0400 Subject: [PATCH 166/393] Add more tests around hookName and namespace validation --- packages/hooks/src/test/index.test.js | 57 ++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 419bdb3aeb5f7..17e76f65251c4 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -115,13 +115,68 @@ test( 'remove an invalid namespace from a filter', () => { ); } ); -test( 'cannot add filters with non-string names', () => { +test( 'cannot add filters with non-string hook names', () => { addFilter( 42, 'my_plugin/my_callback', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The hook name must be a non-empty string.' ); } ); +test( 'cannot add filters with empty-string hook names', () => { + addFilter( '', 'my_plugin/my_callback', () => null ); + expect( console.error ).toHaveBeenCalledWith( + 'The hook name must be a non-empty string.' + ); +} ); + +test( 'cannot add filters with empty-string namespaces', () => { + addFilter( 'hook_name', '', () => null ); + expect( console.error ).toHaveBeenCalledWith( + 'The namespace must be a non-empty string.' + ); +} ); + +test( 'cannot add filters with invalid namespaces', () => { + addFilter( 'hook_name', 'invalid_name', () => null ); + expect( console.error ).toHaveBeenCalledWith( + 'The namespace must take the form `my-plugin-slug/functionDescription`.' + ); +} ); + +test( 'cannot add filters with namespaces missing a functionDescription', () => { + addFilter( 'hook_name', 'invalid_name/', () => null ); + expect( console.error ).toHaveBeenCalledWith( + 'The namespace must take the form `my-plugin-slug/functionDescription`.' + ); +} ); + +test( 'Can add filters with capitals in namespaces', () => { + addFilter( 'hook_name', 'OhNo/action', () => null ); + expect( console.error ).toHaveBeenCalledTimes( 0 ); +} ); + +test( 'Can add filters with capitals in hookName', () => { + addFilter( 'hookName', 'plugin/action', () => null ); + expect( console.error ).toHaveBeenCalledTimes( 0 ); +} ); + +test( 'Can add filters with periods in namespaces', () => { + addFilter( 'hook_name', 'plugin.name/ok.action', () => null ); + expect( console.error ).toHaveBeenCalledTimes( 0 ); +} ); + +test( 'Can add filters with periods in hookName', () => { + addFilter( 'hook.name', 'plugin/action', () => null ); + expect( console.error ).toHaveBeenCalledTimes( 0 ); +} ); + +test( 'cannot add filters with invalid namespaces', () => { + addFilter( 'hook_name', '/invalid_name', () => null ); + expect( console.error ).toHaveBeenCalledWith( + 'The namespace can only contain numbers, letters, dashes, periods and underscores, plus the forward slash dividing slug and description in the namespace.' + ); +} ); + test( 'cannot add filters named with __ prefix', () => { addFilter( '__test', 'my_plugin/my_callback', () => null ); expect( console.error ).toHaveBeenCalledWith( From ac44be339b5895e029854bc3b53617e6c600d282 Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Tue, 15 Aug 2017 15:11:59 +0200 Subject: [PATCH 167/393] Add test for making sure `addQueryArgs` updates existing arguments. This is to ensure it will not leave duplicate arguments behind. --- packages/url/src/test/index.test.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/url/src/test/index.test.js b/packages/url/src/test/index.test.js index 82e5729a8cab2..08d29b64d47c9 100644 --- a/packages/url/src/test/index.test.js +++ b/packages/url/src/test/index.test.js @@ -17,4 +17,11 @@ describe( 'addQueryArgs', () => { expect( addQueryArgs( url, args ) ).toBe( 'https://andalouses.com/beach?night=false&sun=true&sand=false' ); } ); + + test( 'should update args to an URL with conflicting query string', () => { + const url = 'https://andalouses.com/beach?night=false&sun=false&sand=true'; + const args = { sun: 'true', sand: 'false' }; + + expect( addQueryArgs( url, args ) ).toBe( 'https://andalouses.com/beach?night=false&sun=true&sand=false' ); + } ); } ); From a4f78c021b7820fd3e6c8fd7d1321afa27d6607a Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Tue, 15 Aug 2017 23:22:54 +1000 Subject: [PATCH 168/393] tests: Use the generic domain `example.com` in tests --- packages/url/src/test/index.test.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/url/src/test/index.test.js b/packages/url/src/test/index.test.js index 08d29b64d47c9..0772c04a98d05 100644 --- a/packages/url/src/test/index.test.js +++ b/packages/url/src/test/index.test.js @@ -5,23 +5,23 @@ import { addQueryArgs } from '../'; describe( 'addQueryArgs', () => { test( 'should append args to an URL without query string', () => { - const url = 'https://andalouses.com/beach'; + const url = 'https://example.com/beach'; const args = { sun: 'true', sand: 'false' }; - expect( addQueryArgs( url, args ) ).toBe( 'https://andalouses.com/beach?sun=true&sand=false' ); + expect( addQueryArgs( url, args ) ).toBe( 'https://example.com/beach?sun=true&sand=false' ); } ); test( 'should append args to an URL with query string', () => { - const url = 'https://andalouses.com/beach?night=false'; + const url = 'https://example.com/beach?night=false'; const args = { sun: 'true', sand: 'false' }; - expect( addQueryArgs( url, args ) ).toBe( 'https://andalouses.com/beach?night=false&sun=true&sand=false' ); + expect( addQueryArgs( url, args ) ).toBe( 'https://example.com/beach?night=false&sun=true&sand=false' ); } ); test( 'should update args to an URL with conflicting query string', () => { - const url = 'https://andalouses.com/beach?night=false&sun=false&sand=true'; + const url = 'https://example.com/beach?night=false&sun=false&sand=true'; const args = { sun: 'true', sand: 'false' }; - expect( addQueryArgs( url, args ) ).toBe( 'https://andalouses.com/beach?night=false&sun=true&sand=false' ); + expect( addQueryArgs( url, args ) ).toBe( 'https://example.com/beach?night=false&sun=true&sand=false' ); } ); } ); From 92a320ad454f208db514e626eb59e3ee5ebfbe34 Mon Sep 17 00:00:00 2001 From: omarreiss Date: Tue, 15 Aug 2017 16:20:30 +0200 Subject: [PATCH 169/393] unapply all array spacing exceptions. --- packages/a11y/src/clear.js | 2 +- packages/a11y/src/test/addContainer.test.js | 14 ++--- packages/a11y/src/test/clear.test.js | 4 +- packages/a11y/src/test/filterMessage.test.js | 14 ++--- packages/a11y/src/test/index.test.js | 60 ++++++++++---------- packages/dom-ready/src/test/index.test.js | 20 +++---- 6 files changed, 57 insertions(+), 57 deletions(-) diff --git a/packages/a11y/src/clear.js b/packages/a11y/src/clear.js index b2226f0210806..87ae91ab2bcc9 100644 --- a/packages/a11y/src/clear.js +++ b/packages/a11y/src/clear.js @@ -4,7 +4,7 @@ const clear = function() { let regions = document.querySelectorAll( '.a11y-speak-region' ); for ( let i = 0; i < regions.length; i++ ) { - regions[i].textContent = ''; + regions[ i ].textContent = ''; } }; diff --git a/packages/a11y/src/test/addContainer.test.js b/packages/a11y/src/test/addContainer.test.js index 8bde66e6711b2..dfeac8dbbae5e 100644 --- a/packages/a11y/src/test/addContainer.test.js +++ b/packages/a11y/src/test/addContainer.test.js @@ -12,8 +12,8 @@ describe( 'addContainer', () => { expect( container.getAttribute( 'aria-live' ) ).toBe( 'polite' ); expect( container.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); expect( container.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); - }); - }); + } ); + } ); describe( 'with assertive param', () => { it( 'should create an aria-live element with aria-live attr set to assertive', () => { @@ -26,8 +26,8 @@ describe( 'addContainer', () => { expect( container.getAttribute( 'aria-live' ) ).toBe( 'assertive' ); expect( container.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); expect( container.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); - }); - }); + } ); + } ); describe( 'without param', () => { it( 'should default to creating an aria-live element with aria-live attr set to polite', () => { @@ -40,6 +40,6 @@ describe( 'addContainer', () => { expect( container.getAttribute( 'aria-live' ) ).toBe( 'polite' ); expect( container.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); expect( container.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); - }); - }); -}); + } ); + } ); +} ); diff --git a/packages/a11y/src/test/clear.test.js b/packages/a11y/src/test/clear.test.js index 70655bfc748b0..f3c006eebbe53 100644 --- a/packages/a11y/src/test/clear.test.js +++ b/packages/a11y/src/test/clear.test.js @@ -15,5 +15,5 @@ describe( 'clear', () => { clear(); expect( container1.textContent ).toBe( '' ); expect( container2.textContent ).toBe( '' ); - }); -}); + } ); +} ); diff --git a/packages/a11y/src/test/filterMessage.test.js b/packages/a11y/src/test/filterMessage.test.js index 575dd11c6bd7e..9ce179cb2ae19 100644 --- a/packages/a11y/src/test/filterMessage.test.js +++ b/packages/a11y/src/test/filterMessage.test.js @@ -5,21 +5,21 @@ describe( 'filterMessage', () => { it( 'should return the message unfiltered', () => { let actual = filterMessage( 'clean message.' ); expect( actual ).toBe( 'clean message.' ); - }); - }); + } ); + } ); describe( 'when a message is passed in twice in a row', () => { it( 'should add a space to the message to make sure it is announced again', () => { filterMessage( 'repeated message.' ); let actual = filterMessage( 'repeated message.' ); expect( actual ).toBe( 'repeated message.' + '\u00A0' ); - }); - }); + } ); + } ); describe( 'when a message contains html tags', () => { it( 'should strip the html tags and replace them with spaces', () => { let actual = filterMessage( '

html paragraph

' ); expect( actual ).toBe( ' html paragraph ' ); - }); - }); -}); + } ); + } ); +} ); diff --git a/packages/a11y/src/test/index.test.js b/packages/a11y/src/test/index.test.js index 211cb39d8da99..341db56e75315 100644 --- a/packages/a11y/src/test/index.test.js +++ b/packages/a11y/src/test/index.test.js @@ -2,13 +2,13 @@ import { setup, speak } from '../'; jest.mock( '../clear', () => { return jest.fn(); -}); +} ); jest.mock( '@wordpress/dom-ready', () => { - return jest.fn(( callback ) => { callback(); }); -}); + return jest.fn( ( callback ) => { callback(); } ); +} ); jest.mock( '../filterMessage', () => { - return jest.fn(( message ) => { return message; }); -}); + return jest.fn( ( message ) => { return message; } ); +} ); import clear from '../clear'; import domReady from '@wordpress/dom-ready'; @@ -18,16 +18,16 @@ describe( 'speak', () => { let containerPolite = document.getElementById( 'a11y-speak-polite' ); let containerAssertive = document.getElementById( 'a11y-speak-assertive' ); - beforeEach(() => { + beforeEach( () => { containerPolite.textContent = ''; containerAssertive.textContent = ''; - }); + } ); describe( 'on import', () => { it( 'should call domReady', () => { expect( domReady ).toHaveBeenCalled(); - }); - }); + } ); + } ); describe( 'in default mode', () => { it( 'should set the textcontent of the polite aria-live region', () => { @@ -36,59 +36,59 @@ describe( 'speak', () => { expect( containerAssertive.textContent ).toBe( '' ); expect( clear ).toHaveBeenCalled(); expect( filterMessage ).toHaveBeenCalledWith( 'default message' ); - }); - }); + } ); + } ); describe( 'in assertive mode', () => { it( 'should set the textcontent of the assertive aria-live region', () => { speak( 'assertive message', 'assertive' ); expect( containerPolite.textContent ).toBe( '' ); expect( containerAssertive.textContent ).toBe( 'assertive message' ); - }); - }); + } ); + } ); describe( 'in explicit polite mode', () => { it( 'should set the textcontent of the polite aria-live region', () => { speak( 'polite message', 'polite' ); expect( containerPolite.textContent ).toBe( 'polite message' ); expect( containerAssertive.textContent ).toBe( '' ); - }); - }); + } ); + } ); describe( 'when somehow the assertive container is not present', () => { - beforeEach(() => { + beforeEach( () => { document.getElementById( 'a11y-speak-assertive' ).remove(); - }); + } ); - afterEach(() => { + afterEach( () => { setup(); containerAssertive = document.getElementById( 'a11y-speak-assertive' ); - }); + } ); it( 'should set the textcontent of the polite aria-live region', () => { speak( 'message', 'assertive' ); expect( containerPolite.textContent ).toBe( 'message' ); expect( document.getElementById( 'a11y-speak-assertive' ) ).toBe( null ); - }); - }); + } ); + } ); describe( 'when somehow the both containers are not present', () => { - beforeEach(() => { + beforeEach( () => { containerAssertive.remove(); containerPolite.remove(); - }); + } ); - afterEach(() => { + afterEach( () => { setup(); containerPolite = document.getElementById( 'a11y-speak-polite' ); containerAssertive = document.getElementById( 'a11y-speak-assertive' ); - }); + } ); it( 'should set the textcontent of the polite aria-live region', () => { expect( document.getElementById( 'a11y-speak-polite' ) ).toBe( null ); expect( document.getElementById( 'a11y-speak-assertive' ) ).toBe( null ); - }); - }); + } ); + } ); describe( 'setup when the elements already exist', () => { it( 'should not create the aria live regions again', () => { @@ -97,6 +97,6 @@ describe( 'speak', () => { let after = document.getElementsByClassName( 'a11y-speak-region' ).length; expect( before ).toBe( after ); - }); - }); -}); + } ); + } ); +} ); diff --git a/packages/dom-ready/src/test/index.test.js b/packages/dom-ready/src/test/index.test.js index 556594c1ca452..7b14124e7c50b 100644 --- a/packages/dom-ready/src/test/index.test.js +++ b/packages/dom-ready/src/test/index.test.js @@ -3,28 +3,28 @@ import domReady from '../'; describe( 'domReady', () => { describe( 'when document readystate is complete', () => { it( 'should call the callback.', () => { - let callback = jest.fn(() => {}); + let callback = jest.fn( () => {}); domReady( callback ); expect( callback ).toHaveBeenCalled(); - }); - }); + } ); + } ); describe( 'when document readystate is still loading', () => { it( 'should add the callback as an event listener to the DOMContentLoaded event.', () => { - let addEventListener = jest.fn(() => {}); + let addEventListener = jest.fn( () => {} ); Object.defineProperty( document, 'readyState', { value: 'loading', - }); + } ); Object.defineProperty( document, 'addEventListener', { value: addEventListener, - }); + } ); - let callback = jest.fn(() => {}); + let callback = jest.fn( () => {} ); domReady( callback ); expect( callback ).not.toHaveBeenCalled(); expect( addEventListener ).toHaveBeenCalledWith( 'DOMContentLoaded', callback ); - }); - }); -}); + } ); + } ); +} ); From cb4e16c16fe47880ff7380364c5955bef088c22a Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Wed, 16 Aug 2017 09:43:52 +1000 Subject: [PATCH 170/393] Use `andalouses.example` --- packages/url/src/test/index.test.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/url/src/test/index.test.js b/packages/url/src/test/index.test.js index 0772c04a98d05..3b4de6ac0c495 100644 --- a/packages/url/src/test/index.test.js +++ b/packages/url/src/test/index.test.js @@ -5,23 +5,23 @@ import { addQueryArgs } from '../'; describe( 'addQueryArgs', () => { test( 'should append args to an URL without query string', () => { - const url = 'https://example.com/beach'; + const url = 'https://andalouses.example/beach'; const args = { sun: 'true', sand: 'false' }; - expect( addQueryArgs( url, args ) ).toBe( 'https://example.com/beach?sun=true&sand=false' ); + expect( addQueryArgs( url, args ) ).toBe( 'https://andalouses.example/beach?sun=true&sand=false' ); } ); test( 'should append args to an URL with query string', () => { - const url = 'https://example.com/beach?night=false'; + const url = 'https://andalouses.example/beach?night=false'; const args = { sun: 'true', sand: 'false' }; - expect( addQueryArgs( url, args ) ).toBe( 'https://example.com/beach?night=false&sun=true&sand=false' ); + expect( addQueryArgs( url, args ) ).toBe( 'https://andalouses.example/beach?night=false&sun=true&sand=false' ); } ); test( 'should update args to an URL with conflicting query string', () => { - const url = 'https://example.com/beach?night=false&sun=false&sand=true'; + const url = 'https://andalouses.example/beach?night=false&sun=false&sand=true'; const args = { sun: 'true', sand: 'false' }; - expect( addQueryArgs( url, args ) ).toBe( 'https://example.com/beach?night=false&sun=true&sand=false' ); + expect( addQueryArgs( url, args ) ).toBe( 'https://andalouses.example/beach?night=false&sun=true&sand=false' ); } ); } ); From 5fd43bd18f704482420de2ddca15f9d8f5c7932c Mon Sep 17 00:00:00 2001 From: omarreiss Date: Wed, 16 Aug 2017 09:54:23 +0200 Subject: [PATCH 171/393] unapply all spacing exceptions take 2. --- packages/dom-ready/src/test/index.test.js | 2 +- scripts/build.js | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/dom-ready/src/test/index.test.js b/packages/dom-ready/src/test/index.test.js index 7b14124e7c50b..000e2befcbfec 100644 --- a/packages/dom-ready/src/test/index.test.js +++ b/packages/dom-ready/src/test/index.test.js @@ -3,7 +3,7 @@ import domReady from '../'; describe( 'domReady', () => { describe( 'when document readystate is complete', () => { it( 'should call the callback.', () => { - let callback = jest.fn( () => {}); + let callback = jest.fn( () => {} ); domReady( callback ); expect( callback ).toHaveBeenCalled(); diff --git a/scripts/build.js b/scripts/build.js index 5342ebadd4e81..595353b33fa3f 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -66,7 +66,7 @@ function getAllPackages() { * @param {String} file File name * @return {String} Package name */ -function getPackageName(file) { +function getPackageName( file ) { return path.relative( PACKAGES_DIR, file ).split( path.sep )[ 0 ]; } @@ -110,13 +110,13 @@ function buildFileFor( file, silent, environment ) { mkdirp.sync( path.dirname( destPath ) ); const transformed = babel.transformFileSync( file, babelOptions ).code; - fs.writeFileSync(destPath, transformed); + fs.writeFileSync( destPath, transformed ); if ( ! silent ) { process.stdout.write( - chalk.green(' \u2022 ') + - path.relative(PACKAGES_DIR, file) + - chalk.green(' \u21D2 ') + - path.relative(PACKAGES_DIR, destPath) + + chalk.green( ' \u2022 ' ) + + path.relative( PACKAGES_DIR, file ) + + chalk.green( ' \u21D2 ' ) + + path.relative( PACKAGES_DIR, destPath ) + '\n' ); } @@ -141,4 +141,4 @@ function buildPackage( packagePath ) { process.stdout.write( chalk.inverse( '>> Building packages \n' ) ); getAllPackages() .forEach( buildPackage ); -process.stdout.write('\n'); +process.stdout.write( '\n' ); From a617214646c04019c6b21e8b36ff619d38bacb4c Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Wed, 16 Aug 2017 10:39:15 -0400 Subject: [PATCH 172/393] Validate namespace takes form `vendorName/pluginName/functionName` --- packages/hooks/src/validateNamespace.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/hooks/src/validateNamespace.js b/packages/hooks/src/validateNamespace.js index b12605338b379..0298275780fd0 100644 --- a/packages/hooks/src/validateNamespace.js +++ b/packages/hooks/src/validateNamespace.js @@ -18,8 +18,8 @@ function validateNamespace( namespace ) { return false; } - if ( ! /^[a-zA-Z][a-zA-Z0-9_.-]*\/[a-zA-Z][a-zA-Z0-9_.-]*$/.test( namespace ) ) { - console.error( 'The namespace must take the form `my-plugin-slug/functionDescription`.' ); + if ( ! /^[a-zA-Z][a-zA-Z0-9_.-]*\/[a-zA-Z][a-zA-Z0-9_.-]*\/[a-zA-Z][a-zA-Z0-9_.-]*$/.test( namespace ) ) { + console.error( 'The namespace must take the form `vendorName/pluginName/functionName`.' ); return false; } From 30e5e82c3758b138b4af40570b23d9f2e98ca56e Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Wed, 16 Aug 2017 10:39:46 -0400 Subject: [PATCH 173/393] Update tests with new namespace format --- packages/hooks/src/test/index.test.js | 208 +++++++++++++------------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 17e76f65251c4..8824ea330cc94 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -36,17 +36,17 @@ function filter_c( str ) { } function filter_b_removes_self( str ) { - removeFilter( 'test.filter', 'my_plugin/my_callback_filter_b_removes_self' ); + removeFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b_removes_self' ); return str + 'b'; } function filter_removes_b( str ) { - removeFilter( 'test.filter', 'my_plugin/my_callback_filter_b' ); + removeFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b' ); return str; } function filter_removes_c( str ) { - removeFilter( 'test.filter', 'my_plugin/my_callback_filter_c' ); + removeFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c' ); return str; } @@ -86,25 +86,25 @@ test( 'run a filter with no callbacks', () => { } ); test( 'add and remove a filter', () => { - addFilter( 'test.filter', 'my_plugin/my_callback', filter_a ); + addFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_a ); expect( removeAllFilters( 'test.filter' ) ).toEqual( 1 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); expect( removeAllFilters( 'test.filter' ) ).toEqual( 0 ); } ); test( 'add a filter and run it', () => { - addFilter( 'test.filter', 'my_plugin/my_callback', filter_a ); + addFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_a ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testa' ); } ); test( 'add 2 filters in a row and run them', () => { - addFilter( 'test.filter', 'my_plugin/my_callback', filter_a ); - addFilter( 'test.filter', 'my_plugin/my_callback', filter_b ); + addFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_a ); + addFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_b ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); } ); test( 'remove a non-existent filter', () => { - expect( removeFilter( 'test.filter', 'my_plugin/my_callback', filter_a ) ).toEqual( 0 ); + expect( removeFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_a ) ).toEqual( 0 ); expect( removeAllFilters( 'test.filter' ) ).toEqual( 0 ); } ); @@ -116,14 +116,14 @@ test( 'remove an invalid namespace from a filter', () => { } ); test( 'cannot add filters with non-string hook names', () => { - addFilter( 42, 'my_plugin/my_callback', () => null ); + addFilter( 42, 'my_name/my_plugin/my_callback', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The hook name must be a non-empty string.' ); } ); test( 'cannot add filters with empty-string hook names', () => { - addFilter( '', 'my_plugin/my_callback', () => null ); + addFilter( '', 'my_name/my_plugin/my_callback', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The hook name must be a non-empty string.' ); @@ -139,34 +139,34 @@ test( 'cannot add filters with empty-string namespaces', () => { test( 'cannot add filters with invalid namespaces', () => { addFilter( 'hook_name', 'invalid_name', () => null ); expect( console.error ).toHaveBeenCalledWith( - 'The namespace must take the form `my-plugin-slug/functionDescription`.' + 'The namespace must take the form `vendorName/pluginName/functionName`.' ); } ); test( 'cannot add filters with namespaces missing a functionDescription', () => { addFilter( 'hook_name', 'invalid_name/', () => null ); expect( console.error ).toHaveBeenCalledWith( - 'The namespace must take the form `my-plugin-slug/functionDescription`.' + 'The namespace must take the form `vendorName/pluginName/functionName`.' ); } ); test( 'Can add filters with capitals in namespaces', () => { - addFilter( 'hook_name', 'OhNo/action', () => null ); + addFilter( 'hook_name', 'my_name/OhNo/action', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); } ); test( 'Can add filters with capitals in hookName', () => { - addFilter( 'hookName', 'plugin/action', () => null ); + addFilter( 'hookName', 'my_name/plugin/action', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); } ); test( 'Can add filters with periods in namespaces', () => { - addFilter( 'hook_name', 'plugin.name/ok.action', () => null ); + addFilter( 'hook_name', 'my_name/plugin.name/ok.action', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); } ); test( 'Can add filters with periods in hookName', () => { - addFilter( 'hook.name', 'plugin/action', () => null ); + addFilter( 'hook.name', 'my_name/plugin/action', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); } ); @@ -178,21 +178,21 @@ test( 'cannot add filters with invalid namespaces', () => { } ); test( 'cannot add filters named with __ prefix', () => { - addFilter( '__test', 'my_plugin/my_callback', () => null ); + addFilter( '__test', 'my_name/my_plugin/my_callback', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The hook name cannot begin with `__`.' ); } ); test( 'cannot add filters with non-function callbacks', () => { - addFilter( 'test', 'my_plugin/my_callback', '42' ); + addFilter( 'test', 'my_name/my_plugin/my_callback', '42' ); expect( console.error ).toHaveBeenCalledWith( 'The hook callback must be a function.' ); } ); test( 'cannot add filters with non-numeric priorities', () => { - addFilter( 'test', 'my_plugin/my_callback', () => null, '42' ); + addFilter( 'test', 'my_name/my_plugin/my_callback', () => null, '42' ); expect( console.error ).toHaveBeenCalledWith( 'If specified, the hook priority must be a number.' ); @@ -213,9 +213,9 @@ test( 'cannot run filters named with __ prefix', () => { } ); test( 'add 3 filters with different priorities and run them', () => { - addFilter( 'test.filter', 'my_plugin/my_callback_filter_a', filter_a ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_b', filter_b, 2 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_c', filter_c, 8 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 8 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testbca' ); } ); @@ -230,34 +230,34 @@ test( 'filters with the same and different priorities', () => { } ); } ); - addFilter( 'test_order', 'my_plugin/my_callback_fn_3a', callbacks.fn_3a, 3 ); - addFilter( 'test_order', 'my_plugin/my_callback_fn_3b', callbacks.fn_3b, 3 ); - addFilter( 'test_order', 'my_plugin/my_callback_fn_3c', callbacks.fn_3c, 3 ); - addFilter( 'test_order', 'my_plugin/my_callback_fn_2a', callbacks.fn_2a, 2 ); - addFilter( 'test_order', 'my_plugin/my_callback_fn_2b', callbacks.fn_2b, 2 ); - addFilter( 'test_order', 'my_plugin/my_callback_fn_2c', callbacks.fn_2c, 2 ); + addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3a', callbacks.fn_3a, 3 ); + addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3b', callbacks.fn_3b, 3 ); + addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3c', callbacks.fn_3c, 3 ); + addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2a', callbacks.fn_2a, 2 ); + addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2b', callbacks.fn_2b, 2 ); + addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2c', callbacks.fn_2c, 2 ); expect( applyFilters( 'test_order', [] ) ).toEqual( [ '2a', '2b', '2c', '3a', '3b', '3c' ] ); - removeFilter( 'test_order', 'my_plugin/my_callback_fn_2b', callbacks.fn_2b ); - removeFilter( 'test_order', 'my_plugin/my_callback_fn_3a', callbacks.fn_3a ); + removeFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2b', callbacks.fn_2b ); + removeFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3a', callbacks.fn_3a ); expect( applyFilters( 'test_order', [] ) ).toEqual( [ '2a', '2c', '3b', '3c' ] ); - addFilter( 'test_order', 'my_plugin/my_callback_fn_4a', callbacks.fn_4a, 4 ); - addFilter( 'test_order', 'my_plugin/my_callback_fn_4b', callbacks.fn_4b, 4 ); - addFilter( 'test_order', 'my_plugin/my_callback_fn_1a', callbacks.fn_1a, 1 ); - addFilter( 'test_order', 'my_plugin/my_callback_fn_4c', callbacks.fn_4c, 4 ); - addFilter( 'test_order', 'my_plugin/my_callback_fn_1b', callbacks.fn_1b, 1 ); - addFilter( 'test_order', 'my_plugin/my_callback_fn_3d', callbacks.fn_3d, 3 ); - addFilter( 'test_order', 'my_plugin/my_callback_fn_4d', callbacks.fn_4d, 4 ); - addFilter( 'test_order', 'my_plugin/my_callback_fn_1c', callbacks.fn_1c, 1 ); - addFilter( 'test_order', 'my_plugin/my_callback_fn_2d', callbacks.fn_2d, 2 ); - addFilter( 'test_order', 'my_plugin/my_callback_fn_1d', callbacks.fn_1d, 1 ); + addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_4a', callbacks.fn_4a, 4 ); + addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_4b', callbacks.fn_4b, 4 ); + addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_1a', callbacks.fn_1a, 1 ); + addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_4c', callbacks.fn_4c, 4 ); + addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_1b', callbacks.fn_1b, 1 ); + addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3d', callbacks.fn_3d, 3 ); + addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_4d', callbacks.fn_4d, 4 ); + addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_1c', callbacks.fn_1c, 1 ); + addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2d', callbacks.fn_2d, 2 ); + addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_1d', callbacks.fn_1d, 1 ); expect( applyFilters( 'test_order', [] ) ).toEqual( [ // all except 2b and 3a, which we removed earlier @@ -269,29 +269,29 @@ test( 'filters with the same and different priorities', () => { } ); test( 'add and remove an action', () => { - addAction( 'test.action', 'my_plugin/my_callback', action_a ); + addAction( 'test.action', 'my_name/my_plugin/my_callback', action_a ); expect( removeAllActions( 'test.action' ) ).toEqual( 1 ); expect( doAction( 'test.action' ) ).toBe( undefined ); expect( window.actionValue ).toBe( '' ); } ); test( 'add an action and run it', () => { - addAction( 'test.action', 'my_plugin/my_callback', action_a ); + addAction( 'test.action', 'my_name/my_plugin/my_callback', action_a ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'a' ); } ); test( 'add 2 actions in a row and then run them', () => { - addAction( 'test.action', 'my_plugin/my_callback', action_a ); - addAction( 'test.action', 'my_plugin/my_callback', action_b ); + addAction( 'test.action', 'my_name/my_plugin/my_callback', action_a ); + addAction( 'test.action', 'my_name/my_plugin/my_callback', action_b ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'ab' ); } ); test( 'add 3 actions with different priorities and run them', () => { - addAction( 'test.action', 'my_plugin/my_callback', action_a ); - addAction( 'test.action', 'my_plugin/my_callback', action_b, 2 ); - addAction( 'test.action', 'my_plugin/my_callback', action_c, 8 ); + addAction( 'test.action', 'my_name/my_plugin/my_callback', action_a ); + addAction( 'test.action', 'my_name/my_plugin/my_callback', action_b, 2 ); + addAction( 'test.action', 'my_name/my_plugin/my_callback', action_c, 8 ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'bca' ); } ); @@ -300,7 +300,7 @@ test( 'pass in two arguments to an action', () => { const arg1 = { a: 10 }; const arg2 = { b: 20 }; - addAction( 'test.action', 'my_plugin/my_callback', ( a, b ) => { + addAction( 'test.action', 'my_name/my_plugin/my_callback', ( a, b ) => { expect( a ).toBe( arg1 ); expect( b ).toBe( arg2 ); } ); @@ -314,14 +314,14 @@ test( 'fire action multiple times', () => { expect( true ).toBe( true ); }; - addAction( 'test.action', 'my_plugin/my_callback', func ); + addAction( 'test.action', 'my_name/my_plugin/my_callback', func ); doAction( 'test.action' ); doAction( 'test.action' ); } ); test( 'add a filter before the one currently executing', () => { - addFilter( 'test.filter', 'my_plugin/my_callback', val => { - addFilter( 'test.filter', 'my_plugin/my_callback', val => val + 'a', 1 ); + addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => { + addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => val + 'a', 1 ); return val + 'b'; }, 2 ); @@ -329,8 +329,8 @@ test( 'add a filter before the one currently executing', () => { } ); test( 'add a filter after the one currently executing', () => { - addFilter( 'test.filter', 'my_plugin/my_callback', val => { - addFilter( 'test.filter', 'my_plugin/my_callback', val => val + 'b', 2 ); + addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => { + addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => val + 'b', 2 ); return val + 'a'; }, 1 ); @@ -338,8 +338,8 @@ test( 'add a filter after the one currently executing', () => { } ); test( 'add a filter immediately after the one currently executing', () => { - addFilter( 'test.filter', 'my_plugin/my_callback', val => { - addFilter( 'test.filter', 'my_plugin/my_callback', val => val + 'b', 1 ); + addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => { + addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => val + 'b', 1 ); return val + 'a'; }, 1 ); @@ -347,19 +347,19 @@ test( 'add a filter immediately after the one currently executing', () => { } ); test( 'remove specific action callback', () => { - addAction( 'test.action', 'my_plugin/my_callback_action_a', action_a ); - addAction( 'test.action', 'my_plugin/my_callback_action_b', action_b, 2 ); - addAction( 'test.action', 'my_plugin/my_callback_action_c', action_c, 8 ); + addAction( 'test.action', 'my_name/my_plugin/my_callback_action_a', action_a ); + addAction( 'test.action', 'my_name/my_plugin/my_callback_action_b', action_b, 2 ); + addAction( 'test.action', 'my_name/my_plugin/my_callback_action_c', action_c, 8 ); - expect( removeAction( 'test.action', 'my_plugin/my_callback_action_b' ) ).toEqual( 1 ); + expect( removeAction( 'test.action', 'my_name/my_plugin/my_callback_action_b' ) ).toEqual( 1 ); doAction( 'test.action' ); expect( window.actionValue ).toBe( 'ca' ); } ); test( 'remove all action callbacks', () => { - addAction( 'test.action', 'my_plugin/my_callback_action_a', action_a ); - addAction( 'test.action', 'my_plugin/my_callback_action_b', action_b, 2 ); - addAction( 'test.action', 'my_plugin/my_callback_action_c', action_c, 8 ); + addAction( 'test.action', 'my_name/my_plugin/my_callback_action_a', action_a ); + addAction( 'test.action', 'my_name/my_plugin/my_callback_action_b', action_b, 2 ); + addAction( 'test.action', 'my_name/my_plugin/my_callback_action_c', action_c, 8 ); expect( removeAllActions( 'test.action' ) ).toEqual( 3 ); doAction( 'test.action' ); @@ -367,71 +367,71 @@ test( 'remove all action callbacks', () => { } ); test( 'remove specific filter callback', () => { - addFilter( 'test.filter', 'my_plugin/my_callback_filter_a', filter_a ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_b', filter_b, 2 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_c', filter_c, 8 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 8 ); - expect( removeFilter( 'test.filter', 'my_plugin/my_callback_filter_b' ) ).toEqual( 1 ); + expect( removeFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b' ) ).toEqual( 1 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testca' ); } ); test( 'filter removes a callback that has already executed', () => { - addFilter( 'test.filter', 'my_plugin/my_callback_filter_a', filter_a, 1 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_b', filter_b, 3 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_c', filter_c, 5 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_removes_b', filter_removes_b, 4 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 3 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 5 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_b', filter_removes_b, 4 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); test( 'filter removes a callback that has already executed (same priority)', () => { - addFilter( 'test.filter', 'my_plugin/my_callback_filter_a', filter_a, 1 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_b', filter_b, 2 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_removes_b', filter_removes_b, 2 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_c', filter_c, 4 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_b', filter_removes_b, 2 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 4 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); test( 'filter removes the current callback', () => { - addFilter( 'test.filter', 'my_plugin/my_callback_filter_a', filter_a, 1 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_b_removes_self', filter_b_removes_self, 3 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_c', filter_c, 5 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b_removes_self', filter_b_removes_self, 3 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 5 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); test( 'filter removes a callback that has not yet executed (last)', () => { - addFilter( 'test.filter', 'my_plugin/my_callback_filter_a', filter_a, 1 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_b', filter_b, 3 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_c', filter_c, 5 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_removes_c', filter_removes_c, 4 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 3 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 5 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_c', filter_removes_c, 4 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); } ); test( 'filter removes a callback that has not yet executed (middle)', () => { - addFilter( 'test.filter', 'my_plugin/my_callback_filter_a', filter_a, 1 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_b', filter_b, 3 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_c', filter_c, 4 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_removes_b', filter_removes_b, 2 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 3 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 4 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_b', filter_removes_b, 2 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); } ); test( 'filter removes a callback that has not yet executed (same priority)', () => { - addFilter( 'test.filter', 'my_plugin/my_callback_filter_a', filter_a, 1 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_removes_b', filter_removes_b, 2 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_b', filter_b, 2 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_c', filter_c, 4 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_b', filter_removes_b, 2 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 4 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); } ); test( 'remove all filter callbacks', () => { - addFilter( 'test.filter', 'my_plugin/my_callback_filter_a', filter_a ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_b', filter_b, 2 ); - addFilter( 'test.filter', 'my_plugin/my_callback_filter_c', filter_c, 8 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); + addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 8 ); expect( removeAllFilters( 'test.filter' ) ).toEqual( 3 ); expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); @@ -441,7 +441,7 @@ test( 'remove all filter callbacks', () => { test( 'Test doingAction, didAction and hasAction.', () => { let actionCalls = 0; - addAction( 'another.action', 'my_plugin/my_callback', () => {} ); + addAction( 'another.action', 'my_name/my_plugin/my_callback', () => {} ); doAction( 'another.action' ); // Verify no action is running yet. @@ -450,7 +450,7 @@ test( 'Test doingAction, didAction and hasAction.', () => { expect( didAction( 'test.action' ) ).toBe( 0 ); expect( hasAction( 'test.action' ) ).toBe( 0 ); - addAction( 'test.action', 'my_plugin/my_callback', () => { + addAction( 'test.action', 'my_name/my_plugin/my_callback', () => { actionCalls++; expect( currentAction() ).toBe( 'test.action' ); expect( doingAction() ).toBe( true ); @@ -495,7 +495,7 @@ test( 'Test doingAction, didAction and hasAction.', () => { test( 'Verify doingFilter, didFilter and hasFilter.', () => { let filterCalls = 0; - addFilter( 'runtest.filter', 'my_plugin/my_callback', arg => { + addFilter( 'runtest.filter', 'my_name/my_plugin/my_callback', arg => { filterCalls++; expect( currentFilter() ).toBe( 'runtest.filter' ); expect( doingFilter() ).toBe( true ); @@ -522,7 +522,7 @@ test( 'Verify doingFilter, didFilter and hasFilter.', () => { } ); test( 'recursively calling a filter', () => { - addFilter( 'test.filter', 'my_plugin/my_callback', value => { + addFilter( 'test.filter', 'my_name/my_plugin/my_callback', value => { if ( value.length === 7 ) { return value; } @@ -533,11 +533,11 @@ test( 'recursively calling a filter', () => { } ); test( 'current filter when multiple filters are running', () => { - addFilter( 'test.filter1', 'my_plugin/my_callback', value => { + addFilter( 'test.filter1', 'my_name/my_plugin/my_callback', value => { return applyFilters( 'test.filter2', value.concat( currentFilter() ) ); } ); - addFilter( 'test.filter2', 'my_plugin/my_callback', value => { + addFilter( 'test.filter2', 'my_name/my_plugin/my_callback', value => { return value.concat( currentFilter() ); } ); @@ -552,16 +552,16 @@ test( 'current filter when multiple filters are running', () => { test( 'adding and removing filters with recursion', () => { function removeRecurseAndAdd2( val ) { - expect( removeFilter( 'remove_and_add', 'my_plugin/my_callback_recurse' ) ).toEqual( 1 ); + expect( removeFilter( 'remove_and_add', 'my_name/my_plugin/my_callback_recurse' ) ).toEqual( 1 ); val += '-' + applyFilters( 'remove_and_add', '' ) + '-'; - addFilter( 'remove_and_add', 'my_plugin/my_callback_recurse', 10 ); + addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback_recurse', 10 ); return val + '2'; } - addFilter( 'remove_and_add', 'my_plugin/my_callback', val => val + '1', 11 ); - addFilter( 'remove_and_add', 'my_plugin/my_callback_recurse', removeRecurseAndAdd2, 12 ); - addFilter( 'remove_and_add', 'my_plugin/my_callback', val => val + '3', 13 ); - addFilter( 'remove_and_add', 'my_plugin/my_callback', val => val + '4', 14 ); + addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback', val => val + '1', 11 ); + addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback_recurse', removeRecurseAndAdd2, 12 ); + addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback', val => val + '3', 13 ); + addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback', val => val + '4', 14 ); expect( applyFilters( 'remove_and_add', '' ) ).toEqual( '1-134-234' ); } ); From 3a13768e7f4fd4d17e9764d5bcc9fa796e175ce4 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Wed, 16 Aug 2017 11:44:08 -0400 Subject: [PATCH 174/393] update readme with new namespace format --- packages/hooks/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/hooks/README.md b/packages/hooks/README.md index 68b27163deb12..42afb852545bb 100644 --- a/packages/hooks/README.md +++ b/packages/hooks/README.md @@ -6,10 +6,10 @@ A lightweight & efficient EventManager for JavaScript in WordPress. ### API Usage API functions can be called via the global `wp.hooks` like this `wp.hooks.addAction()`, etc. -* `addAction( 'hook_name', 'my_plugin/my_callback', callback, priority )` -* `addFilter( 'hook_name', 'my_plugin/my_callback', callback, priority )` -* `removeAction( 'hook_name', 'my_plugin/my_callback' )` -* `removeFilter( 'hook_name', 'my_plugin/my_callback' )` +* `addAction( 'hook_name', 'vendorName/pluginName/functionName', callback, priority )` +* `addFilter( 'hook_name', 'vendorName/pluginName/functionName', callback, priority )` +* `removeAction( 'hook_name', 'vendorName/pluginName/functionName' )` +* `removeFilter( 'hook_name', 'vendorName/pluginName/functionName' )` * `removeAllActions( 'hook_name' )` * `removeAllFilters( 'hook_name' )` * `doAction( 'hook_name', arg1, arg2, moreArgs, finalArg )` From 7c1fc297df08ea3d1876debfcb2cc1d6bf0c1ef8 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 17 Aug 2017 15:03:24 -0400 Subject: [PATCH 175/393] remove module build from branch --- package.json | 2 -- webpack.config.js | 46 ---------------------------------------------- 2 files changed, 48 deletions(-) delete mode 100644 webpack.config.js diff --git a/package.json b/package.json index e7bef5d82838f..d5c5a2f038330 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,6 @@ "lerna": "^2.0.0", "mkdirp": "^0.5.1", "rimraf": "^2.6.1", - "webpack": "^3.3.0", "babel-loader": "^7.1.1" }, "jest": { @@ -26,7 +25,6 @@ "scripts": { "build-clean": "rimraf ./packages/*/build ./packages/*/build-browser ./packages/*/build-module", "build": "node ./scripts/build.js", - "build-modules": "webpack --progress -p", "test": "jest", "test:coverage": "jest --coverage", "test:coverage-ci": "jest --coverage && coveralls < coverage/lcov.info", diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 index 7b8e8c6c6338b..0000000000000 --- a/webpack.config.js +++ /dev/null @@ -1,46 +0,0 @@ -const entryPointNames = [ - 'hooks', - 'url', -]; - -const externals = { - react: 'React', - 'react-dom': 'ReactDOM', - 'react-dom/server': 'ReactDOMServer', - tinymce: 'tinymce', - moment: 'moment', -}; - -entryPointNames.forEach( entryPointName => { - externals[ entryPointName ] = { - 'this': [ 'wp', entryPointName ], - }; -} ); - -const config = entryPointNames.reduce( ( memo, entryPointName ) => { - memo[ entryPointName ] = './packages/' + entryPointName + '/src/index.js'; - return memo; - }, {} ); - - -module.exports = { - entry: config, - externals, - output: { - filename: 'build/[name]/index.js', - path: __dirname, - library: [ 'wp', '[name]' ], - libraryTarget: 'this', - }, - module: { - rules: [ - { - test: /\.js$/, - exclude: /(node_modules)/, - use: { - loader: 'babel-loader' - } - } - ] - } -} From 45747e5ad147a6b35f2b7bb508eb139a475e2094 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Mon, 4 Sep 2017 09:39:41 -0400 Subject: [PATCH 176/393] Correct namespace strings in docblocks --- packages/hooks/src/createAddHook.js | 2 +- packages/hooks/src/createRemoveHook.js | 2 +- packages/hooks/src/validateNamespace.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index 6162d068766c9..de97d1609bb64 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -13,7 +13,7 @@ function createAddHook( hooks ) { * Adds the hook to the appropriate hooks container. * * @param {string} hookName Name of hook to add - * @param {string} namespace The unique namespace identifying the callback in the form `my-plugin-slug/functionDescription`. + * @param {string} namespace The unique namespace identifying the callback in the form `vendorName/pluginName/functionName`. * @param {Function} callback Function to call when the hook is run * @param {?number} priority Priority of this hook (default=10) */ diff --git a/packages/hooks/src/createRemoveHook.js b/packages/hooks/src/createRemoveHook.js index 9383cc1ec6598..37dfc3027b835 100644 --- a/packages/hooks/src/createRemoveHook.js +++ b/packages/hooks/src/createRemoveHook.js @@ -16,7 +16,7 @@ function createRemoveHook( hooks, removeAll ) { * given hookName and namespace. * * @param {string} hookName The name of the hook to modify. - * @param {string} namespace The unique namespace identifying the callback in the form `my-plugin-slug/functionDescription`. + * @param {string} namespace The unique namespace identifying the callback in the form `vendorName/pluginName/functionName`. * * @return {number} The number of callbacks removed. */ diff --git a/packages/hooks/src/validateNamespace.js b/packages/hooks/src/validateNamespace.js index 0298275780fd0..c246bc3487b33 100644 --- a/packages/hooks/src/validateNamespace.js +++ b/packages/hooks/src/validateNamespace.js @@ -2,7 +2,7 @@ * Validate a namespace string. * * @param {string} namespace The namespace to validate - should take the form - * `my-plugin-slug/functionDescription`. + * `vendorName/pluginName/functionName`. * * @return {bool} Whether the namespace is valid. */ From a24847bc8117fff0adff7244fb5a6ba554a2a9cd Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 7 Sep 2017 10:06:21 -0400 Subject: [PATCH 177/393] Add args to applyFilters docs in readme --- packages/hooks/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/hooks/README.md b/packages/hooks/README.md index 42afb852545bb..12195b10d12cc 100644 --- a/packages/hooks/README.md +++ b/packages/hooks/README.md @@ -13,7 +13,7 @@ API functions can be called via the global `wp.hooks` like this `wp.hooks.addAct * `removeAllActions( 'hook_name' )` * `removeAllFilters( 'hook_name' )` * `doAction( 'hook_name', arg1, arg2, moreArgs, finalArg )` -* `applyFilters( 'hook_name', content )` +* `applyFilters( 'hook_name', content, arg1, arg2, moreArgs, finalArg )` * `doingAction( 'hook_name' )` * `doingFilter( 'hook_name' )` * `didAction( 'hook_name' )` From 9f4cefce276d02448051d28149a6523f7a6263c8 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 7 Sep 2017 10:07:22 -0400 Subject: [PATCH 178/393] camelCase for readme variable names --- packages/hooks/README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/hooks/README.md b/packages/hooks/README.md index 12195b10d12cc..30cc596313f11 100644 --- a/packages/hooks/README.md +++ b/packages/hooks/README.md @@ -6,20 +6,20 @@ A lightweight & efficient EventManager for JavaScript in WordPress. ### API Usage API functions can be called via the global `wp.hooks` like this `wp.hooks.addAction()`, etc. -* `addAction( 'hook_name', 'vendorName/pluginName/functionName', callback, priority )` -* `addFilter( 'hook_name', 'vendorName/pluginName/functionName', callback, priority )` -* `removeAction( 'hook_name', 'vendorName/pluginName/functionName' )` -* `removeFilter( 'hook_name', 'vendorName/pluginName/functionName' )` -* `removeAllActions( 'hook_name' )` -* `removeAllFilters( 'hook_name' )` -* `doAction( 'hook_name', arg1, arg2, moreArgs, finalArg )` -* `applyFilters( 'hook_name', content, arg1, arg2, moreArgs, finalArg )` -* `doingAction( 'hook_name' )` -* `doingFilter( 'hook_name' )` -* `didAction( 'hook_name' )` -* `didFilter( 'hook_name' )` -* `hasAction( 'hook_name' )` -* `hasFilter( 'hook_name' )` +* `addAction( 'hookName', 'vendorName/pluginName/functionName', callback, priority )` +* `addFilter( 'hookName', 'vendorName/pluginName/functionName', callback, priority )` +* `removeAction( 'hookName', 'vendorName/pluginName/functionName' )` +* `removeFilter( 'hookName', 'vendorName/pluginName/functionName' )` +* `removeAllActions( 'hookName' )` +* `removeAllFilters( 'hookName' )` +* `doAction( 'hookName', arg1, arg2, moreArgs, finalArg )` +* `applyFilters( 'hookName', content, arg1, arg2, moreArgs, finalArg )` +* `doingAction( 'hookName' )` +* `doingFilter( 'hookName' )` +* `didAction( 'hookName' )` +* `didFilter( 'hookName' )` +* `hasAction( 'hookName' )` +* `hasFilter( 'hookName' )` ### Background From 73744fa903e428b36f4b0a3006bf737f5bd2f28f Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 12 Sep 2017 08:42:27 -0400 Subject: [PATCH 179/393] update hook and `vendor/plugin/function` wording, removing `Name` --- packages/hooks/README.md | 28 ++++++++++++------------- packages/hooks/src/validateNamespace.js | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/hooks/README.md b/packages/hooks/README.md index 30cc596313f11..06cac123ac2d1 100644 --- a/packages/hooks/README.md +++ b/packages/hooks/README.md @@ -6,20 +6,20 @@ A lightweight & efficient EventManager for JavaScript in WordPress. ### API Usage API functions can be called via the global `wp.hooks` like this `wp.hooks.addAction()`, etc. -* `addAction( 'hookName', 'vendorName/pluginName/functionName', callback, priority )` -* `addFilter( 'hookName', 'vendorName/pluginName/functionName', callback, priority )` -* `removeAction( 'hookName', 'vendorName/pluginName/functionName' )` -* `removeFilter( 'hookName', 'vendorName/pluginName/functionName' )` -* `removeAllActions( 'hookName' )` -* `removeAllFilters( 'hookName' )` -* `doAction( 'hookName', arg1, arg2, moreArgs, finalArg )` -* `applyFilters( 'hookName', content, arg1, arg2, moreArgs, finalArg )` -* `doingAction( 'hookName' )` -* `doingFilter( 'hookName' )` -* `didAction( 'hookName' )` -* `didFilter( 'hookName' )` -* `hasAction( 'hookName' )` -* `hasFilter( 'hookName' )` +* `addAction( 'hook', 'vendor/plugin/function', callback, priority )` +* `addFilter( 'hook', 'vendor/plugin/function', callback, priority )` +* `removeAction( 'hook', 'vendor/plugin/function' )` +* `removeFilter( 'hook', 'vendor/plugin/function' )` +* `removeAllActions( 'hook' )` +* `removeAllFilters( 'hook' )` +* `doAction( 'hook', arg1, arg2, moreArgs, finalArg )` +* `applyFilters( 'hook', content, arg1, arg2, moreArgs, finalArg )` +* `doingAction( 'hook' )` +* `doingFilter( 'hook' )` +* `didAction( 'hook' )` +* `didFilter( 'hook' )` +* `hasAction( 'hook' )` +* `hasFilter( 'hook' )` ### Background diff --git a/packages/hooks/src/validateNamespace.js b/packages/hooks/src/validateNamespace.js index c246bc3487b33..e6ba2369c109e 100644 --- a/packages/hooks/src/validateNamespace.js +++ b/packages/hooks/src/validateNamespace.js @@ -19,7 +19,7 @@ function validateNamespace( namespace ) { } if ( ! /^[a-zA-Z][a-zA-Z0-9_.-]*\/[a-zA-Z][a-zA-Z0-9_.-]*\/[a-zA-Z][a-zA-Z0-9_.-]*$/.test( namespace ) ) { - console.error( 'The namespace must take the form `vendorName/pluginName/functionName`.' ); + console.error( 'The namespace must take the form `vendor/plugin/function`.' ); return false; } From 7465667e91c514b90364b191aa5f52fdfad56edf Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Wed, 13 Sep 2017 10:55:00 -0400 Subject: [PATCH 180/393] complte namespace shortening to `vendor/plugin/function` --- packages/hooks/src/createAddHook.js | 2 +- packages/hooks/src/createRemoveHook.js | 2 +- packages/hooks/src/test/index.test.js | 4 ++-- packages/hooks/src/validateNamespace.js | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index de97d1609bb64..9d4ac8d36af30 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -13,7 +13,7 @@ function createAddHook( hooks ) { * Adds the hook to the appropriate hooks container. * * @param {string} hookName Name of hook to add - * @param {string} namespace The unique namespace identifying the callback in the form `vendorName/pluginName/functionName`. + * @param {string} namespace The unique namespace identifying the callback in the form `vendor/plugin/function`. * @param {Function} callback Function to call when the hook is run * @param {?number} priority Priority of this hook (default=10) */ diff --git a/packages/hooks/src/createRemoveHook.js b/packages/hooks/src/createRemoveHook.js index 37dfc3027b835..42cbf9e49f287 100644 --- a/packages/hooks/src/createRemoveHook.js +++ b/packages/hooks/src/createRemoveHook.js @@ -16,7 +16,7 @@ function createRemoveHook( hooks, removeAll ) { * given hookName and namespace. * * @param {string} hookName The name of the hook to modify. - * @param {string} namespace The unique namespace identifying the callback in the form `vendorName/pluginName/functionName`. + * @param {string} namespace The unique namespace identifying the callback in the form `vendor/plugin/function`. * * @return {number} The number of callbacks removed. */ diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 8824ea330cc94..cfc0aeebfbca2 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -139,14 +139,14 @@ test( 'cannot add filters with empty-string namespaces', () => { test( 'cannot add filters with invalid namespaces', () => { addFilter( 'hook_name', 'invalid_name', () => null ); expect( console.error ).toHaveBeenCalledWith( - 'The namespace must take the form `vendorName/pluginName/functionName`.' + 'The namespace must take the form `vendor/plugin/function`.' ); } ); test( 'cannot add filters with namespaces missing a functionDescription', () => { addFilter( 'hook_name', 'invalid_name/', () => null ); expect( console.error ).toHaveBeenCalledWith( - 'The namespace must take the form `vendorName/pluginName/functionName`.' + 'The namespace must take the form `vendor/plugin/function`.' ); } ); diff --git a/packages/hooks/src/validateNamespace.js b/packages/hooks/src/validateNamespace.js index e6ba2369c109e..a559157275234 100644 --- a/packages/hooks/src/validateNamespace.js +++ b/packages/hooks/src/validateNamespace.js @@ -2,7 +2,7 @@ * Validate a namespace string. * * @param {string} namespace The namespace to validate - should take the form - * `vendorName/pluginName/functionName`. + * `vendor/plugin/function`. * * @return {bool} Whether the namespace is valid. */ From 5b19507bcc92346206a18e26579b350000e93285 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Mon, 25 Sep 2017 09:13:02 -0400 Subject: [PATCH 181/393] Publish - @wordpress/a11y@0.1.0-beta.2 - @wordpress/dom-ready@0.1.0-beta.2 - @wordpress/hooks@0.1.0-beta.0 - @wordpress/url@0.1.0-beta.2 --- packages/a11y/package.json | 4 ++-- packages/dom-ready/package.json | 2 +- packages/hooks/package.json | 2 +- packages/url/package.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/a11y/package.json b/packages/a11y/package.json index b660e93181d41..17a3e46d3371b 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/a11y", - "version": "0.1.0-beta.1", + "version": "0.1.0-beta.2", "description": "Collection of JS modules and tools for WordPress development", "homepage": "https://github.com/WordPress/packages/tree/master/packages/a11y/README.md", "author": "WordPress", @@ -18,7 +18,7 @@ "url": "https://github.com/WordPress/packages/issues" }, "dependencies": { - "@wordpress/dom-ready": "^0.1.0-beta.1" + "@wordpress/dom-ready": "^0.1.0-beta.2" }, "publishConfig": { "access": "public" diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index 80310c2b674e8..27909bd060e87 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom-ready", - "version": "0.1.0-beta.1", + "version": "0.1.0-beta.2", "description": "Execute callback after the DOM is loaded.", "homepage": "https://github.com/WordPress/packages/tree/master/packages/dom-ready/README.md", "author": "WordPress", diff --git a/packages/hooks/package.json b/packages/hooks/package.json index 94ec11ada4e92..25ee097f6c190 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/hooks", - "version": "0.1.0", + "version": "0.1.0-beta.0", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" diff --git a/packages/url/package.json b/packages/url/package.json index 138e9fdd585ce..1bc8aa07d5eab 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/url", - "version": "0.1.0-beta.1", + "version": "0.1.0-beta.2", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" From 01902b386f9255f98ae85c1d47b0eb4b2eb43f55 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Mon, 25 Sep 2017 09:18:21 -0400 Subject: [PATCH 182/393] add publishConfig->access:public for hooks --- packages/hooks/package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/hooks/package.json b/packages/hooks/package.json index 25ee097f6c190..9c7208849c2e0 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -10,5 +10,8 @@ "module": "build-module/index.js", "browser": "build-browser/index.js", "author": "WordPress", - "license": "GPL-2.0+" + "license": "GPL-2.0+", + "publishConfig": { + "access": "public" + } } From cc83cdee05ec3438e57f2337277161623ed91995 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Mon, 25 Sep 2017 09:20:38 -0400 Subject: [PATCH 183/393] Publish - @wordpress/hooks@0.1.0-beta.1 --- packages/hooks/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/hooks/package.json b/packages/hooks/package.json index 9c7208849c2e0..fbd24f781ae0d 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/hooks", - "version": "0.1.0-beta.0", + "version": "0.1.0-beta.1", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" From 5ae0096beb5060643faa30a190a0d1938b1d04b8 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Mon, 25 Sep 2017 12:19:19 -0400 Subject: [PATCH 184/393] correctly enable dashes in regexes in validateNamespace --- packages/hooks/src/validateNamespace.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/hooks/src/validateNamespace.js b/packages/hooks/src/validateNamespace.js index a559157275234..02f49b2c41ab3 100644 --- a/packages/hooks/src/validateNamespace.js +++ b/packages/hooks/src/validateNamespace.js @@ -13,12 +13,12 @@ function validateNamespace( namespace ) { return false; } - if ( ! /^[a-zA-Z][a-zA-Z0-9_.-/]*$/.test( namespace ) ) { + if ( ! /^[a-zA-Z][a-zA-Z0-9_.\-/]*$/.test( namespace ) ) { console.error( 'The namespace can only contain numbers, letters, dashes, periods and underscores, plus the forward slash dividing slug and description in the namespace.' ); return false; } - if ( ! /^[a-zA-Z][a-zA-Z0-9_.-]*\/[a-zA-Z][a-zA-Z0-9_.-]*\/[a-zA-Z][a-zA-Z0-9_.-]*$/.test( namespace ) ) { + if ( ! /^[a-zA-Z][a-zA-Z0-9_.\-]*\/[a-zA-Z][a-zA-Z0-9_.\-]*\/[a-zA-Z][a-zA-Z0-9_.\-]*$/.test( namespace ) ) { console.error( 'The namespace must take the form `vendor/plugin/function`.' ); return false; } From 53290482220ec0ca7e5376819202eb363536f64b Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 26 Sep 2017 22:42:37 -0400 Subject: [PATCH 185/393] Export a hooks function enabling adding hooks via composition --- packages/hooks/src/index.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index 93801c5bfc7c8..bc731e42cb348 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -38,3 +38,24 @@ export const doingFilter = createDoingHook( HOOKS.filters ); // Did action/filter functions. export const didAction = createDidHook( HOOKS.actions ); export const didFilter = createDidHook( HOOKS.filters ); + +export const Hooks = () => { + ( { + addAction, + addFilter, + removeAction, + removeFilter, + hasAction, + hasFilter, + removeAllActions, + removeAllFilters, + doAction, + applyFilters, + currentAction, + currentFilter, + doingAction, + doingFilter, + didAction, + didFilter + } ) +}; From 7dc51981ce83946d768fb64ff0eb3003f7c38802 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 26 Sep 2017 22:43:17 -0400 Subject: [PATCH 186/393] test hooks can be instantiated --- packages/hooks/src/test/index.test.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index cfc0aeebfbca2..fad21a5324354 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -21,6 +21,7 @@ import { doingFilter, didAction, didFilter, + Hooks, } from '../'; function filter_a( str ) { @@ -81,6 +82,12 @@ afterEach( () => { console.error = consoleErrorOriginal; } ); +const hooks = new Hooks(); + +test( 'hooks can be instantiated', () => { + expect( typeof hooks ).toEqual( 'object' ); +} ); + test( 'run a filter with no callbacks', () => { expect( applyFilters( 'test.filter', 42 ) ).toEqual( 42 ); } ); From 8931715ec086ef03d213d28c4d0df86d6a39e816 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 26 Sep 2017 22:52:35 -0400 Subject: [PATCH 187/393] Run test on objects instead of globally --- packages/hooks/src/test/index.test.js | 255 +++++++++++++------------- 1 file changed, 129 insertions(+), 126 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index fad21a5324354..267643192b4da 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -24,6 +24,11 @@ import { Hooks, } from '../'; +const testObject = {}; +testObject.hooks = new Hooks(); + +console.log( testObject.hooks ); + function filter_a( str ) { return str + 'a'; } @@ -37,17 +42,17 @@ function filter_c( str ) { } function filter_b_removes_self( str ) { - removeFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b_removes_self' ); + testObject.hooks.removeFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b_removes_self' ); return str + 'b'; } function filter_removes_b( str ) { - removeFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b' ); + testObject.hooks.removeFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b' ); return str; } function filter_removes_c( str ) { - removeFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c' ); + testObject.hooks.removeFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c' ); return str; } @@ -82,148 +87,146 @@ afterEach( () => { console.error = consoleErrorOriginal; } ); -const hooks = new Hooks(); - test( 'hooks can be instantiated', () => { - expect( typeof hooks ).toEqual( 'object' ); + expect( typeof testObject.hooks ).toEqual( 'object' ); } ); test( 'run a filter with no callbacks', () => { - expect( applyFilters( 'test.filter', 42 ) ).toEqual( 42 ); + expect( testObject.hooks.applyFilters( 'test.filter', 42 ) ).toEqual( 42 ); } ); test( 'add and remove a filter', () => { - addFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_a ); - expect( removeAllFilters( 'test.filter' ) ).toEqual( 1 ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); - expect( removeAllFilters( 'test.filter' ) ).toEqual( 0 ); + testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_a ); + expect( testObject.hooks.removeAllFilters( 'test.filter' ) ).toEqual( 1 ); + expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); + expect( testObject.hooks.removeAllFilters( 'test.filter' ) ).toEqual( 0 ); } ); test( 'add a filter and run it', () => { - addFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_a ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testa' ); + testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_a ); + expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testa' ); } ); test( 'add 2 filters in a row and run them', () => { - addFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_a ); - addFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_b ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); + testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_a ); + testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_b ); + expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); } ); test( 'remove a non-existent filter', () => { - expect( removeFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_a ) ).toEqual( 0 ); - expect( removeAllFilters( 'test.filter' ) ).toEqual( 0 ); + expect( testObject.hooks.removeFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_a ) ).toEqual( 0 ); + expect( testObject.hooks.removeAllFilters( 'test.filter' ) ).toEqual( 0 ); } ); test( 'remove an invalid namespace from a filter', () => { - expect( removeFilter( 'test.filter', 42 ) ).toEqual( undefined ); + expect( testObject.hooks.removeFilter( 'test.filter', 42 ) ).toEqual( undefined ); expect( console.error ).toHaveBeenCalledWith( 'The namespace must be a non-empty string.' ); } ); test( 'cannot add filters with non-string hook names', () => { - addFilter( 42, 'my_name/my_plugin/my_callback', () => null ); + testObject.hooks.addFilter( 42, 'my_name/my_plugin/my_callback', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The hook name must be a non-empty string.' ); } ); test( 'cannot add filters with empty-string hook names', () => { - addFilter( '', 'my_name/my_plugin/my_callback', () => null ); + testObject.hooks.addFilter( '', 'my_name/my_plugin/my_callback', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The hook name must be a non-empty string.' ); } ); test( 'cannot add filters with empty-string namespaces', () => { - addFilter( 'hook_name', '', () => null ); + testObject.hooks.addFilter( 'hook_name', '', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The namespace must be a non-empty string.' ); } ); test( 'cannot add filters with invalid namespaces', () => { - addFilter( 'hook_name', 'invalid_name', () => null ); + testObject.hooks.addFilter( 'hook_name', 'invalid_name', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The namespace must take the form `vendor/plugin/function`.' ); } ); test( 'cannot add filters with namespaces missing a functionDescription', () => { - addFilter( 'hook_name', 'invalid_name/', () => null ); + testObject.hooks.addFilter( 'hook_name', 'invalid_name/', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The namespace must take the form `vendor/plugin/function`.' ); } ); test( 'Can add filters with capitals in namespaces', () => { - addFilter( 'hook_name', 'my_name/OhNo/action', () => null ); + testObject.hooks.addFilter( 'hook_name', 'my_name/OhNo/action', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); } ); test( 'Can add filters with capitals in hookName', () => { - addFilter( 'hookName', 'my_name/plugin/action', () => null ); + testObject.hooks.addFilter( 'hookName', 'my_name/plugin/action', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); } ); test( 'Can add filters with periods in namespaces', () => { - addFilter( 'hook_name', 'my_name/plugin.name/ok.action', () => null ); + testObject.hooks.addFilter( 'hook_name', 'my_name/plugin.name/ok.action', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); } ); test( 'Can add filters with periods in hookName', () => { - addFilter( 'hook.name', 'my_name/plugin/action', () => null ); + testObject.hooks.addFilter( 'hook.name', 'my_name/plugin/action', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); } ); test( 'cannot add filters with invalid namespaces', () => { - addFilter( 'hook_name', '/invalid_name', () => null ); + testObject.hooks.addFilter( 'hook_name', '/invalid_name', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The namespace can only contain numbers, letters, dashes, periods and underscores, plus the forward slash dividing slug and description in the namespace.' ); } ); test( 'cannot add filters named with __ prefix', () => { - addFilter( '__test', 'my_name/my_plugin/my_callback', () => null ); + testObject.hooks.addFilter( '__test', 'my_name/my_plugin/my_callback', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The hook name cannot begin with `__`.' ); } ); test( 'cannot add filters with non-function callbacks', () => { - addFilter( 'test', 'my_name/my_plugin/my_callback', '42' ); + testObject.hooks.addFilter( 'test', 'my_name/my_plugin/my_callback', '42' ); expect( console.error ).toHaveBeenCalledWith( 'The hook callback must be a function.' ); } ); test( 'cannot add filters with non-numeric priorities', () => { - addFilter( 'test', 'my_name/my_plugin/my_callback', () => null, '42' ); + testObject.hooks.addFilter( 'test', 'my_name/my_plugin/my_callback', () => null, '42' ); expect( console.error ).toHaveBeenCalledWith( 'If specified, the hook priority must be a number.' ); } ); test( 'cannot run filters with non-string names', () => { - expect( applyFilters( () => {}, 42 ) ).toBe( undefined ); + expect( testObject.hooks.applyFilters( () => {}, 42 ) ).toBe( undefined ); expect( console.error ).toHaveBeenCalledWith( 'The hook name must be a non-empty string.' ); } ); test( 'cannot run filters named with __ prefix', () => { - expect( applyFilters( '__test', 42 ) ).toBe( undefined ); + expect( testObject.hooks.applyFilters( '__test', 42 ) ).toBe( undefined ); expect( console.error ).toHaveBeenCalledWith( 'The hook name cannot begin with `__`.' ); } ); test( 'add 3 filters with different priorities and run them', () => { - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 8 ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testbca' ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 8 ); + expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testbca' ); } ); test( 'filters with the same and different priorities', () => { @@ -237,36 +240,36 @@ test( 'filters with the same and different priorities', () => { } ); } ); - addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3a', callbacks.fn_3a, 3 ); - addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3b', callbacks.fn_3b, 3 ); - addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3c', callbacks.fn_3c, 3 ); - addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2a', callbacks.fn_2a, 2 ); - addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2b', callbacks.fn_2b, 2 ); - addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2c', callbacks.fn_2c, 2 ); + testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3a', callbacks.fn_3a, 3 ); + testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3b', callbacks.fn_3b, 3 ); + testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3c', callbacks.fn_3c, 3 ); + testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2a', callbacks.fn_2a, 2 ); + testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2b', callbacks.fn_2b, 2 ); + testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2c', callbacks.fn_2c, 2 ); - expect( applyFilters( 'test_order', [] ) ).toEqual( + expect( testObject.hooks.applyFilters( 'test_order', [] ) ).toEqual( [ '2a', '2b', '2c', '3a', '3b', '3c' ] ); - removeFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2b', callbacks.fn_2b ); - removeFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3a', callbacks.fn_3a ); + testObject.hooks.removeFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2b', callbacks.fn_2b ); + testObject.hooks.removeFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3a', callbacks.fn_3a ); - expect( applyFilters( 'test_order', [] ) ).toEqual( + expect( testObject.hooks.applyFilters( 'test_order', [] ) ).toEqual( [ '2a', '2c', '3b', '3c' ] ); - addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_4a', callbacks.fn_4a, 4 ); - addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_4b', callbacks.fn_4b, 4 ); - addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_1a', callbacks.fn_1a, 1 ); - addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_4c', callbacks.fn_4c, 4 ); - addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_1b', callbacks.fn_1b, 1 ); - addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3d', callbacks.fn_3d, 3 ); - addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_4d', callbacks.fn_4d, 4 ); - addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_1c', callbacks.fn_1c, 1 ); - addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2d', callbacks.fn_2d, 2 ); - addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_1d', callbacks.fn_1d, 1 ); - - expect( applyFilters( 'test_order', [] ) ).toEqual( [ + testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_4a', callbacks.fn_4a, 4 ); + testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_4b', callbacks.fn_4b, 4 ); + testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_1a', callbacks.fn_1a, 1 ); + testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_4c', callbacks.fn_4c, 4 ); + testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_1b', callbacks.fn_1b, 1 ); + testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3d', callbacks.fn_3d, 3 ); + testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_4d', callbacks.fn_4d, 4 ); + testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_1c', callbacks.fn_1c, 1 ); + testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2d', callbacks.fn_2d, 2 ); + testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_1d', callbacks.fn_1d, 1 ); + + expect( testObject.hooks.applyFilters( 'test_order', [] ) ).toEqual( [ // all except 2b and 3a, which we removed earlier '1a', '1b', '1c', '1d', '2a', '2c', '2d', @@ -327,30 +330,30 @@ test( 'fire action multiple times', () => { } ); test( 'add a filter before the one currently executing', () => { - addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => { - addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => val + 'a', 1 ); + testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => { + testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => val + 'a', 1 ); return val + 'b'; }, 2 ); - expect( applyFilters( 'test.filter', 'test_' ) ).toEqual( 'test_b' ); + expect( testObject.hooks.applyFilters( 'test.filter', 'test_' ) ).toEqual( 'test_b' ); } ); test( 'add a filter after the one currently executing', () => { - addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => { - addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => val + 'b', 2 ); + testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => { + testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => val + 'b', 2 ); return val + 'a'; }, 1 ); - expect( applyFilters( 'test.filter', 'test_' ) ).toEqual( 'test_ab' ); + expect( testObject.hooks.applyFilters( 'test.filter', 'test_' ) ).toEqual( 'test_ab' ); } ); test( 'add a filter immediately after the one currently executing', () => { - addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => { - addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => val + 'b', 1 ); + testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => { + testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => val + 'b', 1 ); return val + 'a'; }, 1 ); - expect( applyFilters( 'test.filter', 'test_' ) ).toEqual( 'test_ab' ); + expect( testObject.hooks.applyFilters( 'test.filter', 'test_' ) ).toEqual( 'test_ab' ); } ); test( 'remove specific action callback', () => { @@ -374,74 +377,74 @@ test( 'remove all action callbacks', () => { } ); test( 'remove specific filter callback', () => { - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 8 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 8 ); - expect( removeFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b' ) ).toEqual( 1 ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testca' ); + expect( testObject.hooks.removeFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b' ) ).toEqual( 1 ); + expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testca' ); } ); test( 'filter removes a callback that has already executed', () => { - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 3 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 5 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_b', filter_removes_b, 4 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 3 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 5 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_b', filter_removes_b, 4 ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); + expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); test( 'filter removes a callback that has already executed (same priority)', () => { - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_b', filter_removes_b, 2 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 4 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_b', filter_removes_b, 2 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 4 ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); + expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); test( 'filter removes the current callback', () => { - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b_removes_self', filter_b_removes_self, 3 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 5 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b_removes_self', filter_b_removes_self, 3 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 5 ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); + expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); test( 'filter removes a callback that has not yet executed (last)', () => { - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 3 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 5 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_c', filter_removes_c, 4 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 3 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 5 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_c', filter_removes_c, 4 ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); + expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); } ); test( 'filter removes a callback that has not yet executed (middle)', () => { - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 3 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 4 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_b', filter_removes_b, 2 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 3 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 4 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_b', filter_removes_b, 2 ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); + expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); } ); test( 'filter removes a callback that has not yet executed (same priority)', () => { - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_b', filter_removes_b, 2 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 4 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_b', filter_removes_b, 2 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 4 ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); + expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); } ); test( 'remove all filter callbacks', () => { - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); - addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 8 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); + testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 8 ); - expect( removeAllFilters( 'test.filter' ) ).toEqual( 3 ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); + expect( testObject.hooks.removeAllFilters( 'test.filter' ) ).toEqual( 3 ); + expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); } ); // Test doingAction, didAction, hasAction. @@ -502,7 +505,7 @@ test( 'Test doingAction, didAction and hasAction.', () => { test( 'Verify doingFilter, didFilter and hasFilter.', () => { let filterCalls = 0; - addFilter( 'runtest.filter', 'my_name/my_plugin/my_callback', arg => { + testObject.hooks.addFilter( 'runtest.filter', 'my_name/my_plugin/my_callback', arg => { filterCalls++; expect( currentFilter() ).toBe( 'runtest.filter' ); expect( doingFilter() ).toBe( true ); @@ -511,7 +514,7 @@ test( 'Verify doingFilter, didFilter and hasFilter.', () => { } ); // Verify filter added and running. - const test = applyFilters( 'runtest.filter', 'someValue' ); + const test = testObject.hooks.applyFilters( 'runtest.filter', 'someValue' ); expect( test ).toBe( 'someValue' ); expect( filterCalls ).toBe( 1 ); expect( didFilter( 'runtest.filter' ) ).toBe( 1 ); @@ -522,35 +525,35 @@ test( 'Verify doingFilter, didFilter and hasFilter.', () => { expect( doingFilter( 'notatest.filter' ) ).toBe( false ); expect( currentFilter() ).toBe( null ); - expect( removeAllFilters( 'runtest.filter' ) ).toEqual( 1 ); + expect( testObject.hooks.removeAllFilters( 'runtest.filter' ) ).toEqual( 1 ); expect( hasFilter( 'runtest.filter' ) ).toBe( 0 ); expect( didFilter( 'runtest.filter' ) ).toBe( 1 ); } ); test( 'recursively calling a filter', () => { - addFilter( 'test.filter', 'my_name/my_plugin/my_callback', value => { + testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', value => { if ( value.length === 7 ) { return value; } - return applyFilters( 'test.filter', value + 'X' ); + return testObject.hooks.applyFilters( 'test.filter', value + 'X' ); } ); - expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testXXX' ); + expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testXXX' ); } ); test( 'current filter when multiple filters are running', () => { - addFilter( 'test.filter1', 'my_name/my_plugin/my_callback', value => { - return applyFilters( 'test.filter2', value.concat( currentFilter() ) ); + testObject.hooks.addFilter( 'test.filter1', 'my_name/my_plugin/my_callback', value => { + return testObject.hooks.applyFilters( 'test.filter2', value.concat( currentFilter() ) ); } ); - addFilter( 'test.filter2', 'my_name/my_plugin/my_callback', value => { + testObject.hooks.addFilter( 'test.filter2', 'my_name/my_plugin/my_callback', value => { return value.concat( currentFilter() ); } ); expect( currentFilter() ).toBe( null ); - expect( applyFilters( 'test.filter1', [ 'test' ] ) ).toEqual( + expect( testObject.hooks.applyFilters( 'test.filter1', [ 'test' ] ) ).toEqual( [ 'test', 'test.filter1', 'test.filter2' ] ); @@ -559,16 +562,16 @@ test( 'current filter when multiple filters are running', () => { test( 'adding and removing filters with recursion', () => { function removeRecurseAndAdd2( val ) { - expect( removeFilter( 'remove_and_add', 'my_name/my_plugin/my_callback_recurse' ) ).toEqual( 1 ); - val += '-' + applyFilters( 'remove_and_add', '' ) + '-'; - addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback_recurse', 10 ); + expect( testObject.hooks.removeFilter( 'remove_and_add', 'my_name/my_plugin/my_callback_recurse' ) ).toEqual( 1 ); + val += '-' + testObject.hooks.applyFilters( 'remove_and_add', '' ) + '-'; + testObject.hooks.addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback_recurse', 10 ); return val + '2'; } - addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback', val => val + '1', 11 ); - addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback_recurse', removeRecurseAndAdd2, 12 ); - addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback', val => val + '3', 13 ); - addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback', val => val + '4', 14 ); + testObject.hooks.addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback', val => val + '1', 11 ); + testObject.hooks.addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback_recurse', removeRecurseAndAdd2, 12 ); + testObject.hooks.addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback', val => val + '3', 13 ); + testObject.hooks.addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback', val => val + '4', 14 ); - expect( applyFilters( 'remove_and_add', '' ) ).toEqual( '1-134-234' ); + expect( testObject.hooks.applyFilters( 'remove_and_add', '' ) ).toEqual( '1-134-234' ); } ); From 44c0c6fea802ea9f33ebc4d1412f5e019ef8fdeb Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 26 Sep 2017 22:52:48 -0400 Subject: [PATCH 188/393] correct data return for Hooks --- packages/hooks/src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index bc731e42cb348..66c2b4f3877cc 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -40,7 +40,7 @@ export const didAction = createDidHook( HOOKS.actions ); export const didFilter = createDidHook( HOOKS.filters ); export const Hooks = () => { - ( { + return { addAction, addFilter, removeAction, @@ -57,5 +57,5 @@ export const Hooks = () => { doingFilter, didAction, didFilter - } ) + }; }; From e9c70024a8452a5a433a1e4f5a0630983d5f4668 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 26 Sep 2017 23:04:55 -0400 Subject: [PATCH 189/393] Rework the Hooks object, use a local HOOKS instead of global --- packages/hooks/src/index.js | 70 ++++++++++++------------------------- 1 file changed, 22 insertions(+), 48 deletions(-) diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index 66c2b4f3877cc..b059227afdace 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -1,4 +1,3 @@ -import HOOKS from './hooks'; import createAddHook from './createAddHook'; import createRemoveHook from './createRemoveHook'; import createHasHook from './createHasHook'; @@ -7,55 +6,30 @@ import createCurrentHook from './createCurrentHook'; import createDoingHook from './createDoingHook'; import createDidHook from './createDidHook'; -// Add action/filter functions. -export const addAction = createAddHook( HOOKS.actions ); -export const addFilter = createAddHook( HOOKS.filters ); - -// Remove action/filter functions. -export const removeAction = createRemoveHook( HOOKS.actions ); -export const removeFilter = createRemoveHook( HOOKS.filters ); - -// Has action/filter functions. -export const hasAction = createHasHook( HOOKS.actions ); -export const hasFilter = createHasHook( HOOKS.filters ); - -// Remove all actions/filters functions. -export const removeAllActions = createRemoveHook( HOOKS.actions, true ); -export const removeAllFilters = createRemoveHook( HOOKS.filters, true ); - -// Do action/apply filters functions. -export const doAction = createRunHook( HOOKS.actions ); -export const applyFilters = createRunHook( HOOKS.filters, true ); - -// Current action/filter functions. -export const currentAction = createCurrentHook( HOOKS.actions ); -export const currentFilter = createCurrentHook( HOOKS.filters ); - -// Doing action/filter: true while a hook is being run. -export const doingAction = createDoingHook( HOOKS.actions ); -export const doingFilter = createDoingHook( HOOKS.filters ); - -// Did action/filter functions. -export const didAction = createDidHook( HOOKS.actions ); -export const didFilter = createDidHook( HOOKS.filters ); export const Hooks = () => { + const HOOKS = { + actions: {}, + filters: {}, + }; + return { - addAction, - addFilter, - removeAction, - removeFilter, - hasAction, - hasFilter, - removeAllActions, - removeAllFilters, - doAction, - applyFilters, - currentAction, - currentFilter, - doingAction, - doingFilter, - didAction, - didFilter + 'addAction': createAddHook( HOOKS.actions ), + 'addFilter': createAddHook( HOOKS.filters ), + 'removeAction': createRemoveHook( HOOKS.actions ), + 'removeFilter': createRemoveHook( HOOKS.filters ), + 'hasAction': createHasHook( HOOKS.actions ), + 'hasFilter': createHasHook( HOOKS.filters ), + 'removeAllActions': createRemoveHook( HOOKS.actions, true ), + 'removeAllFilters': createRemoveHook( HOOKS.filters, true ), + 'doAction': createRunHook( HOOKS.actions ), + 'applyFilters': createRunHook( HOOKS.filters, true ), + 'currentAction': createCurrentHook( HOOKS.actions ), + 'currentFilter': createCurrentHook( HOOKS.filters ), + 'doingAction': createDoingHook( HOOKS.actions ), + 'doingFilter': createDoingHook( HOOKS.filters ), + 'didAction': createDidHook( HOOKS.actions ), + 'didFilter': createDidHook( HOOKS.filters ), + 'HOOKS': HOOKS, }; }; From 7c69c0347841222ee7ccd2e67016beb4544793dc Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 26 Sep 2017 23:05:23 -0400 Subject: [PATCH 190/393] use object based hooks throughout testing --- packages/hooks/src/test/index.test.js | 175 ++++++++++++-------------- 1 file changed, 79 insertions(+), 96 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 267643192b4da..9451fbb28006d 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -3,24 +3,7 @@ /** * Internal dependencies */ -import HOOKS from '../hooks'; import { - addAction, - addFilter, - removeAction, - removeFilter, - removeAllActions, - removeAllFilters, - hasAction, - hasFilter, - doAction, - applyFilters, - currentAction, - currentFilter, - doingAction, - doingFilter, - didAction, - didFilter, Hooks, } from '../'; @@ -72,10 +55,10 @@ const consoleErrorOriginal = console.error; beforeEach( () => { window.actionValue = ''; - // Reset state in between tests (clear all callbacks, `didAction` counts, + // Reset state in between tests (clear all callbacks, `testObject.hooks.didAction` counts, // etc.) Just reseting HOOKS.actions and HOOKS.filters is not enough // because the internal functions have references to the original objects. - [ HOOKS.actions, HOOKS.filters ].forEach( hooks => { + [ testObject.hooks.HOOKS.actions, testObject.hooks.HOOKS.filters ].forEach( hooks => { for ( const k in hooks ) { delete hooks[ k ]; } @@ -279,30 +262,30 @@ test( 'filters with the same and different priorities', () => { } ); test( 'add and remove an action', () => { - addAction( 'test.action', 'my_name/my_plugin/my_callback', action_a ); - expect( removeAllActions( 'test.action' ) ).toEqual( 1 ); - expect( doAction( 'test.action' ) ).toBe( undefined ); + testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', action_a ); + expect( testObject.hooks.removeAllActions( 'test.action' ) ).toEqual( 1 ); + expect( testObject.hooks.doAction( 'test.action' ) ).toBe( undefined ); expect( window.actionValue ).toBe( '' ); } ); test( 'add an action and run it', () => { - addAction( 'test.action', 'my_name/my_plugin/my_callback', action_a ); - doAction( 'test.action' ); + testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', action_a ); + testObject.hooks.doAction( 'test.action' ); expect( window.actionValue ).toBe( 'a' ); } ); test( 'add 2 actions in a row and then run them', () => { - addAction( 'test.action', 'my_name/my_plugin/my_callback', action_a ); - addAction( 'test.action', 'my_name/my_plugin/my_callback', action_b ); - doAction( 'test.action' ); + testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', action_a ); + testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', action_b ); + testObject.hooks.doAction( 'test.action' ); expect( window.actionValue ).toBe( 'ab' ); } ); test( 'add 3 actions with different priorities and run them', () => { - addAction( 'test.action', 'my_name/my_plugin/my_callback', action_a ); - addAction( 'test.action', 'my_name/my_plugin/my_callback', action_b, 2 ); - addAction( 'test.action', 'my_name/my_plugin/my_callback', action_c, 8 ); - doAction( 'test.action' ); + testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', action_a ); + testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', action_b, 2 ); + testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', action_c, 8 ); + testObject.hooks.doAction( 'test.action' ); expect( window.actionValue ).toBe( 'bca' ); } ); @@ -310,11 +293,11 @@ test( 'pass in two arguments to an action', () => { const arg1 = { a: 10 }; const arg2 = { b: 20 }; - addAction( 'test.action', 'my_name/my_plugin/my_callback', ( a, b ) => { + testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', ( a, b ) => { expect( a ).toBe( arg1 ); expect( b ).toBe( arg2 ); } ); - doAction( 'test.action', arg1, arg2 ); + testObject.hooks.doAction( 'test.action', arg1, arg2 ); } ); test( 'fire action multiple times', () => { @@ -324,9 +307,9 @@ test( 'fire action multiple times', () => { expect( true ).toBe( true ); }; - addAction( 'test.action', 'my_name/my_plugin/my_callback', func ); - doAction( 'test.action' ); - doAction( 'test.action' ); + testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', func ); + testObject.hooks.doAction( 'test.action' ); + testObject.hooks.doAction( 'test.action' ); } ); test( 'add a filter before the one currently executing', () => { @@ -357,22 +340,22 @@ test( 'add a filter immediately after the one currently executing', () => { } ); test( 'remove specific action callback', () => { - addAction( 'test.action', 'my_name/my_plugin/my_callback_action_a', action_a ); - addAction( 'test.action', 'my_name/my_plugin/my_callback_action_b', action_b, 2 ); - addAction( 'test.action', 'my_name/my_plugin/my_callback_action_c', action_c, 8 ); + testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback_action_a', action_a ); + testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback_action_b', action_b, 2 ); + testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback_action_c', action_c, 8 ); - expect( removeAction( 'test.action', 'my_name/my_plugin/my_callback_action_b' ) ).toEqual( 1 ); - doAction( 'test.action' ); + expect( testObject.hooks.removeAction( 'test.action', 'my_name/my_plugin/my_callback_action_b' ) ).toEqual( 1 ); + testObject.hooks.doAction( 'test.action' ); expect( window.actionValue ).toBe( 'ca' ); } ); test( 'remove all action callbacks', () => { - addAction( 'test.action', 'my_name/my_plugin/my_callback_action_a', action_a ); - addAction( 'test.action', 'my_name/my_plugin/my_callback_action_b', action_b, 2 ); - addAction( 'test.action', 'my_name/my_plugin/my_callback_action_c', action_c, 8 ); + testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback_action_a', action_a ); + testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback_action_b', action_b, 2 ); + testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback_action_c', action_c, 8 ); - expect( removeAllActions( 'test.action' ) ).toEqual( 3 ); - doAction( 'test.action' ); + expect( testObject.hooks.removeAllActions( 'test.action' ) ).toEqual( 3 ); + testObject.hooks.doAction( 'test.action' ); expect( window.actionValue ).toBe( '' ); } ); @@ -447,69 +430,69 @@ test( 'remove all filter callbacks', () => { expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); } ); -// Test doingAction, didAction, hasAction. -test( 'Test doingAction, didAction and hasAction.', () => { +// Test testObject.hooks.doingAction, testObject.hooks.didAction, testObject.hooks.hasAction. +test( 'Test testObject.hooks.doingAction, testObject.hooks.didAction and testObject.hooks.hasAction.', () => { let actionCalls = 0; - addAction( 'another.action', 'my_name/my_plugin/my_callback', () => {} ); - doAction( 'another.action' ); + testObject.hooks.addAction( 'another.action', 'my_name/my_plugin/my_callback', () => {} ); + testObject.hooks.doAction( 'another.action' ); // Verify no action is running yet. - expect( doingAction( 'test.action' ) ).toBe( false ); + expect( testObject.hooks.doingAction( 'test.action' ) ).toBe( false ); - expect( didAction( 'test.action' ) ).toBe( 0 ); - expect( hasAction( 'test.action' ) ).toBe( 0 ); + expect( testObject.hooks.didAction( 'test.action' ) ).toBe( 0 ); + expect( testObject.hooks.hasAction( 'test.action' ) ).toBe( 0 ); - addAction( 'test.action', 'my_name/my_plugin/my_callback', () => { + testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', () => { actionCalls++; - expect( currentAction() ).toBe( 'test.action' ); - expect( doingAction() ).toBe( true ); - expect( doingAction( 'test.action' ) ).toBe( true ); + expect( testObject.hooks.currentAction() ).toBe( 'test.action' ); + expect( testObject.hooks.doingAction() ).toBe( true ); + expect( testObject.hooks.doingAction( 'test.action' ) ).toBe( true ); } ); // Verify action added, not running yet. - expect( doingAction( 'test.action' ) ).toBe( false ); - expect( didAction( 'test.action' ) ).toBe( 0 ); - expect( hasAction( 'test.action' ) ).toBe( 1 ); + expect( testObject.hooks.doingAction( 'test.action' ) ).toBe( false ); + expect( testObject.hooks.didAction( 'test.action' ) ).toBe( 0 ); + expect( testObject.hooks.hasAction( 'test.action' ) ).toBe( 1 ); - doAction( 'test.action' ); + testObject.hooks.doAction( 'test.action' ); // Verify action added and running. expect( actionCalls ).toBe( 1 ); - expect( doingAction( 'test.action' ) ).toBe( false ); - expect( didAction( 'test.action' ) ).toBe( 1 ); - expect( hasAction( 'test.action' ) ).toBe( 1 ); - expect( doingAction() ).toBe( false ); - expect( doingAction( 'test.action' ) ).toBe( false ); - expect( doingAction( 'notatest.action' ) ).toBe( false ); - expect( currentAction() ).toBe( null ); - - doAction( 'test.action' ); + expect( testObject.hooks.doingAction( 'test.action' ) ).toBe( false ); + expect( testObject.hooks.didAction( 'test.action' ) ).toBe( 1 ); + expect( testObject.hooks.hasAction( 'test.action' ) ).toBe( 1 ); + expect( testObject.hooks.doingAction() ).toBe( false ); + expect( testObject.hooks.doingAction( 'test.action' ) ).toBe( false ); + expect( testObject.hooks.doingAction( 'notatest.action' ) ).toBe( false ); + expect( testObject.hooks.currentAction() ).toBe( null ); + + testObject.hooks.doAction( 'test.action' ); expect( actionCalls ).toBe( 2 ); - expect( didAction( 'test.action' ) ).toBe( 2 ); + expect( testObject.hooks.didAction( 'test.action' ) ).toBe( 2 ); - expect( removeAllActions( 'test.action' ) ).toEqual( 1 ); + expect( testObject.hooks.removeAllActions( 'test.action' ) ).toEqual( 1 ); // Verify state is reset appropriately. - expect( doingAction( 'test.action' ) ).toBe( false ); - expect( didAction( 'test.action' ) ).toBe( 2 ); - expect( hasAction( 'test.action' ) ).toBe( 0 ); + expect( testObject.hooks.doingAction( 'test.action' ) ).toBe( false ); + expect( testObject.hooks.didAction( 'test.action' ) ).toBe( 2 ); + expect( testObject.hooks.hasAction( 'test.action' ) ).toBe( 0 ); - doAction( 'another.action' ); - expect( doingAction( 'test.action' ) ).toBe( false ); + testObject.hooks.doAction( 'another.action' ); + expect( testObject.hooks.doingAction( 'test.action' ) ).toBe( false ); - // Verify hasAction returns 0 when no matching action. - expect( hasAction( 'notatest.action' ) ).toBe( 0 ); + // Verify testObject.hooks.hasAction returns 0 when no matching action. + expect( testObject.hooks.hasAction( 'notatest.action' ) ).toBe( 0 ); } ); -test( 'Verify doingFilter, didFilter and hasFilter.', () => { +test( 'Verify testObject.hooks.doingFilter, testObject.hooks.didFilter and testObject.hooks.hasFilter.', () => { let filterCalls = 0; testObject.hooks.addFilter( 'runtest.filter', 'my_name/my_plugin/my_callback', arg => { filterCalls++; - expect( currentFilter() ).toBe( 'runtest.filter' ); - expect( doingFilter() ).toBe( true ); - expect( doingFilter( 'runtest.filter' ) ).toBe( true ); + expect( testObject.hooks.currentFilter() ).toBe( 'runtest.filter' ); + expect( testObject.hooks.doingFilter() ).toBe( true ); + expect( testObject.hooks.doingFilter( 'runtest.filter' ) ).toBe( true ); return arg; } ); @@ -517,18 +500,18 @@ test( 'Verify doingFilter, didFilter and hasFilter.', () => { const test = testObject.hooks.applyFilters( 'runtest.filter', 'someValue' ); expect( test ).toBe( 'someValue' ); expect( filterCalls ).toBe( 1 ); - expect( didFilter( 'runtest.filter' ) ).toBe( 1 ); - expect( hasFilter( 'runtest.filter' ) ).toBe( 1 ); - expect( hasFilter( 'notatest.filter' ) ).toBe( 0 ); - expect( doingFilter() ).toBe( false ); - expect( doingFilter( 'runtest.filter' ) ).toBe( false ); - expect( doingFilter( 'notatest.filter' ) ).toBe( false ); - expect( currentFilter() ).toBe( null ); + expect( testObject.hooks.didFilter( 'runtest.filter' ) ).toBe( 1 ); + expect( testObject.hooks.hasFilter( 'runtest.filter' ) ).toBe( 1 ); + expect( testObject.hooks.hasFilter( 'notatest.filter' ) ).toBe( 0 ); + expect( testObject.hooks.doingFilter() ).toBe( false ); + expect( testObject.hooks.doingFilter( 'runtest.filter' ) ).toBe( false ); + expect( testObject.hooks.doingFilter( 'notatest.filter' ) ).toBe( false ); + expect( testObject.hooks.currentFilter() ).toBe( null ); expect( testObject.hooks.removeAllFilters( 'runtest.filter' ) ).toEqual( 1 ); - expect( hasFilter( 'runtest.filter' ) ).toBe( 0 ); - expect( didFilter( 'runtest.filter' ) ).toBe( 1 ); + expect( testObject.hooks.hasFilter( 'runtest.filter' ) ).toBe( 0 ); + expect( testObject.hooks.didFilter( 'runtest.filter' ) ).toBe( 1 ); } ); test( 'recursively calling a filter', () => { @@ -544,20 +527,20 @@ test( 'recursively calling a filter', () => { test( 'current filter when multiple filters are running', () => { testObject.hooks.addFilter( 'test.filter1', 'my_name/my_plugin/my_callback', value => { - return testObject.hooks.applyFilters( 'test.filter2', value.concat( currentFilter() ) ); + return testObject.hooks.applyFilters( 'test.filter2', value.concat( testObject.hooks.currentFilter() ) ); } ); testObject.hooks.addFilter( 'test.filter2', 'my_name/my_plugin/my_callback', value => { - return value.concat( currentFilter() ); + return value.concat( testObject.hooks.currentFilter() ); } ); - expect( currentFilter() ).toBe( null ); + expect( testObject.hooks.currentFilter() ).toBe( null ); expect( testObject.hooks.applyFilters( 'test.filter1', [ 'test' ] ) ).toEqual( [ 'test', 'test.filter1', 'test.filter2' ] ); - expect( currentFilter() ).toBe( null ); + expect( testObject.hooks.currentFilter() ).toBe( null ); } ); test( 'adding and removing filters with recursion', () => { From 3863e35c3250869e938be46ca9e2ef55029eb396 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 26 Sep 2017 23:05:35 -0400 Subject: [PATCH 191/393] remove unused global HOOKS --- packages/hooks/src/hooks.js | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 packages/hooks/src/hooks.js diff --git a/packages/hooks/src/hooks.js b/packages/hooks/src/hooks.js deleted file mode 100644 index 2fa576f48eb26..0000000000000 --- a/packages/hooks/src/hooks.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Contains the registered hooks, keyed by hook type. Each hook type is an - * array of objects with priority and callback of each registered hook. - */ -const HOOKS = { - actions: {}, - filters: {}, -}; - -export default HOOKS; From 3ccbc362724d5dfb2238f5f00d3387189908180d Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 26 Sep 2017 23:05:58 -0400 Subject: [PATCH 192/393] remove some logging --- packages/hooks/src/test/index.test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 9451fbb28006d..28a55a8f98d98 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -10,8 +10,6 @@ import { const testObject = {}; testObject.hooks = new Hooks(); -console.log( testObject.hooks ); - function filter_a( str ) { return str + 'a'; } From 76f706abd8b95de389ced4ea3a5fd7a9170720af Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 26 Sep 2017 23:14:39 -0400 Subject: [PATCH 193/393] remove extra parts from namespace in tests --- packages/hooks/src/test/index.test.js | 212 +++++++++++++------------- 1 file changed, 106 insertions(+), 106 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 28a55a8f98d98..22d5c90936626 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -23,17 +23,17 @@ function filter_c( str ) { } function filter_b_removes_self( str ) { - testObject.hooks.removeFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b_removes_self' ); + testObject.hooks.removeFilter( 'test.filter', 'my_callback_filter_b_removes_self' ); return str + 'b'; } function filter_removes_b( str ) { - testObject.hooks.removeFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b' ); + testObject.hooks.removeFilter( 'test.filter', 'my_callback_filter_b' ); return str; } function filter_removes_c( str ) { - testObject.hooks.removeFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c' ); + testObject.hooks.removeFilter( 'test.filter', 'my_callback_filter_c' ); return str; } @@ -77,25 +77,25 @@ test( 'run a filter with no callbacks', () => { } ); test( 'add and remove a filter', () => { - testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_a ); + testObject.hooks.addFilter( 'test.filter', 'my_callback', filter_a ); expect( testObject.hooks.removeAllFilters( 'test.filter' ) ).toEqual( 1 ); expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); expect( testObject.hooks.removeAllFilters( 'test.filter' ) ).toEqual( 0 ); } ); test( 'add a filter and run it', () => { - testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_a ); + testObject.hooks.addFilter( 'test.filter', 'my_callback', filter_a ); expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testa' ); } ); test( 'add 2 filters in a row and run them', () => { - testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_a ); - testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_b ); + testObject.hooks.addFilter( 'test.filter', 'my_callback', filter_a ); + testObject.hooks.addFilter( 'test.filter', 'my_callback', filter_b ); expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); } ); test( 'remove a non-existent filter', () => { - expect( testObject.hooks.removeFilter( 'test.filter', 'my_name/my_plugin/my_callback', filter_a ) ).toEqual( 0 ); + expect( testObject.hooks.removeFilter( 'test.filter', 'my_callback', filter_a ) ).toEqual( 0 ); expect( testObject.hooks.removeAllFilters( 'test.filter' ) ).toEqual( 0 ); } ); @@ -107,14 +107,14 @@ test( 'remove an invalid namespace from a filter', () => { } ); test( 'cannot add filters with non-string hook names', () => { - testObject.hooks.addFilter( 42, 'my_name/my_plugin/my_callback', () => null ); + testObject.hooks.addFilter( 42, 'my_callback', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The hook name must be a non-empty string.' ); } ); test( 'cannot add filters with empty-string hook names', () => { - testObject.hooks.addFilter( '', 'my_name/my_plugin/my_callback', () => null ); + testObject.hooks.addFilter( '', 'my_callback', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The hook name must be a non-empty string.' ); @@ -128,62 +128,62 @@ test( 'cannot add filters with empty-string namespaces', () => { } ); test( 'cannot add filters with invalid namespaces', () => { - testObject.hooks.addFilter( 'hook_name', 'invalid_name', () => null ); + testObject.hooks.addFilter( 'hook_name', 'invalid_%&name', () => null ); expect( console.error ).toHaveBeenCalledWith( - 'The namespace must take the form `vendor/plugin/function`.' + 'The namespace can only contain numbers, letters, dashes, periods and underscores.' ); } ); test( 'cannot add filters with namespaces missing a functionDescription', () => { testObject.hooks.addFilter( 'hook_name', 'invalid_name/', () => null ); expect( console.error ).toHaveBeenCalledWith( - 'The namespace must take the form `vendor/plugin/function`.' + 'The namespace can only contain numbers, letters, dashes, periods and underscores.' ); } ); test( 'Can add filters with capitals in namespaces', () => { - testObject.hooks.addFilter( 'hook_name', 'my_name/OhNo/action', () => null ); + testObject.hooks.addFilter( 'hook_name', 'my_name-OhNoaction', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); } ); test( 'Can add filters with capitals in hookName', () => { - testObject.hooks.addFilter( 'hookName', 'my_name/plugin/action', () => null ); + testObject.hooks.addFilter( 'hookName', 'action', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); } ); test( 'Can add filters with periods in namespaces', () => { - testObject.hooks.addFilter( 'hook_name', 'my_name/plugin.name/ok.action', () => null ); + testObject.hooks.addFilter( 'hook_name', 'ok.action', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); } ); test( 'Can add filters with periods in hookName', () => { - testObject.hooks.addFilter( 'hook.name', 'my_name/plugin/action', () => null ); + testObject.hooks.addFilter( 'hook.name', 'action', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); } ); test( 'cannot add filters with invalid namespaces', () => { testObject.hooks.addFilter( 'hook_name', '/invalid_name', () => null ); expect( console.error ).toHaveBeenCalledWith( - 'The namespace can only contain numbers, letters, dashes, periods and underscores, plus the forward slash dividing slug and description in the namespace.' + 'The namespace can only contain numbers, letters, dashes, periods and underscores.' ); } ); test( 'cannot add filters named with __ prefix', () => { - testObject.hooks.addFilter( '__test', 'my_name/my_plugin/my_callback', () => null ); + testObject.hooks.addFilter( '__test', 'my_callback', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The hook name cannot begin with `__`.' ); } ); test( 'cannot add filters with non-function callbacks', () => { - testObject.hooks.addFilter( 'test', 'my_name/my_plugin/my_callback', '42' ); + testObject.hooks.addFilter( 'test', 'my_callback', '42' ); expect( console.error ).toHaveBeenCalledWith( 'The hook callback must be a function.' ); } ); test( 'cannot add filters with non-numeric priorities', () => { - testObject.hooks.addFilter( 'test', 'my_name/my_plugin/my_callback', () => null, '42' ); + testObject.hooks.addFilter( 'test', 'my_callback', () => null, '42' ); expect( console.error ).toHaveBeenCalledWith( 'If specified, the hook priority must be a number.' ); @@ -204,9 +204,9 @@ test( 'cannot run filters named with __ prefix', () => { } ); test( 'add 3 filters with different priorities and run them', () => { - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 8 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_a', filter_a ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 2 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 8 ); expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testbca' ); } ); @@ -221,34 +221,34 @@ test( 'filters with the same and different priorities', () => { } ); } ); - testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3a', callbacks.fn_3a, 3 ); - testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3b', callbacks.fn_3b, 3 ); - testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3c', callbacks.fn_3c, 3 ); - testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2a', callbacks.fn_2a, 2 ); - testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2b', callbacks.fn_2b, 2 ); - testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2c', callbacks.fn_2c, 2 ); + testObject.hooks.addFilter( 'test_order', 'my_callback_fn_3a', callbacks.fn_3a, 3 ); + testObject.hooks.addFilter( 'test_order', 'my_callback_fn_3b', callbacks.fn_3b, 3 ); + testObject.hooks.addFilter( 'test_order', 'my_callback_fn_3c', callbacks.fn_3c, 3 ); + testObject.hooks.addFilter( 'test_order', 'my_callback_fn_2a', callbacks.fn_2a, 2 ); + testObject.hooks.addFilter( 'test_order', 'my_callback_fn_2b', callbacks.fn_2b, 2 ); + testObject.hooks.addFilter( 'test_order', 'my_callback_fn_2c', callbacks.fn_2c, 2 ); expect( testObject.hooks.applyFilters( 'test_order', [] ) ).toEqual( [ '2a', '2b', '2c', '3a', '3b', '3c' ] ); - testObject.hooks.removeFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2b', callbacks.fn_2b ); - testObject.hooks.removeFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3a', callbacks.fn_3a ); + testObject.hooks.removeFilter( 'test_order', 'my_callback_fn_2b', callbacks.fn_2b ); + testObject.hooks.removeFilter( 'test_order', 'my_callback_fn_3a', callbacks.fn_3a ); expect( testObject.hooks.applyFilters( 'test_order', [] ) ).toEqual( [ '2a', '2c', '3b', '3c' ] ); - testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_4a', callbacks.fn_4a, 4 ); - testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_4b', callbacks.fn_4b, 4 ); - testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_1a', callbacks.fn_1a, 1 ); - testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_4c', callbacks.fn_4c, 4 ); - testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_1b', callbacks.fn_1b, 1 ); - testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_3d', callbacks.fn_3d, 3 ); - testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_4d', callbacks.fn_4d, 4 ); - testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_1c', callbacks.fn_1c, 1 ); - testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_2d', callbacks.fn_2d, 2 ); - testObject.hooks.addFilter( 'test_order', 'my_name/my_plugin/my_callback_fn_1d', callbacks.fn_1d, 1 ); + testObject.hooks.addFilter( 'test_order', 'my_callback_fn_4a', callbacks.fn_4a, 4 ); + testObject.hooks.addFilter( 'test_order', 'my_callback_fn_4b', callbacks.fn_4b, 4 ); + testObject.hooks.addFilter( 'test_order', 'my_callback_fn_1a', callbacks.fn_1a, 1 ); + testObject.hooks.addFilter( 'test_order', 'my_callback_fn_4c', callbacks.fn_4c, 4 ); + testObject.hooks.addFilter( 'test_order', 'my_callback_fn_1b', callbacks.fn_1b, 1 ); + testObject.hooks.addFilter( 'test_order', 'my_callback_fn_3d', callbacks.fn_3d, 3 ); + testObject.hooks.addFilter( 'test_order', 'my_callback_fn_4d', callbacks.fn_4d, 4 ); + testObject.hooks.addFilter( 'test_order', 'my_callback_fn_1c', callbacks.fn_1c, 1 ); + testObject.hooks.addFilter( 'test_order', 'my_callback_fn_2d', callbacks.fn_2d, 2 ); + testObject.hooks.addFilter( 'test_order', 'my_callback_fn_1d', callbacks.fn_1d, 1 ); expect( testObject.hooks.applyFilters( 'test_order', [] ) ).toEqual( [ // all except 2b and 3a, which we removed earlier @@ -260,29 +260,29 @@ test( 'filters with the same and different priorities', () => { } ); test( 'add and remove an action', () => { - testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', action_a ); + testObject.hooks.addAction( 'test.action', 'my_callback', action_a ); expect( testObject.hooks.removeAllActions( 'test.action' ) ).toEqual( 1 ); expect( testObject.hooks.doAction( 'test.action' ) ).toBe( undefined ); expect( window.actionValue ).toBe( '' ); } ); test( 'add an action and run it', () => { - testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', action_a ); + testObject.hooks.addAction( 'test.action', 'my_callback', action_a ); testObject.hooks.doAction( 'test.action' ); expect( window.actionValue ).toBe( 'a' ); } ); test( 'add 2 actions in a row and then run them', () => { - testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', action_a ); - testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', action_b ); + testObject.hooks.addAction( 'test.action', 'my_callback', action_a ); + testObject.hooks.addAction( 'test.action', 'my_callback', action_b ); testObject.hooks.doAction( 'test.action' ); expect( window.actionValue ).toBe( 'ab' ); } ); test( 'add 3 actions with different priorities and run them', () => { - testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', action_a ); - testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', action_b, 2 ); - testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', action_c, 8 ); + testObject.hooks.addAction( 'test.action', 'my_callback', action_a ); + testObject.hooks.addAction( 'test.action', 'my_callback', action_b, 2 ); + testObject.hooks.addAction( 'test.action', 'my_callback', action_c, 8 ); testObject.hooks.doAction( 'test.action' ); expect( window.actionValue ).toBe( 'bca' ); } ); @@ -291,7 +291,7 @@ test( 'pass in two arguments to an action', () => { const arg1 = { a: 10 }; const arg2 = { b: 20 }; - testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', ( a, b ) => { + testObject.hooks.addAction( 'test.action', 'my_callback', ( a, b ) => { expect( a ).toBe( arg1 ); expect( b ).toBe( arg2 ); } ); @@ -305,14 +305,14 @@ test( 'fire action multiple times', () => { expect( true ).toBe( true ); }; - testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', func ); + testObject.hooks.addAction( 'test.action', 'my_callback', func ); testObject.hooks.doAction( 'test.action' ); testObject.hooks.doAction( 'test.action' ); } ); test( 'add a filter before the one currently executing', () => { - testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => { - testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => val + 'a', 1 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback', val => { + testObject.hooks.addFilter( 'test.filter', 'my_callback', val => val + 'a', 1 ); return val + 'b'; }, 2 ); @@ -320,8 +320,8 @@ test( 'add a filter before the one currently executing', () => { } ); test( 'add a filter after the one currently executing', () => { - testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => { - testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => val + 'b', 2 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback', val => { + testObject.hooks.addFilter( 'test.filter', 'my_callback', val => val + 'b', 2 ); return val + 'a'; }, 1 ); @@ -329,8 +329,8 @@ test( 'add a filter after the one currently executing', () => { } ); test( 'add a filter immediately after the one currently executing', () => { - testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => { - testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', val => val + 'b', 1 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback', val => { + testObject.hooks.addFilter( 'test.filter', 'my_callback', val => val + 'b', 1 ); return val + 'a'; }, 1 ); @@ -338,19 +338,19 @@ test( 'add a filter immediately after the one currently executing', () => { } ); test( 'remove specific action callback', () => { - testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback_action_a', action_a ); - testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback_action_b', action_b, 2 ); - testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback_action_c', action_c, 8 ); + testObject.hooks.addAction( 'test.action', 'my_callback_action_a', action_a ); + testObject.hooks.addAction( 'test.action', 'my_callback_action_b', action_b, 2 ); + testObject.hooks.addAction( 'test.action', 'my_callback_action_c', action_c, 8 ); - expect( testObject.hooks.removeAction( 'test.action', 'my_name/my_plugin/my_callback_action_b' ) ).toEqual( 1 ); + expect( testObject.hooks.removeAction( 'test.action', 'my_callback_action_b' ) ).toEqual( 1 ); testObject.hooks.doAction( 'test.action' ); expect( window.actionValue ).toBe( 'ca' ); } ); test( 'remove all action callbacks', () => { - testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback_action_a', action_a ); - testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback_action_b', action_b, 2 ); - testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback_action_c', action_c, 8 ); + testObject.hooks.addAction( 'test.action', 'my_callback_action_a', action_a ); + testObject.hooks.addAction( 'test.action', 'my_callback_action_b', action_b, 2 ); + testObject.hooks.addAction( 'test.action', 'my_callback_action_c', action_c, 8 ); expect( testObject.hooks.removeAllActions( 'test.action' ) ).toEqual( 3 ); testObject.hooks.doAction( 'test.action' ); @@ -358,71 +358,71 @@ test( 'remove all action callbacks', () => { } ); test( 'remove specific filter callback', () => { - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 8 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_a', filter_a ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 2 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 8 ); - expect( testObject.hooks.removeFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b' ) ).toEqual( 1 ); + expect( testObject.hooks.removeFilter( 'test.filter', 'my_callback_filter_b' ) ).toEqual( 1 ); expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testca' ); } ); test( 'filter removes a callback that has already executed', () => { - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 3 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 5 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_b', filter_removes_b, 4 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_a', filter_a, 1 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 3 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 5 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_removes_b', filter_removes_b, 4 ); expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); test( 'filter removes a callback that has already executed (same priority)', () => { - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_b', filter_removes_b, 2 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 4 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_a', filter_a, 1 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 2 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_removes_b', filter_removes_b, 2 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 4 ); expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); test( 'filter removes the current callback', () => { - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b_removes_self', filter_b_removes_self, 3 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 5 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_a', filter_a, 1 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_b_removes_self', filter_b_removes_self, 3 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 5 ); expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); test( 'filter removes a callback that has not yet executed (last)', () => { - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 3 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 5 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_c', filter_removes_c, 4 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_a', filter_a, 1 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 3 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 5 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_removes_c', filter_removes_c, 4 ); expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); } ); test( 'filter removes a callback that has not yet executed (middle)', () => { - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 3 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 4 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_b', filter_removes_b, 2 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_a', filter_a, 1 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 3 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 4 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_removes_b', filter_removes_b, 2 ); expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); } ); test( 'filter removes a callback that has not yet executed (same priority)', () => { - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a, 1 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_removes_b', filter_removes_b, 2 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 4 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_a', filter_a, 1 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_removes_b', filter_removes_b, 2 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 2 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 4 ); expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); } ); test( 'remove all filter callbacks', () => { - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_a', filter_a ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_b', filter_b, 2 ); - testObject.hooks.addFilter( 'test.filter', 'me_name/my_plugin/my_callback_filter_c', filter_c, 8 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_a', filter_a ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 2 ); + testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 8 ); expect( testObject.hooks.removeAllFilters( 'test.filter' ) ).toEqual( 3 ); expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); @@ -432,7 +432,7 @@ test( 'remove all filter callbacks', () => { test( 'Test testObject.hooks.doingAction, testObject.hooks.didAction and testObject.hooks.hasAction.', () => { let actionCalls = 0; - testObject.hooks.addAction( 'another.action', 'my_name/my_plugin/my_callback', () => {} ); + testObject.hooks.addAction( 'another.action', 'my_callback', () => {} ); testObject.hooks.doAction( 'another.action' ); // Verify no action is running yet. @@ -441,7 +441,7 @@ test( 'Test testObject.hooks.doingAction, testObject.hooks.didAction and testObj expect( testObject.hooks.didAction( 'test.action' ) ).toBe( 0 ); expect( testObject.hooks.hasAction( 'test.action' ) ).toBe( 0 ); - testObject.hooks.addAction( 'test.action', 'my_name/my_plugin/my_callback', () => { + testObject.hooks.addAction( 'test.action', 'my_callback', () => { actionCalls++; expect( testObject.hooks.currentAction() ).toBe( 'test.action' ); expect( testObject.hooks.doingAction() ).toBe( true ); @@ -486,7 +486,7 @@ test( 'Test testObject.hooks.doingAction, testObject.hooks.didAction and testObj test( 'Verify testObject.hooks.doingFilter, testObject.hooks.didFilter and testObject.hooks.hasFilter.', () => { let filterCalls = 0; - testObject.hooks.addFilter( 'runtest.filter', 'my_name/my_plugin/my_callback', arg => { + testObject.hooks.addFilter( 'runtest.filter', 'my_callback', arg => { filterCalls++; expect( testObject.hooks.currentFilter() ).toBe( 'runtest.filter' ); expect( testObject.hooks.doingFilter() ).toBe( true ); @@ -513,7 +513,7 @@ test( 'Verify testObject.hooks.doingFilter, testObject.hooks.didFilter and testO } ); test( 'recursively calling a filter', () => { - testObject.hooks.addFilter( 'test.filter', 'my_name/my_plugin/my_callback', value => { + testObject.hooks.addFilter( 'test.filter', 'my_callback', value => { if ( value.length === 7 ) { return value; } @@ -524,11 +524,11 @@ test( 'recursively calling a filter', () => { } ); test( 'current filter when multiple filters are running', () => { - testObject.hooks.addFilter( 'test.filter1', 'my_name/my_plugin/my_callback', value => { + testObject.hooks.addFilter( 'test.filter1', 'my_callback', value => { return testObject.hooks.applyFilters( 'test.filter2', value.concat( testObject.hooks.currentFilter() ) ); } ); - testObject.hooks.addFilter( 'test.filter2', 'my_name/my_plugin/my_callback', value => { + testObject.hooks.addFilter( 'test.filter2', 'my_callback', value => { return value.concat( testObject.hooks.currentFilter() ); } ); @@ -543,16 +543,16 @@ test( 'current filter when multiple filters are running', () => { test( 'adding and removing filters with recursion', () => { function removeRecurseAndAdd2( val ) { - expect( testObject.hooks.removeFilter( 'remove_and_add', 'my_name/my_plugin/my_callback_recurse' ) ).toEqual( 1 ); + expect( testObject.hooks.removeFilter( 'remove_and_add', 'my_callback_recurse' ) ).toEqual( 1 ); val += '-' + testObject.hooks.applyFilters( 'remove_and_add', '' ) + '-'; - testObject.hooks.addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback_recurse', 10 ); + testObject.hooks.addFilter( 'remove_and_add', 'my_callback_recurse', 10 ); return val + '2'; } - testObject.hooks.addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback', val => val + '1', 11 ); - testObject.hooks.addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback_recurse', removeRecurseAndAdd2, 12 ); - testObject.hooks.addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback', val => val + '3', 13 ); - testObject.hooks.addFilter( 'remove_and_add', 'my_name/my_plugin/my_callback', val => val + '4', 14 ); + testObject.hooks.addFilter( 'remove_and_add', 'my_callback', val => val + '1', 11 ); + testObject.hooks.addFilter( 'remove_and_add', 'my_callback_recurse', removeRecurseAndAdd2, 12 ); + testObject.hooks.addFilter( 'remove_and_add', 'my_callback', val => val + '3', 13 ); + testObject.hooks.addFilter( 'remove_and_add', 'my_callback', val => val + '4', 14 ); expect( testObject.hooks.applyFilters( 'remove_and_add', '' ) ).toEqual( '1-134-234' ); } ); From f552dae81b2cfcf8768fc6b870868e5776afc523 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 26 Sep 2017 23:14:59 -0400 Subject: [PATCH 194/393] remov vendor/plugin prefix requirement for namespaces --- packages/hooks/src/validateNamespace.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/hooks/src/validateNamespace.js b/packages/hooks/src/validateNamespace.js index a559157275234..dc180ab9c3d4c 100644 --- a/packages/hooks/src/validateNamespace.js +++ b/packages/hooks/src/validateNamespace.js @@ -13,13 +13,8 @@ function validateNamespace( namespace ) { return false; } - if ( ! /^[a-zA-Z][a-zA-Z0-9_.-/]*$/.test( namespace ) ) { - console.error( 'The namespace can only contain numbers, letters, dashes, periods and underscores, plus the forward slash dividing slug and description in the namespace.' ); - return false; - } - - if ( ! /^[a-zA-Z][a-zA-Z0-9_.-]*\/[a-zA-Z][a-zA-Z0-9_.-]*\/[a-zA-Z][a-zA-Z0-9_.-]*$/.test( namespace ) ) { - console.error( 'The namespace must take the form `vendor/plugin/function`.' ); + if ( ! /^[a-zA-Z][a-zA-Z0-9_.\-]*$/.test( namespace ) ) { + console.error( 'The namespace can only contain numbers, letters, dashes, periods and underscores.' ); return false; } From a71e346a5f5fac2a305db0e8a9447008c79269aa Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 26 Sep 2017 23:20:20 -0400 Subject: [PATCH 195/393] update docs --- packages/hooks/README.md | 48 ++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/packages/hooks/README.md b/packages/hooks/README.md index 06cac123ac2d1..a3f6a67c14885 100644 --- a/packages/hooks/README.md +++ b/packages/hooks/README.md @@ -1,34 +1,28 @@ # WP-JS-Hooks -A lightweight & efficient EventManager for JavaScript in WordPress. - +A lightweight & efficient event manager. ### API Usage -API functions can be called via the global `wp.hooks` like this `wp.hooks.addAction()`, etc. - -* `addAction( 'hook', 'vendor/plugin/function', callback, priority )` -* `addFilter( 'hook', 'vendor/plugin/function', callback, priority )` -* `removeAction( 'hook', 'vendor/plugin/function' )` -* `removeFilter( 'hook', 'vendor/plugin/function' )` -* `removeAllActions( 'hook' )` -* `removeAllFilters( 'hook' )` -* `doAction( 'hook', arg1, arg2, moreArgs, finalArg )` -* `applyFilters( 'hook', content, arg1, arg2, moreArgs, finalArg )` -* `doingAction( 'hook' )` -* `doingFilter( 'hook' )` -* `didAction( 'hook' )` -* `didFilter( 'hook' )` -* `hasAction( 'hook' )` -* `hasFilter( 'hook' )` - +Hooks can be added to an object via composition: + +`myObject.hooks = new Hooks()` + +API functions can then be called on the object: `myObject.hooks.addAction()`, `myObject.hooks.applyFilters()`,etc. + +* `addAction( 'hookName', 'functionName', callback, priority )` +* `addFilter( 'hookName', 'functionName', callback, priority )` +* `removeAction( 'hookName', 'functionName' )` +* `removeFilter( 'hookName', 'functionName' )` +* `removeAllActions( 'hookName' )` +* `removeAllFilters( 'hookName' )` +* `doAction( 'hookName', arg1, arg2, moreArgs, finalArg )` +* `applyFilters( 'hookName', content, arg1, arg2, moreArgs, finalArg )` +* `doingAction( 'hookName' )` +* `doingFilter( 'hookName' )` +* `didAction( 'hookName' )` +* `didFilter( 'hookName' )` +* `hasAction( 'hookName' )` +* `hasFilter( 'hookName' )` ### Background See ticket [#21170](http://core.trac.wordpress.org/ticket/21170) for more information. - - -### Features - -* Fast and lightweight. -* Priorities system ensures hooks with lower integer priority are fired first. -* Uses native object hash lookup for finding hook callbacks. -* Utilizes insertion sort for keeping priorities correct. Best Case: O(n), worst case: O(n^2) From 3b1986877f0d05924dbd74fffd13cd444cadc00f Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 28 Sep 2017 15:53:27 -0400 Subject: [PATCH 196/393] =?UTF-8?q?Add=20a=20test=20for=20=E2=80=9CCan=20a?= =?UTF-8?q?dd=20filters=20with=20dashes=20in=20namespaces=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/hooks/src/test/index.test.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index cfc0aeebfbca2..50ca70964e10c 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -150,6 +150,11 @@ test( 'cannot add filters with namespaces missing a functionDescription', () => ); } ); +test( 'Can add filters with dashes in namespaces', () => { + addFilter( 'hook_name', 'my_name/with-dashes/action', () => null ); + expect( console.error ).toHaveBeenCalledTimes( 0 ); +} ); + test( 'Can add filters with capitals in namespaces', () => { addFilter( 'hook_name', 'my_name/OhNo/action', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); From 8fffdc8fa5d0ddb9c4d65e81adac32563b80821f Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Mon, 2 Oct 2017 20:54:06 -0400 Subject: [PATCH 197/393] a11y: Apply .screen-reader-text styles to container --- packages/a11y/src/addContainer.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/a11y/src/addContainer.js b/packages/a11y/src/addContainer.js index d478ffcf887f3..f1d3a5b95c1bf 100644 --- a/packages/a11y/src/addContainer.js +++ b/packages/a11y/src/addContainer.js @@ -12,8 +12,17 @@ const addContainer = function( ariaLive ) { container.id = 'a11y-speak-' + ariaLive; container.className = 'a11y-speak-region'; - let screenReaderTextStyle = 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;'; - container.setAttribute( 'style', screenReaderTextStyle ); + container.setAttribute( 'style', ( + 'position: absolute;' + + 'margin: -1px;' + + 'padding: 0;' + + 'height: 1px;' + + 'width: 1px;' + + 'overflow: hidden;' + + 'clip: rect( 0 0 0 0 );' + + 'border: 0;' + + 'word-wrap: normal !important;' + ) ); container.setAttribute( 'aria-live', ariaLive ); container.setAttribute( 'aria-relevant', 'additions text' ); container.setAttribute( 'aria-atomic', 'true' ); From 49e57d929de69f438aa75840884de3c35302950c Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Mon, 2 Oct 2017 22:52:14 -0400 Subject: [PATCH 198/393] a11y: Update tests per updated style Questionable value of the test assertions, which are specific to the implementation and not the expected intent of the test case --- packages/a11y/src/test/addContainer.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/a11y/src/test/addContainer.test.js b/packages/a11y/src/test/addContainer.test.js index dfeac8dbbae5e..0a3d5e76115be 100644 --- a/packages/a11y/src/test/addContainer.test.js +++ b/packages/a11y/src/test/addContainer.test.js @@ -8,7 +8,7 @@ describe( 'addContainer', () => { expect( container ).not.toBe( null ); expect( container.className ).toBe( 'a11y-speak-region' ); expect( container.id ).toBe( 'a11y-speak-polite' ); - expect( container.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); + expect( container.getAttribute( 'style' ) ).not.toBeNull(); expect( container.getAttribute( 'aria-live' ) ).toBe( 'polite' ); expect( container.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); expect( container.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); @@ -22,7 +22,7 @@ describe( 'addContainer', () => { expect( container ).not.toBe( null ); expect( container.className ).toBe( 'a11y-speak-region' ); expect( container.id ).toBe( 'a11y-speak-assertive' ); - expect( container.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); + expect( container.getAttribute( 'style' ) ).not.toBeNull(); expect( container.getAttribute( 'aria-live' ) ).toBe( 'assertive' ); expect( container.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); expect( container.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); @@ -36,7 +36,7 @@ describe( 'addContainer', () => { expect( container ).not.toBe( null ); expect( container.className ).toBe( 'a11y-speak-region' ); expect( container.id ).toBe( 'a11y-speak-polite' ); - expect( container.getAttribute( 'style' ) ).toBe( 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;' ); + expect( container.getAttribute( 'style' ) ).not.toBeNull(); expect( container.getAttribute( 'aria-live' ) ).toBe( 'polite' ); expect( container.getAttribute( 'aria-relevant' ) ).toBe( 'additions text' ); expect( container.getAttribute( 'aria-atomic' ) ).toBe( 'true' ); From adf8b18fc49edce5df04b87e59c456b1e1dddc82 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Mon, 9 Oct 2017 07:38:10 -0400 Subject: [PATCH 199/393] update readme, add some tests --- packages/hooks/README.md | 17 ++++++++--- packages/hooks/src/test/index.test.js | 44 +++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/packages/hooks/README.md b/packages/hooks/README.md index a3f6a67c14885..f5871ccee31fe 100644 --- a/packages/hooks/README.md +++ b/packages/hooks/README.md @@ -3,11 +3,6 @@ A lightweight & efficient event manager. ### API Usage -Hooks can be added to an object via composition: - -`myObject.hooks = new Hooks()` - -API functions can then be called on the object: `myObject.hooks.addAction()`, `myObject.hooks.applyFilters()`,etc. * `addAction( 'hookName', 'functionName', callback, priority )` * `addFilter( 'hookName', 'functionName', callback, priority )` @@ -24,5 +19,17 @@ API functions can then be called on the object: `myObject.hooks.addAction()`, ` * `hasAction( 'hookName' )` * `hasFilter( 'hookName' )` +Hooks can be added to an object via composition: + +`myObject.hooks = new Hooks( myObject )` + +API functions are then be called: `myObject.hooks.addAction()`... + +or as a Mixin: +Object.assign( myObject, new Hooks() ); + +API functions are then be called: `myObject.addAction()`... + + ### Background See ticket [#21170](http://core.trac.wordpress.org/ticket/21170) for more information. diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 22d5c90936626..b455e9dbb8ba3 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -141,6 +141,11 @@ test( 'cannot add filters with namespaces missing a functionDescription', () => ); } ); +test( 'Can add filters with dashes in namespaces', () => { + testObject.hooks.addFilter( 'hook_name', 'with-dashes', () => null ); + expect( console.error ).toHaveBeenCalledTimes( 0 ); +} ); + test( 'Can add filters with capitals in namespaces', () => { testObject.hooks.addFilter( 'hook_name', 'my_name-OhNoaction', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); @@ -556,3 +561,42 @@ test( 'adding and removing filters with recursion', () => { expect( testObject.hooks.applyFilters( 'remove_and_add', '' ) ).toEqual( '1-134-234' ); } ); + + +// Test adding via composition. +test( 'adding hooks via composition', () => { + + var testObject2 = {}; + testObject2.hooks = new Hooks(); + + expect( typeof testObject2.hooks.applyFilters ).toEqual( 'function' ); +} ); + + +// Test adding as a mixin. +test( 'adding hooks as a mixin', () => { + + var testObject3 = {}; + Object.assign( testObject3, new Hooks() ); + + expect( typeof testObject3.applyFilters ).toEqual( 'function' ); +} ); + +// Test context. +test( 'Test `this` context via composition and as a mixin', () => { + + var testObject2 = {}; + testObject2.hooks = new Hooks(); + testObject.hooks.addAction( 'test.action', 'my_callback', function() { + + window.actionValue += 'a'; + console.log( this ); + expect( this ).toEqual( testObject2 ); +} ); + testObject.hooks.doAction( 'test.action' ); + + var testObject3 = {}; + Object.assign( testObject3, new Hooks() ); + +} ); + From b8d5f287b56f8bc056ee76e221611620f2da4da9 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Mon, 9 Oct 2017 08:21:30 -0400 Subject: [PATCH 200/393] switch naming to `createHooks` and correct tests --- packages/hooks/src/index.js | 2 +- packages/hooks/src/test/index.test.js | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index b059227afdace..089225e366eb8 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -7,7 +7,7 @@ import createDoingHook from './createDoingHook'; import createDidHook from './createDidHook'; -export const Hooks = () => { +export const createHooks = () => { const HOOKS = { actions: {}, filters: {}, diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index b455e9dbb8ba3..826163c3b2703 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -4,11 +4,11 @@ * Internal dependencies */ import { - Hooks, + createHooks, } from '../'; const testObject = {}; -testObject.hooks = new Hooks(); +testObject.hooks = createHooks(); function filter_a( str ) { return str + 'a'; @@ -567,7 +567,7 @@ test( 'adding and removing filters with recursion', () => { test( 'adding hooks via composition', () => { var testObject2 = {}; - testObject2.hooks = new Hooks(); + testObject2.hooks = createHooks(); expect( typeof testObject2.hooks.applyFilters ).toEqual( 'function' ); } ); @@ -577,26 +577,26 @@ test( 'adding hooks via composition', () => { test( 'adding hooks as a mixin', () => { var testObject3 = {}; - Object.assign( testObject3, new Hooks() ); + Object.assign( testObject3, createHooks() ); expect( typeof testObject3.applyFilters ).toEqual( 'function' ); } ); // Test context. -test( 'Test `this` context via composition and as a mixin', () => { +test( 'Test `this` context via composition', () => { - var testObject2 = {}; - testObject2.hooks = new Hooks(); - testObject.hooks.addAction( 'test.action', 'my_callback', function() { + var testObject2 = { test: 'test this' }; - window.actionValue += 'a'; - console.log( this ); - expect( this ).toEqual( testObject2 ); -} ); + testObject2.hooks = createHooks(); + + var theCallback = function() { + expect( this.test ).toEqual( 'test this' ); + }; + testObject.hooks.addAction( 'test.action', 'my_callback', theCallback.apply( testObject2 ) ); testObject.hooks.doAction( 'test.action' ); var testObject3 = {}; - Object.assign( testObject3, new Hooks() ); + Object.assign( testObject3, createHooks() ); } ); From 031fdfddb6484329c6d884edd8440de69a256e58 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Mon, 9 Oct 2017 08:21:43 -0400 Subject: [PATCH 201/393] remove extraneous single quotes --- packages/hooks/src/index.js | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index 089225e366eb8..b9744598379b7 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -14,22 +14,22 @@ export const createHooks = () => { }; return { - 'addAction': createAddHook( HOOKS.actions ), - 'addFilter': createAddHook( HOOKS.filters ), - 'removeAction': createRemoveHook( HOOKS.actions ), - 'removeFilter': createRemoveHook( HOOKS.filters ), - 'hasAction': createHasHook( HOOKS.actions ), - 'hasFilter': createHasHook( HOOKS.filters ), - 'removeAllActions': createRemoveHook( HOOKS.actions, true ), - 'removeAllFilters': createRemoveHook( HOOKS.filters, true ), - 'doAction': createRunHook( HOOKS.actions ), - 'applyFilters': createRunHook( HOOKS.filters, true ), - 'currentAction': createCurrentHook( HOOKS.actions ), - 'currentFilter': createCurrentHook( HOOKS.filters ), - 'doingAction': createDoingHook( HOOKS.actions ), - 'doingFilter': createDoingHook( HOOKS.filters ), - 'didAction': createDidHook( HOOKS.actions ), - 'didFilter': createDidHook( HOOKS.filters ), - 'HOOKS': HOOKS, + addAction: createAddHook( HOOKS.actions ), + addFilter: createAddHook( HOOKS.filters ), + removeAction: createRemoveHook( HOOKS.actions ), + removeFilter: createRemoveHook( HOOKS.filters ), + hasAction: createHasHook( HOOKS.actions ), + hasFilter: createHasHook( HOOKS.filters ), + removeAllActions: createRemoveHook( HOOKS.actions, true ), + removeAllFilters: createRemoveHook( HOOKS.filters, true ), + doAction: createRunHook( HOOKS.actions ), + applyFilters: createRunHook( HOOKS.filters, true ), + currentAction: createCurrentHook( HOOKS.actions ), + currentFilter: createCurrentHook( HOOKS.filters ), + doingAction: createDoingHook( HOOKS.actions ), + doingFilter: createDoingHook( HOOKS.filters ), + didAction: createDidHook( HOOKS.actions ), + didFilter: createDidHook( HOOKS.filters ), + HOOKS: HOOKS, }; }; From 4cf37499bb4fb8fd6ae03d54a228164d708591da Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 12 Oct 2017 09:45:25 -0400 Subject: [PATCH 202/393] remove the HOOKS global abstraction --- packages/hooks/src/index.js | 42 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index b9744598379b7..71995a6ba0b88 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -8,28 +8,26 @@ import createDidHook from './createDidHook'; export const createHooks = () => { - const HOOKS = { - actions: {}, - filters: {}, - }; - + const actions = {}; + const filters = {}; return { - addAction: createAddHook( HOOKS.actions ), - addFilter: createAddHook( HOOKS.filters ), - removeAction: createRemoveHook( HOOKS.actions ), - removeFilter: createRemoveHook( HOOKS.filters ), - hasAction: createHasHook( HOOKS.actions ), - hasFilter: createHasHook( HOOKS.filters ), - removeAllActions: createRemoveHook( HOOKS.actions, true ), - removeAllFilters: createRemoveHook( HOOKS.filters, true ), - doAction: createRunHook( HOOKS.actions ), - applyFilters: createRunHook( HOOKS.filters, true ), - currentAction: createCurrentHook( HOOKS.actions ), - currentFilter: createCurrentHook( HOOKS.filters ), - doingAction: createDoingHook( HOOKS.actions ), - doingFilter: createDoingHook( HOOKS.filters ), - didAction: createDidHook( HOOKS.actions ), - didFilter: createDidHook( HOOKS.filters ), - HOOKS: HOOKS, + addAction: createAddHook( actions ), + addFilter: createAddHook( filters ), + removeAction: createRemoveHook( actions ), + removeFilter: createRemoveHook( filters ), + hasAction: createHasHook( actions ), + hasFilter: createHasHook( filters ), + removeAllActions: createRemoveHook( actions, true ), + removeAllFilters: createRemoveHook( filters, true ), + doAction: createRunHook( actions ), + applyFilters: createRunHook( filters, true ), + currentAction: createCurrentHook( actions ), + currentFilter: createCurrentHook( filters ), + doingAction: createDoingHook( actions ), + doingFilter: createDoingHook( filters ), + didAction: createDidHook( actions ), + didFilter: createDidHook( filters ), + actions: actions, + filters: filters, }; }; From e91f92c0dcc232fe7da1ca610170e341c5a2716e Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 12 Oct 2017 09:46:04 -0400 Subject: [PATCH 203/393] update test beforeEach cleanup to match new object structure --- packages/hooks/src/test/index.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 826163c3b2703..d9c0802dc280b 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -54,9 +54,9 @@ const consoleErrorOriginal = console.error; beforeEach( () => { window.actionValue = ''; // Reset state in between tests (clear all callbacks, `testObject.hooks.didAction` counts, - // etc.) Just reseting HOOKS.actions and HOOKS.filters is not enough + // etc.) Just reseting actions and filters is not enough // because the internal functions have references to the original objects. - [ testObject.hooks.HOOKS.actions, testObject.hooks.HOOKS.filters ].forEach( hooks => { + [ testObject.hooks.actions, testObject.hooks.filters ].forEach( hooks => { for ( const k in hooks ) { delete hooks[ k ]; } From 5a6a91887c2a98a0f1fcb9a9ca1477ef0093c0d2 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 12 Oct 2017 09:51:11 -0400 Subject: [PATCH 204/393] use export defaults --- packages/hooks/src/index.js | 5 +++-- packages/hooks/src/test/index.test.js | 4 +--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index 71995a6ba0b88..cfd22f088f444 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -6,10 +6,10 @@ import createCurrentHook from './createCurrentHook'; import createDoingHook from './createDoingHook'; import createDidHook from './createDidHook'; - -export const createHooks = () => { +function createHooks() { const actions = {}; const filters = {}; + return { addAction: createAddHook( actions ), addFilter: createAddHook( filters ), @@ -31,3 +31,4 @@ export const createHooks = () => { filters: filters, }; }; +export default createHooks; diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index d9c0802dc280b..06a9bb98063c2 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -3,9 +3,7 @@ /** * Internal dependencies */ -import { - createHooks, -} from '../'; +import createHooks from '../'; const testObject = {}; testObject.hooks = createHooks(); From f1c4f1fa0d8760e72d93604292e3466b9d2716c5 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 12 Oct 2017 09:59:26 -0400 Subject: [PATCH 205/393] Clean up readme for new approach --- packages/hooks/README.md | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/packages/hooks/README.md b/packages/hooks/README.md index f5871ccee31fe..00552d0c24880 100644 --- a/packages/hooks/README.md +++ b/packages/hooks/README.md @@ -1,6 +1,6 @@ # WP-JS-Hooks -A lightweight & efficient event manager. +A lightweight & efficient filter and action manager. ### API Usage @@ -20,16 +20,8 @@ A lightweight & efficient event manager. * `hasFilter( 'hookName' )` Hooks can be added to an object via composition: +`import createHooks from '../';` -`myObject.hooks = new Hooks( myObject )` +`myObject.hooks = createHooks();` API functions are then be called: `myObject.hooks.addAction()`... - -or as a Mixin: -Object.assign( myObject, new Hooks() ); - -API functions are then be called: `myObject.addAction()`... - - -### Background -See ticket [#21170](http://core.trac.wordpress.org/ticket/21170) for more information. From a38c8b5fdf47c0a50bf8097358ce8b4936c72fad Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Sun, 22 Oct 2017 10:41:20 -0400 Subject: [PATCH 206/393] url - add built files --- packages/url/build-browser/index.js | 36 +++++++++++++++++++ packages/url/build-browser/test/index.test.js | 21 +++++++++++ packages/url/build-module/index.js | 23 ++++++++++++ packages/url/build/index.js | 32 +++++++++++++++++ 4 files changed, 112 insertions(+) create mode 100644 packages/url/build-browser/index.js create mode 100644 packages/url/build-browser/test/index.test.js create mode 100644 packages/url/build-module/index.js create mode 100644 packages/url/build/index.js diff --git a/packages/url/build-browser/index.js b/packages/url/build-browser/index.js new file mode 100644 index 0000000000000..3ee6190b05a88 --- /dev/null +++ b/packages/url/build-browser/index.js @@ -0,0 +1,36 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _extends2 = require('babel-runtime/helpers/extends'); + +var _extends3 = _interopRequireDefault(_extends2); + +exports.addQueryArgs = addQueryArgs; + +var _url = require('url'); + +var _querystring = require('querystring'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Appends arguments to the query string of the url + * + * @param {String} url URL + * @param {Object} args Query Args + * + * @return {String} Updated URL + */ +/** + * External dependencies + */ +function addQueryArgs(url, args) { + var parsedURL = (0, _url.parse)(url, true); + var query = (0, _extends3.default)({}, parsedURL.query, args); + delete parsedURL.search; + + return (0, _url.format)((0, _extends3.default)({}, parsedURL, { query: query })); +} \ No newline at end of file diff --git a/packages/url/build-browser/test/index.test.js b/packages/url/build-browser/test/index.test.js new file mode 100644 index 0000000000000..b772adfed3466 --- /dev/null +++ b/packages/url/build-browser/test/index.test.js @@ -0,0 +1,21 @@ +'use strict'; + +var _ = require('../'); + +describe('addQueryArgs', function () { + test('should append args to an URL without query string', function () { + var url = 'https://andalouses.com/beach'; + var args = { sun: 'true', sand: 'false' }; + + expect((0, _.addQueryArgs)(url, args)).toBe('https://andalouses.com/beach?sun=true&sand=false'); + }); + + test('should append args to an URL with query string', function () { + var url = 'https://andalouses.com/beach?night=false'; + var args = { sun: 'true', sand: 'false' }; + + expect((0, _.addQueryArgs)(url, args)).toBe('https://andalouses.com/beach?night=false&sun=true&sand=false'); + }); +}); /** + * Internal Dependencies + */ \ No newline at end of file diff --git a/packages/url/build-module/index.js b/packages/url/build-module/index.js new file mode 100644 index 0000000000000..9fde0cc29e7c8 --- /dev/null +++ b/packages/url/build-module/index.js @@ -0,0 +1,23 @@ +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +/** + * External dependencies + */ +import { parse, format } from 'url'; +import { parse as parseQueryString, stringify } from 'querystring'; + +/** + * Appends arguments to the query string of the url + * + * @param {String} url URL + * @param {Object} args Query Args + * + * @return {String} Updated URL + */ +export function addQueryArgs(url, args) { + var parsedURL = parse(url, true); + var query = _extends({}, parsedURL.query, args); + delete parsedURL.search; + + return format(_extends({}, parsedURL, { query: query })); +} \ No newline at end of file diff --git a/packages/url/build/index.js b/packages/url/build/index.js new file mode 100644 index 0000000000000..ae914b643d140 --- /dev/null +++ b/packages/url/build/index.js @@ -0,0 +1,32 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /** + * External dependencies + */ + + +exports.addQueryArgs = addQueryArgs; + +var _url = require('url'); + +var _querystring = require('querystring'); + +/** + * Appends arguments to the query string of the url + * + * @param {String} url URL + * @param {Object} args Query Args + * + * @return {String} Updated URL + */ +function addQueryArgs(url, args) { + var parsedURL = (0, _url.parse)(url, true); + var query = _extends({}, parsedURL.query, args); + delete parsedURL.search; + + return (0, _url.format)(_extends({}, parsedURL, { query: query })); +} \ No newline at end of file From 7664e9822c1165b0d752056344702403117ef190 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Sun, 22 Oct 2017 10:42:57 -0400 Subject: [PATCH 207/393] hooks - add built files --- packages/hooks/build-module/createAddHook.js | 76 ++++++++++++++++ .../hooks/build-module/createCurrentHook.js | 27 ++++++ packages/hooks/build-module/createDidHook.js | 29 ++++++ .../hooks/build-module/createDoingHook.js | 30 +++++++ packages/hooks/build-module/createHasHook.js | 24 +++++ .../hooks/build-module/createRemoveHook.js | 76 ++++++++++++++++ packages/hooks/build-module/createRunHook.js | 74 +++++++++++++++ packages/hooks/build-module/hooks.js | 10 +++ packages/hooks/build-module/index.js | 40 +++++++++ .../hooks/build-module/validateHookName.js | 30 +++++++ .../hooks/build-module/validateNamespace.js | 29 ++++++ packages/hooks/build/createAddHook.js | 89 +++++++++++++++++++ packages/hooks/build/createCurrentHook.js | 32 +++++++ packages/hooks/build/createDidHook.js | 39 ++++++++ packages/hooks/build/createDoingHook.js | 35 ++++++++ packages/hooks/build/createHasHook.js | 29 ++++++ packages/hooks/build/createRemoveHook.js | 89 +++++++++++++++++++ packages/hooks/build/createRunHook.js | 84 +++++++++++++++++ packages/hooks/build/hooks.js | 15 ++++ packages/hooks/build/index.js | 72 +++++++++++++++ packages/hooks/build/validateHookName.js | 35 ++++++++ packages/hooks/build/validateNamespace.js | 29 ++++++ 22 files changed, 993 insertions(+) create mode 100644 packages/hooks/build-module/createAddHook.js create mode 100644 packages/hooks/build-module/createCurrentHook.js create mode 100644 packages/hooks/build-module/createDidHook.js create mode 100644 packages/hooks/build-module/createDoingHook.js create mode 100644 packages/hooks/build-module/createHasHook.js create mode 100644 packages/hooks/build-module/createRemoveHook.js create mode 100644 packages/hooks/build-module/createRunHook.js create mode 100644 packages/hooks/build-module/hooks.js create mode 100644 packages/hooks/build-module/index.js create mode 100644 packages/hooks/build-module/validateHookName.js create mode 100644 packages/hooks/build-module/validateNamespace.js create mode 100644 packages/hooks/build/createAddHook.js create mode 100644 packages/hooks/build/createCurrentHook.js create mode 100644 packages/hooks/build/createDidHook.js create mode 100644 packages/hooks/build/createDoingHook.js create mode 100644 packages/hooks/build/createHasHook.js create mode 100644 packages/hooks/build/createRemoveHook.js create mode 100644 packages/hooks/build/createRunHook.js create mode 100644 packages/hooks/build/hooks.js create mode 100644 packages/hooks/build/index.js create mode 100644 packages/hooks/build/validateHookName.js create mode 100644 packages/hooks/build/validateNamespace.js diff --git a/packages/hooks/build-module/createAddHook.js b/packages/hooks/build-module/createAddHook.js new file mode 100644 index 0000000000000..8144fe615b091 --- /dev/null +++ b/packages/hooks/build-module/createAddHook.js @@ -0,0 +1,76 @@ +import validateNamespace from './validateNamespace.js'; +import validateHookName from './validateHookName.js'; + +/** + * Returns a function which, when invoked, will add a hook. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * + * @return {Function} Function that adds a new hook. + */ +function createAddHook(hooks) { + /** + * Adds the hook to the appropriate hooks container. + * + * @param {string} hookName Name of hook to add + * @param {string} namespace The unique namespace identifying the callback in the form `vendor/plugin/function`. + * @param {Function} callback Function to call when the hook is run + * @param {?number} priority Priority of this hook (default=10) + */ + return function addHook(hookName, namespace, callback) { + var priority = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 10; + + + if (!validateHookName(hookName)) { + return; + } + + if (!validateNamespace(namespace)) { + return; + } + + if ('function' !== typeof callback) { + console.error('The hook callback must be a function.'); + return; + } + + // Validate numeric priority + if ('number' !== typeof priority) { + console.error('If specified, the hook priority must be a number.'); + return; + } + + var handler = { callback: callback, priority: priority, namespace: namespace }; + + if (hooks.hasOwnProperty(hookName)) { + // Find the correct insert index of the new hook. + var handlers = hooks[hookName].handlers; + var i = 0; + while (i < handlers.length) { + if (handlers[i].priority > priority) { + break; + } + i++; + } + // Insert (or append) the new hook. + handlers.splice(i, 0, handler); + // We may also be currently executing this hook. If the callback + // we're adding would come after the current callback, there's no + // problem; otherwise we need to increase the execution index of + // any other runs by 1 to account for the added element. + (hooks.__current || []).forEach(function (hookInfo) { + if (hookInfo.name === hookName && hookInfo.currentIndex >= i) { + hookInfo.currentIndex++; + } + }); + } else { + // This is the first hook of its type. + hooks[hookName] = { + handlers: [handler], + runs: 0 + }; + } + }; +} + +export default createAddHook; \ No newline at end of file diff --git a/packages/hooks/build-module/createCurrentHook.js b/packages/hooks/build-module/createCurrentHook.js new file mode 100644 index 0000000000000..18a4f71807102 --- /dev/null +++ b/packages/hooks/build-module/createCurrentHook.js @@ -0,0 +1,27 @@ +/** + * Returns a function which, when invoked, will return the name of the + * currently running hook, or `null` if no hook of the given type is currently + * running. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * + * @return {Function} Function that returns the current hook. + */ +function createCurrentHook(hooks, returnFirstArg) { + /** + * Returns the name of the currently running hook, or `null` if no hook of + * the given type is currently running. + * + * @return {?string} The name of the currently running hook, or + * `null` if no hook is currently running. + */ + return function currentHook() { + if (!hooks.__current || !hooks.__current.length) { + return null; + } + + return hooks.__current[hooks.__current.length - 1].name; + }; +} + +export default createCurrentHook; \ No newline at end of file diff --git a/packages/hooks/build-module/createDidHook.js b/packages/hooks/build-module/createDidHook.js new file mode 100644 index 0000000000000..f05807b59b749 --- /dev/null +++ b/packages/hooks/build-module/createDidHook.js @@ -0,0 +1,29 @@ +import validateHookName from './validateHookName.js'; + +/** + * Returns a function which, when invoked, will return the number of times a + * hook has been called. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * + * @return {Function} Function that returns a hook's call count. + */ +function createDidHook(hooks) { + /** + * Returns the number of times an action has been fired. + * + * @param {string} hookName The hook name to check. + * + * @return {number} The number of times the hook has run. + */ + return function didHook(hookName) { + + if (!validateHookName(hookName)) { + return; + } + + return hooks.hasOwnProperty(hookName) && hooks[hookName].runs ? hooks[hookName].runs : 0; + }; +} + +export default createDidHook; \ No newline at end of file diff --git a/packages/hooks/build-module/createDoingHook.js b/packages/hooks/build-module/createDoingHook.js new file mode 100644 index 0000000000000..7e7b4f09e5584 --- /dev/null +++ b/packages/hooks/build-module/createDoingHook.js @@ -0,0 +1,30 @@ +/** + * Returns a function which, when invoked, will return whether a hook is + * currently being executed. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * + * @return {Function} Function that returns whether a hook is currently + * being executed. + */ +function createDoingHook(hooks) { + /** + * Returns whether a hook is currently being executed. + * + * @param {?string} hookName The name of the hook to check for. If + * omitted, will check for any hook being executed. + * + * @return {bool} Whether the hook is being executed. + */ + return function doingHook(hookName) { + // If the hookName was not passed, check for any current hook. + if ('undefined' === typeof hookName) { + return 'undefined' !== typeof hooks.__current[0]; + } + + // Return the __current hook. + return hooks.__current[0] ? hookName === hooks.__current[0].name : false; + }; +} + +export default createDoingHook; \ No newline at end of file diff --git a/packages/hooks/build-module/createHasHook.js b/packages/hooks/build-module/createHasHook.js new file mode 100644 index 0000000000000..7de143789e581 --- /dev/null +++ b/packages/hooks/build-module/createHasHook.js @@ -0,0 +1,24 @@ +/** + * Returns a function which, when invoked, will return whether any handlers are + * attached to a particular hook. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * + * @return {Function} Function that returns whether any handlers are + * attached to a particular hook. + */ +function createHasHook(hooks) { + /** + * Returns how many handlers are attached for the given hook. + * + * @param {string} hookName The name of the hook to check for. + * + * @return {number} The number of handlers that are attached to + * the given hook. + */ + return function hasHook(hookName) { + return hooks.hasOwnProperty(hookName) ? hooks[hookName].handlers.length : 0; + }; +} + +export default createHasHook; \ No newline at end of file diff --git a/packages/hooks/build-module/createRemoveHook.js b/packages/hooks/build-module/createRemoveHook.js new file mode 100644 index 0000000000000..fcd77a00eeb7c --- /dev/null +++ b/packages/hooks/build-module/createRemoveHook.js @@ -0,0 +1,76 @@ +import validateNamespace from './validateNamespace.js'; +import validateHookName from './validateHookName.js'; + +/** + * Returns a function which, when invoked, will remove a specified hook or all + * hooks by the given name. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * @param {bool} removeAll Whether to remove all callbacks for a hookName, without regard to namespace. Used to create `removeAll*` functions. + * + * @return {Function} Function that removes hooks. + */ +function createRemoveHook(hooks, removeAll) { + /** + * Removes the specified callback (or all callbacks) from the hook with a + * given hookName and namespace. + * + * @param {string} hookName The name of the hook to modify. + * @param {string} namespace The unique namespace identifying the callback in the form `vendor/plugin/function`. + * + * @return {number} The number of callbacks removed. + */ + return function removeHook(hookName, namespace) { + + if (!validateHookName(hookName)) { + return; + } + + if (!removeAll && !validateNamespace(namespace)) { + return; + } + + // Bail if no hooks exist by this name + if (!hooks.hasOwnProperty(hookName)) { + return 0; + } + + var handlersRemoved = 0; + + if (removeAll) { + handlersRemoved = hooks[hookName].handlers.length; + hooks[hookName] = { + runs: hooks[hookName].runs, + handlers: [] + }; + } else { + // Try to find the specified callback to remove. + var handlers = hooks[hookName].handlers; + + var _loop = function _loop(i) { + if (handlers[i].namespace === namespace) { + handlers.splice(i, 1); + handlersRemoved++; + // This callback may also be part of a hook that is + // currently executing. If the callback we're removing + // comes after the current callback, there's no problem; + // otherwise we need to decrease the execution index of any + // other runs by 1 to account for the removed element. + (hooks.__current || []).forEach(function (hookInfo) { + if (hookInfo.name === hookName && hookInfo.currentIndex >= i) { + hookInfo.currentIndex--; + } + }); + } + }; + + for (var i = handlers.length - 1; i >= 0; i--) { + _loop(i); + } + } + + return handlersRemoved; + }; +} + +export default createRemoveHook; \ No newline at end of file diff --git a/packages/hooks/build-module/createRunHook.js b/packages/hooks/build-module/createRunHook.js new file mode 100644 index 0000000000000..982d8c86f12c1 --- /dev/null +++ b/packages/hooks/build-module/createRunHook.js @@ -0,0 +1,74 @@ +import validateHookName from './validateHookName.js'; + +/** + * Returns a function which, when invoked, will execute all callbacks + * registered to a hook of the specified type, optionally returning the final + * value of the call chain. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * @param {?bool} returnFirstArg Whether each hook callback is expected to + * return its first argument. + * + * @return {Function} Function that runs hook callbacks. + */ +function createRunHook(hooks, returnFirstArg) { + /** + * Runs all callbacks for the specified hook. + * + * @param {string} hookName The name of the hook to run. + * @param {...*} args Arguments to pass to the hook callbacks. + * + * @return {*} Return value of runner, if applicable. + */ + return function runHooks(hookName) { + + if (!validateHookName(hookName)) { + return; + } + + if (!hooks.hasOwnProperty(hookName)) { + hooks[hookName] = { + runs: 0, + handlers: [] + }; + } + + var handlers = hooks[hookName].handlers; + + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + if (!handlers.length) { + return returnFirstArg ? args[0] : undefined; + } + + var hookInfo = { + name: hookName, + currentIndex: 0 + }; + + hooks.__current = hooks.__current || []; + hooks.__current.push(hookInfo); + hooks[hookName].runs++; + + var maybeReturnValue = args[0]; + + while (hookInfo.currentIndex < handlers.length) { + var handler = handlers[hookInfo.currentIndex]; + maybeReturnValue = handler.callback.apply(null, args); + if (returnFirstArg) { + args[0] = maybeReturnValue; + } + hookInfo.currentIndex++; + } + + hooks.__current.pop(); + + if (returnFirstArg) { + return maybeReturnValue; + } + }; +} + +export default createRunHook; \ No newline at end of file diff --git a/packages/hooks/build-module/hooks.js b/packages/hooks/build-module/hooks.js new file mode 100644 index 0000000000000..a0967775f2a47 --- /dev/null +++ b/packages/hooks/build-module/hooks.js @@ -0,0 +1,10 @@ +/** + * Contains the registered hooks, keyed by hook type. Each hook type is an + * array of objects with priority and callback of each registered hook. + */ +var HOOKS = { + actions: {}, + filters: {} +}; + +export default HOOKS; \ No newline at end of file diff --git a/packages/hooks/build-module/index.js b/packages/hooks/build-module/index.js new file mode 100644 index 0000000000000..a61ccb23b9a9f --- /dev/null +++ b/packages/hooks/build-module/index.js @@ -0,0 +1,40 @@ +import HOOKS from './hooks'; +import createAddHook from './createAddHook'; +import createRemoveHook from './createRemoveHook'; +import createHasHook from './createHasHook'; +import createRunHook from './createRunHook'; +import createCurrentHook from './createCurrentHook'; +import createDoingHook from './createDoingHook'; +import createDidHook from './createDidHook'; + +// Add action/filter functions. +export var addAction = createAddHook(HOOKS.actions); +export var addFilter = createAddHook(HOOKS.filters); + +// Remove action/filter functions. +export var removeAction = createRemoveHook(HOOKS.actions); +export var removeFilter = createRemoveHook(HOOKS.filters); + +// Has action/filter functions. +export var hasAction = createHasHook(HOOKS.actions); +export var hasFilter = createHasHook(HOOKS.filters); + +// Remove all actions/filters functions. +export var removeAllActions = createRemoveHook(HOOKS.actions, true); +export var removeAllFilters = createRemoveHook(HOOKS.filters, true); + +// Do action/apply filters functions. +export var doAction = createRunHook(HOOKS.actions); +export var applyFilters = createRunHook(HOOKS.filters, true); + +// Current action/filter functions. +export var currentAction = createCurrentHook(HOOKS.actions); +export var currentFilter = createCurrentHook(HOOKS.filters); + +// Doing action/filter: true while a hook is being run. +export var doingAction = createDoingHook(HOOKS.actions); +export var doingFilter = createDoingHook(HOOKS.filters); + +// Did action/filter functions. +export var didAction = createDidHook(HOOKS.actions); +export var didFilter = createDidHook(HOOKS.filters); \ No newline at end of file diff --git a/packages/hooks/build-module/validateHookName.js b/packages/hooks/build-module/validateHookName.js new file mode 100644 index 0000000000000..df8ec8191b197 --- /dev/null +++ b/packages/hooks/build-module/validateHookName.js @@ -0,0 +1,30 @@ +/** + * Validate a hookName string. + * + * @param {string} hookName The hook name to validate. Should be a non empty string containing + * only numbers, letters, dashes, periods and underscores. Also, + * the hook name cannot begin with `__`. + * + * @return {bool} Whether the hook name is valid. + */ +function validateHookName(hookName) { + + if ('string' !== typeof hookName || '' === hookName) { + console.error('The hook name must be a non-empty string.'); + return false; + } + + if (/^__/.test(hookName)) { + console.error('The hook name cannot begin with `__`.'); + return false; + } + + if (!/^[a-zA-Z][a-zA-Z0-9_.-]*$/.test(hookName)) { + console.error('The hook name can only contain numbers, letters, dashes, periods and underscores.'); + return false; + } + + return true; +} + +export default validateHookName; \ No newline at end of file diff --git a/packages/hooks/build-module/validateNamespace.js b/packages/hooks/build-module/validateNamespace.js new file mode 100644 index 0000000000000..1165942903948 --- /dev/null +++ b/packages/hooks/build-module/validateNamespace.js @@ -0,0 +1,29 @@ +/** + * Validate a namespace string. + * + * @param {string} namespace The namespace to validate - should take the form + * `vendor/plugin/function`. + * + * @return {bool} Whether the namespace is valid. + */ +function validateNamespace(namespace) { + + if ('string' !== typeof namespace || '' === namespace) { + console.error('The namespace must be a non-empty string.'); + return false; + } + + if (!/^[a-zA-Z][a-zA-Z0-9_.-/]*$/.test(namespace)) { + console.error('The namespace can only contain numbers, letters, dashes, periods and underscores, plus the forward slash dividing slug and description in the namespace.'); + return false; + } + + if (!/^[a-zA-Z][a-zA-Z0-9_.-]*\/[a-zA-Z][a-zA-Z0-9_.-]*\/[a-zA-Z][a-zA-Z0-9_.-]*$/.test(namespace)) { + console.error('The namespace must take the form `vendor/plugin/function`.'); + return false; + } + + return true; +} + +export default validateNamespace; \ No newline at end of file diff --git a/packages/hooks/build/createAddHook.js b/packages/hooks/build/createAddHook.js new file mode 100644 index 0000000000000..445eb93a0887d --- /dev/null +++ b/packages/hooks/build/createAddHook.js @@ -0,0 +1,89 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _validateNamespace = require('./validateNamespace.js'); + +var _validateNamespace2 = _interopRequireDefault(_validateNamespace); + +var _validateHookName = require('./validateHookName.js'); + +var _validateHookName2 = _interopRequireDefault(_validateHookName); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Returns a function which, when invoked, will add a hook. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * + * @return {Function} Function that adds a new hook. + */ +function createAddHook(hooks) { + /** + * Adds the hook to the appropriate hooks container. + * + * @param {string} hookName Name of hook to add + * @param {string} namespace The unique namespace identifying the callback in the form `vendor/plugin/function`. + * @param {Function} callback Function to call when the hook is run + * @param {?number} priority Priority of this hook (default=10) + */ + return function addHook(hookName, namespace, callback) { + var priority = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 10; + + + if (!(0, _validateHookName2.default)(hookName)) { + return; + } + + if (!(0, _validateNamespace2.default)(namespace)) { + return; + } + + if ('function' !== typeof callback) { + console.error('The hook callback must be a function.'); + return; + } + + // Validate numeric priority + if ('number' !== typeof priority) { + console.error('If specified, the hook priority must be a number.'); + return; + } + + var handler = { callback: callback, priority: priority, namespace: namespace }; + + if (hooks.hasOwnProperty(hookName)) { + // Find the correct insert index of the new hook. + var handlers = hooks[hookName].handlers; + var i = 0; + while (i < handlers.length) { + if (handlers[i].priority > priority) { + break; + } + i++; + } + // Insert (or append) the new hook. + handlers.splice(i, 0, handler); + // We may also be currently executing this hook. If the callback + // we're adding would come after the current callback, there's no + // problem; otherwise we need to increase the execution index of + // any other runs by 1 to account for the added element. + (hooks.__current || []).forEach(function (hookInfo) { + if (hookInfo.name === hookName && hookInfo.currentIndex >= i) { + hookInfo.currentIndex++; + } + }); + } else { + // This is the first hook of its type. + hooks[hookName] = { + handlers: [handler], + runs: 0 + }; + } + }; +} + +exports.default = createAddHook; \ No newline at end of file diff --git a/packages/hooks/build/createCurrentHook.js b/packages/hooks/build/createCurrentHook.js new file mode 100644 index 0000000000000..f2de16dce9aae --- /dev/null +++ b/packages/hooks/build/createCurrentHook.js @@ -0,0 +1,32 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +/** + * Returns a function which, when invoked, will return the name of the + * currently running hook, or `null` if no hook of the given type is currently + * running. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * + * @return {Function} Function that returns the current hook. + */ +function createCurrentHook(hooks, returnFirstArg) { + /** + * Returns the name of the currently running hook, or `null` if no hook of + * the given type is currently running. + * + * @return {?string} The name of the currently running hook, or + * `null` if no hook is currently running. + */ + return function currentHook() { + if (!hooks.__current || !hooks.__current.length) { + return null; + } + + return hooks.__current[hooks.__current.length - 1].name; + }; +} + +exports.default = createCurrentHook; \ No newline at end of file diff --git a/packages/hooks/build/createDidHook.js b/packages/hooks/build/createDidHook.js new file mode 100644 index 0000000000000..bb18bd321bac7 --- /dev/null +++ b/packages/hooks/build/createDidHook.js @@ -0,0 +1,39 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _validateHookName = require('./validateHookName.js'); + +var _validateHookName2 = _interopRequireDefault(_validateHookName); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Returns a function which, when invoked, will return the number of times a + * hook has been called. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * + * @return {Function} Function that returns a hook's call count. + */ +function createDidHook(hooks) { + /** + * Returns the number of times an action has been fired. + * + * @param {string} hookName The hook name to check. + * + * @return {number} The number of times the hook has run. + */ + return function didHook(hookName) { + + if (!(0, _validateHookName2.default)(hookName)) { + return; + } + + return hooks.hasOwnProperty(hookName) && hooks[hookName].runs ? hooks[hookName].runs : 0; + }; +} + +exports.default = createDidHook; \ No newline at end of file diff --git a/packages/hooks/build/createDoingHook.js b/packages/hooks/build/createDoingHook.js new file mode 100644 index 0000000000000..a46165ae108fe --- /dev/null +++ b/packages/hooks/build/createDoingHook.js @@ -0,0 +1,35 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +/** + * Returns a function which, when invoked, will return whether a hook is + * currently being executed. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * + * @return {Function} Function that returns whether a hook is currently + * being executed. + */ +function createDoingHook(hooks) { + /** + * Returns whether a hook is currently being executed. + * + * @param {?string} hookName The name of the hook to check for. If + * omitted, will check for any hook being executed. + * + * @return {bool} Whether the hook is being executed. + */ + return function doingHook(hookName) { + // If the hookName was not passed, check for any current hook. + if ('undefined' === typeof hookName) { + return 'undefined' !== typeof hooks.__current[0]; + } + + // Return the __current hook. + return hooks.__current[0] ? hookName === hooks.__current[0].name : false; + }; +} + +exports.default = createDoingHook; \ No newline at end of file diff --git a/packages/hooks/build/createHasHook.js b/packages/hooks/build/createHasHook.js new file mode 100644 index 0000000000000..03622df5bde1b --- /dev/null +++ b/packages/hooks/build/createHasHook.js @@ -0,0 +1,29 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +/** + * Returns a function which, when invoked, will return whether any handlers are + * attached to a particular hook. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * + * @return {Function} Function that returns whether any handlers are + * attached to a particular hook. + */ +function createHasHook(hooks) { + /** + * Returns how many handlers are attached for the given hook. + * + * @param {string} hookName The name of the hook to check for. + * + * @return {number} The number of handlers that are attached to + * the given hook. + */ + return function hasHook(hookName) { + return hooks.hasOwnProperty(hookName) ? hooks[hookName].handlers.length : 0; + }; +} + +exports.default = createHasHook; \ No newline at end of file diff --git a/packages/hooks/build/createRemoveHook.js b/packages/hooks/build/createRemoveHook.js new file mode 100644 index 0000000000000..731154752a841 --- /dev/null +++ b/packages/hooks/build/createRemoveHook.js @@ -0,0 +1,89 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _validateNamespace = require('./validateNamespace.js'); + +var _validateNamespace2 = _interopRequireDefault(_validateNamespace); + +var _validateHookName = require('./validateHookName.js'); + +var _validateHookName2 = _interopRequireDefault(_validateHookName); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Returns a function which, when invoked, will remove a specified hook or all + * hooks by the given name. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * @param {bool} removeAll Whether to remove all callbacks for a hookName, without regard to namespace. Used to create `removeAll*` functions. + * + * @return {Function} Function that removes hooks. + */ +function createRemoveHook(hooks, removeAll) { + /** + * Removes the specified callback (or all callbacks) from the hook with a + * given hookName and namespace. + * + * @param {string} hookName The name of the hook to modify. + * @param {string} namespace The unique namespace identifying the callback in the form `vendor/plugin/function`. + * + * @return {number} The number of callbacks removed. + */ + return function removeHook(hookName, namespace) { + + if (!(0, _validateHookName2.default)(hookName)) { + return; + } + + if (!removeAll && !(0, _validateNamespace2.default)(namespace)) { + return; + } + + // Bail if no hooks exist by this name + if (!hooks.hasOwnProperty(hookName)) { + return 0; + } + + var handlersRemoved = 0; + + if (removeAll) { + handlersRemoved = hooks[hookName].handlers.length; + hooks[hookName] = { + runs: hooks[hookName].runs, + handlers: [] + }; + } else { + // Try to find the specified callback to remove. + var handlers = hooks[hookName].handlers; + + var _loop = function _loop(i) { + if (handlers[i].namespace === namespace) { + handlers.splice(i, 1); + handlersRemoved++; + // This callback may also be part of a hook that is + // currently executing. If the callback we're removing + // comes after the current callback, there's no problem; + // otherwise we need to decrease the execution index of any + // other runs by 1 to account for the removed element. + (hooks.__current || []).forEach(function (hookInfo) { + if (hookInfo.name === hookName && hookInfo.currentIndex >= i) { + hookInfo.currentIndex--; + } + }); + } + }; + + for (var i = handlers.length - 1; i >= 0; i--) { + _loop(i); + } + } + + return handlersRemoved; + }; +} + +exports.default = createRemoveHook; \ No newline at end of file diff --git a/packages/hooks/build/createRunHook.js b/packages/hooks/build/createRunHook.js new file mode 100644 index 0000000000000..6e7ad94dffa45 --- /dev/null +++ b/packages/hooks/build/createRunHook.js @@ -0,0 +1,84 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _validateHookName = require('./validateHookName.js'); + +var _validateHookName2 = _interopRequireDefault(_validateHookName); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Returns a function which, when invoked, will execute all callbacks + * registered to a hook of the specified type, optionally returning the final + * value of the call chain. + * + * @param {Object} hooks Stored hooks, keyed by hook name. + * @param {?bool} returnFirstArg Whether each hook callback is expected to + * return its first argument. + * + * @return {Function} Function that runs hook callbacks. + */ +function createRunHook(hooks, returnFirstArg) { + /** + * Runs all callbacks for the specified hook. + * + * @param {string} hookName The name of the hook to run. + * @param {...*} args Arguments to pass to the hook callbacks. + * + * @return {*} Return value of runner, if applicable. + */ + return function runHooks(hookName) { + + if (!(0, _validateHookName2.default)(hookName)) { + return; + } + + if (!hooks.hasOwnProperty(hookName)) { + hooks[hookName] = { + runs: 0, + handlers: [] + }; + } + + var handlers = hooks[hookName].handlers; + + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + if (!handlers.length) { + return returnFirstArg ? args[0] : undefined; + } + + var hookInfo = { + name: hookName, + currentIndex: 0 + }; + + hooks.__current = hooks.__current || []; + hooks.__current.push(hookInfo); + hooks[hookName].runs++; + + var maybeReturnValue = args[0]; + + while (hookInfo.currentIndex < handlers.length) { + var handler = handlers[hookInfo.currentIndex]; + maybeReturnValue = handler.callback.apply(null, args); + if (returnFirstArg) { + args[0] = maybeReturnValue; + } + hookInfo.currentIndex++; + } + + hooks.__current.pop(); + + if (returnFirstArg) { + return maybeReturnValue; + } + }; +} + +exports.default = createRunHook; \ No newline at end of file diff --git a/packages/hooks/build/hooks.js b/packages/hooks/build/hooks.js new file mode 100644 index 0000000000000..586fd6af35971 --- /dev/null +++ b/packages/hooks/build/hooks.js @@ -0,0 +1,15 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +/** + * Contains the registered hooks, keyed by hook type. Each hook type is an + * array of objects with priority and callback of each registered hook. + */ +var HOOKS = { + actions: {}, + filters: {} +}; + +exports.default = HOOKS; \ No newline at end of file diff --git a/packages/hooks/build/index.js b/packages/hooks/build/index.js new file mode 100644 index 0000000000000..fe54cd482bb4f --- /dev/null +++ b/packages/hooks/build/index.js @@ -0,0 +1,72 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.didFilter = exports.didAction = exports.doingFilter = exports.doingAction = exports.currentFilter = exports.currentAction = exports.applyFilters = exports.doAction = exports.removeAllFilters = exports.removeAllActions = exports.hasFilter = exports.hasAction = exports.removeFilter = exports.removeAction = exports.addFilter = exports.addAction = undefined; + +var _hooks = require('./hooks'); + +var _hooks2 = _interopRequireDefault(_hooks); + +var _createAddHook = require('./createAddHook'); + +var _createAddHook2 = _interopRequireDefault(_createAddHook); + +var _createRemoveHook = require('./createRemoveHook'); + +var _createRemoveHook2 = _interopRequireDefault(_createRemoveHook); + +var _createHasHook = require('./createHasHook'); + +var _createHasHook2 = _interopRequireDefault(_createHasHook); + +var _createRunHook = require('./createRunHook'); + +var _createRunHook2 = _interopRequireDefault(_createRunHook); + +var _createCurrentHook = require('./createCurrentHook'); + +var _createCurrentHook2 = _interopRequireDefault(_createCurrentHook); + +var _createDoingHook = require('./createDoingHook'); + +var _createDoingHook2 = _interopRequireDefault(_createDoingHook); + +var _createDidHook = require('./createDidHook'); + +var _createDidHook2 = _interopRequireDefault(_createDidHook); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// Add action/filter functions. +var addAction = exports.addAction = (0, _createAddHook2.default)(_hooks2.default.actions); +var addFilter = exports.addFilter = (0, _createAddHook2.default)(_hooks2.default.filters); + +// Remove action/filter functions. +var removeAction = exports.removeAction = (0, _createRemoveHook2.default)(_hooks2.default.actions); +var removeFilter = exports.removeFilter = (0, _createRemoveHook2.default)(_hooks2.default.filters); + +// Has action/filter functions. +var hasAction = exports.hasAction = (0, _createHasHook2.default)(_hooks2.default.actions); +var hasFilter = exports.hasFilter = (0, _createHasHook2.default)(_hooks2.default.filters); + +// Remove all actions/filters functions. +var removeAllActions = exports.removeAllActions = (0, _createRemoveHook2.default)(_hooks2.default.actions, true); +var removeAllFilters = exports.removeAllFilters = (0, _createRemoveHook2.default)(_hooks2.default.filters, true); + +// Do action/apply filters functions. +var doAction = exports.doAction = (0, _createRunHook2.default)(_hooks2.default.actions); +var applyFilters = exports.applyFilters = (0, _createRunHook2.default)(_hooks2.default.filters, true); + +// Current action/filter functions. +var currentAction = exports.currentAction = (0, _createCurrentHook2.default)(_hooks2.default.actions); +var currentFilter = exports.currentFilter = (0, _createCurrentHook2.default)(_hooks2.default.filters); + +// Doing action/filter: true while a hook is being run. +var doingAction = exports.doingAction = (0, _createDoingHook2.default)(_hooks2.default.actions); +var doingFilter = exports.doingFilter = (0, _createDoingHook2.default)(_hooks2.default.filters); + +// Did action/filter functions. +var didAction = exports.didAction = (0, _createDidHook2.default)(_hooks2.default.actions); +var didFilter = exports.didFilter = (0, _createDidHook2.default)(_hooks2.default.filters); \ No newline at end of file diff --git a/packages/hooks/build/validateHookName.js b/packages/hooks/build/validateHookName.js new file mode 100644 index 0000000000000..3b85b5279a858 --- /dev/null +++ b/packages/hooks/build/validateHookName.js @@ -0,0 +1,35 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +/** + * Validate a hookName string. + * + * @param {string} hookName The hook name to validate. Should be a non empty string containing + * only numbers, letters, dashes, periods and underscores. Also, + * the hook name cannot begin with `__`. + * + * @return {bool} Whether the hook name is valid. + */ +function validateHookName(hookName) { + + if ('string' !== typeof hookName || '' === hookName) { + console.error('The hook name must be a non-empty string.'); + return false; + } + + if (/^__/.test(hookName)) { + console.error('The hook name cannot begin with `__`.'); + return false; + } + + if (!/^[a-zA-Z][a-zA-Z0-9_.-]*$/.test(hookName)) { + console.error('The hook name can only contain numbers, letters, dashes, periods and underscores.'); + return false; + } + + return true; +} + +exports.default = validateHookName; \ No newline at end of file diff --git a/packages/hooks/build/validateNamespace.js b/packages/hooks/build/validateNamespace.js new file mode 100644 index 0000000000000..8e844098ab1c9 --- /dev/null +++ b/packages/hooks/build/validateNamespace.js @@ -0,0 +1,29 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +/** + * Validate a namespace string. + * + * @param {string} namespace The namespace to validate - should take the form + * `vendor/plugin/function`. + * + * @return {bool} Whether the namespace is valid. + */ +function validateNamespace(namespace) { + + if ('string' !== typeof namespace || '' === namespace) { + console.error('The namespace must be a non-empty string.'); + return false; + } + + if (!/^[a-zA-Z][a-zA-Z0-9]*$/.test(namespace)) { + console.error('The namespace can only contain numbers, letters, dashes, periods and underscores.'); + return false; + } + + return true; +} + +exports.default = validateNamespace; From 352f832990a68c6bee6022e06d46305e09eb16d1 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Sun, 22 Oct 2017 10:43:16 -0400 Subject: [PATCH 208/393] dom-ready - add built files --- packages/dom-ready/build-module/index.js | 16 ++++++++++++++++ packages/dom-ready/build/index.js | 21 +++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 packages/dom-ready/build-module/index.js create mode 100644 packages/dom-ready/build/index.js diff --git a/packages/dom-ready/build-module/index.js b/packages/dom-ready/build-module/index.js new file mode 100644 index 0000000000000..74c49cbe35aab --- /dev/null +++ b/packages/dom-ready/build-module/index.js @@ -0,0 +1,16 @@ +/** + * Specify a function to execute when the DOM is fully loaded. + * + * @param {Function} callback A function to execute after the DOM is ready. + * + * @returns {void} + */ +var domReady = function domReady(callback) { + if (document.readyState === 'complete') { + return callback(); + } + + document.addEventListener('DOMContentLoaded', callback); +}; + +export default domReady; \ No newline at end of file diff --git a/packages/dom-ready/build/index.js b/packages/dom-ready/build/index.js new file mode 100644 index 0000000000000..3795bad776179 --- /dev/null +++ b/packages/dom-ready/build/index.js @@ -0,0 +1,21 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +/** + * Specify a function to execute when the DOM is fully loaded. + * + * @param {Function} callback A function to execute after the DOM is ready. + * + * @returns {void} + */ +var domReady = function domReady(callback) { + if (document.readyState === 'complete') { + return callback(); + } + + document.addEventListener('DOMContentLoaded', callback); +}; + +exports.default = domReady; \ No newline at end of file From ed024aa8171142ea0038782c3f1aff9a5ff1bcc6 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Sun, 22 Oct 2017 10:44:26 -0400 Subject: [PATCH 209/393] a11y - add built files --- packages/a11y/build-module/addContainer.js | 25 ++++++++ packages/a11y/build-module/clear.js | 11 ++++ packages/a11y/build-module/filterMessage.js | 30 +++++++++ packages/a11y/build-module/index.js | 47 +++++++++++++++ packages/a11y/build/addContainer.js | 30 +++++++++ packages/a11y/build/clear.js | 16 +++++ packages/a11y/build/filterMessage.js | 35 +++++++++++ packages/a11y/build/index.js | 67 +++++++++++++++++++++ 8 files changed, 261 insertions(+) create mode 100644 packages/a11y/build-module/addContainer.js create mode 100644 packages/a11y/build-module/clear.js create mode 100644 packages/a11y/build-module/filterMessage.js create mode 100644 packages/a11y/build-module/index.js create mode 100644 packages/a11y/build/addContainer.js create mode 100644 packages/a11y/build/clear.js create mode 100644 packages/a11y/build/filterMessage.js create mode 100644 packages/a11y/build/index.js diff --git a/packages/a11y/build-module/addContainer.js b/packages/a11y/build-module/addContainer.js new file mode 100644 index 0000000000000..29f59ea572cf7 --- /dev/null +++ b/packages/a11y/build-module/addContainer.js @@ -0,0 +1,25 @@ +/** + * Build the live regions markup. + * + * @param {String} ariaLive Optional. Value for the 'aria-live' attribute, default 'polite'. + * + * @returns {Object} $container The ARIA live region jQuery object. + */ +var addContainer = function addContainer(ariaLive) { + ariaLive = ariaLive || 'polite'; + + var container = document.createElement('div'); + container.id = 'a11y-speak-' + ariaLive; + container.className = 'a11y-speak-region'; + + var screenReaderTextStyle = 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;'; + container.setAttribute('style', screenReaderTextStyle); + container.setAttribute('aria-live', ariaLive); + container.setAttribute('aria-relevant', 'additions text'); + container.setAttribute('aria-atomic', 'true'); + + document.querySelector('body').appendChild(container); + return container; +}; + +export default addContainer; \ No newline at end of file diff --git a/packages/a11y/build-module/clear.js b/packages/a11y/build-module/clear.js new file mode 100644 index 0000000000000..816ebd8cd5785 --- /dev/null +++ b/packages/a11y/build-module/clear.js @@ -0,0 +1,11 @@ +/** + * Clear the a11y-speak-region elements. + */ +var clear = function clear() { + var regions = document.querySelectorAll('.a11y-speak-region'); + for (var i = 0; i < regions.length; i++) { + regions[i].textContent = ''; + } +}; + +export default clear; \ No newline at end of file diff --git a/packages/a11y/build-module/filterMessage.js b/packages/a11y/build-module/filterMessage.js new file mode 100644 index 0000000000000..389435c2ce01f --- /dev/null +++ b/packages/a11y/build-module/filterMessage.js @@ -0,0 +1,30 @@ +var previousMessage = ''; + +/** + * Filter the message to be announced to the screenreader. + * + * @param {String} message The message to be announced. + * + * @returns {String} + */ +var filterMessage = function filterMessage(message) { + + /* + * Strip HTML tags (if any) from the message string. Ideally, messages should + * be simple strings, carefully crafted for specific use with A11ySpeak. + * When re-using already existing strings this will ensure simple HTML to be + * stripped out and replaced with a space. Browsers will collapse multiple + * spaces natively. + */ + message = message.replace(/<[^<>]+>/g, ' '); + + if (previousMessage === message) { + message += '\xA0'; + } + + previousMessage = message; + + return message; +}; + +export default filterMessage; \ No newline at end of file diff --git a/packages/a11y/build-module/index.js b/packages/a11y/build-module/index.js new file mode 100644 index 0000000000000..d2ddf1e4efb4a --- /dev/null +++ b/packages/a11y/build-module/index.js @@ -0,0 +1,47 @@ +import addContainer from './addContainer'; +import clear from './clear'; +import domReady from '@wordpress/dom-ready'; +import filterMessage from './filterMessage'; + +/** + * Create the live regions. + */ +export var setup = function setup() { + var containerPolite = document.getElementById('a11y-speak-polite'); + var containerAssertive = document.getElementById('a11y-speak-assertive'); + + if (containerPolite === null) { + containerPolite = addContainer('polite'); + } + if (containerAssertive === null) { + containerAssertive = addContainer('assertive'); + } +}; + +/** + * Run setup on domReady. + */ +domReady(setup); + +/** + * Update the ARIA live notification area text node. + * + * @param {String} message The message to be announced by Assistive Technologies. + * @param {String} ariaLive Optional. The politeness level for aria-live. Possible values: + * polite or assertive. Default polite. + */ +export var speak = function speak(message, ariaLive) { + // Clear previous messages to allow repeated strings being read out. + clear(); + + message = filterMessage(message); + + var containerPolite = document.getElementById('a11y-speak-polite'); + var containerAssertive = document.getElementById('a11y-speak-assertive'); + + if (containerAssertive && 'assertive' === ariaLive) { + containerAssertive.textContent = message; + } else if (containerPolite) { + containerPolite.textContent = message; + } +}; \ No newline at end of file diff --git a/packages/a11y/build/addContainer.js b/packages/a11y/build/addContainer.js new file mode 100644 index 0000000000000..ba68d10a29f65 --- /dev/null +++ b/packages/a11y/build/addContainer.js @@ -0,0 +1,30 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +/** + * Build the live regions markup. + * + * @param {String} ariaLive Optional. Value for the 'aria-live' attribute, default 'polite'. + * + * @returns {Object} $container The ARIA live region jQuery object. + */ +var addContainer = function addContainer(ariaLive) { + ariaLive = ariaLive || 'polite'; + + var container = document.createElement('div'); + container.id = 'a11y-speak-' + ariaLive; + container.className = 'a11y-speak-region'; + + var screenReaderTextStyle = 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;'; + container.setAttribute('style', screenReaderTextStyle); + container.setAttribute('aria-live', ariaLive); + container.setAttribute('aria-relevant', 'additions text'); + container.setAttribute('aria-atomic', 'true'); + + document.querySelector('body').appendChild(container); + return container; +}; + +exports.default = addContainer; \ No newline at end of file diff --git a/packages/a11y/build/clear.js b/packages/a11y/build/clear.js new file mode 100644 index 0000000000000..738fc7ac2e27e --- /dev/null +++ b/packages/a11y/build/clear.js @@ -0,0 +1,16 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +/** + * Clear the a11y-speak-region elements. + */ +var clear = function clear() { + var regions = document.querySelectorAll('.a11y-speak-region'); + for (var i = 0; i < regions.length; i++) { + regions[i].textContent = ''; + } +}; + +exports.default = clear; \ No newline at end of file diff --git a/packages/a11y/build/filterMessage.js b/packages/a11y/build/filterMessage.js new file mode 100644 index 0000000000000..98be77adb39d1 --- /dev/null +++ b/packages/a11y/build/filterMessage.js @@ -0,0 +1,35 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var previousMessage = ''; + +/** + * Filter the message to be announced to the screenreader. + * + * @param {String} message The message to be announced. + * + * @returns {String} + */ +var filterMessage = function filterMessage(message) { + + /* + * Strip HTML tags (if any) from the message string. Ideally, messages should + * be simple strings, carefully crafted for specific use with A11ySpeak. + * When re-using already existing strings this will ensure simple HTML to be + * stripped out and replaced with a space. Browsers will collapse multiple + * spaces natively. + */ + message = message.replace(/<[^<>]+>/g, ' '); + + if (previousMessage === message) { + message += '\xA0'; + } + + previousMessage = message; + + return message; +}; + +exports.default = filterMessage; \ No newline at end of file diff --git a/packages/a11y/build/index.js b/packages/a11y/build/index.js new file mode 100644 index 0000000000000..eb79740557ccb --- /dev/null +++ b/packages/a11y/build/index.js @@ -0,0 +1,67 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.speak = exports.setup = undefined; + +var _addContainer = require('./addContainer'); + +var _addContainer2 = _interopRequireDefault(_addContainer); + +var _clear = require('./clear'); + +var _clear2 = _interopRequireDefault(_clear); + +var _domReady = require('@wordpress/dom-ready'); + +var _domReady2 = _interopRequireDefault(_domReady); + +var _filterMessage = require('./filterMessage'); + +var _filterMessage2 = _interopRequireDefault(_filterMessage); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Create the live regions. + */ +var setup = exports.setup = function setup() { + var containerPolite = document.getElementById('a11y-speak-polite'); + var containerAssertive = document.getElementById('a11y-speak-assertive'); + + if (containerPolite === null) { + containerPolite = (0, _addContainer2.default)('polite'); + } + if (containerAssertive === null) { + containerAssertive = (0, _addContainer2.default)('assertive'); + } +}; + +/** + * Run setup on domReady. + */ +(0, _domReady2.default)(setup); + +/** + * Update the ARIA live notification area text node. + * + * @param {String} message The message to be announced by Assistive Technologies. + * @param {String} ariaLive Optional. The politeness level for aria-live. Possible values: + * polite or assertive. Default polite. + */ +var speak = exports.speak = function speak(message, ariaLive) { + // Clear previous messages to allow repeated strings being read out. + (0, _clear2.default)(); + + message = (0, _filterMessage2.default)(message); + + var containerPolite = document.getElementById('a11y-speak-polite'); + var containerAssertive = document.getElementById('a11y-speak-assertive'); + + if (containerAssertive && 'assertive' === ariaLive) { + containerAssertive.textContent = message; + } else if (containerPolite) { + containerPolite.textContent = message; + } +}; \ No newline at end of file From ebeb02979037289e3ab60be799dfe5faa70bf4df Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Sun, 22 Oct 2017 10:44:39 -0400 Subject: [PATCH 210/393] remove build filders from gitignore --- .gitignore | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.gitignore b/.gitignore index 1e386cf42fc58..c6b9df27f6c01 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,3 @@ node_modules/ -/packages/*/build/ -/packages/*/build-module/ -/packages/*/build-browser/ - coverage/ From c5594e3a84c39bf21fe30b9a3c1951bd18981249 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Sun, 22 Oct 2017 10:56:22 -0400 Subject: [PATCH 211/393] Publish - @wordpress/a11y@0.1.0-beta.3 - @wordpress/dom-ready@0.1.0-beta.3 - @wordpress/hooks@0.1.0-beta.2 - @wordpress/url@0.1.0-beta.3 --- packages/a11y/package.json | 4 ++-- packages/dom-ready/package.json | 2 +- packages/hooks/package.json | 2 +- packages/url/package.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/a11y/package.json b/packages/a11y/package.json index 17a3e46d3371b..d9447a0014804 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/a11y", - "version": "0.1.0-beta.2", + "version": "0.1.0-beta.3", "description": "Collection of JS modules and tools for WordPress development", "homepage": "https://github.com/WordPress/packages/tree/master/packages/a11y/README.md", "author": "WordPress", @@ -18,7 +18,7 @@ "url": "https://github.com/WordPress/packages/issues" }, "dependencies": { - "@wordpress/dom-ready": "^0.1.0-beta.2" + "@wordpress/dom-ready": "^0.1.0-beta.3" }, "publishConfig": { "access": "public" diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index 27909bd060e87..554578dc0928c 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom-ready", - "version": "0.1.0-beta.2", + "version": "0.1.0-beta.3", "description": "Execute callback after the DOM is loaded.", "homepage": "https://github.com/WordPress/packages/tree/master/packages/dom-ready/README.md", "author": "WordPress", diff --git a/packages/hooks/package.json b/packages/hooks/package.json index fbd24f781ae0d..63bab26587786 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/hooks", - "version": "0.1.0-beta.1", + "version": "0.1.0-beta.2", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" diff --git a/packages/url/package.json b/packages/url/package.json index 1bc8aa07d5eab..d1518b26fbe03 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/url", - "version": "0.1.0-beta.2", + "version": "0.1.0-beta.3", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" From 9546ea6de9c0a465199495eaf33f522598eae544 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Sun, 22 Oct 2017 11:01:43 -0400 Subject: [PATCH 212/393] =?UTF-8?q?re-ignore=20build=20files;=20didn?= =?UTF-8?q?=E2=80=99t=20resolve=20publishing=20issue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index c6b9df27f6c01..1e386cf42fc58 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ node_modules/ +/packages/*/build/ +/packages/*/build-module/ +/packages/*/build-browser/ + coverage/ From 00650e95f601f30daf99e638eec4905f37f34ce4 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Sun, 22 Oct 2017 11:10:03 -0400 Subject: [PATCH 213/393] Simplify dom-ready package.json, add a license field --- packages/dom-ready/package.json | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index 554578dc0928c..74f89a00fffd1 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -1,22 +1,15 @@ { "name": "@wordpress/dom-ready", "version": "0.1.0-beta.3", - "description": "Execute callback after the DOM is loaded.", - "homepage": "https://github.com/WordPress/packages/tree/master/packages/dom-ready/README.md", - "author": "WordPress", - "keywords": [ - "DOM", - "Readystate" - ], - "main": "build/index.js", - "module": "build-module/index.js", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" }, - "bugs": { - "url": "https://github.com/WordPress/packages/issues" - }, + "description": "Execute callback after the DOM is loaded.", + "main": "build/index.js", + "module": "build-module/index.js", + "author": "WordPress", + "license": "GPL-2.0+", "publishConfig": { "access": "public" } From 0ae2073be0cdc6d6122b2a36fc5fc43cd1d0a015 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Sun, 22 Oct 2017 11:14:42 -0400 Subject: [PATCH 214/393] Publish - @wordpress/a11y@0.1.0-beta.4 - @wordpress/dom-ready@0.1.0-beta.4 - @wordpress/hooks@0.1.0-beta.3 --- packages/a11y/package.json | 4 ++-- packages/dom-ready/package.json | 2 +- packages/hooks/package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/a11y/package.json b/packages/a11y/package.json index d9447a0014804..139e680a00a38 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/a11y", - "version": "0.1.0-beta.3", + "version": "0.1.0-beta.4", "description": "Collection of JS modules and tools for WordPress development", "homepage": "https://github.com/WordPress/packages/tree/master/packages/a11y/README.md", "author": "WordPress", @@ -18,7 +18,7 @@ "url": "https://github.com/WordPress/packages/issues" }, "dependencies": { - "@wordpress/dom-ready": "^0.1.0-beta.3" + "@wordpress/dom-ready": "^0.1.0-beta.4" }, "publishConfig": { "access": "public" diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index 74f89a00fffd1..0b88af74255c1 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom-ready", - "version": "0.1.0-beta.3", + "version": "0.1.0-beta.4", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" diff --git a/packages/hooks/package.json b/packages/hooks/package.json index 63bab26587786..d441c2ae7f0f5 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/hooks", - "version": "0.1.0-beta.2", + "version": "0.1.0-beta.3", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" From ba3796a22348af02ca7c0c7f8650254c9ee0c1e7 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Sun, 22 Oct 2017 11:37:01 -0400 Subject: [PATCH 215/393] Update readmes to include `@next` in npm install line Since our packages are still in pre-release, the @next tag is required to install the latest published version. We can remove this instruction once the packages are past pre-release. --- packages/a11y/README.md | 2 +- packages/dom-ready/README.md | 2 +- packages/hooks/README.md | 12 ++++++++++-- packages/url/README.md | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/a11y/README.md b/packages/a11y/README.md index 45a4c0aa2bfcc..a32be37bd641e 100644 --- a/packages/a11y/README.md +++ b/packages/a11y/README.md @@ -7,7 +7,7 @@ Collection of JS modules for enhancing accessibility. Install the module ```bash -npm install @wordpress/a11y --save +npm install @wordpress/a11y@next --save ``` ## speak diff --git a/packages/dom-ready/README.md b/packages/dom-ready/README.md index a8c7bd0262877..a17eb9df6817d 100644 --- a/packages/dom-ready/README.md +++ b/packages/dom-ready/README.md @@ -7,7 +7,7 @@ Executes a function after the DOM has loaded. Install the module ```bash -npm install @wordpress/dom-ready --save +npm install @wordpress/dom-ready@next --save ``` ### Usage diff --git a/packages/hooks/README.md b/packages/hooks/README.md index 06cac123ac2d1..00615cde0fff1 100644 --- a/packages/hooks/README.md +++ b/packages/hooks/README.md @@ -1,9 +1,17 @@ -# WP-JS-Hooks +# @wordpress/hooks A lightweight & efficient EventManager for JavaScript in WordPress. +## Installation + +Install the module + +```bash +npm install @wordpress/hooks@next --save +``` + +### Usage -### API Usage API functions can be called via the global `wp.hooks` like this `wp.hooks.addAction()`, etc. * `addAction( 'hook', 'vendor/plugin/function', callback, priority )` diff --git a/packages/url/README.md b/packages/url/README.md index 3943a364a21c1..ae31e95e7f0ee 100644 --- a/packages/url/README.md +++ b/packages/url/README.md @@ -7,7 +7,7 @@ A collection of utilities to manipulate URLs Install the module ```bash -npm install @wordpress/url --save +npm install @wordpress/url@next --save ``` ## Usage From b16c8ba78d00da60eafbb1e684a25742b1893e0e Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Sun, 22 Oct 2017 11:47:10 -0400 Subject: [PATCH 216/393] Publish - @wordpress/a11y@0.1.0-beta.5 - @wordpress/dom-ready@0.1.0-beta.5 - @wordpress/hooks@0.1.0-beta.4 - @wordpress/url@0.1.0-beta.4 --- packages/a11y/package.json | 4 ++-- packages/dom-ready/package.json | 2 +- packages/hooks/package.json | 2 +- packages/url/package.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/a11y/package.json b/packages/a11y/package.json index 139e680a00a38..ce41cd87ba3ab 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/a11y", - "version": "0.1.0-beta.4", + "version": "0.1.0-beta.5", "description": "Collection of JS modules and tools for WordPress development", "homepage": "https://github.com/WordPress/packages/tree/master/packages/a11y/README.md", "author": "WordPress", @@ -18,7 +18,7 @@ "url": "https://github.com/WordPress/packages/issues" }, "dependencies": { - "@wordpress/dom-ready": "^0.1.0-beta.4" + "@wordpress/dom-ready": "^0.1.0-beta.5" }, "publishConfig": { "access": "public" diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index 0b88af74255c1..fa0f781aece3b 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom-ready", - "version": "0.1.0-beta.4", + "version": "0.1.0-beta.5", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" diff --git a/packages/hooks/package.json b/packages/hooks/package.json index d441c2ae7f0f5..a936c9899cf4d 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/hooks", - "version": "0.1.0-beta.3", + "version": "0.1.0-beta.4", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" diff --git a/packages/url/package.json b/packages/url/package.json index d1518b26fbe03..52387de3ab52b 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/url", - "version": "0.1.0-beta.3", + "version": "0.1.0-beta.4", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" From 04ce84e125f8941f4ead9d13e3fe65dc52d3c7d6 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Sun, 22 Oct 2017 12:04:44 -0400 Subject: [PATCH 217/393] remove the built files which were added by mistake --- packages/a11y/build-module/addContainer.js | 25 ------ packages/a11y/build-module/clear.js | 11 --- packages/a11y/build-module/filterMessage.js | 30 ------- packages/a11y/build-module/index.js | 47 ---------- packages/a11y/build/addContainer.js | 30 ------- packages/a11y/build/clear.js | 16 ---- packages/a11y/build/filterMessage.js | 35 -------- packages/a11y/build/index.js | 67 -------------- packages/dom-ready/build-module/index.js | 16 ---- packages/dom-ready/build/index.js | 21 ----- packages/hooks/build-module/createAddHook.js | 76 ---------------- .../hooks/build-module/createCurrentHook.js | 27 ------ packages/hooks/build-module/createDidHook.js | 29 ------ .../hooks/build-module/createDoingHook.js | 30 ------- packages/hooks/build-module/createHasHook.js | 24 ----- .../hooks/build-module/createRemoveHook.js | 76 ---------------- packages/hooks/build-module/createRunHook.js | 74 --------------- packages/hooks/build-module/hooks.js | 10 --- packages/hooks/build-module/index.js | 40 --------- .../hooks/build-module/validateHookName.js | 30 ------- .../hooks/build-module/validateNamespace.js | 29 ------ packages/hooks/build/createAddHook.js | 89 ------------------- packages/hooks/build/createCurrentHook.js | 32 ------- packages/hooks/build/createDidHook.js | 39 -------- packages/hooks/build/createDoingHook.js | 35 -------- packages/hooks/build/createHasHook.js | 29 ------ packages/hooks/build/createRemoveHook.js | 89 ------------------- packages/hooks/build/createRunHook.js | 84 ----------------- packages/hooks/build/hooks.js | 15 ---- packages/hooks/build/index.js | 72 --------------- packages/hooks/build/validateHookName.js | 35 -------- packages/hooks/build/validateNamespace.js | 29 ------ packages/url/build-browser/index.js | 36 -------- packages/url/build-browser/test/index.test.js | 21 ----- packages/url/build-module/index.js | 23 ----- packages/url/build/index.js | 32 ------- 36 files changed, 1403 deletions(-) delete mode 100644 packages/a11y/build-module/addContainer.js delete mode 100644 packages/a11y/build-module/clear.js delete mode 100644 packages/a11y/build-module/filterMessage.js delete mode 100644 packages/a11y/build-module/index.js delete mode 100644 packages/a11y/build/addContainer.js delete mode 100644 packages/a11y/build/clear.js delete mode 100644 packages/a11y/build/filterMessage.js delete mode 100644 packages/a11y/build/index.js delete mode 100644 packages/dom-ready/build-module/index.js delete mode 100644 packages/dom-ready/build/index.js delete mode 100644 packages/hooks/build-module/createAddHook.js delete mode 100644 packages/hooks/build-module/createCurrentHook.js delete mode 100644 packages/hooks/build-module/createDidHook.js delete mode 100644 packages/hooks/build-module/createDoingHook.js delete mode 100644 packages/hooks/build-module/createHasHook.js delete mode 100644 packages/hooks/build-module/createRemoveHook.js delete mode 100644 packages/hooks/build-module/createRunHook.js delete mode 100644 packages/hooks/build-module/hooks.js delete mode 100644 packages/hooks/build-module/index.js delete mode 100644 packages/hooks/build-module/validateHookName.js delete mode 100644 packages/hooks/build-module/validateNamespace.js delete mode 100644 packages/hooks/build/createAddHook.js delete mode 100644 packages/hooks/build/createCurrentHook.js delete mode 100644 packages/hooks/build/createDidHook.js delete mode 100644 packages/hooks/build/createDoingHook.js delete mode 100644 packages/hooks/build/createHasHook.js delete mode 100644 packages/hooks/build/createRemoveHook.js delete mode 100644 packages/hooks/build/createRunHook.js delete mode 100644 packages/hooks/build/hooks.js delete mode 100644 packages/hooks/build/index.js delete mode 100644 packages/hooks/build/validateHookName.js delete mode 100644 packages/hooks/build/validateNamespace.js delete mode 100644 packages/url/build-browser/index.js delete mode 100644 packages/url/build-browser/test/index.test.js delete mode 100644 packages/url/build-module/index.js delete mode 100644 packages/url/build/index.js diff --git a/packages/a11y/build-module/addContainer.js b/packages/a11y/build-module/addContainer.js deleted file mode 100644 index 29f59ea572cf7..0000000000000 --- a/packages/a11y/build-module/addContainer.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Build the live regions markup. - * - * @param {String} ariaLive Optional. Value for the 'aria-live' attribute, default 'polite'. - * - * @returns {Object} $container The ARIA live region jQuery object. - */ -var addContainer = function addContainer(ariaLive) { - ariaLive = ariaLive || 'polite'; - - var container = document.createElement('div'); - container.id = 'a11y-speak-' + ariaLive; - container.className = 'a11y-speak-region'; - - var screenReaderTextStyle = 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;'; - container.setAttribute('style', screenReaderTextStyle); - container.setAttribute('aria-live', ariaLive); - container.setAttribute('aria-relevant', 'additions text'); - container.setAttribute('aria-atomic', 'true'); - - document.querySelector('body').appendChild(container); - return container; -}; - -export default addContainer; \ No newline at end of file diff --git a/packages/a11y/build-module/clear.js b/packages/a11y/build-module/clear.js deleted file mode 100644 index 816ebd8cd5785..0000000000000 --- a/packages/a11y/build-module/clear.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Clear the a11y-speak-region elements. - */ -var clear = function clear() { - var regions = document.querySelectorAll('.a11y-speak-region'); - for (var i = 0; i < regions.length; i++) { - regions[i].textContent = ''; - } -}; - -export default clear; \ No newline at end of file diff --git a/packages/a11y/build-module/filterMessage.js b/packages/a11y/build-module/filterMessage.js deleted file mode 100644 index 389435c2ce01f..0000000000000 --- a/packages/a11y/build-module/filterMessage.js +++ /dev/null @@ -1,30 +0,0 @@ -var previousMessage = ''; - -/** - * Filter the message to be announced to the screenreader. - * - * @param {String} message The message to be announced. - * - * @returns {String} - */ -var filterMessage = function filterMessage(message) { - - /* - * Strip HTML tags (if any) from the message string. Ideally, messages should - * be simple strings, carefully crafted for specific use with A11ySpeak. - * When re-using already existing strings this will ensure simple HTML to be - * stripped out and replaced with a space. Browsers will collapse multiple - * spaces natively. - */ - message = message.replace(/<[^<>]+>/g, ' '); - - if (previousMessage === message) { - message += '\xA0'; - } - - previousMessage = message; - - return message; -}; - -export default filterMessage; \ No newline at end of file diff --git a/packages/a11y/build-module/index.js b/packages/a11y/build-module/index.js deleted file mode 100644 index d2ddf1e4efb4a..0000000000000 --- a/packages/a11y/build-module/index.js +++ /dev/null @@ -1,47 +0,0 @@ -import addContainer from './addContainer'; -import clear from './clear'; -import domReady from '@wordpress/dom-ready'; -import filterMessage from './filterMessage'; - -/** - * Create the live regions. - */ -export var setup = function setup() { - var containerPolite = document.getElementById('a11y-speak-polite'); - var containerAssertive = document.getElementById('a11y-speak-assertive'); - - if (containerPolite === null) { - containerPolite = addContainer('polite'); - } - if (containerAssertive === null) { - containerAssertive = addContainer('assertive'); - } -}; - -/** - * Run setup on domReady. - */ -domReady(setup); - -/** - * Update the ARIA live notification area text node. - * - * @param {String} message The message to be announced by Assistive Technologies. - * @param {String} ariaLive Optional. The politeness level for aria-live. Possible values: - * polite or assertive. Default polite. - */ -export var speak = function speak(message, ariaLive) { - // Clear previous messages to allow repeated strings being read out. - clear(); - - message = filterMessage(message); - - var containerPolite = document.getElementById('a11y-speak-polite'); - var containerAssertive = document.getElementById('a11y-speak-assertive'); - - if (containerAssertive && 'assertive' === ariaLive) { - containerAssertive.textContent = message; - } else if (containerPolite) { - containerPolite.textContent = message; - } -}; \ No newline at end of file diff --git a/packages/a11y/build/addContainer.js b/packages/a11y/build/addContainer.js deleted file mode 100644 index ba68d10a29f65..0000000000000 --- a/packages/a11y/build/addContainer.js +++ /dev/null @@ -1,30 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -/** - * Build the live regions markup. - * - * @param {String} ariaLive Optional. Value for the 'aria-live' attribute, default 'polite'. - * - * @returns {Object} $container The ARIA live region jQuery object. - */ -var addContainer = function addContainer(ariaLive) { - ariaLive = ariaLive || 'polite'; - - var container = document.createElement('div'); - container.id = 'a11y-speak-' + ariaLive; - container.className = 'a11y-speak-region'; - - var screenReaderTextStyle = 'clip: rect(1px, 1px, 1px, 1px); position: absolute; height: 1px; width: 1px; overflow: hidden; word-wrap: normal;'; - container.setAttribute('style', screenReaderTextStyle); - container.setAttribute('aria-live', ariaLive); - container.setAttribute('aria-relevant', 'additions text'); - container.setAttribute('aria-atomic', 'true'); - - document.querySelector('body').appendChild(container); - return container; -}; - -exports.default = addContainer; \ No newline at end of file diff --git a/packages/a11y/build/clear.js b/packages/a11y/build/clear.js deleted file mode 100644 index 738fc7ac2e27e..0000000000000 --- a/packages/a11y/build/clear.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -/** - * Clear the a11y-speak-region elements. - */ -var clear = function clear() { - var regions = document.querySelectorAll('.a11y-speak-region'); - for (var i = 0; i < regions.length; i++) { - regions[i].textContent = ''; - } -}; - -exports.default = clear; \ No newline at end of file diff --git a/packages/a11y/build/filterMessage.js b/packages/a11y/build/filterMessage.js deleted file mode 100644 index 98be77adb39d1..0000000000000 --- a/packages/a11y/build/filterMessage.js +++ /dev/null @@ -1,35 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -var previousMessage = ''; - -/** - * Filter the message to be announced to the screenreader. - * - * @param {String} message The message to be announced. - * - * @returns {String} - */ -var filterMessage = function filterMessage(message) { - - /* - * Strip HTML tags (if any) from the message string. Ideally, messages should - * be simple strings, carefully crafted for specific use with A11ySpeak. - * When re-using already existing strings this will ensure simple HTML to be - * stripped out and replaced with a space. Browsers will collapse multiple - * spaces natively. - */ - message = message.replace(/<[^<>]+>/g, ' '); - - if (previousMessage === message) { - message += '\xA0'; - } - - previousMessage = message; - - return message; -}; - -exports.default = filterMessage; \ No newline at end of file diff --git a/packages/a11y/build/index.js b/packages/a11y/build/index.js deleted file mode 100644 index eb79740557ccb..0000000000000 --- a/packages/a11y/build/index.js +++ /dev/null @@ -1,67 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.speak = exports.setup = undefined; - -var _addContainer = require('./addContainer'); - -var _addContainer2 = _interopRequireDefault(_addContainer); - -var _clear = require('./clear'); - -var _clear2 = _interopRequireDefault(_clear); - -var _domReady = require('@wordpress/dom-ready'); - -var _domReady2 = _interopRequireDefault(_domReady); - -var _filterMessage = require('./filterMessage'); - -var _filterMessage2 = _interopRequireDefault(_filterMessage); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - * Create the live regions. - */ -var setup = exports.setup = function setup() { - var containerPolite = document.getElementById('a11y-speak-polite'); - var containerAssertive = document.getElementById('a11y-speak-assertive'); - - if (containerPolite === null) { - containerPolite = (0, _addContainer2.default)('polite'); - } - if (containerAssertive === null) { - containerAssertive = (0, _addContainer2.default)('assertive'); - } -}; - -/** - * Run setup on domReady. - */ -(0, _domReady2.default)(setup); - -/** - * Update the ARIA live notification area text node. - * - * @param {String} message The message to be announced by Assistive Technologies. - * @param {String} ariaLive Optional. The politeness level for aria-live. Possible values: - * polite or assertive. Default polite. - */ -var speak = exports.speak = function speak(message, ariaLive) { - // Clear previous messages to allow repeated strings being read out. - (0, _clear2.default)(); - - message = (0, _filterMessage2.default)(message); - - var containerPolite = document.getElementById('a11y-speak-polite'); - var containerAssertive = document.getElementById('a11y-speak-assertive'); - - if (containerAssertive && 'assertive' === ariaLive) { - containerAssertive.textContent = message; - } else if (containerPolite) { - containerPolite.textContent = message; - } -}; \ No newline at end of file diff --git a/packages/dom-ready/build-module/index.js b/packages/dom-ready/build-module/index.js deleted file mode 100644 index 74c49cbe35aab..0000000000000 --- a/packages/dom-ready/build-module/index.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Specify a function to execute when the DOM is fully loaded. - * - * @param {Function} callback A function to execute after the DOM is ready. - * - * @returns {void} - */ -var domReady = function domReady(callback) { - if (document.readyState === 'complete') { - return callback(); - } - - document.addEventListener('DOMContentLoaded', callback); -}; - -export default domReady; \ No newline at end of file diff --git a/packages/dom-ready/build/index.js b/packages/dom-ready/build/index.js deleted file mode 100644 index 3795bad776179..0000000000000 --- a/packages/dom-ready/build/index.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -/** - * Specify a function to execute when the DOM is fully loaded. - * - * @param {Function} callback A function to execute after the DOM is ready. - * - * @returns {void} - */ -var domReady = function domReady(callback) { - if (document.readyState === 'complete') { - return callback(); - } - - document.addEventListener('DOMContentLoaded', callback); -}; - -exports.default = domReady; \ No newline at end of file diff --git a/packages/hooks/build-module/createAddHook.js b/packages/hooks/build-module/createAddHook.js deleted file mode 100644 index 8144fe615b091..0000000000000 --- a/packages/hooks/build-module/createAddHook.js +++ /dev/null @@ -1,76 +0,0 @@ -import validateNamespace from './validateNamespace.js'; -import validateHookName from './validateHookName.js'; - -/** - * Returns a function which, when invoked, will add a hook. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * - * @return {Function} Function that adds a new hook. - */ -function createAddHook(hooks) { - /** - * Adds the hook to the appropriate hooks container. - * - * @param {string} hookName Name of hook to add - * @param {string} namespace The unique namespace identifying the callback in the form `vendor/plugin/function`. - * @param {Function} callback Function to call when the hook is run - * @param {?number} priority Priority of this hook (default=10) - */ - return function addHook(hookName, namespace, callback) { - var priority = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 10; - - - if (!validateHookName(hookName)) { - return; - } - - if (!validateNamespace(namespace)) { - return; - } - - if ('function' !== typeof callback) { - console.error('The hook callback must be a function.'); - return; - } - - // Validate numeric priority - if ('number' !== typeof priority) { - console.error('If specified, the hook priority must be a number.'); - return; - } - - var handler = { callback: callback, priority: priority, namespace: namespace }; - - if (hooks.hasOwnProperty(hookName)) { - // Find the correct insert index of the new hook. - var handlers = hooks[hookName].handlers; - var i = 0; - while (i < handlers.length) { - if (handlers[i].priority > priority) { - break; - } - i++; - } - // Insert (or append) the new hook. - handlers.splice(i, 0, handler); - // We may also be currently executing this hook. If the callback - // we're adding would come after the current callback, there's no - // problem; otherwise we need to increase the execution index of - // any other runs by 1 to account for the added element. - (hooks.__current || []).forEach(function (hookInfo) { - if (hookInfo.name === hookName && hookInfo.currentIndex >= i) { - hookInfo.currentIndex++; - } - }); - } else { - // This is the first hook of its type. - hooks[hookName] = { - handlers: [handler], - runs: 0 - }; - } - }; -} - -export default createAddHook; \ No newline at end of file diff --git a/packages/hooks/build-module/createCurrentHook.js b/packages/hooks/build-module/createCurrentHook.js deleted file mode 100644 index 18a4f71807102..0000000000000 --- a/packages/hooks/build-module/createCurrentHook.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Returns a function which, when invoked, will return the name of the - * currently running hook, or `null` if no hook of the given type is currently - * running. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * - * @return {Function} Function that returns the current hook. - */ -function createCurrentHook(hooks, returnFirstArg) { - /** - * Returns the name of the currently running hook, or `null` if no hook of - * the given type is currently running. - * - * @return {?string} The name of the currently running hook, or - * `null` if no hook is currently running. - */ - return function currentHook() { - if (!hooks.__current || !hooks.__current.length) { - return null; - } - - return hooks.__current[hooks.__current.length - 1].name; - }; -} - -export default createCurrentHook; \ No newline at end of file diff --git a/packages/hooks/build-module/createDidHook.js b/packages/hooks/build-module/createDidHook.js deleted file mode 100644 index f05807b59b749..0000000000000 --- a/packages/hooks/build-module/createDidHook.js +++ /dev/null @@ -1,29 +0,0 @@ -import validateHookName from './validateHookName.js'; - -/** - * Returns a function which, when invoked, will return the number of times a - * hook has been called. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * - * @return {Function} Function that returns a hook's call count. - */ -function createDidHook(hooks) { - /** - * Returns the number of times an action has been fired. - * - * @param {string} hookName The hook name to check. - * - * @return {number} The number of times the hook has run. - */ - return function didHook(hookName) { - - if (!validateHookName(hookName)) { - return; - } - - return hooks.hasOwnProperty(hookName) && hooks[hookName].runs ? hooks[hookName].runs : 0; - }; -} - -export default createDidHook; \ No newline at end of file diff --git a/packages/hooks/build-module/createDoingHook.js b/packages/hooks/build-module/createDoingHook.js deleted file mode 100644 index 7e7b4f09e5584..0000000000000 --- a/packages/hooks/build-module/createDoingHook.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Returns a function which, when invoked, will return whether a hook is - * currently being executed. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * - * @return {Function} Function that returns whether a hook is currently - * being executed. - */ -function createDoingHook(hooks) { - /** - * Returns whether a hook is currently being executed. - * - * @param {?string} hookName The name of the hook to check for. If - * omitted, will check for any hook being executed. - * - * @return {bool} Whether the hook is being executed. - */ - return function doingHook(hookName) { - // If the hookName was not passed, check for any current hook. - if ('undefined' === typeof hookName) { - return 'undefined' !== typeof hooks.__current[0]; - } - - // Return the __current hook. - return hooks.__current[0] ? hookName === hooks.__current[0].name : false; - }; -} - -export default createDoingHook; \ No newline at end of file diff --git a/packages/hooks/build-module/createHasHook.js b/packages/hooks/build-module/createHasHook.js deleted file mode 100644 index 7de143789e581..0000000000000 --- a/packages/hooks/build-module/createHasHook.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Returns a function which, when invoked, will return whether any handlers are - * attached to a particular hook. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * - * @return {Function} Function that returns whether any handlers are - * attached to a particular hook. - */ -function createHasHook(hooks) { - /** - * Returns how many handlers are attached for the given hook. - * - * @param {string} hookName The name of the hook to check for. - * - * @return {number} The number of handlers that are attached to - * the given hook. - */ - return function hasHook(hookName) { - return hooks.hasOwnProperty(hookName) ? hooks[hookName].handlers.length : 0; - }; -} - -export default createHasHook; \ No newline at end of file diff --git a/packages/hooks/build-module/createRemoveHook.js b/packages/hooks/build-module/createRemoveHook.js deleted file mode 100644 index fcd77a00eeb7c..0000000000000 --- a/packages/hooks/build-module/createRemoveHook.js +++ /dev/null @@ -1,76 +0,0 @@ -import validateNamespace from './validateNamespace.js'; -import validateHookName from './validateHookName.js'; - -/** - * Returns a function which, when invoked, will remove a specified hook or all - * hooks by the given name. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * @param {bool} removeAll Whether to remove all callbacks for a hookName, without regard to namespace. Used to create `removeAll*` functions. - * - * @return {Function} Function that removes hooks. - */ -function createRemoveHook(hooks, removeAll) { - /** - * Removes the specified callback (or all callbacks) from the hook with a - * given hookName and namespace. - * - * @param {string} hookName The name of the hook to modify. - * @param {string} namespace The unique namespace identifying the callback in the form `vendor/plugin/function`. - * - * @return {number} The number of callbacks removed. - */ - return function removeHook(hookName, namespace) { - - if (!validateHookName(hookName)) { - return; - } - - if (!removeAll && !validateNamespace(namespace)) { - return; - } - - // Bail if no hooks exist by this name - if (!hooks.hasOwnProperty(hookName)) { - return 0; - } - - var handlersRemoved = 0; - - if (removeAll) { - handlersRemoved = hooks[hookName].handlers.length; - hooks[hookName] = { - runs: hooks[hookName].runs, - handlers: [] - }; - } else { - // Try to find the specified callback to remove. - var handlers = hooks[hookName].handlers; - - var _loop = function _loop(i) { - if (handlers[i].namespace === namespace) { - handlers.splice(i, 1); - handlersRemoved++; - // This callback may also be part of a hook that is - // currently executing. If the callback we're removing - // comes after the current callback, there's no problem; - // otherwise we need to decrease the execution index of any - // other runs by 1 to account for the removed element. - (hooks.__current || []).forEach(function (hookInfo) { - if (hookInfo.name === hookName && hookInfo.currentIndex >= i) { - hookInfo.currentIndex--; - } - }); - } - }; - - for (var i = handlers.length - 1; i >= 0; i--) { - _loop(i); - } - } - - return handlersRemoved; - }; -} - -export default createRemoveHook; \ No newline at end of file diff --git a/packages/hooks/build-module/createRunHook.js b/packages/hooks/build-module/createRunHook.js deleted file mode 100644 index 982d8c86f12c1..0000000000000 --- a/packages/hooks/build-module/createRunHook.js +++ /dev/null @@ -1,74 +0,0 @@ -import validateHookName from './validateHookName.js'; - -/** - * Returns a function which, when invoked, will execute all callbacks - * registered to a hook of the specified type, optionally returning the final - * value of the call chain. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * @param {?bool} returnFirstArg Whether each hook callback is expected to - * return its first argument. - * - * @return {Function} Function that runs hook callbacks. - */ -function createRunHook(hooks, returnFirstArg) { - /** - * Runs all callbacks for the specified hook. - * - * @param {string} hookName The name of the hook to run. - * @param {...*} args Arguments to pass to the hook callbacks. - * - * @return {*} Return value of runner, if applicable. - */ - return function runHooks(hookName) { - - if (!validateHookName(hookName)) { - return; - } - - if (!hooks.hasOwnProperty(hookName)) { - hooks[hookName] = { - runs: 0, - handlers: [] - }; - } - - var handlers = hooks[hookName].handlers; - - for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; - } - - if (!handlers.length) { - return returnFirstArg ? args[0] : undefined; - } - - var hookInfo = { - name: hookName, - currentIndex: 0 - }; - - hooks.__current = hooks.__current || []; - hooks.__current.push(hookInfo); - hooks[hookName].runs++; - - var maybeReturnValue = args[0]; - - while (hookInfo.currentIndex < handlers.length) { - var handler = handlers[hookInfo.currentIndex]; - maybeReturnValue = handler.callback.apply(null, args); - if (returnFirstArg) { - args[0] = maybeReturnValue; - } - hookInfo.currentIndex++; - } - - hooks.__current.pop(); - - if (returnFirstArg) { - return maybeReturnValue; - } - }; -} - -export default createRunHook; \ No newline at end of file diff --git a/packages/hooks/build-module/hooks.js b/packages/hooks/build-module/hooks.js deleted file mode 100644 index a0967775f2a47..0000000000000 --- a/packages/hooks/build-module/hooks.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Contains the registered hooks, keyed by hook type. Each hook type is an - * array of objects with priority and callback of each registered hook. - */ -var HOOKS = { - actions: {}, - filters: {} -}; - -export default HOOKS; \ No newline at end of file diff --git a/packages/hooks/build-module/index.js b/packages/hooks/build-module/index.js deleted file mode 100644 index a61ccb23b9a9f..0000000000000 --- a/packages/hooks/build-module/index.js +++ /dev/null @@ -1,40 +0,0 @@ -import HOOKS from './hooks'; -import createAddHook from './createAddHook'; -import createRemoveHook from './createRemoveHook'; -import createHasHook from './createHasHook'; -import createRunHook from './createRunHook'; -import createCurrentHook from './createCurrentHook'; -import createDoingHook from './createDoingHook'; -import createDidHook from './createDidHook'; - -// Add action/filter functions. -export var addAction = createAddHook(HOOKS.actions); -export var addFilter = createAddHook(HOOKS.filters); - -// Remove action/filter functions. -export var removeAction = createRemoveHook(HOOKS.actions); -export var removeFilter = createRemoveHook(HOOKS.filters); - -// Has action/filter functions. -export var hasAction = createHasHook(HOOKS.actions); -export var hasFilter = createHasHook(HOOKS.filters); - -// Remove all actions/filters functions. -export var removeAllActions = createRemoveHook(HOOKS.actions, true); -export var removeAllFilters = createRemoveHook(HOOKS.filters, true); - -// Do action/apply filters functions. -export var doAction = createRunHook(HOOKS.actions); -export var applyFilters = createRunHook(HOOKS.filters, true); - -// Current action/filter functions. -export var currentAction = createCurrentHook(HOOKS.actions); -export var currentFilter = createCurrentHook(HOOKS.filters); - -// Doing action/filter: true while a hook is being run. -export var doingAction = createDoingHook(HOOKS.actions); -export var doingFilter = createDoingHook(HOOKS.filters); - -// Did action/filter functions. -export var didAction = createDidHook(HOOKS.actions); -export var didFilter = createDidHook(HOOKS.filters); \ No newline at end of file diff --git a/packages/hooks/build-module/validateHookName.js b/packages/hooks/build-module/validateHookName.js deleted file mode 100644 index df8ec8191b197..0000000000000 --- a/packages/hooks/build-module/validateHookName.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Validate a hookName string. - * - * @param {string} hookName The hook name to validate. Should be a non empty string containing - * only numbers, letters, dashes, periods and underscores. Also, - * the hook name cannot begin with `__`. - * - * @return {bool} Whether the hook name is valid. - */ -function validateHookName(hookName) { - - if ('string' !== typeof hookName || '' === hookName) { - console.error('The hook name must be a non-empty string.'); - return false; - } - - if (/^__/.test(hookName)) { - console.error('The hook name cannot begin with `__`.'); - return false; - } - - if (!/^[a-zA-Z][a-zA-Z0-9_.-]*$/.test(hookName)) { - console.error('The hook name can only contain numbers, letters, dashes, periods and underscores.'); - return false; - } - - return true; -} - -export default validateHookName; \ No newline at end of file diff --git a/packages/hooks/build-module/validateNamespace.js b/packages/hooks/build-module/validateNamespace.js deleted file mode 100644 index 1165942903948..0000000000000 --- a/packages/hooks/build-module/validateNamespace.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Validate a namespace string. - * - * @param {string} namespace The namespace to validate - should take the form - * `vendor/plugin/function`. - * - * @return {bool} Whether the namespace is valid. - */ -function validateNamespace(namespace) { - - if ('string' !== typeof namespace || '' === namespace) { - console.error('The namespace must be a non-empty string.'); - return false; - } - - if (!/^[a-zA-Z][a-zA-Z0-9_.-/]*$/.test(namespace)) { - console.error('The namespace can only contain numbers, letters, dashes, periods and underscores, plus the forward slash dividing slug and description in the namespace.'); - return false; - } - - if (!/^[a-zA-Z][a-zA-Z0-9_.-]*\/[a-zA-Z][a-zA-Z0-9_.-]*\/[a-zA-Z][a-zA-Z0-9_.-]*$/.test(namespace)) { - console.error('The namespace must take the form `vendor/plugin/function`.'); - return false; - } - - return true; -} - -export default validateNamespace; \ No newline at end of file diff --git a/packages/hooks/build/createAddHook.js b/packages/hooks/build/createAddHook.js deleted file mode 100644 index 445eb93a0887d..0000000000000 --- a/packages/hooks/build/createAddHook.js +++ /dev/null @@ -1,89 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _validateNamespace = require('./validateNamespace.js'); - -var _validateNamespace2 = _interopRequireDefault(_validateNamespace); - -var _validateHookName = require('./validateHookName.js'); - -var _validateHookName2 = _interopRequireDefault(_validateHookName); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - * Returns a function which, when invoked, will add a hook. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * - * @return {Function} Function that adds a new hook. - */ -function createAddHook(hooks) { - /** - * Adds the hook to the appropriate hooks container. - * - * @param {string} hookName Name of hook to add - * @param {string} namespace The unique namespace identifying the callback in the form `vendor/plugin/function`. - * @param {Function} callback Function to call when the hook is run - * @param {?number} priority Priority of this hook (default=10) - */ - return function addHook(hookName, namespace, callback) { - var priority = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 10; - - - if (!(0, _validateHookName2.default)(hookName)) { - return; - } - - if (!(0, _validateNamespace2.default)(namespace)) { - return; - } - - if ('function' !== typeof callback) { - console.error('The hook callback must be a function.'); - return; - } - - // Validate numeric priority - if ('number' !== typeof priority) { - console.error('If specified, the hook priority must be a number.'); - return; - } - - var handler = { callback: callback, priority: priority, namespace: namespace }; - - if (hooks.hasOwnProperty(hookName)) { - // Find the correct insert index of the new hook. - var handlers = hooks[hookName].handlers; - var i = 0; - while (i < handlers.length) { - if (handlers[i].priority > priority) { - break; - } - i++; - } - // Insert (or append) the new hook. - handlers.splice(i, 0, handler); - // We may also be currently executing this hook. If the callback - // we're adding would come after the current callback, there's no - // problem; otherwise we need to increase the execution index of - // any other runs by 1 to account for the added element. - (hooks.__current || []).forEach(function (hookInfo) { - if (hookInfo.name === hookName && hookInfo.currentIndex >= i) { - hookInfo.currentIndex++; - } - }); - } else { - // This is the first hook of its type. - hooks[hookName] = { - handlers: [handler], - runs: 0 - }; - } - }; -} - -exports.default = createAddHook; \ No newline at end of file diff --git a/packages/hooks/build/createCurrentHook.js b/packages/hooks/build/createCurrentHook.js deleted file mode 100644 index f2de16dce9aae..0000000000000 --- a/packages/hooks/build/createCurrentHook.js +++ /dev/null @@ -1,32 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -/** - * Returns a function which, when invoked, will return the name of the - * currently running hook, or `null` if no hook of the given type is currently - * running. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * - * @return {Function} Function that returns the current hook. - */ -function createCurrentHook(hooks, returnFirstArg) { - /** - * Returns the name of the currently running hook, or `null` if no hook of - * the given type is currently running. - * - * @return {?string} The name of the currently running hook, or - * `null` if no hook is currently running. - */ - return function currentHook() { - if (!hooks.__current || !hooks.__current.length) { - return null; - } - - return hooks.__current[hooks.__current.length - 1].name; - }; -} - -exports.default = createCurrentHook; \ No newline at end of file diff --git a/packages/hooks/build/createDidHook.js b/packages/hooks/build/createDidHook.js deleted file mode 100644 index bb18bd321bac7..0000000000000 --- a/packages/hooks/build/createDidHook.js +++ /dev/null @@ -1,39 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _validateHookName = require('./validateHookName.js'); - -var _validateHookName2 = _interopRequireDefault(_validateHookName); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - * Returns a function which, when invoked, will return the number of times a - * hook has been called. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * - * @return {Function} Function that returns a hook's call count. - */ -function createDidHook(hooks) { - /** - * Returns the number of times an action has been fired. - * - * @param {string} hookName The hook name to check. - * - * @return {number} The number of times the hook has run. - */ - return function didHook(hookName) { - - if (!(0, _validateHookName2.default)(hookName)) { - return; - } - - return hooks.hasOwnProperty(hookName) && hooks[hookName].runs ? hooks[hookName].runs : 0; - }; -} - -exports.default = createDidHook; \ No newline at end of file diff --git a/packages/hooks/build/createDoingHook.js b/packages/hooks/build/createDoingHook.js deleted file mode 100644 index a46165ae108fe..0000000000000 --- a/packages/hooks/build/createDoingHook.js +++ /dev/null @@ -1,35 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -/** - * Returns a function which, when invoked, will return whether a hook is - * currently being executed. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * - * @return {Function} Function that returns whether a hook is currently - * being executed. - */ -function createDoingHook(hooks) { - /** - * Returns whether a hook is currently being executed. - * - * @param {?string} hookName The name of the hook to check for. If - * omitted, will check for any hook being executed. - * - * @return {bool} Whether the hook is being executed. - */ - return function doingHook(hookName) { - // If the hookName was not passed, check for any current hook. - if ('undefined' === typeof hookName) { - return 'undefined' !== typeof hooks.__current[0]; - } - - // Return the __current hook. - return hooks.__current[0] ? hookName === hooks.__current[0].name : false; - }; -} - -exports.default = createDoingHook; \ No newline at end of file diff --git a/packages/hooks/build/createHasHook.js b/packages/hooks/build/createHasHook.js deleted file mode 100644 index 03622df5bde1b..0000000000000 --- a/packages/hooks/build/createHasHook.js +++ /dev/null @@ -1,29 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -/** - * Returns a function which, when invoked, will return whether any handlers are - * attached to a particular hook. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * - * @return {Function} Function that returns whether any handlers are - * attached to a particular hook. - */ -function createHasHook(hooks) { - /** - * Returns how many handlers are attached for the given hook. - * - * @param {string} hookName The name of the hook to check for. - * - * @return {number} The number of handlers that are attached to - * the given hook. - */ - return function hasHook(hookName) { - return hooks.hasOwnProperty(hookName) ? hooks[hookName].handlers.length : 0; - }; -} - -exports.default = createHasHook; \ No newline at end of file diff --git a/packages/hooks/build/createRemoveHook.js b/packages/hooks/build/createRemoveHook.js deleted file mode 100644 index 731154752a841..0000000000000 --- a/packages/hooks/build/createRemoveHook.js +++ /dev/null @@ -1,89 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _validateNamespace = require('./validateNamespace.js'); - -var _validateNamespace2 = _interopRequireDefault(_validateNamespace); - -var _validateHookName = require('./validateHookName.js'); - -var _validateHookName2 = _interopRequireDefault(_validateHookName); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - * Returns a function which, when invoked, will remove a specified hook or all - * hooks by the given name. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * @param {bool} removeAll Whether to remove all callbacks for a hookName, without regard to namespace. Used to create `removeAll*` functions. - * - * @return {Function} Function that removes hooks. - */ -function createRemoveHook(hooks, removeAll) { - /** - * Removes the specified callback (or all callbacks) from the hook with a - * given hookName and namespace. - * - * @param {string} hookName The name of the hook to modify. - * @param {string} namespace The unique namespace identifying the callback in the form `vendor/plugin/function`. - * - * @return {number} The number of callbacks removed. - */ - return function removeHook(hookName, namespace) { - - if (!(0, _validateHookName2.default)(hookName)) { - return; - } - - if (!removeAll && !(0, _validateNamespace2.default)(namespace)) { - return; - } - - // Bail if no hooks exist by this name - if (!hooks.hasOwnProperty(hookName)) { - return 0; - } - - var handlersRemoved = 0; - - if (removeAll) { - handlersRemoved = hooks[hookName].handlers.length; - hooks[hookName] = { - runs: hooks[hookName].runs, - handlers: [] - }; - } else { - // Try to find the specified callback to remove. - var handlers = hooks[hookName].handlers; - - var _loop = function _loop(i) { - if (handlers[i].namespace === namespace) { - handlers.splice(i, 1); - handlersRemoved++; - // This callback may also be part of a hook that is - // currently executing. If the callback we're removing - // comes after the current callback, there's no problem; - // otherwise we need to decrease the execution index of any - // other runs by 1 to account for the removed element. - (hooks.__current || []).forEach(function (hookInfo) { - if (hookInfo.name === hookName && hookInfo.currentIndex >= i) { - hookInfo.currentIndex--; - } - }); - } - }; - - for (var i = handlers.length - 1; i >= 0; i--) { - _loop(i); - } - } - - return handlersRemoved; - }; -} - -exports.default = createRemoveHook; \ No newline at end of file diff --git a/packages/hooks/build/createRunHook.js b/packages/hooks/build/createRunHook.js deleted file mode 100644 index 6e7ad94dffa45..0000000000000 --- a/packages/hooks/build/createRunHook.js +++ /dev/null @@ -1,84 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _validateHookName = require('./validateHookName.js'); - -var _validateHookName2 = _interopRequireDefault(_validateHookName); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - * Returns a function which, when invoked, will execute all callbacks - * registered to a hook of the specified type, optionally returning the final - * value of the call chain. - * - * @param {Object} hooks Stored hooks, keyed by hook name. - * @param {?bool} returnFirstArg Whether each hook callback is expected to - * return its first argument. - * - * @return {Function} Function that runs hook callbacks. - */ -function createRunHook(hooks, returnFirstArg) { - /** - * Runs all callbacks for the specified hook. - * - * @param {string} hookName The name of the hook to run. - * @param {...*} args Arguments to pass to the hook callbacks. - * - * @return {*} Return value of runner, if applicable. - */ - return function runHooks(hookName) { - - if (!(0, _validateHookName2.default)(hookName)) { - return; - } - - if (!hooks.hasOwnProperty(hookName)) { - hooks[hookName] = { - runs: 0, - handlers: [] - }; - } - - var handlers = hooks[hookName].handlers; - - for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; - } - - if (!handlers.length) { - return returnFirstArg ? args[0] : undefined; - } - - var hookInfo = { - name: hookName, - currentIndex: 0 - }; - - hooks.__current = hooks.__current || []; - hooks.__current.push(hookInfo); - hooks[hookName].runs++; - - var maybeReturnValue = args[0]; - - while (hookInfo.currentIndex < handlers.length) { - var handler = handlers[hookInfo.currentIndex]; - maybeReturnValue = handler.callback.apply(null, args); - if (returnFirstArg) { - args[0] = maybeReturnValue; - } - hookInfo.currentIndex++; - } - - hooks.__current.pop(); - - if (returnFirstArg) { - return maybeReturnValue; - } - }; -} - -exports.default = createRunHook; \ No newline at end of file diff --git a/packages/hooks/build/hooks.js b/packages/hooks/build/hooks.js deleted file mode 100644 index 586fd6af35971..0000000000000 --- a/packages/hooks/build/hooks.js +++ /dev/null @@ -1,15 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -/** - * Contains the registered hooks, keyed by hook type. Each hook type is an - * array of objects with priority and callback of each registered hook. - */ -var HOOKS = { - actions: {}, - filters: {} -}; - -exports.default = HOOKS; \ No newline at end of file diff --git a/packages/hooks/build/index.js b/packages/hooks/build/index.js deleted file mode 100644 index fe54cd482bb4f..0000000000000 --- a/packages/hooks/build/index.js +++ /dev/null @@ -1,72 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.didFilter = exports.didAction = exports.doingFilter = exports.doingAction = exports.currentFilter = exports.currentAction = exports.applyFilters = exports.doAction = exports.removeAllFilters = exports.removeAllActions = exports.hasFilter = exports.hasAction = exports.removeFilter = exports.removeAction = exports.addFilter = exports.addAction = undefined; - -var _hooks = require('./hooks'); - -var _hooks2 = _interopRequireDefault(_hooks); - -var _createAddHook = require('./createAddHook'); - -var _createAddHook2 = _interopRequireDefault(_createAddHook); - -var _createRemoveHook = require('./createRemoveHook'); - -var _createRemoveHook2 = _interopRequireDefault(_createRemoveHook); - -var _createHasHook = require('./createHasHook'); - -var _createHasHook2 = _interopRequireDefault(_createHasHook); - -var _createRunHook = require('./createRunHook'); - -var _createRunHook2 = _interopRequireDefault(_createRunHook); - -var _createCurrentHook = require('./createCurrentHook'); - -var _createCurrentHook2 = _interopRequireDefault(_createCurrentHook); - -var _createDoingHook = require('./createDoingHook'); - -var _createDoingHook2 = _interopRequireDefault(_createDoingHook); - -var _createDidHook = require('./createDidHook'); - -var _createDidHook2 = _interopRequireDefault(_createDidHook); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// Add action/filter functions. -var addAction = exports.addAction = (0, _createAddHook2.default)(_hooks2.default.actions); -var addFilter = exports.addFilter = (0, _createAddHook2.default)(_hooks2.default.filters); - -// Remove action/filter functions. -var removeAction = exports.removeAction = (0, _createRemoveHook2.default)(_hooks2.default.actions); -var removeFilter = exports.removeFilter = (0, _createRemoveHook2.default)(_hooks2.default.filters); - -// Has action/filter functions. -var hasAction = exports.hasAction = (0, _createHasHook2.default)(_hooks2.default.actions); -var hasFilter = exports.hasFilter = (0, _createHasHook2.default)(_hooks2.default.filters); - -// Remove all actions/filters functions. -var removeAllActions = exports.removeAllActions = (0, _createRemoveHook2.default)(_hooks2.default.actions, true); -var removeAllFilters = exports.removeAllFilters = (0, _createRemoveHook2.default)(_hooks2.default.filters, true); - -// Do action/apply filters functions. -var doAction = exports.doAction = (0, _createRunHook2.default)(_hooks2.default.actions); -var applyFilters = exports.applyFilters = (0, _createRunHook2.default)(_hooks2.default.filters, true); - -// Current action/filter functions. -var currentAction = exports.currentAction = (0, _createCurrentHook2.default)(_hooks2.default.actions); -var currentFilter = exports.currentFilter = (0, _createCurrentHook2.default)(_hooks2.default.filters); - -// Doing action/filter: true while a hook is being run. -var doingAction = exports.doingAction = (0, _createDoingHook2.default)(_hooks2.default.actions); -var doingFilter = exports.doingFilter = (0, _createDoingHook2.default)(_hooks2.default.filters); - -// Did action/filter functions. -var didAction = exports.didAction = (0, _createDidHook2.default)(_hooks2.default.actions); -var didFilter = exports.didFilter = (0, _createDidHook2.default)(_hooks2.default.filters); \ No newline at end of file diff --git a/packages/hooks/build/validateHookName.js b/packages/hooks/build/validateHookName.js deleted file mode 100644 index 3b85b5279a858..0000000000000 --- a/packages/hooks/build/validateHookName.js +++ /dev/null @@ -1,35 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -/** - * Validate a hookName string. - * - * @param {string} hookName The hook name to validate. Should be a non empty string containing - * only numbers, letters, dashes, periods and underscores. Also, - * the hook name cannot begin with `__`. - * - * @return {bool} Whether the hook name is valid. - */ -function validateHookName(hookName) { - - if ('string' !== typeof hookName || '' === hookName) { - console.error('The hook name must be a non-empty string.'); - return false; - } - - if (/^__/.test(hookName)) { - console.error('The hook name cannot begin with `__`.'); - return false; - } - - if (!/^[a-zA-Z][a-zA-Z0-9_.-]*$/.test(hookName)) { - console.error('The hook name can only contain numbers, letters, dashes, periods and underscores.'); - return false; - } - - return true; -} - -exports.default = validateHookName; \ No newline at end of file diff --git a/packages/hooks/build/validateNamespace.js b/packages/hooks/build/validateNamespace.js deleted file mode 100644 index 8e844098ab1c9..0000000000000 --- a/packages/hooks/build/validateNamespace.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -/** - * Validate a namespace string. - * - * @param {string} namespace The namespace to validate - should take the form - * `vendor/plugin/function`. - * - * @return {bool} Whether the namespace is valid. - */ -function validateNamespace(namespace) { - - if ('string' !== typeof namespace || '' === namespace) { - console.error('The namespace must be a non-empty string.'); - return false; - } - - if (!/^[a-zA-Z][a-zA-Z0-9]*$/.test(namespace)) { - console.error('The namespace can only contain numbers, letters, dashes, periods and underscores.'); - return false; - } - - return true; -} - -exports.default = validateNamespace; diff --git a/packages/url/build-browser/index.js b/packages/url/build-browser/index.js deleted file mode 100644 index 3ee6190b05a88..0000000000000 --- a/packages/url/build-browser/index.js +++ /dev/null @@ -1,36 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _extends2 = require('babel-runtime/helpers/extends'); - -var _extends3 = _interopRequireDefault(_extends2); - -exports.addQueryArgs = addQueryArgs; - -var _url = require('url'); - -var _querystring = require('querystring'); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - * Appends arguments to the query string of the url - * - * @param {String} url URL - * @param {Object} args Query Args - * - * @return {String} Updated URL - */ -/** - * External dependencies - */ -function addQueryArgs(url, args) { - var parsedURL = (0, _url.parse)(url, true); - var query = (0, _extends3.default)({}, parsedURL.query, args); - delete parsedURL.search; - - return (0, _url.format)((0, _extends3.default)({}, parsedURL, { query: query })); -} \ No newline at end of file diff --git a/packages/url/build-browser/test/index.test.js b/packages/url/build-browser/test/index.test.js deleted file mode 100644 index b772adfed3466..0000000000000 --- a/packages/url/build-browser/test/index.test.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict'; - -var _ = require('../'); - -describe('addQueryArgs', function () { - test('should append args to an URL without query string', function () { - var url = 'https://andalouses.com/beach'; - var args = { sun: 'true', sand: 'false' }; - - expect((0, _.addQueryArgs)(url, args)).toBe('https://andalouses.com/beach?sun=true&sand=false'); - }); - - test('should append args to an URL with query string', function () { - var url = 'https://andalouses.com/beach?night=false'; - var args = { sun: 'true', sand: 'false' }; - - expect((0, _.addQueryArgs)(url, args)).toBe('https://andalouses.com/beach?night=false&sun=true&sand=false'); - }); -}); /** - * Internal Dependencies - */ \ No newline at end of file diff --git a/packages/url/build-module/index.js b/packages/url/build-module/index.js deleted file mode 100644 index 9fde0cc29e7c8..0000000000000 --- a/packages/url/build-module/index.js +++ /dev/null @@ -1,23 +0,0 @@ -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -/** - * External dependencies - */ -import { parse, format } from 'url'; -import { parse as parseQueryString, stringify } from 'querystring'; - -/** - * Appends arguments to the query string of the url - * - * @param {String} url URL - * @param {Object} args Query Args - * - * @return {String} Updated URL - */ -export function addQueryArgs(url, args) { - var parsedURL = parse(url, true); - var query = _extends({}, parsedURL.query, args); - delete parsedURL.search; - - return format(_extends({}, parsedURL, { query: query })); -} \ No newline at end of file diff --git a/packages/url/build/index.js b/packages/url/build/index.js deleted file mode 100644 index ae914b643d140..0000000000000 --- a/packages/url/build/index.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /** - * External dependencies - */ - - -exports.addQueryArgs = addQueryArgs; - -var _url = require('url'); - -var _querystring = require('querystring'); - -/** - * Appends arguments to the query string of the url - * - * @param {String} url URL - * @param {Object} args Query Args - * - * @return {String} Updated URL - */ -function addQueryArgs(url, args) { - var parsedURL = (0, _url.parse)(url, true); - var query = _extends({}, parsedURL.query, args); - delete parsedURL.search; - - return (0, _url.format)(_extends({}, parsedURL, { query: query })); -} \ No newline at end of file From d62ecb778b95421fda0a069ddc52ac12a5480e73 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Sun, 22 Oct 2017 12:05:53 -0400 Subject: [PATCH 218/393] Publish - @wordpress/a11y@0.1.0-beta.6 - @wordpress/dom-ready@0.1.0-beta.6 - @wordpress/hooks@0.1.0-beta.5 - @wordpress/url@0.1.0-beta.5 --- packages/a11y/package.json | 4 ++-- packages/dom-ready/package.json | 2 +- packages/hooks/package.json | 2 +- packages/url/package.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/a11y/package.json b/packages/a11y/package.json index ce41cd87ba3ab..a4a28eaef2d0a 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/a11y", - "version": "0.1.0-beta.5", + "version": "0.1.0-beta.6", "description": "Collection of JS modules and tools for WordPress development", "homepage": "https://github.com/WordPress/packages/tree/master/packages/a11y/README.md", "author": "WordPress", @@ -18,7 +18,7 @@ "url": "https://github.com/WordPress/packages/issues" }, "dependencies": { - "@wordpress/dom-ready": "^0.1.0-beta.5" + "@wordpress/dom-ready": "^0.1.0-beta.6" }, "publishConfig": { "access": "public" diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index fa0f781aece3b..639b832895d38 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom-ready", - "version": "0.1.0-beta.5", + "version": "0.1.0-beta.6", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" diff --git a/packages/hooks/package.json b/packages/hooks/package.json index a936c9899cf4d..22f0a140aa8d6 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/hooks", - "version": "0.1.0-beta.4", + "version": "0.1.0-beta.5", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" diff --git a/packages/url/package.json b/packages/url/package.json index 52387de3ab52b..ad7657e8efa8f 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/url", - "version": "0.1.0-beta.4", + "version": "0.1.0-beta.5", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" From 12b5c6cf23564bb4c9215769a94dcd1e160a37f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Mon, 27 Nov 2017 17:03:17 +0100 Subject: [PATCH 219/393] Hooks: Update hooks public API to make it possible to apply to wp.hooks directly (#45) --- packages/hooks/README.md | 5 +- packages/hooks/src/createHooks.js | 40 +++ packages/hooks/src/index.js | 72 ++-- packages/hooks/src/test/index.test.js | 468 +++++++++++++------------- 4 files changed, 325 insertions(+), 260 deletions(-) create mode 100644 packages/hooks/src/createHooks.js diff --git a/packages/hooks/README.md b/packages/hooks/README.md index 727af4d71f0b6..625a7be235a42 100644 --- a/packages/hooks/README.md +++ b/packages/hooks/README.md @@ -18,6 +18,7 @@ A lightweight & efficient filter and action manager. ### API Usage +* `createHooks()` * `addAction( 'hookName', 'functionName', callback, priority )` * `addFilter( 'hookName', 'functionName', callback, priority )` * `removeAction( 'hookName', 'functionName' )` @@ -32,9 +33,11 @@ A lightweight & efficient filter and action manager. * `didFilter( 'hookName' )` * `hasAction( 'hookName' )` * `hasFilter( 'hookName' )` +* `actions` +* `filters` Hooks can be added to an object via composition: -`import createHooks from '../';` +`import { createHooks } from '@wordpress/hooks';` `myObject.hooks = createHooks();` diff --git a/packages/hooks/src/createHooks.js b/packages/hooks/src/createHooks.js new file mode 100644 index 0000000000000..58d4749a3e01b --- /dev/null +++ b/packages/hooks/src/createHooks.js @@ -0,0 +1,40 @@ +import createAddHook from './createAddHook'; +import createRemoveHook from './createRemoveHook'; +import createHasHook from './createHasHook'; +import createRunHook from './createRunHook'; +import createCurrentHook from './createCurrentHook'; +import createDoingHook from './createDoingHook'; +import createDidHook from './createDidHook'; + +/** + * Returns an instance of the hooks object. + * + * @return {Object} Object that contains all hooks. + */ +function createHooks() { + const actions = {}; + const filters = {}; + + return { + addAction: createAddHook( actions ), + addFilter: createAddHook( filters ), + removeAction: createRemoveHook( actions ), + removeFilter: createRemoveHook( filters ), + hasAction: createHasHook( actions ), + hasFilter: createHasHook( filters ), + removeAllActions: createRemoveHook( actions, true ), + removeAllFilters: createRemoveHook( filters, true ), + doAction: createRunHook( actions ), + applyFilters: createRunHook( filters, true ), + currentAction: createCurrentHook( actions ), + currentFilter: createCurrentHook( filters ), + doingAction: createDoingHook( actions ), + doingFilter: createDoingHook( filters ), + didAction: createDidHook( actions ), + didFilter: createDidHook( filters ), + actions: actions, + filters: filters, + }; +} + +export default createHooks; diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index cfd22f088f444..508e27fc0c140 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -1,34 +1,44 @@ -import createAddHook from './createAddHook'; -import createRemoveHook from './createRemoveHook'; -import createHasHook from './createHasHook'; -import createRunHook from './createRunHook'; -import createCurrentHook from './createCurrentHook'; -import createDoingHook from './createDoingHook'; -import createDidHook from './createDidHook'; +import createHooks from './createHooks'; -function createHooks() { - const actions = {}; - const filters = {}; +const { + addAction, + addFilter, + removeAction, + removeFilter, + hasAction, + hasFilter, + removeAllActions, + removeAllFilters, + doAction, + applyFilters, + currentAction, + currentFilter, + doingAction, + doingFilter, + didAction, + didFilter, + actions, + filters, +} = createHooks(); - return { - addAction: createAddHook( actions ), - addFilter: createAddHook( filters ), - removeAction: createRemoveHook( actions ), - removeFilter: createRemoveHook( filters ), - hasAction: createHasHook( actions ), - hasFilter: createHasHook( filters ), - removeAllActions: createRemoveHook( actions, true ), - removeAllFilters: createRemoveHook( filters, true ), - doAction: createRunHook( actions ), - applyFilters: createRunHook( filters, true ), - currentAction: createCurrentHook( actions ), - currentFilter: createCurrentHook( filters ), - doingAction: createDoingHook( actions ), - doingFilter: createDoingHook( filters ), - didAction: createDidHook( actions ), - didFilter: createDidHook( filters ), - actions: actions, - filters: filters, - }; +export { + createHooks, + addAction, + addFilter, + removeAction, + removeFilter, + hasAction, + hasFilter, + removeAllActions, + removeAllFilters, + doAction, + applyFilters, + currentAction, + currentFilter, + doingAction, + doingFilter, + didAction, + didFilter, + actions, + filters, }; -export default createHooks; diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 06a9bb98063c2..98626936fb9b3 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -3,10 +3,27 @@ /** * Internal dependencies */ -import createHooks from '../'; - -const testObject = {}; -testObject.hooks = createHooks(); +import { + createHooks, + addAction, + addFilter, + removeAction, + removeFilter, + hasAction, + hasFilter, + removeAllActions, + removeAllFilters, + doAction, + applyFilters, + currentAction, + currentFilter, + doingAction, + doingFilter, + didAction, + didFilter, + actions, + filters, +} from '../'; function filter_a( str ) { return str + 'a'; @@ -21,17 +38,17 @@ function filter_c( str ) { } function filter_b_removes_self( str ) { - testObject.hooks.removeFilter( 'test.filter', 'my_callback_filter_b_removes_self' ); + removeFilter( 'test.filter', 'my_callback_filter_b_removes_self' ); return str + 'b'; } function filter_removes_b( str ) { - testObject.hooks.removeFilter( 'test.filter', 'my_callback_filter_b' ); + removeFilter( 'test.filter', 'my_callback_filter_b' ); return str; } function filter_removes_c( str ) { - testObject.hooks.removeFilter( 'test.filter', 'my_callback_filter_c' ); + removeFilter( 'test.filter', 'my_callback_filter_c' ); return str; } @@ -51,10 +68,10 @@ const consoleErrorOriginal = console.error; beforeEach( () => { window.actionValue = ''; - // Reset state in between tests (clear all callbacks, `testObject.hooks.didAction` counts, + // Reset state in between tests (clear all callbacks, `didAction` counts, // etc.) Just reseting actions and filters is not enough // because the internal functions have references to the original objects. - [ testObject.hooks.actions, testObject.hooks.filters ].forEach( hooks => { + [ actions, filters ].forEach( hooks => { for ( const k in hooks ) { delete hooks[ k ]; } @@ -67,150 +84,152 @@ afterEach( () => { } ); test( 'hooks can be instantiated', () => { - expect( typeof testObject.hooks ).toEqual( 'object' ); + const hooks = createHooks(); + + expect( typeof hooks ).toBe( 'object' ); } ); test( 'run a filter with no callbacks', () => { - expect( testObject.hooks.applyFilters( 'test.filter', 42 ) ).toEqual( 42 ); + expect( applyFilters( 'test.filter', 42 ) ).toBe( 42 ); } ); test( 'add and remove a filter', () => { - testObject.hooks.addFilter( 'test.filter', 'my_callback', filter_a ); - expect( testObject.hooks.removeAllFilters( 'test.filter' ) ).toEqual( 1 ); - expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); - expect( testObject.hooks.removeAllFilters( 'test.filter' ) ).toEqual( 0 ); + addFilter( 'test.filter', 'my_callback', filter_a ); + expect( removeAllFilters( 'test.filter' ) ).toBe( 1 ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); + expect( removeAllFilters( 'test.filter' ) ).toBe( 0 ); } ); test( 'add a filter and run it', () => { - testObject.hooks.addFilter( 'test.filter', 'my_callback', filter_a ); - expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testa' ); + addFilter( 'test.filter', 'my_callback', filter_a ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testa' ); } ); test( 'add 2 filters in a row and run them', () => { - testObject.hooks.addFilter( 'test.filter', 'my_callback', filter_a ); - testObject.hooks.addFilter( 'test.filter', 'my_callback', filter_b ); - expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); + addFilter( 'test.filter', 'my_callback', filter_a ); + addFilter( 'test.filter', 'my_callback', filter_b ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); } ); test( 'remove a non-existent filter', () => { - expect( testObject.hooks.removeFilter( 'test.filter', 'my_callback', filter_a ) ).toEqual( 0 ); - expect( testObject.hooks.removeAllFilters( 'test.filter' ) ).toEqual( 0 ); + expect( removeFilter( 'test.filter', 'my_callback', filter_a ) ).toBe( 0 ); + expect( removeAllFilters( 'test.filter' ) ).toBe( 0 ); } ); test( 'remove an invalid namespace from a filter', () => { - expect( testObject.hooks.removeFilter( 'test.filter', 42 ) ).toEqual( undefined ); + expect( removeFilter( 'test.filter', 42 ) ).toBe( undefined ); expect( console.error ).toHaveBeenCalledWith( 'The namespace must be a non-empty string.' ); } ); test( 'cannot add filters with non-string hook names', () => { - testObject.hooks.addFilter( 42, 'my_callback', () => null ); + addFilter( 42, 'my_callback', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The hook name must be a non-empty string.' ); } ); test( 'cannot add filters with empty-string hook names', () => { - testObject.hooks.addFilter( '', 'my_callback', () => null ); + addFilter( '', 'my_callback', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The hook name must be a non-empty string.' ); } ); test( 'cannot add filters with empty-string namespaces', () => { - testObject.hooks.addFilter( 'hook_name', '', () => null ); + addFilter( 'hook_name', '', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The namespace must be a non-empty string.' ); } ); test( 'cannot add filters with invalid namespaces', () => { - testObject.hooks.addFilter( 'hook_name', 'invalid_%&name', () => null ); + addFilter( 'hook_name', 'invalid_%&name', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The namespace can only contain numbers, letters, dashes, periods and underscores.' ); } ); test( 'cannot add filters with namespaces missing a functionDescription', () => { - testObject.hooks.addFilter( 'hook_name', 'invalid_name/', () => null ); + addFilter( 'hook_name', 'invalid_name/', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The namespace can only contain numbers, letters, dashes, periods and underscores.' ); } ); test( 'Can add filters with dashes in namespaces', () => { - testObject.hooks.addFilter( 'hook_name', 'with-dashes', () => null ); + addFilter( 'hook_name', 'with-dashes', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); } ); test( 'Can add filters with capitals in namespaces', () => { - testObject.hooks.addFilter( 'hook_name', 'my_name-OhNoaction', () => null ); + addFilter( 'hook_name', 'my_name-OhNoaction', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); } ); test( 'Can add filters with capitals in hookName', () => { - testObject.hooks.addFilter( 'hookName', 'action', () => null ); + addFilter( 'hookName', 'action', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); } ); test( 'Can add filters with periods in namespaces', () => { - testObject.hooks.addFilter( 'hook_name', 'ok.action', () => null ); + addFilter( 'hook_name', 'ok.action', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); } ); test( 'Can add filters with periods in hookName', () => { - testObject.hooks.addFilter( 'hook.name', 'action', () => null ); + addFilter( 'hook.name', 'action', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); } ); test( 'cannot add filters with invalid namespaces', () => { - testObject.hooks.addFilter( 'hook_name', '/invalid_name', () => null ); + addFilter( 'hook_name', '/invalid_name', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The namespace can only contain numbers, letters, dashes, periods and underscores.' ); } ); test( 'cannot add filters named with __ prefix', () => { - testObject.hooks.addFilter( '__test', 'my_callback', () => null ); + addFilter( '__test', 'my_callback', () => null ); expect( console.error ).toHaveBeenCalledWith( 'The hook name cannot begin with `__`.' ); } ); test( 'cannot add filters with non-function callbacks', () => { - testObject.hooks.addFilter( 'test', 'my_callback', '42' ); + addFilter( 'test', 'my_callback', '42' ); expect( console.error ).toHaveBeenCalledWith( 'The hook callback must be a function.' ); } ); test( 'cannot add filters with non-numeric priorities', () => { - testObject.hooks.addFilter( 'test', 'my_callback', () => null, '42' ); + addFilter( 'test', 'my_callback', () => null, '42' ); expect( console.error ).toHaveBeenCalledWith( 'If specified, the hook priority must be a number.' ); } ); test( 'cannot run filters with non-string names', () => { - expect( testObject.hooks.applyFilters( () => {}, 42 ) ).toBe( undefined ); + expect( applyFilters( () => {}, 42 ) ).toBe( undefined ); expect( console.error ).toHaveBeenCalledWith( 'The hook name must be a non-empty string.' ); } ); test( 'cannot run filters named with __ prefix', () => { - expect( testObject.hooks.applyFilters( '__test', 42 ) ).toBe( undefined ); + expect( applyFilters( '__test', 42 ) ).toBe( undefined ); expect( console.error ).toHaveBeenCalledWith( 'The hook name cannot begin with `__`.' ); } ); test( 'add 3 filters with different priorities and run them', () => { - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_a', filter_a ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 2 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 8 ); - expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testbca' ); + addFilter( 'test.filter', 'my_callback_filter_a', filter_a ); + addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 2 ); + addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 8 ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testbca' ); } ); test( 'filters with the same and different priorities', () => { @@ -224,36 +243,36 @@ test( 'filters with the same and different priorities', () => { } ); } ); - testObject.hooks.addFilter( 'test_order', 'my_callback_fn_3a', callbacks.fn_3a, 3 ); - testObject.hooks.addFilter( 'test_order', 'my_callback_fn_3b', callbacks.fn_3b, 3 ); - testObject.hooks.addFilter( 'test_order', 'my_callback_fn_3c', callbacks.fn_3c, 3 ); - testObject.hooks.addFilter( 'test_order', 'my_callback_fn_2a', callbacks.fn_2a, 2 ); - testObject.hooks.addFilter( 'test_order', 'my_callback_fn_2b', callbacks.fn_2b, 2 ); - testObject.hooks.addFilter( 'test_order', 'my_callback_fn_2c', callbacks.fn_2c, 2 ); + addFilter( 'test_order', 'my_callback_fn_3a', callbacks.fn_3a, 3 ); + addFilter( 'test_order', 'my_callback_fn_3b', callbacks.fn_3b, 3 ); + addFilter( 'test_order', 'my_callback_fn_3c', callbacks.fn_3c, 3 ); + addFilter( 'test_order', 'my_callback_fn_2a', callbacks.fn_2a, 2 ); + addFilter( 'test_order', 'my_callback_fn_2b', callbacks.fn_2b, 2 ); + addFilter( 'test_order', 'my_callback_fn_2c', callbacks.fn_2c, 2 ); - expect( testObject.hooks.applyFilters( 'test_order', [] ) ).toEqual( + expect( applyFilters( 'test_order', [] ) ).toEqual( [ '2a', '2b', '2c', '3a', '3b', '3c' ] ); - testObject.hooks.removeFilter( 'test_order', 'my_callback_fn_2b', callbacks.fn_2b ); - testObject.hooks.removeFilter( 'test_order', 'my_callback_fn_3a', callbacks.fn_3a ); + removeFilter( 'test_order', 'my_callback_fn_2b', callbacks.fn_2b ); + removeFilter( 'test_order', 'my_callback_fn_3a', callbacks.fn_3a ); - expect( testObject.hooks.applyFilters( 'test_order', [] ) ).toEqual( + expect( applyFilters( 'test_order', [] ) ).toEqual( [ '2a', '2c', '3b', '3c' ] ); - testObject.hooks.addFilter( 'test_order', 'my_callback_fn_4a', callbacks.fn_4a, 4 ); - testObject.hooks.addFilter( 'test_order', 'my_callback_fn_4b', callbacks.fn_4b, 4 ); - testObject.hooks.addFilter( 'test_order', 'my_callback_fn_1a', callbacks.fn_1a, 1 ); - testObject.hooks.addFilter( 'test_order', 'my_callback_fn_4c', callbacks.fn_4c, 4 ); - testObject.hooks.addFilter( 'test_order', 'my_callback_fn_1b', callbacks.fn_1b, 1 ); - testObject.hooks.addFilter( 'test_order', 'my_callback_fn_3d', callbacks.fn_3d, 3 ); - testObject.hooks.addFilter( 'test_order', 'my_callback_fn_4d', callbacks.fn_4d, 4 ); - testObject.hooks.addFilter( 'test_order', 'my_callback_fn_1c', callbacks.fn_1c, 1 ); - testObject.hooks.addFilter( 'test_order', 'my_callback_fn_2d', callbacks.fn_2d, 2 ); - testObject.hooks.addFilter( 'test_order', 'my_callback_fn_1d', callbacks.fn_1d, 1 ); - - expect( testObject.hooks.applyFilters( 'test_order', [] ) ).toEqual( [ + addFilter( 'test_order', 'my_callback_fn_4a', callbacks.fn_4a, 4 ); + addFilter( 'test_order', 'my_callback_fn_4b', callbacks.fn_4b, 4 ); + addFilter( 'test_order', 'my_callback_fn_1a', callbacks.fn_1a, 1 ); + addFilter( 'test_order', 'my_callback_fn_4c', callbacks.fn_4c, 4 ); + addFilter( 'test_order', 'my_callback_fn_1b', callbacks.fn_1b, 1 ); + addFilter( 'test_order', 'my_callback_fn_3d', callbacks.fn_3d, 3 ); + addFilter( 'test_order', 'my_callback_fn_4d', callbacks.fn_4d, 4 ); + addFilter( 'test_order', 'my_callback_fn_1c', callbacks.fn_1c, 1 ); + addFilter( 'test_order', 'my_callback_fn_2d', callbacks.fn_2d, 2 ); + addFilter( 'test_order', 'my_callback_fn_1d', callbacks.fn_1d, 1 ); + + expect( applyFilters( 'test_order', [] ) ).toEqual( [ // all except 2b and 3a, which we removed earlier '1a', '1b', '1c', '1d', '2a', '2c', '2d', @@ -263,30 +282,30 @@ test( 'filters with the same and different priorities', () => { } ); test( 'add and remove an action', () => { - testObject.hooks.addAction( 'test.action', 'my_callback', action_a ); - expect( testObject.hooks.removeAllActions( 'test.action' ) ).toEqual( 1 ); - expect( testObject.hooks.doAction( 'test.action' ) ).toBe( undefined ); + addAction( 'test.action', 'my_callback', action_a ); + expect( removeAllActions( 'test.action' ) ).toBe( 1 ); + expect( doAction( 'test.action' ) ).toBe( undefined ); expect( window.actionValue ).toBe( '' ); } ); test( 'add an action and run it', () => { - testObject.hooks.addAction( 'test.action', 'my_callback', action_a ); - testObject.hooks.doAction( 'test.action' ); + addAction( 'test.action', 'my_callback', action_a ); + doAction( 'test.action' ); expect( window.actionValue ).toBe( 'a' ); } ); test( 'add 2 actions in a row and then run them', () => { - testObject.hooks.addAction( 'test.action', 'my_callback', action_a ); - testObject.hooks.addAction( 'test.action', 'my_callback', action_b ); - testObject.hooks.doAction( 'test.action' ); + addAction( 'test.action', 'my_callback', action_a ); + addAction( 'test.action', 'my_callback', action_b ); + doAction( 'test.action' ); expect( window.actionValue ).toBe( 'ab' ); } ); test( 'add 3 actions with different priorities and run them', () => { - testObject.hooks.addAction( 'test.action', 'my_callback', action_a ); - testObject.hooks.addAction( 'test.action', 'my_callback', action_b, 2 ); - testObject.hooks.addAction( 'test.action', 'my_callback', action_c, 8 ); - testObject.hooks.doAction( 'test.action' ); + addAction( 'test.action', 'my_callback', action_a ); + addAction( 'test.action', 'my_callback', action_b, 2 ); + addAction( 'test.action', 'my_callback', action_c, 8 ); + doAction( 'test.action' ); expect( window.actionValue ).toBe( 'bca' ); } ); @@ -294,11 +313,11 @@ test( 'pass in two arguments to an action', () => { const arg1 = { a: 10 }; const arg2 = { b: 20 }; - testObject.hooks.addAction( 'test.action', 'my_callback', ( a, b ) => { + addAction( 'test.action', 'my_callback', ( a, b ) => { expect( a ).toBe( arg1 ); expect( b ).toBe( arg2 ); } ); - testObject.hooks.doAction( 'test.action', arg1, arg2 ); + doAction( 'test.action', arg1, arg2 ); } ); test( 'fire action multiple times', () => { @@ -308,293 +327,286 @@ test( 'fire action multiple times', () => { expect( true ).toBe( true ); }; - testObject.hooks.addAction( 'test.action', 'my_callback', func ); - testObject.hooks.doAction( 'test.action' ); - testObject.hooks.doAction( 'test.action' ); + addAction( 'test.action', 'my_callback', func ); + doAction( 'test.action' ); + doAction( 'test.action' ); } ); test( 'add a filter before the one currently executing', () => { - testObject.hooks.addFilter( 'test.filter', 'my_callback', val => { - testObject.hooks.addFilter( 'test.filter', 'my_callback', val => val + 'a', 1 ); + addFilter( 'test.filter', 'my_callback', val => { + addFilter( 'test.filter', 'my_callback', val => val + 'a', 1 ); return val + 'b'; }, 2 ); - expect( testObject.hooks.applyFilters( 'test.filter', 'test_' ) ).toEqual( 'test_b' ); + expect( applyFilters( 'test.filter', 'test_' ) ).toBe( 'test_b' ); } ); test( 'add a filter after the one currently executing', () => { - testObject.hooks.addFilter( 'test.filter', 'my_callback', val => { - testObject.hooks.addFilter( 'test.filter', 'my_callback', val => val + 'b', 2 ); + addFilter( 'test.filter', 'my_callback', val => { + addFilter( 'test.filter', 'my_callback', val => val + 'b', 2 ); return val + 'a'; }, 1 ); - expect( testObject.hooks.applyFilters( 'test.filter', 'test_' ) ).toEqual( 'test_ab' ); + expect( applyFilters( 'test.filter', 'test_' ) ).toBe( 'test_ab' ); } ); test( 'add a filter immediately after the one currently executing', () => { - testObject.hooks.addFilter( 'test.filter', 'my_callback', val => { - testObject.hooks.addFilter( 'test.filter', 'my_callback', val => val + 'b', 1 ); + addFilter( 'test.filter', 'my_callback', val => { + addFilter( 'test.filter', 'my_callback', val => val + 'b', 1 ); return val + 'a'; }, 1 ); - expect( testObject.hooks.applyFilters( 'test.filter', 'test_' ) ).toEqual( 'test_ab' ); + expect( applyFilters( 'test.filter', 'test_' ) ).toBe( 'test_ab' ); } ); test( 'remove specific action callback', () => { - testObject.hooks.addAction( 'test.action', 'my_callback_action_a', action_a ); - testObject.hooks.addAction( 'test.action', 'my_callback_action_b', action_b, 2 ); - testObject.hooks.addAction( 'test.action', 'my_callback_action_c', action_c, 8 ); + addAction( 'test.action', 'my_callback_action_a', action_a ); + addAction( 'test.action', 'my_callback_action_b', action_b, 2 ); + addAction( 'test.action', 'my_callback_action_c', action_c, 8 ); - expect( testObject.hooks.removeAction( 'test.action', 'my_callback_action_b' ) ).toEqual( 1 ); - testObject.hooks.doAction( 'test.action' ); + expect( removeAction( 'test.action', 'my_callback_action_b' ) ).toBe( 1 ); + doAction( 'test.action' ); expect( window.actionValue ).toBe( 'ca' ); } ); test( 'remove all action callbacks', () => { - testObject.hooks.addAction( 'test.action', 'my_callback_action_a', action_a ); - testObject.hooks.addAction( 'test.action', 'my_callback_action_b', action_b, 2 ); - testObject.hooks.addAction( 'test.action', 'my_callback_action_c', action_c, 8 ); + addAction( 'test.action', 'my_callback_action_a', action_a ); + addAction( 'test.action', 'my_callback_action_b', action_b, 2 ); + addAction( 'test.action', 'my_callback_action_c', action_c, 8 ); - expect( testObject.hooks.removeAllActions( 'test.action' ) ).toEqual( 3 ); - testObject.hooks.doAction( 'test.action' ); + expect( removeAllActions( 'test.action' ) ).toBe( 3 ); + doAction( 'test.action' ); expect( window.actionValue ).toBe( '' ); } ); test( 'remove specific filter callback', () => { - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_a', filter_a ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 2 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 8 ); + addFilter( 'test.filter', 'my_callback_filter_a', filter_a ); + addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 2 ); + addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 8 ); - expect( testObject.hooks.removeFilter( 'test.filter', 'my_callback_filter_b' ) ).toEqual( 1 ); - expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testca' ); + expect( removeFilter( 'test.filter', 'my_callback_filter_b' ) ).toBe( 1 ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testca' ); } ); test( 'filter removes a callback that has already executed', () => { - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_a', filter_a, 1 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 3 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 5 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_removes_b', filter_removes_b, 4 ); + addFilter( 'test.filter', 'my_callback_filter_a', filter_a, 1 ); + addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 3 ); + addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 5 ); + addFilter( 'test.filter', 'my_callback_filter_removes_b', filter_removes_b, 4 ); - expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); test( 'filter removes a callback that has already executed (same priority)', () => { - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_a', filter_a, 1 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 2 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_removes_b', filter_removes_b, 2 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 4 ); + addFilter( 'test.filter', 'my_callback_filter_a', filter_a, 1 ); + addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 2 ); + addFilter( 'test.filter', 'my_callback_filter_removes_b', filter_removes_b, 2 ); + addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 4 ); - expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); test( 'filter removes the current callback', () => { - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_a', filter_a, 1 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_b_removes_self', filter_b_removes_self, 3 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 5 ); + addFilter( 'test.filter', 'my_callback_filter_a', filter_a, 1 ); + addFilter( 'test.filter', 'my_callback_filter_b_removes_self', filter_b_removes_self, 3 ); + addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 5 ); - expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testabc' ); } ); test( 'filter removes a callback that has not yet executed (last)', () => { - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_a', filter_a, 1 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 3 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 5 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_removes_c', filter_removes_c, 4 ); + addFilter( 'test.filter', 'my_callback_filter_a', filter_a, 1 ); + addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 3 ); + addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 5 ); + addFilter( 'test.filter', 'my_callback_filter_removes_c', filter_removes_c, 4 ); - expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testab' ); } ); test( 'filter removes a callback that has not yet executed (middle)', () => { - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_a', filter_a, 1 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 3 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 4 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_removes_b', filter_removes_b, 2 ); + addFilter( 'test.filter', 'my_callback_filter_a', filter_a, 1 ); + addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 3 ); + addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 4 ); + addFilter( 'test.filter', 'my_callback_filter_removes_b', filter_removes_b, 2 ); - expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); } ); test( 'filter removes a callback that has not yet executed (same priority)', () => { - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_a', filter_a, 1 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_removes_b', filter_removes_b, 2 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 2 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 4 ); + addFilter( 'test.filter', 'my_callback_filter_a', filter_a, 1 ); + addFilter( 'test.filter', 'my_callback_filter_removes_b', filter_removes_b, 2 ); + addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 2 ); + addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 4 ); - expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testac' ); } ); test( 'remove all filter callbacks', () => { - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_a', filter_a ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 2 ); - testObject.hooks.addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 8 ); + addFilter( 'test.filter', 'my_callback_filter_a', filter_a ); + addFilter( 'test.filter', 'my_callback_filter_b', filter_b, 2 ); + addFilter( 'test.filter', 'my_callback_filter_c', filter_c, 8 ); - expect( testObject.hooks.removeAllFilters( 'test.filter' ) ).toEqual( 3 ); - expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); + expect( removeAllFilters( 'test.filter' ) ).toBe( 3 ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'test' ); } ); -// Test testObject.hooks.doingAction, testObject.hooks.didAction, testObject.hooks.hasAction. -test( 'Test testObject.hooks.doingAction, testObject.hooks.didAction and testObject.hooks.hasAction.', () => { +// Test doingAction, didAction, hasAction. +test( 'Test doingAction, didAction and hasAction.', () => { let actionCalls = 0; - testObject.hooks.addAction( 'another.action', 'my_callback', () => {} ); - testObject.hooks.doAction( 'another.action' ); + addAction( 'another.action', 'my_callback', () => {} ); + doAction( 'another.action' ); // Verify no action is running yet. - expect( testObject.hooks.doingAction( 'test.action' ) ).toBe( false ); + expect( doingAction( 'test.action' ) ).toBe( false ); - expect( testObject.hooks.didAction( 'test.action' ) ).toBe( 0 ); - expect( testObject.hooks.hasAction( 'test.action' ) ).toBe( 0 ); + expect( didAction( 'test.action' ) ).toBe( 0 ); + expect( hasAction( 'test.action' ) ).toBe( 0 ); - testObject.hooks.addAction( 'test.action', 'my_callback', () => { + addAction( 'test.action', 'my_callback', () => { actionCalls++; - expect( testObject.hooks.currentAction() ).toBe( 'test.action' ); - expect( testObject.hooks.doingAction() ).toBe( true ); - expect( testObject.hooks.doingAction( 'test.action' ) ).toBe( true ); + expect( currentAction() ).toBe( 'test.action' ); + expect( doingAction() ).toBe( true ); + expect( doingAction( 'test.action' ) ).toBe( true ); } ); // Verify action added, not running yet. - expect( testObject.hooks.doingAction( 'test.action' ) ).toBe( false ); - expect( testObject.hooks.didAction( 'test.action' ) ).toBe( 0 ); - expect( testObject.hooks.hasAction( 'test.action' ) ).toBe( 1 ); + expect( doingAction( 'test.action' ) ).toBe( false ); + expect( didAction( 'test.action' ) ).toBe( 0 ); + expect( hasAction( 'test.action' ) ).toBe( 1 ); - testObject.hooks.doAction( 'test.action' ); + doAction( 'test.action' ); // Verify action added and running. expect( actionCalls ).toBe( 1 ); - expect( testObject.hooks.doingAction( 'test.action' ) ).toBe( false ); - expect( testObject.hooks.didAction( 'test.action' ) ).toBe( 1 ); - expect( testObject.hooks.hasAction( 'test.action' ) ).toBe( 1 ); - expect( testObject.hooks.doingAction() ).toBe( false ); - expect( testObject.hooks.doingAction( 'test.action' ) ).toBe( false ); - expect( testObject.hooks.doingAction( 'notatest.action' ) ).toBe( false ); - expect( testObject.hooks.currentAction() ).toBe( null ); - - testObject.hooks.doAction( 'test.action' ); + expect( doingAction( 'test.action' ) ).toBe( false ); + expect( didAction( 'test.action' ) ).toBe( 1 ); + expect( hasAction( 'test.action' ) ).toBe( 1 ); + expect( doingAction() ).toBe( false ); + expect( doingAction( 'test.action' ) ).toBe( false ); + expect( doingAction( 'notatest.action' ) ).toBe( false ); + expect( currentAction() ).toBe( null ); + + doAction( 'test.action' ); expect( actionCalls ).toBe( 2 ); - expect( testObject.hooks.didAction( 'test.action' ) ).toBe( 2 ); + expect( didAction( 'test.action' ) ).toBe( 2 ); - expect( testObject.hooks.removeAllActions( 'test.action' ) ).toEqual( 1 ); + expect( removeAllActions( 'test.action' ) ).toBe( 1 ); // Verify state is reset appropriately. - expect( testObject.hooks.doingAction( 'test.action' ) ).toBe( false ); - expect( testObject.hooks.didAction( 'test.action' ) ).toBe( 2 ); - expect( testObject.hooks.hasAction( 'test.action' ) ).toBe( 0 ); + expect( doingAction( 'test.action' ) ).toBe( false ); + expect( didAction( 'test.action' ) ).toBe( 2 ); + expect( hasAction( 'test.action' ) ).toBe( 0 ); - testObject.hooks.doAction( 'another.action' ); - expect( testObject.hooks.doingAction( 'test.action' ) ).toBe( false ); + doAction( 'another.action' ); + expect( doingAction( 'test.action' ) ).toBe( false ); - // Verify testObject.hooks.hasAction returns 0 when no matching action. - expect( testObject.hooks.hasAction( 'notatest.action' ) ).toBe( 0 ); + // Verify hasAction returns 0 when no matching action. + expect( hasAction( 'notatest.action' ) ).toBe( 0 ); } ); -test( 'Verify testObject.hooks.doingFilter, testObject.hooks.didFilter and testObject.hooks.hasFilter.', () => { +test( 'Verify doingFilter, didFilter and hasFilter.', () => { let filterCalls = 0; - testObject.hooks.addFilter( 'runtest.filter', 'my_callback', arg => { + addFilter( 'runtest.filter', 'my_callback', arg => { filterCalls++; - expect( testObject.hooks.currentFilter() ).toBe( 'runtest.filter' ); - expect( testObject.hooks.doingFilter() ).toBe( true ); - expect( testObject.hooks.doingFilter( 'runtest.filter' ) ).toBe( true ); + expect( currentFilter() ).toBe( 'runtest.filter' ); + expect( doingFilter() ).toBe( true ); + expect( doingFilter( 'runtest.filter' ) ).toBe( true ); return arg; } ); // Verify filter added and running. - const test = testObject.hooks.applyFilters( 'runtest.filter', 'someValue' ); + const test = applyFilters( 'runtest.filter', 'someValue' ); expect( test ).toBe( 'someValue' ); expect( filterCalls ).toBe( 1 ); - expect( testObject.hooks.didFilter( 'runtest.filter' ) ).toBe( 1 ); - expect( testObject.hooks.hasFilter( 'runtest.filter' ) ).toBe( 1 ); - expect( testObject.hooks.hasFilter( 'notatest.filter' ) ).toBe( 0 ); - expect( testObject.hooks.doingFilter() ).toBe( false ); - expect( testObject.hooks.doingFilter( 'runtest.filter' ) ).toBe( false ); - expect( testObject.hooks.doingFilter( 'notatest.filter' ) ).toBe( false ); - expect( testObject.hooks.currentFilter() ).toBe( null ); + expect( didFilter( 'runtest.filter' ) ).toBe( 1 ); + expect( hasFilter( 'runtest.filter' ) ).toBe( 1 ); + expect( hasFilter( 'notatest.filter' ) ).toBe( 0 ); + expect( doingFilter() ).toBe( false ); + expect( doingFilter( 'runtest.filter' ) ).toBe( false ); + expect( doingFilter( 'notatest.filter' ) ).toBe( false ); + expect( currentFilter() ).toBe( null ); - expect( testObject.hooks.removeAllFilters( 'runtest.filter' ) ).toEqual( 1 ); + expect( removeAllFilters( 'runtest.filter' ) ).toBe( 1 ); - expect( testObject.hooks.hasFilter( 'runtest.filter' ) ).toBe( 0 ); - expect( testObject.hooks.didFilter( 'runtest.filter' ) ).toBe( 1 ); + expect( hasFilter( 'runtest.filter' ) ).toBe( 0 ); + expect( didFilter( 'runtest.filter' ) ).toBe( 1 ); } ); test( 'recursively calling a filter', () => { - testObject.hooks.addFilter( 'test.filter', 'my_callback', value => { + addFilter( 'test.filter', 'my_callback', value => { if ( value.length === 7 ) { return value; } - return testObject.hooks.applyFilters( 'test.filter', value + 'X' ); + return applyFilters( 'test.filter', value + 'X' ); } ); - expect( testObject.hooks.applyFilters( 'test.filter', 'test' ) ).toBe( 'testXXX' ); + expect( applyFilters( 'test.filter', 'test' ) ).toBe( 'testXXX' ); } ); test( 'current filter when multiple filters are running', () => { - testObject.hooks.addFilter( 'test.filter1', 'my_callback', value => { - return testObject.hooks.applyFilters( 'test.filter2', value.concat( testObject.hooks.currentFilter() ) ); + addFilter( 'test.filter1', 'my_callback', value => { + return applyFilters( 'test.filter2', value.concat( currentFilter() ) ); } ); - testObject.hooks.addFilter( 'test.filter2', 'my_callback', value => { - return value.concat( testObject.hooks.currentFilter() ); + addFilter( 'test.filter2', 'my_callback', value => { + return value.concat( currentFilter() ); } ); - expect( testObject.hooks.currentFilter() ).toBe( null ); + expect( currentFilter() ).toBe( null ); - expect( testObject.hooks.applyFilters( 'test.filter1', [ 'test' ] ) ).toEqual( + expect( applyFilters( 'test.filter1', [ 'test' ] ) ).toEqual( [ 'test', 'test.filter1', 'test.filter2' ] ); - expect( testObject.hooks.currentFilter() ).toBe( null ); + expect( currentFilter() ).toBe( null ); } ); test( 'adding and removing filters with recursion', () => { function removeRecurseAndAdd2( val ) { - expect( testObject.hooks.removeFilter( 'remove_and_add', 'my_callback_recurse' ) ).toEqual( 1 ); - val += '-' + testObject.hooks.applyFilters( 'remove_and_add', '' ) + '-'; - testObject.hooks.addFilter( 'remove_and_add', 'my_callback_recurse', 10 ); + expect( removeFilter( 'remove_and_add', 'my_callback_recurse' ) ).toBe( 1 ); + val += '-' + applyFilters( 'remove_and_add', '' ) + '-'; + addFilter( 'remove_and_add', 'my_callback_recurse', 10 ); return val + '2'; } - testObject.hooks.addFilter( 'remove_and_add', 'my_callback', val => val + '1', 11 ); - testObject.hooks.addFilter( 'remove_and_add', 'my_callback_recurse', removeRecurseAndAdd2, 12 ); - testObject.hooks.addFilter( 'remove_and_add', 'my_callback', val => val + '3', 13 ); - testObject.hooks.addFilter( 'remove_and_add', 'my_callback', val => val + '4', 14 ); + addFilter( 'remove_and_add', 'my_callback', val => val + '1', 11 ); + addFilter( 'remove_and_add', 'my_callback_recurse', removeRecurseAndAdd2, 12 ); + addFilter( 'remove_and_add', 'my_callback', val => val + '3', 13 ); + addFilter( 'remove_and_add', 'my_callback', val => val + '4', 14 ); - expect( testObject.hooks.applyFilters( 'remove_and_add', '' ) ).toEqual( '1-134-234' ); + expect( applyFilters( 'remove_and_add', '' ) ).toBe( '1-134-234' ); } ); - // Test adding via composition. test( 'adding hooks via composition', () => { + const testObject = {}; + testObject.hooks = createHooks(); - var testObject2 = {}; - testObject2.hooks = createHooks(); - - expect( typeof testObject2.hooks.applyFilters ).toEqual( 'function' ); + expect( typeof testObject.hooks.applyFilters ).toBe( 'function' ); } ); - // Test adding as a mixin. test( 'adding hooks as a mixin', () => { + const testObject = {}; + Object.assign( testObject, createHooks() ); - var testObject3 = {}; - Object.assign( testObject3, createHooks() ); - - expect( typeof testObject3.applyFilters ).toEqual( 'function' ); + expect( typeof testObject.applyFilters ).toBe( 'function' ); } ); // Test context. test( 'Test `this` context via composition', () => { + const testObject = { test: 'test this' }; - var testObject2 = { test: 'test this' }; - - testObject2.hooks = createHooks(); + testObject.hooks = createHooks(); - var theCallback = function() { - expect( this.test ).toEqual( 'test this' ); + const theCallback = function() { + expect( this.test ).toBe( 'test this' ); }; - testObject.hooks.addAction( 'test.action', 'my_callback', theCallback.apply( testObject2 ) ); - testObject.hooks.doAction( 'test.action' ); - - var testObject3 = {}; - Object.assign( testObject3, createHooks() ); + addAction( 'test.action', 'my_callback', theCallback.apply( testObject ) ); + doAction( 'test.action' ); + const testObject2 = {}; + Object.assign( testObject2, createHooks() ); } ); - From 4ad05652141df39a4921108f89980bc5cfbc44be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Tue, 28 Nov 2017 15:10:42 +0100 Subject: [PATCH 220/393] Development: Improve onboarding experience for new contributors (#46) --- .travis.yml | 1 - CONTRIBUTING.md | 29 +++++++++- README.md | 10 +++- package-lock.json | 102 ++++++++++++++++++++++++++++-------- package.json | 1 + packages/hooks/package.json | 1 - 6 files changed, 119 insertions(+), 25 deletions(-) diff --git a/.travis.yml b/.travis.yml index 411cc075760fe..e9db6ebc0ffc7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,6 @@ node_js: - '6' script: - - lerna bootstrap && npm run build - npm run test:coverage-ci notifications: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3eefbe9325317..18cb9cd7464ca 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,8 +12,35 @@ Ideally name your branches with prefixes and descriptions, like this: `[type]/[c For example, `add/foo-module` means you're working on adding a new foo module. -You can pick among all the tickets, or some of the ones labelled Good First Task. +You can pick among all the issues, or some of the ones labelled Good First Issue. +## Developing + +Packages is built for Node 6 and up. You can check this with `node -v`. + +Make sure that npm is installed with version >= `5.0.0` using `npm -v`. + +### Setup + +```sh +$ git clone https://github.com/WordPress/packages.git +$ cd packages +$ npm install +``` + +### Testing + +In order to run the tests: + +```sh +$ npm test + +# If you want to watch for changes +$ npm run test:watch + +# If you want to check code coverage +$ npm run test:coverage +``` ## Releasing diff --git a/README.md b/README.md index 0c9d55151dc4a..81ec814a093db 100644 --- a/README.md +++ b/README.md @@ -2,5 +2,13 @@ [![Build Status](https://img.shields.io/travis/WordPress/packages/master.svg)](https://travis-ci.org/WordPress/packages) [![Coverage](https://img.shields.io/codecov/c/github/WordPress/packages/master.svg)](https://codecov.io/gh/WordPress/packages) +[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lernajs.io/) -Collection of JS modules and tools for WordPress development available at https://www.npmjs.com/org/wordpress +Collection of JS modules and tools for WordPress development available at https://www.npmjs.com/org/wordpress. + +### Want to contribute to packages? + +Check out our [CONTRIBUTING.md](CONTRIBUTING.md) to get started with setting up the repo. + +- If you have already joined Slack, join our [#core-js](https://wordpress.slack.com/messages/core-js) channel and say hi! +- Check out the issues with the [good first issue](https://github.com/WordPress/packages/labels/Good%20First%20Issue) and [help wanted](https://github.com/WordPress/packages/labels/help%20wanted) label. We suggest also looking at the closed ones to get a sense of the kinds of issues you can tackle. diff --git a/package-lock.json b/package-lock.json index 836473e8f3c86..43e1609cc7a7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2,6 +2,16 @@ "requires": true, "lockfileVersion": 1, "dependencies": { + "JSONStream": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz", + "integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=", + "dev": true, + "requires": { + "jsonparse": "1.3.1", + "through": "2.3.8" + } + }, "abab": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.3.tgz", @@ -440,6 +450,17 @@ "babel-preset-jest": "20.0.3" } }, + "babel-loader": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.2.tgz", + "integrity": "sha512-jRwlFbINAeyDStqK6Dd5YuY0k5YuzQUvlz2ZamuXrXmxav3pNqe9vfJ402+2G+OmlJSXxCOpB6Uz0INM7RQe2A==", + "dev": true, + "requires": { + "find-cache-dir": "1.0.0", + "loader-utils": "1.1.0", + "mkdirp": "0.5.1" + } + }, "babel-messages": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", @@ -920,6 +941,12 @@ "tweetnacl": "0.14.5" } }, + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true + }, "boom": { "version": "2.10.1", "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", @@ -1283,6 +1310,12 @@ "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", "dev": true }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, "compare-func": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.2.tgz", @@ -1543,8 +1576,8 @@ "integrity": "sha1-4ye1MZThp61dxjR57pCZpSsCSGU=", "dev": true, "requires": { - "is-text-path": "1.0.1", "JSONStream": "1.3.1", + "is-text-path": "1.0.1", "lodash": "4.17.4", "meow": "3.7.0", "split2": "2.1.1", @@ -1573,8 +1606,8 @@ "integrity": "sha512-8od6g684Fhi5Vpp4ABRv/RBsW1AY6wSHbJHEK6FGTv+8jvAAnlABniZu/FVmX9TcirkHepaEsa1QGkRvbg0CKw==", "dev": true, "requires": { - "is-text-path": "1.0.1", "JSONStream": "1.3.1", + "is-text-path": "1.0.1", "lodash": "4.17.4", "meow": "3.7.0", "split2": "2.1.1", @@ -1785,6 +1818,12 @@ "integrity": "sha1-0OAmc1dUdwkBrjAaIWZMukXZL30=", "dev": true }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, "errno": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", @@ -1993,6 +2032,17 @@ "repeat-string": "1.6.1" } }, + "find-cache-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", + "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=", + "dev": true, + "requires": { + "commondir": "1.0.1", + "make-dir": "1.0.0", + "pkg-dir": "2.0.0" + } + }, "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", @@ -3330,16 +3380,6 @@ "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", "dev": true }, - "JSONStream": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz", - "integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=", - "dev": true, - "requires": { - "jsonparse": "1.3.1", - "through": "2.3.8" - } - }, "jsprim": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", @@ -3673,6 +3713,17 @@ "strip-bom": "2.0.0" } }, + "loader-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "dev": true, + "requires": { + "big.js": "3.2.0", + "emojis-list": "2.1.0", + "json5": "0.5.1" + } + }, "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", @@ -4197,6 +4248,15 @@ "pinkie": "2.0.4" } }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "2.1.0" + } + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -4793,15 +4853,6 @@ } } }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, "string-length": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", @@ -4822,6 +4873,15 @@ "strip-ansi": "3.0.1" } }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, "stringstream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", diff --git a/package.json b/package.json index 88a84ad5981bc..3526f01103fbf 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "scripts": { "build-clean": "rimraf ./packages/*/build ./packages/*/build-module", "build": "node ./scripts/build.js", + "postinstall": "lerna bootstrap --hoist && npm run build", "test": "jest", "test:coverage": "jest --coverage", "test:coverage-ci": "jest --coverage && codecov", diff --git a/packages/hooks/package.json b/packages/hooks/package.json index 22f0a140aa8d6..113950dda1aef 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -8,7 +8,6 @@ "description": "WordPress Hooks library", "main": "build/index.js", "module": "build-module/index.js", - "browser": "build-browser/index.js", "author": "WordPress", "license": "GPL-2.0+", "publishConfig": { From 2c9059bc787a56ac944e040c5be909c82207ee41 Mon Sep 17 00:00:00 2001 From: Andrea Fercia Date: Tue, 28 Nov 2017 16:27:31 +0100 Subject: [PATCH 221/393] Update screen-reader-text CSS. --- packages/a11y/src/addContainer.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/a11y/src/addContainer.js b/packages/a11y/src/addContainer.js index f1d3a5b95c1bf..915c308c411fe 100644 --- a/packages/a11y/src/addContainer.js +++ b/packages/a11y/src/addContainer.js @@ -19,7 +19,9 @@ const addContainer = function( ariaLive ) { 'height: 1px;' + 'width: 1px;' + 'overflow: hidden;' + - 'clip: rect( 0 0 0 0 );' + + 'clip: rect(1px, 1px, 1px, 1px);' + + '-webkit-clip-path: inset(50%);' + + 'clip-path: inset(50%);' + 'border: 0;' + 'word-wrap: normal !important;' ) ); From 2d1f4789849099021ce3288c61a74fb5506d16b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Tue, 28 Nov 2017 17:34:56 +0100 Subject: [PATCH 222/393] Hooks: Allow slashes in the namespace (#47) * Hooks: Allow slashes in the namespace * Hooks: Add test ensuring backlash is not allowed inside namespace --- packages/hooks/src/test/index.test.js | 30 ++++++++++++++++--------- packages/hooks/src/validateNamespace.js | 4 ++-- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 98626936fb9b3..c2383207f0b29 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -147,14 +147,7 @@ test( 'cannot add filters with empty-string namespaces', () => { test( 'cannot add filters with invalid namespaces', () => { addFilter( 'hook_name', 'invalid_%&name', () => null ); expect( console.error ).toHaveBeenCalledWith( - 'The namespace can only contain numbers, letters, dashes, periods and underscores.' - ); -} ); - -test( 'cannot add filters with namespaces missing a functionDescription', () => { - addFilter( 'hook_name', 'invalid_name/', () => null ); - expect( console.error ).toHaveBeenCalledWith( - 'The namespace can only contain numbers, letters, dashes, periods and underscores.' + 'The namespace can only contain numbers, letters, dashes, periods, underscores and slashes.' ); } ); @@ -164,7 +157,17 @@ test( 'Can add filters with dashes in namespaces', () => { } ); test( 'Can add filters with capitals in namespaces', () => { - addFilter( 'hook_name', 'my_name-OhNoaction', () => null ); + addFilter( 'hook_name', 'My_Name-OhNoaction', () => null ); + expect( console.error ).toHaveBeenCalledTimes( 0 ); +} ); + +test( 'Can add filters with slashes in namespaces', () => { + addFilter( 'hook_name', 'my/name/action', () => null ); + expect( console.error ).toHaveBeenCalledTimes( 0 ); +} ); + +test( 'Can add filters with periods in namespaces', () => { + addFilter( 'hook_name', 'my.name.action', () => null ); expect( console.error ).toHaveBeenCalledTimes( 0 ); } ); @@ -186,7 +189,14 @@ test( 'Can add filters with periods in hookName', () => { test( 'cannot add filters with invalid namespaces', () => { addFilter( 'hook_name', '/invalid_name', () => null ); expect( console.error ).toHaveBeenCalledWith( - 'The namespace can only contain numbers, letters, dashes, periods and underscores.' + 'The namespace can only contain numbers, letters, dashes, periods, underscores and slashes.' + ); +} ); + +test( 'cannot add filters with namespace containing backslash', () => { + addFilter( 'hook_name', 'i\n\v\a\l\i\d\n\a\m\e', () => null ); + expect( console.error ).toHaveBeenCalledWith( + 'The namespace can only contain numbers, letters, dashes, periods, underscores and slashes.' ); } ); diff --git a/packages/hooks/src/validateNamespace.js b/packages/hooks/src/validateNamespace.js index dc180ab9c3d4c..aa6867e7f6eeb 100644 --- a/packages/hooks/src/validateNamespace.js +++ b/packages/hooks/src/validateNamespace.js @@ -13,8 +13,8 @@ function validateNamespace( namespace ) { return false; } - if ( ! /^[a-zA-Z][a-zA-Z0-9_.\-]*$/.test( namespace ) ) { - console.error( 'The namespace can only contain numbers, letters, dashes, periods and underscores.' ); + if ( ! /^[a-zA-Z][a-zA-Z0-9_.\-\/]*$/.test( namespace ) ) { + console.error( 'The namespace can only contain numbers, letters, dashes, periods, underscores and slashes.' ); return false; } From 1b693b96f953c3d7adc74df3d508e988087d77f9 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 28 Nov 2017 15:48:04 -0500 Subject: [PATCH 223/393] Publish - @wordpress/a11y@1.0.0 - @wordpress/hooks@1.0.0 --- packages/a11y/package.json | 2 +- packages/hooks/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/a11y/package.json b/packages/a11y/package.json index a4a28eaef2d0a..dfa3d36a1ebc6 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/a11y", - "version": "0.1.0-beta.6", + "version": "1.0.0", "description": "Collection of JS modules and tools for WordPress development", "homepage": "https://github.com/WordPress/packages/tree/master/packages/a11y/README.md", "author": "WordPress", diff --git a/packages/hooks/package.json b/packages/hooks/package.json index 113950dda1aef..ea67a8bcf5927 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/hooks", - "version": "0.1.0-beta.5", + "version": "1.0.0", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" From 99f5046880fa28a145722d5ca35df591f6cd31a9 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Tue, 28 Nov 2017 15:53:42 -0500 Subject: [PATCH 224/393] =?UTF-8?q?a11y=20&=20hooks:=20remove=20=E2=80=98@?= =?UTF-8?q?next=E2=80=99=20from=20install=20instructions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/a11y/README.md | 2 +- packages/hooks/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/a11y/README.md b/packages/a11y/README.md index a32be37bd641e..45a4c0aa2bfcc 100644 --- a/packages/a11y/README.md +++ b/packages/a11y/README.md @@ -7,7 +7,7 @@ Collection of JS modules for enhancing accessibility. Install the module ```bash -npm install @wordpress/a11y@next --save +npm install @wordpress/a11y --save ``` ## speak diff --git a/packages/hooks/README.md b/packages/hooks/README.md index 625a7be235a42..55bac54e0472f 100644 --- a/packages/hooks/README.md +++ b/packages/hooks/README.md @@ -7,7 +7,7 @@ A lightweight & efficient EventManager for JavaScript in WordPress. Install the module ```bash -npm install @wordpress/hooks@next --save +npm install @wordpress/hooks --save ``` ### Usage From 96ec440507a60469fc2b8ce4321f84d964ef1212 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Wed, 29 Nov 2017 08:07:48 -0500 Subject: [PATCH 225/393] tag a11y and hooks at 1.0.1 --- packages/a11y/package.json | 2 +- packages/hooks/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/a11y/package.json b/packages/a11y/package.json index dfa3d36a1ebc6..ed0096e7c1897 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/a11y", - "version": "1.0.0", + "version": "1.0.1", "description": "Collection of JS modules and tools for WordPress development", "homepage": "https://github.com/WordPress/packages/tree/master/packages/a11y/README.md", "author": "WordPress", diff --git a/packages/hooks/package.json b/packages/hooks/package.json index ea67a8bcf5927..1feaf3c0d6de0 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/hooks", - "version": "1.0.0", + "version": "1.0.1", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" From 8bf869760fb2ebbf0f5ac0f370e1fba435febe29 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Thu, 14 Dec 2017 22:50:27 -0500 Subject: [PATCH 226/393] Trigger actions when adding or removing hooks --- packages/hooks/src/createAddHook.js | 3 +++ packages/hooks/src/createRemoveHook.js | 2 ++ 2 files changed, 5 insertions(+) diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index 9d4ac8d36af30..f23a5a4e8660f 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -1,5 +1,6 @@ import validateNamespace from './validateNamespace.js'; import validateHookName from './validateHookName.js'; +import { doAction } from './'; /** * Returns a function which, when invoked, will add a hook. @@ -68,6 +69,8 @@ function createAddHook( hooks ) { runs: 0, }; } + + doAction( 'hookAdded', hookName, namespace, callback, priority ); }; } diff --git a/packages/hooks/src/createRemoveHook.js b/packages/hooks/src/createRemoveHook.js index 42cbf9e49f287..977bd5c8094c4 100644 --- a/packages/hooks/src/createRemoveHook.js +++ b/packages/hooks/src/createRemoveHook.js @@ -1,5 +1,6 @@ import validateNamespace from './validateNamespace.js'; import validateHookName from './validateHookName.js'; +import { doAction } from './'; /** * Returns a function which, when invoked, will remove a specified hook or all @@ -65,6 +66,7 @@ function createRemoveHook( hooks, removeAll ) { } } } + doAction( 'hookRemoved', hookName, namespace ); return handlersRemoved; }; From a0da7d382b33b8b76342f23e9468e08eb6015eaa Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 15 Dec 2017 10:27:09 -0500 Subject: [PATCH 227/393] add tests for expected hookAdded and hookRemoved events --- packages/hooks/src/test/index.test.js | 35 +++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index c2383207f0b29..3ce5cfc054bd3 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -64,6 +64,14 @@ function action_c() { window.actionValue += 'c'; } +function handle_hook_added ( ...args ) { + window.hookAdded = { ...args }; +} + +function handle_hook_removed ( ...args ) { + window.hookRemoved = { ...args }; +} + const consoleErrorOriginal = console.error; beforeEach( () => { @@ -620,3 +628,30 @@ test( 'Test `this` context via composition', () => { const testObject2 = {}; Object.assign( testObject2, createHooks() ); } ); + +// Test adding a hook triggers a hookAdded action. +test( 'adding a hood triggers a hookAdded action passing all callback details', () => { + const testObject = {}; + + addAction( 'hookAdded', 'my_callback', handle_hook_added ); + addAction( 'testHook', 'my_callback2', action_a, 9 ); + expect( window.hookAdded ).toEqual( { + '0': 'testHook', + '1': 'my_callback2', + '2': action_a, + '3': 9 + } ); +} ); + +// Test removing a hood triggers a hookRemoved action. +test( 'adding a hood triggers a hookRemoved action passing all callback details', () => { + const testObject = {}; + + addAction( 'hookRemoved', 'my_callback', handle_hook_removed ); + addAction( 'testHook', 'my_callback2', action_a, 9 ); + removeAction( 'testHook', 'my_callback2' ); + expect( window.hookRemoved ).toEqual( { + '0': 'testHook', + '1': 'my_callback2' + } ); +} ); From 91c32b8ecff5697ada22a46571c49a459caacbd0 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 15 Dec 2017 10:27:49 -0500 Subject: [PATCH 228/393] these are hooks not hoods (typo) --- packages/hooks/src/test/index.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 3ce5cfc054bd3..cbf76ee50e696 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -630,7 +630,7 @@ test( 'Test `this` context via composition', () => { } ); // Test adding a hook triggers a hookAdded action. -test( 'adding a hood triggers a hookAdded action passing all callback details', () => { +test( 'adding a hook triggers a hookAdded action passing all callback details', () => { const testObject = {}; addAction( 'hookAdded', 'my_callback', handle_hook_added ); @@ -643,8 +643,8 @@ test( 'adding a hood triggers a hookAdded action passing all callback details', } ); } ); -// Test removing a hood triggers a hookRemoved action. -test( 'adding a hood triggers a hookRemoved action passing all callback details', () => { +// Test removing a hook triggers a hookRemoved action. +test( 'adding a hook triggers a hookRemoved action passing all callback details', () => { const testObject = {}; addAction( 'hookRemoved', 'my_callback', handle_hook_removed ); From 80cc0760b45d68d585ea4f3d9ff4cb711446aff3 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Tue, 19 Dec 2017 10:34:40 +0100 Subject: [PATCH 229/393] Tests: Refactor tests to use Jest mocks --- packages/hooks/src/createAddHook.js | 4 ++- packages/hooks/src/createRemoveHook.js | 4 ++- packages/hooks/src/test/index.test.js | 42 +++++++++++--------------- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index f23a5a4e8660f..c83e48098d40c 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -70,7 +70,9 @@ function createAddHook( hooks ) { }; } - doAction( 'hookAdded', hookName, namespace, callback, priority ); + if ( hookName !== 'hookAdded' ) { + doAction( 'hookAdded', hookName, namespace, callback, priority ); + } }; } diff --git a/packages/hooks/src/createRemoveHook.js b/packages/hooks/src/createRemoveHook.js index 977bd5c8094c4..97d6cc1745631 100644 --- a/packages/hooks/src/createRemoveHook.js +++ b/packages/hooks/src/createRemoveHook.js @@ -66,7 +66,9 @@ function createRemoveHook( hooks, removeAll ) { } } } - doAction( 'hookRemoved', hookName, namespace ); + if ( hookName !== 'hookRemoved' ) { + doAction( 'hookRemoved', hookName, namespace ); + } return handlersRemoved; }; diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index cbf76ee50e696..e78406ab1bc6a 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -64,14 +64,6 @@ function action_c() { window.actionValue += 'c'; } -function handle_hook_added ( ...args ) { - window.hookAdded = { ...args }; -} - -function handle_hook_removed ( ...args ) { - window.hookRemoved = { ...args }; -} - const consoleErrorOriginal = console.error; beforeEach( () => { @@ -629,29 +621,31 @@ test( 'Test `this` context via composition', () => { Object.assign( testObject2, createHooks() ); } ); -// Test adding a hook triggers a hookAdded action. test( 'adding a hook triggers a hookAdded action passing all callback details', () => { - const testObject = {}; + const hook_added_spy = jest.fn(); - addAction( 'hookAdded', 'my_callback', handle_hook_added ); + addAction( 'hookAdded', 'my_callback', hook_added_spy ); addAction( 'testHook', 'my_callback2', action_a, 9 ); - expect( window.hookAdded ).toEqual( { - '0': 'testHook', - '1': 'my_callback2', - '2': action_a, - '3': 9 - } ); + + expect( hook_added_spy ).toHaveBeenCalledTimes( 1 ); + expect( hook_added_spy ).toHaveBeenCalledWith( + 'testHook', + 'my_callback2', + action_a, + 9 + ); } ); -// Test removing a hook triggers a hookRemoved action. test( 'adding a hook triggers a hookRemoved action passing all callback details', () => { - const testObject = {}; + const hook_removed_spy = jest.fn(); - addAction( 'hookRemoved', 'my_callback', handle_hook_removed ); + addAction( 'hookRemoved', 'my_callback', hook_removed_spy ); addAction( 'testHook', 'my_callback2', action_a, 9 ); removeAction( 'testHook', 'my_callback2' ); - expect( window.hookRemoved ).toEqual( { - '0': 'testHook', - '1': 'my_callback2' - } ); + + expect( hook_removed_spy ).toHaveBeenCalledTimes( 1 ); + expect( hook_removed_spy ).toHaveBeenCalledWith( + 'testHook', + 'my_callback2' + ); } ); From f4ef6617dd015e472541cb178bbc1a1dd07f2c19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Tue, 19 Dec 2017 13:03:08 +0100 Subject: [PATCH 230/393] Standardize format of package.json files (#54) --- package.json | 1 + packages/a11y/package.json | 7 ++++--- packages/dom-ready/package.json | 13 ++++++++++--- packages/hooks/package.json | 13 ++++++++++--- packages/url/package.json | 13 ++++++++++--- 5 files changed, 35 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 3526f01103fbf..41e5a9b14d831 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,5 @@ { + "license": "GPL-2.0+", "devDependencies": { "babel-core": "^6.25.0", "babel-plugin-transform-object-rest-spread": "^6.23.0", diff --git a/packages/a11y/package.json b/packages/a11y/package.json index ed0096e7c1897..a40214f00f551 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -2,14 +2,13 @@ "name": "@wordpress/a11y", "version": "1.0.1", "description": "Collection of JS modules and tools for WordPress development", - "homepage": "https://github.com/WordPress/packages/tree/master/packages/a11y/README.md", "author": "WordPress", + "license": "GPL-2.0+", "keywords": [ "a11y", "aria-live" ], - "main": "build/index.js", - "module": "build-module/index.js", + "homepage": "https://github.com/WordPress/packages/tree/master/packages/a11y/README.md", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" @@ -17,6 +16,8 @@ "bugs": { "url": "https://github.com/WordPress/packages/issues" }, + "main": "build/index.js", + "module": "build-module/index.js", "dependencies": { "@wordpress/dom-ready": "^0.1.0-beta.6" }, diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index 639b832895d38..48674f129af98 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -1,15 +1,22 @@ { "name": "@wordpress/dom-ready", "version": "0.1.0-beta.6", + "description": "Execute callback after the DOM is loaded.", + "author": "WordPress", + "license": "GPL-2.0+", + "keywords": [ + "dom-ready" + ], + "homepage": "https://github.com/WordPress/packages/tree/master/packages/dom-ready/README.md", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" }, - "description": "Execute callback after the DOM is loaded.", + "bugs": { + "url": "https://github.com/WordPress/packages/issues" + }, "main": "build/index.js", "module": "build-module/index.js", - "author": "WordPress", - "license": "GPL-2.0+", "publishConfig": { "access": "public" } diff --git a/packages/hooks/package.json b/packages/hooks/package.json index 1feaf3c0d6de0..a6916e26a5d28 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,15 +1,22 @@ { "name": "@wordpress/hooks", "version": "1.0.1", + "description": "WordPress Hooks library", + "author": "WordPress", + "license": "GPL-2.0+", + "keywords": [ + "hooks" + ], + "homepage": "https://github.com/WordPress/packages/tree/master/packages/hooks/README.md", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" }, - "description": "WordPress Hooks library", + "bugs": { + "url": "https://github.com/WordPress/packages/issues" + }, "main": "build/index.js", "module": "build-module/index.js", - "author": "WordPress", - "license": "GPL-2.0+", "publishConfig": { "access": "public" } diff --git a/packages/url/package.json b/packages/url/package.json index ad7657e8efa8f..436a93c3e9682 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -1,15 +1,22 @@ { "name": "@wordpress/url", "version": "0.1.0-beta.5", + "description": "WordPress URL utilities", + "author": "WordPress", + "license": "GPL-2.0+", + "keywords": [ + "url" + ], + "homepage": "https://github.com/WordPress/packages/tree/master/packages/url/README.md", "repository": { "type": "git", "url": "https://github.com/WordPress/packages.git" }, - "description": "WordPress URL utilities", + "bugs": { + "url": "https://github.com/WordPress/packages/issues" + }, "main": "build/index.js", "module": "build-module/index.js", - "author": "WordPress", - "license": "GPL-2.0+", "publishConfig": { "access": "public" } From 17cab19410b148eb04f649fb615ceb340d0d35ff Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Wed, 20 Dec 2017 10:16:16 -0500 Subject: [PATCH 231/393] Add tests for addFilter/removeFilter --- packages/hooks/src/test/index.test.js | 39 ++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index e78406ab1bc6a..4f065bffbc348 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -624,28 +624,55 @@ test( 'Test `this` context via composition', () => { test( 'adding a hook triggers a hookAdded action passing all callback details', () => { const hook_added_spy = jest.fn(); + // Set up a listener for the 'hookAdded' action. addAction( 'hookAdded', 'my_callback', hook_added_spy ); - addAction( 'testHook', 'my_callback2', action_a, 9 ); + // Test addAction. + addAction( 'testAction', 'my_callback2', action_a, 9 ); expect( hook_added_spy ).toHaveBeenCalledTimes( 1 ); expect( hook_added_spy ).toHaveBeenCalledWith( - 'testHook', + 'testAction', 'my_callback2', action_a, 9 ); + + // Test addFilter. + addFilter( 'testFilter', 'my_callback3', filter_a, 8 ); + expect( hook_added_spy ).toHaveBeenCalledTimes( 2 ); + expect( hook_added_spy ).toHaveBeenCalledWith( + 'testFilter', + 'my_callback3', + filter_a, + 8 + ); + } ); -test( 'adding a hook triggers a hookRemoved action passing all callback details', () => { +test( 'removing a hook triggers a hookRemoved action passing all callback details', () => { const hook_removed_spy = jest.fn(); + // Set up a listener for the 'hookRemoved' action. addAction( 'hookRemoved', 'my_callback', hook_removed_spy ); - addAction( 'testHook', 'my_callback2', action_a, 9 ); - removeAction( 'testHook', 'my_callback2' ); + + // Test removeAction. + addAction( 'testAction', 'my_callback2', action_a, 9 ); + removeAction( 'testAction', 'my_callback2' ); expect( hook_removed_spy ).toHaveBeenCalledTimes( 1 ); expect( hook_removed_spy ).toHaveBeenCalledWith( - 'testHook', + 'testAction', 'my_callback2' ); + + // Test removeFilter. + addFilter( 'testFilter', 'my_callback3', filter_a, 8 ); + removeFilter( 'testFilter', 'my_callback3' ); + expect( hook_removed_spy ).toHaveBeenCalledTimes( 2 ); + expect( hook_removed_spy ).toHaveBeenCalledWith( + 'testFilter', + 'my_callback3' + ); + + } ); From ffaeb177618f809478e72c5ab94d0605f70190bf Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Wed, 20 Dec 2017 10:16:48 -0500 Subject: [PATCH 232/393] whitespace --- packages/hooks/src/test/index.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index 4f065bffbc348..e724859379dae 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -674,5 +674,4 @@ test( 'removing a hook triggers a hookRemoved action passing all callback detail 'my_callback3' ); - } ); From 9d7c064261a1b09ef93a23f682836a6ba31bbe25 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Wed, 20 Dec 2017 10:29:58 -0500 Subject: [PATCH 233/393] Docs update for hooks added/removed events --- packages/hooks/README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/hooks/README.md b/packages/hooks/README.md index 55bac54e0472f..44d15f23818a0 100644 --- a/packages/hooks/README.md +++ b/packages/hooks/README.md @@ -22,7 +22,7 @@ A lightweight & efficient filter and action manager. * `addAction( 'hookName', 'functionName', callback, priority )` * `addFilter( 'hookName', 'functionName', callback, priority )` * `removeAction( 'hookName', 'functionName' )` -* `removeFilter( 'hookName', 'functionName' )` +* `removeFilter( 'hookName', 'functionName' )` * `removeAllActions( 'hookName' )` * `removeAllFilters( 'hookName' )` * `doAction( 'hookName', arg1, arg2, moreArgs, finalArg )` @@ -41,4 +41,11 @@ Hooks can be added to an object via composition: `myObject.hooks = createHooks();` -API functions are then be called: `myObject.hooks.addAction()`... +API functions are then be called: `myObject.hooks.addAction()`. + +### Events on action/filter add or remove. + +Whenever an action or filter is added or removed, a matching `hookAdded` or `hookRemoved` action is triggered. + +* `hookAdded` is triggered when `hooks.addFilter` or `hooks.addAction` is called, passing values for `hookName`, `functionName`, `callback` and `priority`. +* `hookRemoved` is triggered when `hooks.removeFilter` or `hooks.removeAction` is called, passing values for `hookName` and `functionName`. From cceb16f445113576e06dde43db9b050f0b0add76 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Thu, 21 Dec 2017 12:54:56 +0100 Subject: [PATCH 234/393] Hooks: Final touches for the add/remove actions --- packages/hooks/README.md | 6 ++--- packages/hooks/src/test/index.test.js | 36 ++++++++++++++++----------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/packages/hooks/README.md b/packages/hooks/README.md index 44d15f23818a0..8bd908f772c60 100644 --- a/packages/hooks/README.md +++ b/packages/hooks/README.md @@ -43,9 +43,9 @@ Hooks can be added to an object via composition: API functions are then be called: `myObject.hooks.addAction()`. -### Events on action/filter add or remove. +### Events on action/filter add or remove Whenever an action or filter is added or removed, a matching `hookAdded` or `hookRemoved` action is triggered. -* `hookAdded` is triggered when `hooks.addFilter` or `hooks.addAction` is called, passing values for `hookName`, `functionName`, `callback` and `priority`. -* `hookRemoved` is triggered when `hooks.removeFilter` or `hooks.removeAction` is called, passing values for `hookName` and `functionName`. +* `hookAdded` action is triggered when `addFilter()` or `addAction()` method is called, passing values for `hookName`, `functionName`, `callback` and `priority`. +* `hookRemoved` action is triggered when `removeFilter()` or `removeAction()` method is called, passing values for `hookName` and `functionName`. diff --git a/packages/hooks/src/test/index.test.js b/packages/hooks/src/test/index.test.js index e724859379dae..f0d52952371ad 100644 --- a/packages/hooks/src/test/index.test.js +++ b/packages/hooks/src/test/index.test.js @@ -621,13 +621,14 @@ test( 'Test `this` context via composition', () => { Object.assign( testObject2, createHooks() ); } ); -test( 'adding a hook triggers a hookAdded action passing all callback details', () => { +const setupActionListener = ( hookName, callback ) => + addAction( hookName, 'my_callback', callback ); + +test( 'adding an action triggers a hookAdded action passing all callback details', () => { const hook_added_spy = jest.fn(); - // Set up a listener for the 'hookAdded' action. - addAction( 'hookAdded', 'my_callback', hook_added_spy ); + setupActionListener( 'hookAdded', hook_added_spy ); - // Test addAction. addAction( 'testAction', 'my_callback2', action_a, 9 ); expect( hook_added_spy ).toHaveBeenCalledTimes( 1 ); expect( hook_added_spy ).toHaveBeenCalledWith( @@ -636,26 +637,28 @@ test( 'adding a hook triggers a hookAdded action passing all callback details', action_a, 9 ); +} ); + +test( 'adding a filter triggers a hookAdded action passing all callback details', () => { + const hook_added_spy = jest.fn(); + + setupActionListener( 'hookAdded', hook_added_spy ); - // Test addFilter. addFilter( 'testFilter', 'my_callback3', filter_a, 8 ); - expect( hook_added_spy ).toHaveBeenCalledTimes( 2 ); + expect( hook_added_spy ).toHaveBeenCalledTimes( 1 ); expect( hook_added_spy ).toHaveBeenCalledWith( 'testFilter', 'my_callback3', filter_a, 8 ); - } ); -test( 'removing a hook triggers a hookRemoved action passing all callback details', () => { +test( 'removing an action triggers a hookRemoved action passing all callback details', () => { const hook_removed_spy = jest.fn(); - // Set up a listener for the 'hookRemoved' action. - addAction( 'hookRemoved', 'my_callback', hook_removed_spy ); + setupActionListener( 'hookRemoved', hook_removed_spy ); - // Test removeAction. addAction( 'testAction', 'my_callback2', action_a, 9 ); removeAction( 'testAction', 'my_callback2' ); @@ -664,14 +667,19 @@ test( 'removing a hook triggers a hookRemoved action passing all callback detail 'testAction', 'my_callback2' ); +} ); + +test( 'removing a filter triggers a hookRemoved action passing all callback details', () => { + const hook_removed_spy = jest.fn(); + + setupActionListener( 'hookRemoved', hook_removed_spy ); - // Test removeFilter. addFilter( 'testFilter', 'my_callback3', filter_a, 8 ); removeFilter( 'testFilter', 'my_callback3' ); - expect( hook_removed_spy ).toHaveBeenCalledTimes( 2 ); + + expect( hook_removed_spy ).toHaveBeenCalledTimes( 1 ); expect( hook_removed_spy ).toHaveBeenCalledWith( 'testFilter', 'my_callback3' ); - } ); From e3cec64f7ffc6efdad8e68b45fff2ea7d721116b Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Thu, 21 Dec 2017 13:14:31 +0100 Subject: [PATCH 235/393] Publish - @wordpress/a11y@1.0.2 - @wordpress/dom-ready@0.1.0-beta.7 - @wordpress/hooks@1.1.0 - @wordpress/url@0.1.0-beta.6 --- packages/a11y/package.json | 4 ++-- packages/dom-ready/package.json | 2 +- packages/hooks/package.json | 2 +- packages/url/package.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/a11y/package.json b/packages/a11y/package.json index a40214f00f551..e1707e356812f 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/a11y", - "version": "1.0.1", + "version": "1.0.2", "description": "Collection of JS modules and tools for WordPress development", "author": "WordPress", "license": "GPL-2.0+", @@ -19,7 +19,7 @@ "main": "build/index.js", "module": "build-module/index.js", "dependencies": { - "@wordpress/dom-ready": "^0.1.0-beta.6" + "@wordpress/dom-ready": "^0.1.0-beta.7" }, "publishConfig": { "access": "public" diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index 48674f129af98..467aaed9d42f1 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom-ready", - "version": "0.1.0-beta.6", + "version": "0.1.0-beta.7", "description": "Execute callback after the DOM is loaded.", "author": "WordPress", "license": "GPL-2.0+", diff --git a/packages/hooks/package.json b/packages/hooks/package.json index a6916e26a5d28..238a26bdb956c 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/hooks", - "version": "1.0.1", + "version": "1.1.0", "description": "WordPress Hooks library", "author": "WordPress", "license": "GPL-2.0+", diff --git a/packages/url/package.json b/packages/url/package.json index 436a93c3e9682..5c5cd316d212b 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/url", - "version": "0.1.0-beta.5", + "version": "0.1.0-beta.6", "description": "WordPress URL utilities", "author": "WordPress", "license": "GPL-2.0+", From 6cbae56c2da8ed65d70916f0e4b9938fab2b3ff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Thu, 21 Dec 2017 14:53:11 +0100 Subject: [PATCH 236/393] Update Lerna and Jest to the latest version (#56) --- package-lock.json | 3464 ++++++++++++++++++++++++++++++++------------- package.json | 10 +- 2 files changed, 2459 insertions(+), 1015 deletions(-) diff --git a/package-lock.json b/package-lock.json index 43e1609cc7a7e..2cea493019123 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2,10 +2,27 @@ "requires": true, "lockfileVersion": 1, "dependencies": { + "@babel/code-frame": { + "version": "7.0.0-beta.35", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.35.tgz", + "integrity": "sha512-l0SE8cl9DUIY4hYAFAKTLX3F2Yr14Qri7uTsuI7iegB5E4KyQy4XY72L3VOxmj6kwR/RDQURoKYr2NzyETGo7A==", + "dev": true, + "requires": { + "chalk": "2.0.1", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "@types/node": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.2.tgz", + "integrity": "sha512-KA4GKOpgXnrqEH2eCVhiv2CsxgXGQJgV1X0vsGlh+WCnxbeAE1GT44ZsTU1IN5dEeV/gDupKa7gWo08V5IxWVQ==", + "dev": true + }, "JSONStream": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz", - "integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", + "integrity": "sha1-wQI3G27Dp887hHygDCC7D85Mbeo=", "dev": true, "requires": { "jsonparse": "1.3.1", @@ -13,24 +30,24 @@ } }, "abab": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.3.tgz", - "integrity": "sha1-uB3l9ydOxOdW15fNg08wNkJyTl0=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", + "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=", "dev": true }, "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", "dev": true }, "acorn-globals": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", - "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.1.0.tgz", + "integrity": "sha512-KjZwU26uG3u6eZcfGbTULzFcsoz6pegNKtHPksZPOUsiKo5bUmiBPa38FuHZ/Eun+XYh/JCCkS9AS3Lu4McQOQ==", "dev": true, "requires": { - "acorn": "4.0.13" + "acorn": "5.2.1" } }, "add-stream": { @@ -40,13 +57,15 @@ "dev": true }, "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "dev": true, "requires": { "co": "4.6.0", - "json-stable-stringify": "1.0.1" + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" } }, "align-text": { @@ -67,9 +86,9 @@ "dev": true }, "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", + "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", "dev": true }, "ansi-regex": { @@ -85,13 +104,13 @@ "dev": true }, "anymatch": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz", - "integrity": "sha1-o+Uvo5FoyCX/V7AkgSbOWo/5VQc=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", "dev": true, "requires": { - "arrify": "1.0.1", - "micromatch": "2.3.11" + "micromatch": "2.3.11", + "normalize-path": "2.1.1" } }, "append-transform": { @@ -104,9 +123,9 @@ } }, "aproba": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.2.tgz", - "integrity": "sha1-RcZikJTeTpb2k+9+q3SuB5wkD8E=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true }, "are-we-there-yet": { @@ -206,10 +225,16 @@ "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", "dev": true }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, "async": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", - "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "dev": true, "requires": { "lodash": "4.17.4" @@ -440,14 +465,13 @@ } }, "babel-jest": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-20.0.3.tgz", - "integrity": "sha1-5KA7E9wQOJ4UD8ZF0J/8TO0wFnE=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-22.0.3.tgz", + "integrity": "sha512-vIJAdq0YuLwg5TF6DDvcSFYx+Cqb9f2pTzC3ZcpGUBeysUUzPxZ6J3WVvuFMzpxgHa23tDKlNivDN9C4jIAKUQ==", "dev": true, "requires": { - "babel-core": "6.25.0", - "babel-plugin-istanbul": "4.1.4", - "babel-preset-jest": "20.0.3" + "babel-plugin-istanbul": "4.1.5", + "babel-preset-jest": "22.0.3" } }, "babel-loader": { @@ -480,20 +504,20 @@ } }, "babel-plugin-istanbul": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.4.tgz", - "integrity": "sha1-GN3oS/POMp/d8/QQP66SFFbY5Yc=", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.5.tgz", + "integrity": "sha1-Z2DN2Xf0EdPhdbsGTyvDJ9mbK24=", "dev": true, "requires": { "find-up": "2.1.0", - "istanbul-lib-instrument": "1.7.4", + "istanbul-lib-instrument": "1.9.1", "test-exclude": "4.1.1" } }, "babel-plugin-jest-hoist": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-20.0.3.tgz", - "integrity": "sha1-r+3IU70/jcNUjqZx++adA8wsF2c=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-22.0.3.tgz", + "integrity": "sha512-Z0pOZFs0xDctwF0bPEKrnAzvbbgDi2vDFbQ0EdofnLI2bOa3P1H66gNLb2vMJJaa00VDjfiGhIocsHvBkqtyEQ==", "dev": true }, "babel-plugin-syntax-async-functions": { @@ -844,12 +868,13 @@ } }, "babel-preset-jest": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-20.0.3.tgz", - "integrity": "sha1-y6yq3stdaJyh4d4TYOv8ZoYsF4o=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-22.0.3.tgz", + "integrity": "sha512-FbMMniSMXFvkKldCf+e4Tuol/v3XMaIpIp8xiT1WFlEW3ZapTKDW9YgVt3hqcpZXsIGFf6eUF3Owxom7yFlI8w==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "20.0.3" + "babel-plugin-jest-hoist": "22.0.3", + "babel-plugin-syntax-object-rest-spread": "6.13.0" } }, "babel-register": { @@ -947,6 +972,13 @@ "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", "dev": true }, + "bindings": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", + "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==", + "dev": true, + "optional": true + }, "boom": { "version": "2.10.1", "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", @@ -977,6 +1009,12 @@ "repeat-element": "1.1.2" } }, + "browser-process-hrtime": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz", + "integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44=", + "dev": true + }, "browser-resolve": { "version": "1.11.2", "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", @@ -984,14 +1022,6 @@ "dev": true, "requires": { "resolve": "1.1.7" - }, - "dependencies": { - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - } } }, "browserslist": { @@ -1062,6 +1092,12 @@ "integrity": "sha1-rbbqARNFFWY2gtuTq6spHUwClGs=", "dev": true }, + "capture-stack-trace": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", + "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=", + "dev": true + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -1110,6 +1146,12 @@ } } }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true + }, "ci-info": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.0.0.tgz", @@ -1126,9 +1168,9 @@ } }, "cli-width": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", - "integrity": "sha1-sjTKIJsp72b8UY2bmNWEewDt8Ao=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", "dev": true }, "cliui": { @@ -1153,9 +1195,9 @@ } }, "clone": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", - "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", + "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", "dev": true }, "cmd-shim": { @@ -1350,168 +1392,116 @@ "dev": true }, "content-type-parser": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.1.tgz", - "integrity": "sha1-w+VpiMU8ZRJ/tG1AMqOpACRv3JQ=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz", + "integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ==", "dev": true }, "conventional-changelog": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-1.1.4.tgz", - "integrity": "sha1-EIvHUMKjF+IA4vm0E8qqH4x++js=", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-1.1.7.tgz", + "integrity": "sha1-kVGmKx2O2y2CcR2r9bfPcQQfgrE=", "dev": true, "requires": { - "conventional-changelog-angular": "1.4.0", - "conventional-changelog-atom": "0.1.1", - "conventional-changelog-codemirror": "0.1.0", - "conventional-changelog-core": "1.9.0", - "conventional-changelog-ember": "0.2.6", - "conventional-changelog-eslint": "0.1.0", - "conventional-changelog-express": "0.1.0", + "conventional-changelog-angular": "1.6.0", + "conventional-changelog-atom": "0.1.2", + "conventional-changelog-codemirror": "0.2.1", + "conventional-changelog-core": "1.9.5", + "conventional-changelog-ember": "0.2.10", + "conventional-changelog-eslint": "0.2.1", + "conventional-changelog-express": "0.2.1", "conventional-changelog-jquery": "0.1.0", "conventional-changelog-jscs": "0.1.0", - "conventional-changelog-jshint": "0.1.0" + "conventional-changelog-jshint": "0.2.1" } }, "conventional-changelog-angular": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-1.4.0.tgz", - "integrity": "sha512-ukKX22lJl9ewogze1hKbBuff/dGMG2uyGpOhhw0ehhlv6GtdeCxj51YfGOZ5qC89WwsHT7SDXFzBKidwH3pwmQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-1.6.0.tgz", + "integrity": "sha1-CiagcfLJ/PzyuGugz79uYwG3W/o=", "dev": true, "requires": { "compare-func": "1.3.2", - "github-url-from-git": "1.5.0", - "q": "1.5.0", - "read-pkg-up": "2.0.0" - }, - "dependencies": { - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "strip-bom": "3.0.0" - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "2.3.0" - } - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "2.0.0", - "normalize-package-data": "2.4.0", - "path-type": "2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "2.1.0", - "read-pkg": "2.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } + "q": "1.5.1" } }, "conventional-changelog-atom": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-0.1.1.tgz", - "integrity": "sha512-6Nlu/+MiD4gi7k3Z+N1vMJWpaPSdvFPWzPGnH4OXewHAxiAl0L/TT9CGgA01fosPxmYr4hMNtD7kyN0tkg8vIA==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-0.1.2.tgz", + "integrity": "sha1-Ella1SZ6aTfDTPkAKBscZRmKTGM=", "dev": true, "requires": { - "q": "1.5.0" + "q": "1.5.1" } }, "conventional-changelog-cli": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/conventional-changelog-cli/-/conventional-changelog-cli-1.3.2.tgz", - "integrity": "sha512-Z89mXKV0IIB0q8tNvIIZtNNrun3MUuQC0YJPzsF2t5UyaqmqnOpLNLHX28+Pwi+aHI2LQjEar1OmEoZgYP+6Kw==", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/conventional-changelog-cli/-/conventional-changelog-cli-1.3.5.tgz", + "integrity": "sha1-RsUUliFrdAZYiIPe+m+sWJ6bsx4=", "dev": true, "requires": { "add-stream": "1.0.0", - "conventional-changelog": "1.1.4", + "conventional-changelog": "1.1.7", "lodash": "4.17.4", "meow": "3.7.0", "tempfile": "1.1.1" } }, "conventional-changelog-codemirror": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-0.1.0.tgz", - "integrity": "sha1-dXelkdv5tTjnoVCn7mL2WihyszQ=", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-0.2.1.tgz", + "integrity": "sha1-KZpPcUe681DmyBWPxUlUopHFzAk=", "dev": true, "requires": { - "q": "1.5.0" + "q": "1.5.1" } }, "conventional-changelog-core": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-1.9.0.tgz", - "integrity": "sha1-3l37wJGEdlZQjUo4njXJobxJ5/Q=", + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-1.9.5.tgz", + "integrity": "sha1-XbdWba18DLddr0f7spdve/mSjB0=", "dev": true, "requires": { - "conventional-changelog-writer": "1.4.1", - "conventional-commits-parser": "1.3.0", + "conventional-changelog-writer": "2.0.3", + "conventional-commits-parser": "2.1.0", "dateformat": "1.0.12", "get-pkg-repo": "1.4.0", - "git-raw-commits": "1.2.0", + "git-raw-commits": "1.3.0", "git-remote-origin-url": "2.0.0", - "git-semver-tags": "1.2.1", + "git-semver-tags": "1.2.3", "lodash": "4.17.4", "normalize-package-data": "2.4.0", - "q": "1.5.0", + "q": "1.5.1", "read-pkg": "1.1.0", "read-pkg-up": "1.0.1", "through2": "2.0.3" } }, "conventional-changelog-ember": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-0.2.6.tgz", - "integrity": "sha1-i3NVQZ9RJ0k8TFYkc6svx5LxwrY=", + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-0.2.10.tgz", + "integrity": "sha512-LBBBZO6Q7ib4HhSdyCNVR25OtaXl710UJg1aSHCLmR8AjuXKs3BO8tnbY1MH+D1C+z5IFoEDkpjOddefNTyhCQ==", "dev": true, "requires": { - "q": "1.5.0" + "q": "1.5.1" } }, "conventional-changelog-eslint": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-0.1.0.tgz", - "integrity": "sha1-pSQR6ZngUBzlALhWsKZD0DMJB+I=", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-0.2.1.tgz", + "integrity": "sha1-LCoRvrIW+AZJunKDQYApO2h8BmI=", "dev": true, "requires": { - "q": "1.5.0" + "q": "1.5.1" } }, "conventional-changelog-express": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-0.1.0.tgz", - "integrity": "sha1-VcbIQcgRliA2wDe9vZZKVK4xD84=", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-0.2.1.tgz", + "integrity": "sha1-g42eHmyQmXA7FQucGaoteBdCvWw=", "dev": true, "requires": { - "q": "1.5.0" + "q": "1.5.1" } }, "conventional-changelog-jquery": { @@ -1520,7 +1510,7 @@ "integrity": "sha1-Agg5cWLjhGmG5xJztsecW1+A9RA=", "dev": true, "requires": { - "q": "1.5.0" + "q": "1.5.1" } }, "conventional-changelog-jscs": { @@ -1529,41 +1519,41 @@ "integrity": "sha1-BHnrRDzH1yxYvwvPDvHURKkvDlw=", "dev": true, "requires": { - "q": "1.5.0" + "q": "1.5.1" } }, "conventional-changelog-jshint": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-0.1.0.tgz", - "integrity": "sha1-AMq46aMxdIer2UxNhGcTQpGNKgc=", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-0.2.1.tgz", + "integrity": "sha1-hhObs6yZiZ8rF36WF+CbN9mbzzo=", "dev": true, "requires": { "compare-func": "1.3.2", - "q": "1.5.0" + "q": "1.5.1" } }, "conventional-changelog-writer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-1.4.1.tgz", - "integrity": "sha1-P0y00APrtWmJ0w00WJO1KkNjnI4=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-2.0.3.tgz", + "integrity": "sha512-2E1h7UXL0fhRO5h0CxDZ5EBc5sfBZEQePvuZ+gPvApiRrICUyNDy/NQIP+2TBd4wKZQf2Zm7TxbzXHG5HkPIbA==", "dev": true, "requires": { "compare-func": "1.3.2", - "conventional-commits-filter": "1.0.0", + "conventional-commits-filter": "1.1.1", "dateformat": "1.0.12", "handlebars": "4.0.10", "json-stringify-safe": "5.0.1", "lodash": "4.17.4", "meow": "3.7.0", "semver": "5.3.0", - "split": "1.0.0", + "split": "1.0.1", "through2": "2.0.3" } }, "conventional-commits-filter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-1.0.0.tgz", - "integrity": "sha1-b8KmWTcrw/IznPn//34bA0S5MDk=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-1.1.1.tgz", + "integrity": "sha512-bQyatySNKHhcaeKVr9vFxYWA1W1Tdz6ybVMYDmv4/FhOXY1+fchiW07TzRbIQZhVa4cvBwrEaEUQBbCncFSdJQ==", "dev": true, "requires": { "is-subset": "0.1.1", @@ -1571,50 +1561,33 @@ } }, "conventional-commits-parser": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-1.3.0.tgz", - "integrity": "sha1-4ye1MZThp61dxjR57pCZpSsCSGU=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-2.1.0.tgz", + "integrity": "sha512-8MD05yN0Zb6aRsZnFX1ET+8rHWfWJk+my7ANCJZBU2mhz7TSB1fk2vZhkrwVy/PCllcTYAP/1T1NiWQ7Z01mKw==", "dev": true, "requires": { - "JSONStream": "1.3.1", + "JSONStream": "1.3.2", "is-text-path": "1.0.1", "lodash": "4.17.4", "meow": "3.7.0", - "split2": "2.1.1", + "split2": "2.2.0", "through2": "2.0.3", "trim-off-newlines": "1.0.1" } }, "conventional-recommended-bump": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-1.0.1.tgz", - "integrity": "sha512-2FrE8UJwt2EKpICi/E7P+xqyYUysdfMnFYiGV+7ANzJsixkBOrBKrKlCEV2NllCjR0XOmNfnA/mgozC5jAhhGQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-1.1.0.tgz", + "integrity": "sha512-WK0HnYnXd9e8J1YezUlfle+Pz7HB1RYvIH6gPLAXoroQTzDSfNfGM1tHHmdrJw0/4BMr+zw0U9V1WzFEfQwE3w==", "dev": true, "requires": { "concat-stream": "1.6.0", - "conventional-commits-filter": "1.0.0", - "conventional-commits-parser": "2.0.0", - "git-raw-commits": "1.2.0", - "git-semver-tags": "1.2.1", + "conventional-commits-filter": "1.1.1", + "conventional-commits-parser": "2.1.0", + "git-raw-commits": "1.3.0", + "git-semver-tags": "1.2.3", "meow": "3.7.0", "object-assign": "4.1.1" - }, - "dependencies": { - "conventional-commits-parser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-2.0.0.tgz", - "integrity": "sha512-8od6g684Fhi5Vpp4ABRv/RBsW1AY6wSHbJHEK6FGTv+8jvAAnlABniZu/FVmX9TcirkHepaEsa1QGkRvbg0CKw==", - "dev": true, - "requires": { - "JSONStream": "1.3.1", - "is-text-path": "1.0.1", - "lodash": "4.17.4", - "meow": "3.7.0", - "split2": "2.1.1", - "through2": "2.0.3", - "trim-off-newlines": "1.0.1" - } - } } }, "convert-source-map": { @@ -1635,6 +1608,15 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "dev": true, + "requires": { + "capture-stack-trace": "1.0.0" + } + }, "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", @@ -1736,6 +1718,12 @@ "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", "dev": true }, + "deep-extend": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", + "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", + "dev": true + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -1757,7 +1745,17 @@ "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", "dev": true, "requires": { - "clone": "1.0.2" + "clone": "1.0.3" + } + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "2.0.5", + "object-keys": "1.0.11" } }, "delayed-stream": { @@ -1781,10 +1779,22 @@ "repeating": "2.0.1" } }, + "detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", + "dev": true + }, "diff": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.0.tgz", - "integrity": "sha512-w0XZubFWn0Adlsapj9EAWX0FqWdO4tz8kc3RiYdWLh4k/V8PTb6i0SMgXt0vRM3zyKnT8tKO7mUlieRQHIjMNg==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", + "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==", + "dev": true + }, + "domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.0.tgz", + "integrity": "sha512-WpwuBlZ2lQRFa4H/4w49deb9rJLot9KmqrKKjMc9qBl7CID+DdC2swoa34ccRl+anL2B6bLp6TjFdIdnzekMBQ==", "dev": true }, "dot-prop": { @@ -1802,6 +1812,12 @@ "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", "dev": true }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, "ecc-jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", @@ -1824,15 +1840,6 @@ "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", "dev": true }, - "errno": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", - "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=", - "dev": true, - "requires": { - "prr": "0.0.0" - } - }, "error-ex": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", @@ -1842,6 +1849,30 @@ "is-arrayish": "0.2.1" } }, + "es-abstract": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", + "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", + "dev": true, + "requires": { + "es-to-primitive": "1.1.1", + "function-bind": "1.1.1", + "has": "1.0.1", + "is-callable": "1.1.3", + "is-regex": "1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "requires": { + "is-callable": "1.1.3", + "is-date-object": "1.0.1", + "is-symbol": "1.0.1" + } + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -1849,33 +1880,23 @@ "dev": true }, "escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz", + "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==", "dev": true, "requires": { - "esprima": "2.7.3", - "estraverse": "1.9.3", + "esprima": "3.1.3", + "estraverse": "4.2.0", "esutils": "2.0.2", "optionator": "0.8.2", - "source-map": "0.2.0" + "source-map": "0.5.6" }, "dependencies": { "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", "dev": true - }, - "source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", - "dev": true, - "optional": true, - "requires": { - "amdefine": "1.0.1" - } } } }, @@ -1886,9 +1907,9 @@ "dev": true }, "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", "dev": true }, "esutils": { @@ -1898,18 +1919,18 @@ "dev": true }, "exec-sh": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.0.tgz", - "integrity": "sha1-FPdd4/INKG75MwmbLOUKkDWc7xA=", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.1.tgz", + "integrity": "sha512-aLt95pexaugVtQerpmE51+4QfWrNc304uez7jvj6fWnN8GeEHpttB8F36n8N7uVhUMbH/1enbxQ9HImZ4w/9qg==", "dev": true, "requires": { "merge": "1.2.0" } }, "execa": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.6.3.tgz", - "integrity": "sha1-V7aaWU8IF1nGnlNw8NF7nLEWWP4=", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", + "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", "dev": true, "requires": { "cross-spawn": "5.1.0", @@ -1939,6 +1960,31 @@ "fill-range": "2.2.3" } }, + "expect": { + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-22.0.3.tgz", + "integrity": "sha512-QapzeQkcA3jCx4pDnD07I4SPPxScKbey8TD/WwrnzmpHmL5q0dUtXfUt5OIFOjVBCg+C4zn4Y1zK9Rb9SIDL1g==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "jest-diff": "22.0.3", + "jest-get-type": "22.0.3", + "jest-matcher-utils": "22.0.3", + "jest-message-util": "22.0.3", + "jest-regex-util": "22.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + } + } + }, "extend": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", @@ -1946,20 +1992,20 @@ "dev": true }, "external-editor": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.4.tgz", - "integrity": "sha1-HtkZnanL/i7y96MbL96LDRI2iXI=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", + "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", "dev": true, "requires": { - "iconv-lite": "0.4.18", - "jschardet": "1.5.0", - "tmp": "0.0.31" + "chardet": "0.4.2", + "iconv-lite": "0.4.19", + "tmp": "0.0.33" }, "dependencies": { "iconv-lite": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz", - "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==", + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", "dev": true } } @@ -1979,6 +2025,18 @@ "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=", "dev": true }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", @@ -2067,6 +2125,12 @@ "for-in": "1.0.2" } }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -2085,13 +2149,13 @@ } }, "fs-extra": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", - "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", "dev": true, "requires": { "graceful-fs": "4.1.11", - "jsonfile": "3.0.1", + "jsonfile": "4.0.0", "universalify": "0.1.1" } }, @@ -2101,64 +2165,974 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "requires": { - "aproba": "1.1.2", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" - } - }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", - "dev": true - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "requires": { - "is-property": "1.0.2" - } - }, - "get-caller-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", - "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", - "dev": true - }, - "get-pkg-repo": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz", - "integrity": "sha1-xztInAbYDMVTbCyFP54FIyBWly0=", + "fsevents": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", + "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", "dev": true, + "optional": true, "requires": { - "hosted-git-info": "2.5.0", - "meow": "3.7.0", - "normalize-package-data": "2.4.0", - "parse-github-repo-url": "1.4.0", - "through2": "2.0.3" - } - }, - "get-port": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.1.0.tgz", - "integrity": "sha1-7wGxioTKZIaXD/meVERhQac//T4=", - "dev": true - }, - "get-stdin": { - "version": "4.0.1", + "nan": "2.8.0", + "node-pre-gyp": "0.6.39" + }, + "dependencies": { + "abbrev": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "ajv": { + "version": "4.11.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.2.9" + } + }, + "asn1": { + "version": "0.2.3", + "bundled": true, + "dev": true, + "optional": true + }, + "assert-plus": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "asynckit": { + "version": "0.4.0", + "bundled": true, + "dev": true, + "optional": true + }, + "aws-sign2": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "aws4": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "balanced-match": { + "version": "0.4.2", + "bundled": true, + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "block-stream": { + "version": "0.0.9", + "bundled": true, + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "boom": { + "version": "2.10.1", + "bundled": true, + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "brace-expansion": { + "version": "1.1.7", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + } + }, + "buffer-shims": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "caseless": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true + }, + "co": { + "version": "4.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "combined-stream": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "requires": { + "delayed-stream": "1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "cryptiles": { + "version": "2.0.5", + "bundled": true, + "dev": true, + "requires": { + "boom": "2.10.1" + } + }, + "dashdash": { + "version": "1.14.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "debug": { + "version": "2.6.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.4.2", + "bundled": true, + "dev": true, + "optional": true + }, + "delayed-stream": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "ecc-jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "extend": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "extsprintf": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + }, + "form-data": { + "version": "2.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.15" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "fstream": { + "version": "1.0.11", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.1" + } + }, + "fstream-ignore": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fstream": "1.0.11", + "inherits": "2.0.3", + "minimatch": "3.0.4" + } + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "1.1.1", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" + } + }, + "getpass": { + "version": "0.1.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true, + "dev": true + }, + "har-schema": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "har-validator": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ajv": "4.11.8", + "har-schema": "1.0.5" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "hawk": { + "version": "3.1.3", + "bundled": true, + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "bundled": true, + "dev": true + }, + "http-signature": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.0", + "sshpk": "1.13.0" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.4", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "isstream": { + "version": "0.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "jodid25519": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "bundled": true, + "dev": true, + "optional": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "jsonify": { + "version": "0.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "jsprim": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.0.2", + "json-schema": "0.2.3", + "verror": "1.3.6" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "mime-db": { + "version": "1.27.0", + "bundled": true, + "dev": true + }, + "mime-types": { + "version": "2.1.15", + "bundled": true, + "dev": true, + "requires": { + "mime-db": "1.27.0" + } + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "node-pre-gyp": { + "version": "0.6.39", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "1.0.2", + "hawk": "3.1.3", + "mkdirp": "0.5.1", + "nopt": "4.0.1", + "npmlog": "4.1.0", + "rc": "1.2.1", + "request": "2.81.0", + "rimraf": "2.6.1", + "semver": "5.3.0", + "tar": "2.2.1", + "tar-pack": "3.4.0" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1.1.0", + "osenv": "0.1.4" + } + }, + "npmlog": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "performance-now": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "1.0.7", + "bundled": true, + "dev": true + }, + "punycode": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true + }, + "qs": { + "version": "6.4.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.2.9", + "bundled": true, + "dev": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.1", + "util-deprecate": "1.0.2" + } + }, + "request": { + "version": "2.81.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.15", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.0.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.6.0", + "uuid": "3.0.1" + } + }, + "rimraf": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "safe-buffer": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.3.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sntp": { + "version": "1.0.9", + "bundled": true, + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "sshpk": { + "version": "1.13.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jodid25519": "1.0.2", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, + "stringstream": { + "version": "0.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "2.2.1", + "bundled": true, + "dev": true, + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } + }, + "tar-pack": { + "version": "3.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "2.6.8", + "fstream": "1.0.11", + "fstream-ignore": "1.0.5", + "once": "1.4.0", + "readable-stream": "2.2.9", + "rimraf": "2.6.1", + "tar": "2.2.1", + "uid-number": "0.0.6" + } + }, + "tough-cookie": { + "version": "2.3.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "punycode": "1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "bundled": true, + "dev": true, + "optional": true + }, + "uid-number": { + "version": "0.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "uuid": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "verror": { + "version": "1.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "extsprintf": "1.0.2" + } + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "requires": { + "aproba": "1.2.0", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" + } + }, + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "requires": { + "is-property": "1.0.2" + } + }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "dev": true + }, + "get-pkg-repo": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz", + "integrity": "sha1-xztInAbYDMVTbCyFP54FIyBWly0=", + "dev": true, + "requires": { + "hosted-git-info": "2.5.0", + "meow": "3.7.0", + "normalize-package-data": "2.4.0", + "parse-github-repo-url": "1.4.1", + "through2": "2.0.3" + } + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", "dev": true @@ -2187,15 +3161,15 @@ } }, "git-raw-commits": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-1.2.0.tgz", - "integrity": "sha1-DzqL/ZmuDy2LkiTViJKXXppS0Dw=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-1.3.0.tgz", + "integrity": "sha1-C8hZbpDV/+c29/VUa9LRL3OrqsY=", "dev": true, "requires": { "dargs": "4.1.0", "lodash.template": "4.4.0", "meow": "3.7.0", - "split2": "2.1.1", + "split2": "2.2.0", "through2": "2.0.3" } }, @@ -2210,9 +3184,9 @@ } }, "git-semver-tags": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-1.2.1.tgz", - "integrity": "sha512-fFyxtzTHCTQKwB4clA2AInVrlflBbVbbJD4NWwmxKXHUgsU/K9kmHNlkPLqFiuy9xu9q3lNopghR4VXeQwZbTQ==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-1.2.3.tgz", + "integrity": "sha1-GItFOIK/nXojr9Mbq6U32rc4jV0=", "dev": true, "requires": { "meow": "3.7.0", @@ -2225,15 +3199,9 @@ "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=", "dev": true, "requires": { - "ini": "1.3.4" + "ini": "1.3.5" } }, - "github-url-from-git": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/github-url-from-git/-/github-url-from-git-1.5.0.tgz", - "integrity": "sha1-+YX+3MCpqledyI16/waNVcxiUaA=", - "dev": true - }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", @@ -2286,6 +3254,25 @@ "pinkie-promise": "2.0.1" } }, + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "dev": true, + "requires": { + "create-error-class": "3.0.2", + "duplexer3": "0.1.4", + "get-stream": "3.0.0", + "is-redirect": "1.0.0", + "is-retry-allowed": "1.1.0", + "is-stream": "1.1.0", + "lowercase-keys": "1.0.0", + "safe-buffer": "5.1.1", + "timed-out": "4.0.1", + "unzip-response": "2.0.1", + "url-parse-lax": "1.0.0" + } + }, "graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", @@ -2328,19 +3315,28 @@ } }, "har-schema": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", - "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", "dev": true }, "har-validator": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", - "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "dev": true, + "requires": { + "ajv": "5.5.2", + "har-schema": "2.0.0" + } + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", "dev": true, "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" + "function-bind": "1.1.1" } }, "has-ansi": { @@ -2399,12 +3395,12 @@ "dev": true }, "html-encoding-sniffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.1.tgz", - "integrity": "sha1-eb96eF6klf5mFl5zQVPzY/9UN9o=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", "dev": true, "requires": { - "whatwg-encoding": "1.0.1" + "whatwg-encoding": "1.0.3" } }, "http-signature": { @@ -2419,9 +3415,9 @@ } }, "iconv-lite": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", - "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", "dev": true }, "imurmurhash": { @@ -2456,22 +3452,22 @@ "dev": true }, "ini": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", - "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, "inquirer": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.2.0.tgz", - "integrity": "sha512-4CyUYMP7lOBkiUU1rR24WGrfRX6SucwbY2Mqb1PdApU24wnTIk4TsnkQwV72dDdIKZ2ycLP+fWCV+tA7wwgoew==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", "dev": true, "requires": { - "ansi-escapes": "2.0.0", + "ansi-escapes": "3.0.0", "chalk": "2.0.1", "cli-cursor": "2.1.0", - "cli-width": "2.1.0", - "external-editor": "2.0.4", + "cli-width": "2.2.0", + "external-editor": "2.1.0", "figures": "2.0.0", "lodash": "4.17.4", "mute-stream": "0.0.7", @@ -2484,9 +3480,9 @@ }, "dependencies": { "ansi-escapes": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-2.0.0.tgz", - "integrity": "sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", + "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", "dev": true }, "ansi-regex": { @@ -2558,6 +3554,12 @@ "builtin-modules": "1.1.1" } }, + "is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", + "dev": true + }, "is-ci": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", @@ -2567,6 +3569,12 @@ "ci-info": "1.0.0" } }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, "is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", @@ -2678,6 +3686,27 @@ "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", "dev": true }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "1.0.1" + } + }, + "is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", + "dev": true + }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -2690,13 +3719,19 @@ "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=", "dev": true }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", + "dev": true + }, "is-text-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", "dev": true, "requires": { - "text-extensions": "1.5.0" + "text-extensions": "1.7.0" } }, "is-typedarray": { @@ -2739,20 +3774,20 @@ "dev": true }, "istanbul-api": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.1.11.tgz", - "integrity": "sha1-/MC0YeKzvaceMFFVE4I4doJX2d4=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.2.1.tgz", + "integrity": "sha512-oFCwXvd65amgaPCzqrR+a2XjanS1MvpXN6l/MlMUTv6uiA1NOgGX+I0uyq8Lg3GDxsxPsaP1049krz3hIJ5+KA==", "dev": true, "requires": { - "async": "2.5.0", + "async": "2.6.0", "fileset": "2.0.3", "istanbul-lib-coverage": "1.1.1", - "istanbul-lib-hook": "1.0.7", - "istanbul-lib-instrument": "1.7.4", - "istanbul-lib-report": "1.1.1", - "istanbul-lib-source-maps": "1.2.1", - "istanbul-reports": "1.1.1", - "js-yaml": "3.9.0", + "istanbul-lib-hook": "1.1.0", + "istanbul-lib-instrument": "1.9.1", + "istanbul-lib-report": "1.1.2", + "istanbul-lib-source-maps": "1.2.2", + "istanbul-reports": "1.1.3", + "js-yaml": "3.10.0", "mkdirp": "0.5.1", "once": "1.4.0" } @@ -2760,37 +3795,45 @@ "istanbul-lib-coverage": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz", - "integrity": "sha1-c7+5mIhSmUFck9OKPprfeEp3qdo=", + "integrity": "sha512-0+1vDkmzxqJIn5rcoEqapSB4DmPxE31EtI2dF2aCkV5esN9EWHxZ0dwgDClivMXJqE7zaYQxq30hj5L0nlTN5Q==", "dev": true }, "istanbul-lib-hook": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz", - "integrity": "sha1-3WYH8DB2V4/n1vKmMM8UO0m6zdw=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz", + "integrity": "sha512-U3qEgwVDUerZ0bt8cfl3dSP3S6opBoOtk3ROO5f2EfBr/SRiD9FQqzwaZBqFORu8W7O0EXpai+k7kxHK13beRg==", "dev": true, "requires": { "append-transform": "0.4.0" } }, "istanbul-lib-instrument": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.4.tgz", - "integrity": "sha1-6f2SDkdn89Ge3HZeLWs/XMvQ7qg=", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.1.tgz", + "integrity": "sha512-RQmXeQ7sphar7k7O1wTNzVczF9igKpaeGQAG9qR2L+BS4DCJNTI9nytRmIVYevwO0bbq+2CXvJmYDuz0gMrywA==", "dev": true, "requires": { "babel-generator": "6.25.0", "babel-template": "6.25.0", "babel-traverse": "6.25.0", "babel-types": "6.25.0", - "babylon": "6.17.4", + "babylon": "6.18.0", "istanbul-lib-coverage": "1.1.1", "semver": "5.3.0" + }, + "dependencies": { + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + } } }, "istanbul-lib-report": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz", - "integrity": "sha1-8OVfVmVf+jQiIIC3oM1HYOFAX8k=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz", + "integrity": "sha512-UTv4VGx+HZivJQwAo1wnRwe1KTvFpfi/NYwN7DcsrdzMXwpRT/Yb6r4SBPoHWj4VuQPakR32g4PUUeyKkdDkBA==", "dev": true, "requires": { "istanbul-lib-coverage": "1.1.1", @@ -2817,359 +3860,336 @@ } }, "istanbul-lib-source-maps": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz", - "integrity": "sha1-pv4ay6jOCO68Y45XLilNJnAIqgw=", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz", + "integrity": "sha512-8BfdqSfEdtip7/wo1RnrvLpHVEd8zMZEDmOFEnpC6dg0vXflHt9nvoAyQUzig2uMSXfF2OBEYBV3CVjIL9JvaQ==", "dev": true, "requires": { - "debug": "2.6.8", + "debug": "3.1.0", "istanbul-lib-coverage": "1.1.1", "mkdirp": "0.5.1", "rimraf": "2.6.1", "source-map": "0.5.6" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } } }, "istanbul-reports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.1.1.tgz", - "integrity": "sha1-BCvlyJ4XW8P4ZSPKqynAFOd/7k4=", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.1.3.tgz", + "integrity": "sha512-ZEelkHh8hrZNI5xDaKwPMFwDsUf5wIEI2bXAFGp1e6deR2mnEKBPhLJEgr4ZBt8Gi6Mj38E/C8kcy9XLggVO2Q==", "dev": true, "requires": { "handlebars": "4.0.10" } }, "jest": { - "version": "20.0.4", - "resolved": "https://registry.npmjs.org/jest/-/jest-20.0.4.tgz", - "integrity": "sha1-PdJgwpidba1nix6cxNkZRPbWAqw=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-22.0.3.tgz", + "integrity": "sha512-90H1wLqiNR3tLhQUgwhC6GWHfRCG+Da14m7vxD608Mt/QTKR0TA751D+QH09x5bvcrLfvxLtxArtA0VEC0ORow==", "dev": true, "requires": { - "jest-cli": "20.0.4" + "jest-cli": "22.0.3" }, "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true }, "jest-cli": { - "version": "20.0.4", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-20.0.4.tgz", - "integrity": "sha1-5TKxnYiuW8bEF+iwWTpv6VSx3JM=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-22.0.3.tgz", + "integrity": "sha512-aX71DL4q9aLxbSmYI8uuPVlXVRyREU4VbApOdiuD79oqqqSGYu9E5S1SLXRm/PB5lJPh5xd8bVRrdsrMVs2hyw==", "dev": true, "requires": { - "ansi-escapes": "1.4.0", - "callsites": "2.0.0", - "chalk": "1.1.3", + "ansi-escapes": "3.0.0", + "chalk": "2.0.1", + "glob": "7.1.2", "graceful-fs": "4.1.11", "is-ci": "1.0.10", - "istanbul-api": "1.1.11", + "istanbul-api": "1.2.1", "istanbul-lib-coverage": "1.1.1", - "istanbul-lib-instrument": "1.7.4", - "istanbul-lib-source-maps": "1.2.1", - "jest-changed-files": "20.0.3", - "jest-config": "20.0.4", - "jest-docblock": "20.0.3", - "jest-environment-jsdom": "20.0.3", - "jest-haste-map": "20.0.4", - "jest-jasmine2": "20.0.4", - "jest-message-util": "20.0.3", - "jest-regex-util": "20.0.3", - "jest-resolve-dependencies": "20.0.3", - "jest-runtime": "20.0.4", - "jest-snapshot": "20.0.3", - "jest-util": "20.0.3", + "istanbul-lib-instrument": "1.9.1", + "istanbul-lib-source-maps": "1.2.2", + "jest-changed-files": "22.0.3", + "jest-config": "22.0.3", + "jest-environment-jsdom": "22.0.3", + "jest-get-type": "22.0.3", + "jest-haste-map": "22.0.3", + "jest-message-util": "22.0.3", + "jest-regex-util": "22.0.3", + "jest-resolve-dependencies": "22.0.3", + "jest-runner": "22.0.3", + "jest-runtime": "22.0.3", + "jest-snapshot": "22.0.3", + "jest-util": "22.0.3", + "jest-worker": "22.0.3", "micromatch": "2.3.11", "node-notifier": "5.1.2", - "pify": "2.3.0", + "realpath-native": "1.0.0", + "rimraf": "2.6.1", "slash": "1.0.0", - "string-length": "1.0.1", - "throat": "3.2.0", + "string-length": "2.0.0", + "strip-ansi": "4.0.0", "which": "1.2.14", - "worker-farm": "1.4.1", - "yargs": "7.1.0" + "yargs": "10.0.3" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" } } } }, "jest-changed-files": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-20.0.3.tgz", - "integrity": "sha1-k5TVzGXEOEBhSb7xv01Sto4D4/g=", - "dev": true + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-22.0.3.tgz", + "integrity": "sha512-CG7eNJNO9x1O/3J4Uhe2QXra1MnC9+KS1f2NeOg+7iQ+8dDCgxCtpusmKfu44TnEyKwkIDhDr6htPfPaI+Fwbw==", + "dev": true, + "requires": { + "throat": "4.1.0" + } }, "jest-config": { - "version": "20.0.4", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-20.0.4.tgz", - "integrity": "sha1-43kwqyIXyRNgXv8T5712PsSPruo=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-22.0.3.tgz", + "integrity": "sha512-omqyzFPhRm+YaHku+jPuqpSFJ0QD61G/hqR+m09r2IajJbaRjV9XDezCIOD+rJiQlAyfFfo+DAc+u1mLy2IEaA==", "dev": true, "requires": { - "chalk": "1.1.3", + "chalk": "2.0.1", "glob": "7.1.2", - "jest-environment-jsdom": "20.0.3", - "jest-environment-node": "20.0.3", - "jest-jasmine2": "20.0.4", - "jest-matcher-utils": "20.0.3", - "jest-regex-util": "20.0.3", - "jest-resolve": "20.0.4", - "jest-validate": "20.0.3", - "pretty-format": "20.0.3" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - } + "jest-environment-jsdom": "22.0.3", + "jest-environment-node": "22.0.3", + "jest-get-type": "22.0.3", + "jest-jasmine2": "22.0.3", + "jest-regex-util": "22.0.3", + "jest-resolve": "22.0.3", + "jest-util": "22.0.3", + "jest-validate": "22.0.3", + "pretty-format": "22.0.3" } }, "jest-diff": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-20.0.3.tgz", - "integrity": "sha1-gfKI/Z5nXw+yPHXxwrGURf5YZhc=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-22.0.3.tgz", + "integrity": "sha512-Y7xN9Lc/NgFvR14lvjrJXB6x2x1LLe5NnMyzLvilBSSOyjy9uAVnR2Bt1YgzdfRrfaxsx7xFUVcqXLUnPkrJcA==", "dev": true, "requires": { - "chalk": "1.1.3", - "diff": "3.3.0", - "jest-matcher-utils": "20.0.3", - "pretty-format": "20.0.3" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - } + "chalk": "2.0.1", + "diff": "3.4.0", + "jest-get-type": "22.0.3", + "pretty-format": "22.0.3" } }, "jest-docblock": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-20.0.3.tgz", - "integrity": "sha1-F76phDQswz2DxQ++FUXqDvqkRxI=", - "dev": true + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-22.0.3.tgz", + "integrity": "sha512-LhviP2rqIg2IzS6m97W7T032oMrT699Tr6Njjhhl4FCLj+75BUy9CsSmGgfoVEql1uc+myBkssvcbn7T9xDR+A==", + "dev": true, + "requires": { + "detect-newline": "2.1.0" + } }, "jest-environment-jsdom": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-20.0.3.tgz", - "integrity": "sha1-BIqKwS7iJfcZBBdxODS7mZeH3pk=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-22.0.3.tgz", + "integrity": "sha512-LrR9flT6I4IZKIA/dmoAiTmTzGi7W8sP5mCXbgsTjFop1Jh3rNluza/xnf6VfK/aOZvBglJIVYbKqGxtcm0KsQ==", "dev": true, "requires": { - "jest-mock": "20.0.3", - "jest-util": "20.0.3", - "jsdom": "9.12.0" + "jest-mock": "22.0.3", + "jest-util": "22.0.3", + "jsdom": "11.5.1" } }, "jest-environment-node": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-20.0.3.tgz", - "integrity": "sha1-1Ii8RhKvLCRumG6K52caCZFj1AM=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-22.0.3.tgz", + "integrity": "sha512-Kk7FYtCQZ+CFwwCL1t3DJ/Lxvjoda4qRt/NJh/6jsAEWM7VcSBAzmmayA5JcMRpQQ4FRiUcLrvrKEfO01/Fgsw==", "dev": true, "requires": { - "jest-mock": "20.0.3", - "jest-util": "20.0.3" + "jest-mock": "22.0.3", + "jest-util": "22.0.3" } }, + "jest-get-type": { + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-22.0.3.tgz", + "integrity": "sha512-TaJnc/lnJQ3jwry+NUWkqaJmKrM/Ut3XdK89HfiqdI3DMRLd6Zb4wyKjwuNP37MEQqlNg0YWH4sbBR8D4exjCA==", + "dev": true + }, "jest-haste-map": { - "version": "20.0.4", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-20.0.4.tgz", - "integrity": "sha1-ZT61XIic48Ah97lGk/IKQVm63wM=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-22.0.3.tgz", + "integrity": "sha512-VosIMOFQFu1rTF+MvOWVuv2KVmZ9eTkRgfwW2yUAs6/AhwmIfXRl/tih+fIOYcHzU4Auu1G8Fvl2kkF5g0k6/A==", "dev": true, "requires": { "fb-watchman": "2.0.0", "graceful-fs": "4.1.11", - "jest-docblock": "20.0.3", + "jest-docblock": "22.0.3", + "jest-worker": "22.0.3", "micromatch": "2.3.11", - "sane": "1.6.0", - "worker-farm": "1.4.1" + "sane": "2.2.0" } }, "jest-jasmine2": { - "version": "20.0.4", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-20.0.4.tgz", - "integrity": "sha1-/MWxQReA2RHQQpAu8YWehS5g1eE=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-22.0.3.tgz", + "integrity": "sha512-0Gz3pFZytCjbCKssBJWzx5NolNLg179gkT0Zfe+fWrJS9Ap9EH7eTB9UHoiT2O3lRNBfaYTzrXhOMgf4l/jCMg==", "dev": true, "requires": { - "chalk": "1.1.3", + "callsites": "2.0.0", + "chalk": "2.0.1", + "expect": "22.0.3", "graceful-fs": "4.1.11", - "jest-diff": "20.0.3", - "jest-matcher-utils": "20.0.3", - "jest-matchers": "20.0.3", - "jest-message-util": "20.0.3", - "jest-snapshot": "20.0.3", - "once": "1.4.0", - "p-map": "1.1.1" + "jest-diff": "22.0.3", + "jest-matcher-utils": "22.0.3", + "jest-message-util": "22.0.3", + "jest-snapshot": "22.0.3", + "source-map-support": "0.5.0" }, "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.0.tgz", + "integrity": "sha512-vUoN3I7fHQe0R/SJLKRdKYuEdRGogsviXFkHHo17AWaTGv17VLnxw+CFXvqy+y4ORZ3doWLQcxRYfwKrsd/H7Q==", "dev": true, "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "source-map": "0.6.1" } } } }, - "jest-matcher-utils": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-20.0.3.tgz", - "integrity": "sha1-s6a443yld4A7CDKpixZPRLeBVhI=", + "jest-leak-detector": { + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-22.0.3.tgz", + "integrity": "sha512-xyVdAmcG8M3jWtVeadDUU6MAHLBrjkP4clz2UtTZ1gpe5bRLk27VjQOpzTwK20MkV/6iZQhSuRVuzHS5kD0HpA==", "dev": true, "requires": { - "chalk": "1.1.3", - "pretty-format": "20.0.3" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - } + "pretty-format": "22.0.3", + "weak": "1.0.1" } }, - "jest-matchers": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jest-matchers/-/jest-matchers-20.0.3.tgz", - "integrity": "sha1-ymnbHDLbWm9wf6XgQBq7VXAN/WA=", + "jest-matcher-utils": { + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-22.0.3.tgz", + "integrity": "sha512-FJbKpCR3K7YYE/Pnvy5OrLFgPEswpYWIfVtdwT2NC6pBARbYGX39KF3bTxS9yg2mv0YL2zHe3UbwzFsi9nFpVA==", "dev": true, "requires": { - "jest-diff": "20.0.3", - "jest-matcher-utils": "20.0.3", - "jest-message-util": "20.0.3", - "jest-regex-util": "20.0.3" + "chalk": "2.0.1", + "jest-get-type": "22.0.3", + "pretty-format": "22.0.3" } }, "jest-message-util": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-20.0.3.tgz", - "integrity": "sha1-auwoRDBvyw5udNV5bBAG2W/dgxw=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-22.0.3.tgz", + "integrity": "sha512-AVBdCx7Oj5wBpMOH089lx7Zgwpdz9HbReA82HuVAlIT4kEQRvCy6Sl9yVWDGJwHTgB/OYQGkgmbv/P/K8TkWNw==", "dev": true, "requires": { - "chalk": "1.1.3", + "@babel/code-frame": "7.0.0-beta.35", + "chalk": "2.0.1", "micromatch": "2.3.11", - "slash": "1.0.0" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - } + "slash": "1.0.0", + "stack-utils": "1.0.1" } }, "jest-mock": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-20.0.3.tgz", - "integrity": "sha1-i8Bw6QQUqhVcEajWTIaaDVxx2lk=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-22.0.3.tgz", + "integrity": "sha512-donODXcDG03EAEavc9xfJ7fBF/LNVjoZYkmj9DLrQ1B9YcT6wh8Xx7IYg25b8V/8F/eXPMAE0KK5q6Fqe6yAeg==", "dev": true }, "jest-regex-util": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-20.0.3.tgz", - "integrity": "sha1-hburXRM+RGJbGfr4xqpRItCF12I=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-22.0.3.tgz", + "integrity": "sha512-mplC9chiAotES3ClzNhy0SJcfHB2DivooKJZW+2hDdvP8LLB+OUI+D6bJd7sncbKUsyFcmblEvpm/zz/hef7HA==", "dev": true }, "jest-resolve": { - "version": "20.0.4", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-20.0.4.tgz", - "integrity": "sha1-lEiz6La6/BVHlETGSZBFt//ll6U=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-22.0.3.tgz", + "integrity": "sha512-UHpim1kXTXH5hlftIpVOUkh0n+wd36/QNuYgpZnzwX8PsB8DizBuaPJbl5VvorHBpRouz21Ty0K0QM1pPny9cw==", "dev": true, "requires": { "browser-resolve": "1.11.2", - "is-builtin-module": "1.0.0", - "resolve": "1.3.3" + "chalk": "2.0.1" } }, "jest-resolve-dependencies": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-20.0.3.tgz", - "integrity": "sha1-bhSntxevDyyzZnxUneQK8Bexcjo=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-22.0.3.tgz", + "integrity": "sha512-u9MUNJIa9GJ0YFhvM0+Scr4tyX84nC42d3w18Cly1doY7pTT+9momm+TncpuDlFyB2aNmS8SfdEbiLr1e6tBwg==", + "dev": true, + "requires": { + "jest-regex-util": "22.0.3" + } + }, + "jest-runner": { + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-22.0.3.tgz", + "integrity": "sha512-b/Eh+bPFLU09R0AULy4/IcUQ4Cgiao7YcmCehI7eailVj2xGQAfhmzSlhDpVIYmvoRZFyReOseihZXXRsdFafA==", "dev": true, "requires": { - "jest-regex-util": "20.0.3" + "jest-config": "22.0.3", + "jest-docblock": "22.0.3", + "jest-haste-map": "22.0.3", + "jest-jasmine2": "22.0.3", + "jest-leak-detector": "22.0.3", + "jest-message-util": "22.0.3", + "jest-runtime": "22.0.3", + "jest-util": "22.0.3", + "jest-worker": "22.0.3", + "throat": "4.1.0" } }, "jest-runtime": { - "version": "20.0.4", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-20.0.4.tgz", - "integrity": "sha1-osgCIZxCA/dU3xQE5JAYYWnRJNg=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-22.0.3.tgz", + "integrity": "sha512-SSOiAde16JhEtVtNaWV2OmimmyxP8lmUdHxYde5rwv7iibkRy/o4QtalmmmH48oUxwy/epZVDaEyBKBA/iDFBg==", "dev": true, "requires": { "babel-core": "6.25.0", - "babel-jest": "20.0.3", - "babel-plugin-istanbul": "4.1.4", - "chalk": "1.1.3", + "babel-jest": "22.0.3", + "babel-plugin-istanbul": "4.1.5", + "chalk": "2.0.1", "convert-source-map": "1.5.0", "graceful-fs": "4.1.11", - "jest-config": "20.0.4", - "jest-haste-map": "20.0.4", - "jest-regex-util": "20.0.3", - "jest-resolve": "20.0.4", - "jest-util": "20.0.3", + "jest-config": "22.0.3", + "jest-haste-map": "22.0.3", + "jest-regex-util": "22.0.3", + "jest-resolve": "22.0.3", + "jest-util": "22.0.3", "json-stable-stringify": "1.0.1", "micromatch": "2.3.11", + "realpath-native": "1.0.0", + "slash": "1.0.0", "strip-bom": "3.0.0", - "yargs": "7.1.0" + "write-file-atomic": "2.3.0", + "yargs": "10.0.3" }, "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -3179,89 +4199,53 @@ } }, "jest-snapshot": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-20.0.3.tgz", - "integrity": "sha1-W4R+GtsaTZCFKn+fElCG4YfHZWY=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-22.0.3.tgz", + "integrity": "sha512-e/a/EvMsY5XROWy4QWX6PvYziuJ8ttD6+QcnbogODWtx2LGhvVQOb7pmqGTo0tL/p0vzFetZA9GlZSh/EfMepg==", "dev": true, "requires": { - "chalk": "1.1.3", - "jest-diff": "20.0.3", - "jest-matcher-utils": "20.0.3", - "jest-util": "20.0.3", + "chalk": "2.0.1", + "jest-diff": "22.0.3", + "jest-matcher-utils": "22.0.3", + "mkdirp": "0.5.1", "natural-compare": "1.4.0", - "pretty-format": "20.0.3" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - } + "pretty-format": "22.0.3" } }, "jest-util": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-20.0.3.tgz", - "integrity": "sha1-DAf32A2C9OWmfG+LnD/n9lz9Mq0=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-22.0.3.tgz", + "integrity": "sha512-iDnKIw4P+9433L7II90UGYZ4rQOatbbcjZO/+1+Fga+rNUF1wEijDfTDjGQil98smAquvB02RBrDgfbquUHLmg==", "dev": true, "requires": { - "chalk": "1.1.3", + "callsites": "2.0.0", + "chalk": "2.0.1", "graceful-fs": "4.1.11", - "jest-message-util": "20.0.3", - "jest-mock": "20.0.3", - "jest-validate": "20.0.3", - "leven": "2.1.0", + "is-ci": "1.0.10", + "jest-message-util": "22.0.3", + "jest-validate": "22.0.3", "mkdirp": "0.5.1" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - } } }, "jest-validate": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-20.0.3.tgz", - "integrity": "sha1-0M/R3k9XnymEhJJcKA+PHZTsPKs=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-22.0.3.tgz", + "integrity": "sha512-GmlLmPCtrSQ3iB4A1uxcfjawaaQnwESCDcUg5tMxJKeBbmPdcWPAb6EWzvANxULPUV7hfPKLwg4xIPpi7cx1/g==", "dev": true, "requires": { - "chalk": "1.1.3", - "jest-matcher-utils": "20.0.3", - "leven": "2.1.0", - "pretty-format": "20.0.3" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - } + "chalk": "2.0.1", + "jest-get-type": "22.0.3", + "leven": "2.1.0", + "pretty-format": "22.0.3" + } + }, + "jest-worker": { + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-22.0.3.tgz", + "integrity": "sha512-fPdCTnogFQiR0CP6whEsIly2RfcHxvalqyLjhui6qa1SnOmHiX7L8k4Umo8CBIp5ndWY0+ej1o7OTE5MlzPabg==", + "dev": true, + "requires": { + "merge-stream": "1.0.1" } }, "js-tokens": { @@ -3271,9 +4255,9 @@ "dev": true }, "js-yaml": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.0.tgz", - "integrity": "sha512-0LoUNELX4S+iofCT8f4uEHIiRBR+c2AINyC8qRWfC6QNruLtxVZRJaPcu/xwMgFIgDxF25tGHaDjvxzJCNE9yw==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", "dev": true, "requires": { "argparse": "1.0.9", @@ -3287,37 +4271,47 @@ "dev": true, "optional": true }, - "jschardet": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.5.0.tgz", - "integrity": "sha512-+Q8JsoEQbrdE+a/gg1F9XO92gcKXgpE5UACqr0sIubjDmBEkd+OOWPGzQeMrWSLxd73r4dHxBeRW7edHu5LmJQ==", - "dev": true - }, "jsdom": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-9.12.0.tgz", - "integrity": "sha1-6MVG//ywbADUgzyoRBD+1/igl9Q=", + "version": "11.5.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.5.1.tgz", + "integrity": "sha512-89ztIZ03aYK9f1uUrLXLsZndRge/JnZjzjpaN+lrse3coqz+8PR/dX4WLHpbF5fIKTXhDjFODOJw2328lPJ90g==", "dev": true, "requires": { - "abab": "1.0.3", - "acorn": "4.0.13", - "acorn-globals": "3.1.0", + "abab": "1.0.4", + "acorn": "5.2.1", + "acorn-globals": "4.1.0", "array-equal": "1.0.0", - "content-type-parser": "1.0.1", + "browser-process-hrtime": "0.1.2", + "content-type-parser": "1.0.2", "cssom": "0.3.2", "cssstyle": "0.2.37", - "escodegen": "1.8.1", - "html-encoding-sniffer": "1.0.1", - "nwmatcher": "1.4.1", - "parse5": "1.5.1", - "request": "2.81.0", + "domexception": "1.0.0", + "escodegen": "1.9.0", + "html-encoding-sniffer": "1.0.2", + "left-pad": "1.2.0", + "nwmatcher": "1.4.3", + "parse5": "3.0.3", + "pn": "1.0.0", + "request": "2.83.0", + "request-promise-native": "1.0.5", "sax": "1.2.4", "symbol-tree": "3.2.2", - "tough-cookie": "2.3.2", - "webidl-conversions": "4.0.1", - "whatwg-encoding": "1.0.1", - "whatwg-url": "4.8.0", + "tough-cookie": "2.3.3", + "webidl-conversions": "4.0.2", + "whatwg-encoding": "1.0.3", + "whatwg-url": "6.4.0", "xml-name-validator": "2.0.1" + }, + "dependencies": { + "tough-cookie": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", + "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "dev": true, + "requires": { + "punycode": "1.4.1" + } + } } }, "jsesc": { @@ -3332,6 +4326,12 @@ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", "dev": true }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true + }, "json-stable-stringify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", @@ -3354,9 +4354,9 @@ "dev": true }, "jsonfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", - "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true, "requires": { "graceful-fs": "4.1.11" @@ -3425,45 +4425,54 @@ "invert-kv": "1.0.0" } }, + "left-pad": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.2.0.tgz", + "integrity": "sha1-0wpzxrggHY99jnlWupYWCHpo4O4=", + "dev": true + }, "lerna": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lerna/-/lerna-2.0.0.tgz", - "integrity": "sha1-Sacv5w4Grr/X6iPvsqtBq+YOvuo=", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/lerna/-/lerna-2.5.1.tgz", + "integrity": "sha512-Qz2fajqCPtZf4SFQQpQ2R/Ml/RvGvTNuIHix/vAMMSAdbtnPe2QTw34vLD24Clfsfy8FEojy+tqsjejWKqkDFw==", "dev": true, "requires": { "async": "1.5.2", - "chalk": "1.1.3", + "chalk": "2.3.0", "cmd-shim": "2.0.2", "columnify": "1.5.4", "command-join": "2.0.0", - "conventional-changelog-cli": "1.3.2", - "conventional-recommended-bump": "1.0.1", + "conventional-changelog-cli": "1.3.5", + "conventional-recommended-bump": "1.1.0", "dedent": "0.7.0", - "execa": "0.6.3", + "execa": "0.8.0", "find-up": "2.1.0", - "fs-extra": "3.0.1", - "get-port": "3.1.0", + "fs-extra": "4.0.3", + "get-port": "3.2.0", "glob": "7.1.2", + "glob-parent": "3.1.0", "globby": "6.1.0", "graceful-fs": "4.1.11", - "inquirer": "3.2.0", + "hosted-git-info": "2.5.0", + "inquirer": "3.3.0", "is-ci": "1.0.10", - "load-json-file": "2.0.0", + "load-json-file": "3.0.0", "lodash": "4.17.4", "minimatch": "3.0.4", "npmlog": "4.1.2", "p-finally": "1.0.0", + "package-json": "4.0.1", "path-exists": "3.0.0", "read-cmd-shim": "1.0.1", "read-pkg": "2.0.0", "rimraf": "2.6.1", "safe-buffer": "5.1.1", - "semver": "5.3.0", + "semver": "5.4.1", "signal-exit": "3.0.2", "strong-log-transformer": "1.0.6", "temp-write": "3.3.0", - "write-file-atomic": "2.1.0", - "write-json-file": "2.2.0", + "write-file-atomic": "2.3.0", + "write-json-file": "2.3.0", "write-pkg": "3.1.0", "yargs": "8.0.2" }, @@ -3474,6 +4483,15 @@ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", @@ -3487,16 +4505,14 @@ "dev": true }, "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { - "ansi-styles": "2.2.1", + "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "supports-color": "4.5.0" } }, "cliui": { @@ -3523,57 +4539,62 @@ } } }, - "cross-spawn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "lru-cache": "4.1.1", - "which": "1.2.14" + "is-glob": "3.1.0", + "path-dirname": "1.0.2" } }, - "get-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "object-assign": "4.1.1", - "pinkie-promise": "2.0.1" + "is-extglob": "2.1.1" } }, "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-3.0.0.tgz", + "integrity": "sha1-frNzXZg6ftImKt5P92mvU2nFxEA=", "dev": true, "requires": { "graceful-fs": "4.1.11", - "parse-json": "2.2.0", + "parse-json": "3.0.0", "pify": "2.3.0", "strip-bom": "3.0.0" } }, "os-locale": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.0.0.tgz", - "integrity": "sha1-FZGN7VEFIrge565aMJ1U9jn8OaQ=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", "dev": true, "requires": { - "execa": "0.5.1", + "execa": "0.7.0", "lcid": "1.0.0", "mem": "1.1.0" }, "dependencies": { "execa": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.5.1.tgz", - "integrity": "sha1-3j+4XLjW6RyFvLzrFkWBeFy1ezY=", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "dev": true, "requires": { - "cross-spawn": "4.0.2", - "get-stream": "2.3.1", + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", "is-stream": "1.1.0", "npm-run-path": "2.0.2", "p-finally": "1.0.0", @@ -3583,6 +4604,15 @@ } } }, + "parse-json": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-3.0.0.tgz", + "integrity": "sha1-+m9HsY4jgm6tMvJj50TQ4ehH+xM=", + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + }, "path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", @@ -3601,6 +4631,29 @@ "load-json-file": "2.0.0", "normalize-package-data": "2.4.0", "path-type": "2.0.0" + }, + "dependencies": { + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + } } }, "read-pkg-up": { @@ -3613,6 +4666,12 @@ "read-pkg": "2.0.0" } }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true + }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -3646,6 +4705,15 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", @@ -3662,7 +4730,7 @@ "cliui": "3.2.0", "decamelize": "1.2.0", "get-caller-file": "1.0.2", - "os-locale": "2.0.0", + "os-locale": "2.1.0", "read-pkg-up": "2.0.0", "require-directory": "2.1.1", "require-main-filename": "1.0.1", @@ -3746,6 +4814,12 @@ "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", "dev": true }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, "lodash.template": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", @@ -3790,10 +4864,16 @@ "signal-exit": "3.0.2" } }, + "lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", + "dev": true + }, "lru-cache": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha1-Yi4y6CSItJJ5EUpPns9F581rulU=", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", "dev": true, "requires": { "pseudomap": "1.0.2", @@ -3865,6 +4945,15 @@ "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=", "dev": true }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "dev": true, + "requires": { + "readable-stream": "2.3.3" + } + }, "micromatch": { "version": "2.3.11", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", @@ -3883,7 +4972,7 @@ "normalize-path": "2.1.1", "object.omit": "2.0.1", "parse-glob": "3.0.4", - "regex-cache": "0.4.3" + "regex-cache": "0.4.4" } }, "mime-db": { @@ -3938,9 +5027,9 @@ "dev": true }, "moment": { - "version": "2.18.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz", - "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8=", + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.20.1.tgz", + "integrity": "sha512-Yh9y73JRljxW5QxN08Fner68eFLxM5ynNOAw2LbIB1YAGeQzZT8QFSUvkAz609Zf+IHhhaUxqZK8dG3W/+HEvg==", "dev": true }, "ms": { @@ -3955,6 +5044,13 @@ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, + "nan": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", + "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=", + "dev": true, + "optional": true + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -3975,7 +5071,7 @@ "requires": { "growly": "1.3.0", "semver": "5.3.0", - "shellwords": "0.1.0", + "shellwords": "0.1.1", "which": "1.2.14" } }, @@ -3997,7 +5093,7 @@ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { - "remove-trailing-separator": "1.0.2" + "remove-trailing-separator": "1.1.0" } }, "npm-run-path": { @@ -4012,7 +5108,7 @@ "npmlog": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha1-CKfyqL9zRgR3mp76StXMcXq7lUs=", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dev": true, "requires": { "are-we-there-yet": "1.1.4", @@ -4028,9 +5124,9 @@ "dev": true }, "nwmatcher": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.1.tgz", - "integrity": "sha1-eumwew6oBNt+JfBctf5Al9TklJ8=", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.3.tgz", + "integrity": "sha512-IKdSTiDWCarf2JTS5e9e2+5tPZGdkRJ79XjYV0pzK8Q9BpsFyBq1RGKxzs7Q8UBushGw7m6TzVKz6fcY99iSWw==", "dev": true }, "oauth-sign": { @@ -4045,6 +5141,22 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", + "dev": true + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "dev": true, + "requires": { + "define-properties": "1.1.2", + "es-abstract": "1.10.0" + } + }, "object.omit": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", @@ -4112,12 +5224,31 @@ "dev": true }, "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", "dev": true, "requires": { - "lcid": "1.0.0" + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + }, + "dependencies": { + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + } } }, "os-tmpdir": { @@ -4147,16 +5278,22 @@ "p-limit": "1.1.0" } }, - "p-map": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.1.1.tgz", - "integrity": "sha1-BfXkrpegaDcbwqXMhr+9vBnErno=", - "dev": true + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "dev": true, + "requires": { + "got": "6.7.1", + "registry-auth-token": "3.3.1", + "registry-url": "3.1.0", + "semver": "5.3.0" + } }, "parse-github-repo-url": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.0.tgz", - "integrity": "sha1-KGxT4smWLgZBZJ7jrJUI/KTdlZw=", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz", + "integrity": "sha1-nn2LslKmy2ukJZUGC3v23z28H1A=", "dev": true }, "parse-glob": { @@ -4181,9 +5318,18 @@ } }, "parse5": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", - "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", + "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "dev": true, + "requires": { + "@types/node": "8.5.2" + } + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", "dev": true }, "path-exists": { @@ -4222,9 +5368,9 @@ } }, "performance-now": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, "pify": { @@ -4257,12 +5403,24 @@ "find-up": "2.1.0" } }, + "pn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.0.0.tgz", + "integrity": "sha1-HPWjCw2AbNGPiPxBprXUrWFbO6k=", + "dev": true + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, "preserve": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", @@ -4270,19 +5428,25 @@ "dev": true }, "pretty-format": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-20.0.3.tgz", - "integrity": "sha1-Ag41ClYKH+GpjcO+tsz/s4beixQ=", + "version": "22.0.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-22.0.3.tgz", + "integrity": "sha512-qXbDFJ2/Kk3HFIaLdOblbsCKQ09kZu4MKbXB+m/EaqD7PZ/wXe2XcRREmQleMh4wmerxlma6eJTh3nxCXYUmmA==", "dev": true, "requires": { - "ansi-regex": "2.1.1", - "ansi-styles": "3.1.0" + "ansi-regex": "3.0.0", + "ansi-styles": "3.2.0" }, "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, "ansi-styles": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.1.0.tgz", - "integrity": "sha1-CcIC1ckX7CMYjKpcnLkXnNlUd1A=", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { "color-convert": "1.9.0" @@ -4302,12 +5466,6 @@ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", "dev": true }, - "prr": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", - "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", - "dev": true - }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -4321,21 +5479,21 @@ "dev": true }, "q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz", - "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", "dev": true }, "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", "dev": true }, "randomatic": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha1-x6vpzIuHwLqodrGf3oP9RkeX44w=", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", "dev": true, "requires": { "is-number": "3.0.0", @@ -4373,6 +5531,26 @@ } } }, + "rc": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz", + "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=", + "dev": true, + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.5", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, "read-cmd-shim": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz", @@ -4427,7 +5605,7 @@ "readable-stream": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha1-No8lEtefnUb9/HE0mueHi7weuVw=", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", "dev": true, "requires": { "core-util-is": "1.0.2", @@ -4439,6 +5617,15 @@ "util-deprecate": "1.0.2" } }, + "realpath-native": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.0.0.tgz", + "integrity": "sha512-XJtlRJ9jf0E1H1SLeJyQ9PGzQD7S65h1pRXEcAeK48doKOnKxcgPeNohJvD5u/2sI9J1oke6E8bZHS/fmW1UiQ==", + "dev": true, + "requires": { + "util.promisify": "1.0.0" + } + }, "redent": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", @@ -4473,13 +5660,12 @@ } }, "regex-cache": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz", - "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=", + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", "dev": true, "requires": { - "is-equal-shallow": "0.1.3", - "is-primitive": "2.0.0" + "is-equal-shallow": "0.1.3" } }, "regexpu-core": { @@ -4493,6 +5679,25 @@ "regjsparser": "0.1.5" } }, + "registry-auth-token": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz", + "integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=", + "dev": true, + "requires": { + "rc": "1.2.2", + "safe-buffer": "5.1.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "dev": true, + "requires": { + "rc": "1.2.2" + } + }, "regjsgen": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", @@ -4516,61 +5721,208 @@ } } }, - "remove-trailing-separator": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz", - "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=", - "dev": true - }, - "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "1.0.2" + } + }, + "request": { + "version": "2.83.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", + "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", + "dev": true, + "requires": { + "aws-sign2": "0.7.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.3.1", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.17", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.1", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.3", + "tunnel-agent": "0.6.0", + "uuid": "3.1.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "boom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "dev": true, + "requires": { + "hoek": "4.2.0" + } + }, + "cryptiles": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", + "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", + "dev": true, + "requires": { + "boom": "5.2.0" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "dev": true, + "requires": { + "hoek": "4.2.0" + } + } + } + }, + "form-data": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", + "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", + "dev": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" + } + }, + "hawk": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "dev": true, + "requires": { + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.0", + "sntp": "2.1.0" + } + }, + "hoek": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", + "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==", + "dev": true + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "jsprim": "1.4.0", + "sshpk": "1.13.1" + } + }, + "mime-db": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=", + "dev": true + }, + "mime-types": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", + "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "dev": true, + "requires": { + "mime-db": "1.30.0" + } + }, + "sntp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "dev": true, + "requires": { + "hoek": "4.2.0" + } + }, + "tough-cookie": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", + "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "dev": true, + "requires": { + "punycode": "1.4.1" + } + } + } + }, + "request-promise-core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", + "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", "dev": true, "requires": { - "is-finite": "1.0.2" + "lodash": "4.17.4" } }, - "request": { - "version": "2.81.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", - "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "request-promise-native": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz", + "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=", "dev": true, "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.15", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.2", - "tunnel-agent": "0.6.0", - "uuid": "3.1.0" + "request-promise-core": "1.1.1", + "stealthy-require": "1.1.1", + "tough-cookie": "2.3.3" + }, + "dependencies": { + "tough-cookie": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", + "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "dev": true, + "requires": { + "punycode": "1.4.1" + } + } } }, "require-directory": { @@ -4586,13 +5938,10 @@ "dev": true }, "resolve": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.3.3.tgz", - "integrity": "sha1-ZVkHw0aahoDcLeOidaj91paR8OU=", - "dev": true, - "requires": { - "path-parse": "1.0.5" - } + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true }, "restore-cursor": { "version": "2.0.0", @@ -4654,38 +6003,21 @@ "dev": true }, "sane": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-1.6.0.tgz", - "integrity": "sha1-lhDEUjB6E10pwf3+JUcDQYDEZ3U=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-2.2.0.tgz", + "integrity": "sha512-OSJxhHO0CgPUw3lUm3GhfREAfza45smvEI9ozuFrxKG10GHVo0ryW9FK5VYlLvxj0SV7HVKHW0voYJIRu27GWg==", "dev": true, "requires": { - "anymatch": "1.3.0", - "exec-sh": "0.2.0", - "fb-watchman": "1.9.2", + "anymatch": "1.3.2", + "exec-sh": "0.2.1", + "fb-watchman": "2.0.0", + "fsevents": "1.1.3", "minimatch": "3.0.4", "minimist": "1.2.0", "walker": "1.0.7", - "watch": "0.10.0" + "watch": "0.18.0" }, "dependencies": { - "bser": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bser/-/bser-1.0.2.tgz", - "integrity": "sha1-OBEWlwsqbe6lZG3RXdcnhES1YWk=", - "dev": true, - "requires": { - "node-int64": "0.4.0" - } - }, - "fb-watchman": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-1.9.2.tgz", - "integrity": "sha1-okz0eCf4LTj7Waaa1wt247auc4M=", - "dev": true, - "requires": { - "bser": "1.0.2" - } - }, "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", @@ -4697,7 +6029,7 @@ "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, "semver": { @@ -4728,9 +6060,9 @@ "dev": true }, "shellwords": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.0.tgz", - "integrity": "sha1-Zq/Ue2oSky2Qccv9mKUueFzQuhQ=", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", "dev": true }, "signal-exit": { @@ -4745,12 +6077,6 @@ "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", "dev": true }, - "slide": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", - "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", - "dev": true - }, "sntp": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", @@ -4761,9 +6087,9 @@ } }, "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", "dev": true, "requires": { "is-plain-obj": "1.1.0" @@ -4806,18 +6132,18 @@ "dev": true }, "split": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.0.tgz", - "integrity": "sha1-xDlc5oOrzSVLwo/h2rtuXCfc/64=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", "dev": true, "requires": { "through": "2.3.8" } }, "split2": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/split2/-/split2-2.1.1.tgz", - "integrity": "sha1-eh9VHhdqkOzTNF9yRqDP4XXvT9A=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", + "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", "dev": true, "requires": { "through2": "2.0.3" @@ -4853,13 +6179,43 @@ } } }, - "string-length": { + "stack-utils": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", - "integrity": "sha1-VpcPscOFWOnnC3KL894mmsRa36w=", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha1-1PM6tU6OOHeLDKXP07OvsS22hiA=", + "dev": true + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "string-length": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", + "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=", "dev": true, "requires": { - "strip-ansi": "3.0.1" + "astral-regex": "1.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } } }, "string-width": { @@ -4876,7 +6232,7 @@ "string_decoder": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", "dev": true, "requires": { "safe-buffer": "5.1.1" @@ -4921,6 +6277,12 @@ "get-stdin": "4.0.1" } }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, "strong-log-transformer": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-1.0.6.tgz", @@ -4930,7 +6292,7 @@ "byline": "5.0.0", "duplexer": "0.1.1", "minimist": "0.1.0", - "moment": "2.18.1", + "moment": "2.20.1", "through": "2.3.8" }, "dependencies": { @@ -4995,7 +6357,7 @@ "test-exclude": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.1.1.tgz", - "integrity": "sha1-TYSWSwlmsAh+zDNKLOAC09k0HiY=", + "integrity": "sha512-35+Asrsk3XHJDBgf/VRFexPgh3UyETv8IAn/LRTiZjVy6rjPVqdEk8dJcJYBzl1w0XCJM48lvTy8SfEsCWS4nA==", "dev": true, "requires": { "arrify": "1.0.1", @@ -5006,15 +6368,15 @@ } }, "text-extensions": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.5.0.tgz", - "integrity": "sha1-0cstFLXQvEW/3Kigikc/aMfrDLw=", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.7.0.tgz", + "integrity": "sha512-AKXZeDq230UaSzaO5s3qQUZOaC7iKbzq0jOFL614R7d9R593HLqAOL0cYoqLdkNrjBSOdmoQI06yigq1TSBXAg==", "dev": true }, "throat": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-3.2.0.tgz", - "integrity": "sha1-UMsGcO28QCN7njR9fh+I5GIK+DY=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", + "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", "dev": true }, "through": { @@ -5033,10 +6395,16 @@ "xtend": "4.0.1" } }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, "tmp": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", - "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { "os-tmpdir": "1.0.2" @@ -5064,10 +6432,21 @@ } }, "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "requires": { + "punycode": "2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", + "dev": true + } + } }, "trim-newlines": { "version": "1.0.0", @@ -5158,6 +6537,21 @@ "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=", "dev": true }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", + "dev": true + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true, + "requires": { + "prepend-http": "1.0.4" + } + }, "urlgrey": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-0.4.4.tgz", @@ -5170,6 +6564,16 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "dev": true, + "requires": { + "define-properties": "1.1.2", + "object.getownpropertydescriptors": "2.0.3" + } + }, "uuid": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", @@ -5205,10 +6609,22 @@ } }, "watch": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/watch/-/watch-0.10.0.tgz", - "integrity": "sha1-d3mLLaD5kQ1ZXxrOWwwiWFIfIdw=", - "dev": true + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/watch/-/watch-0.18.0.tgz", + "integrity": "sha1-KAlUdsbffJDJYxOJkMClQj60uYY=", + "dev": true, + "requires": { + "exec-sh": "0.2.1", + "minimist": "1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } }, "wcwidth": { "version": "1.0.1", @@ -5219,37 +6635,41 @@ "defaults": "1.0.3" } }, + "weak": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/weak/-/weak-1.0.1.tgz", + "integrity": "sha1-q5mqswcGlZqgIAy4z1RbucszuZ4=", + "dev": true, + "optional": true, + "requires": { + "bindings": "1.3.0", + "nan": "2.8.0" + } + }, "webidl-conversions": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.1.tgz", - "integrity": "sha1-gBWherg+fhsxFjhIas6B2mziBqA=", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", "dev": true }, "whatwg-encoding": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.1.tgz", - "integrity": "sha1-PGxFGhmO567FWx7GHQkgxngBpfQ=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz", + "integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==", "dev": true, "requires": { - "iconv-lite": "0.4.13" + "iconv-lite": "0.4.19" } }, "whatwg-url": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz", - "integrity": "sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA=", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.4.0.tgz", + "integrity": "sha512-Z0CVh/YE217Foyb488eo+iBv+r7eAQ0wSTyApi9n06jhcA3z6Nidg/EGvl0UFkg7kMdKxfBzzr+o9JF+cevgMg==", "dev": true, "requires": { - "tr46": "0.0.3", - "webidl-conversions": "3.0.1" - }, - "dependencies": { - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true - } + "lodash.sortby": "4.7.0", + "tr46": "1.0.1", + "webidl-conversions": "4.0.2" } }, "which": { @@ -5262,15 +6682,15 @@ } }, "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, "wide-align": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", - "integrity": "sha1-Vx4PGwYEY268DfwhsDObvjE0FxA=", + "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", "dev": true, "requires": { "string-width": "1.0.2" @@ -5289,16 +6709,6 @@ "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", "dev": true }, - "worker-farm": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.4.1.tgz", - "integrity": "sha1-pDi8mTp6fRM7y2VHyV7KfP9Il9g=", - "dev": true, - "requires": { - "errno": "0.1.4", - "xtend": "4.0.1" - } - }, "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", @@ -5316,28 +6726,28 @@ "dev": true }, "write-file-atomic": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.1.0.tgz", - "integrity": "sha1-F2n0tVHu3OQZ8FBd6uLiZ2NULTc=", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", + "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", "dev": true, "requires": { "graceful-fs": "4.1.11", "imurmurhash": "0.1.4", - "slide": "1.1.6" + "signal-exit": "3.0.2" } }, "write-json-file": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-2.2.0.tgz", - "integrity": "sha1-UYYlBruzthnu+reFnx/WxtBTCHY=", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-2.3.0.tgz", + "integrity": "sha1-K2TIozAE1UuGmMdtWFp3zrYdoy8=", "dev": true, "requires": { "detect-indent": "5.0.0", "graceful-fs": "4.1.11", "make-dir": "1.0.0", - "pify": "2.3.0", - "sort-keys": "1.1.2", - "write-file-atomic": "2.1.0" + "pify": "3.0.0", + "sort-keys": "2.0.0", + "write-file-atomic": "2.3.0" }, "dependencies": { "detect-indent": { @@ -5345,6 +6755,12 @@ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=", "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true } } }, @@ -5355,18 +6771,7 @@ "dev": true, "requires": { "sort-keys": "2.0.0", - "write-json-file": "2.2.0" - }, - "dependencies": { - "sort-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", - "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", - "dev": true, - "requires": { - "is-plain-obj": "1.1.0" - } - } + "write-json-file": "2.3.0" } }, "xml-name-validator": { @@ -5394,30 +6799,29 @@ "dev": true }, "yargs": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", - "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-10.0.3.tgz", + "integrity": "sha512-DqBpQ8NAUX4GyPP/ijDGHsJya4tYqLQrjPr95HNsr1YwL3+daCfvBwg7+gIC6IdJhR2kATh3hb61vjzMWEtjdw==", "dev": true, "requires": { - "camelcase": "3.0.0", "cliui": "3.2.0", "decamelize": "1.2.0", + "find-up": "2.1.0", "get-caller-file": "1.0.2", - "os-locale": "1.4.0", - "read-pkg-up": "1.0.1", + "os-locale": "2.1.0", "require-directory": "2.1.1", "require-main-filename": "1.0.1", "set-blocking": "2.0.0", - "string-width": "1.0.2", - "which-module": "1.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", "y18n": "3.2.1", - "yargs-parser": "5.0.0" + "yargs-parser": "8.1.0" }, "dependencies": { - "camelcase": { + "ansi-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "cliui": { @@ -5429,23 +6833,63 @@ "string-width": "1.0.2", "strip-ansi": "3.0.1", "wrap-ansi": "2.1.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } } } } }, "yargs-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", - "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz", + "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", "dev": true, "requires": { - "camelcase": "3.0.0" + "camelcase": "4.1.0" }, "dependencies": { "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", "dev": true } } diff --git a/package.json b/package.json index 41e5a9b14d831..d8929db6d9710 100644 --- a/package.json +++ b/package.json @@ -2,16 +2,16 @@ "license": "GPL-2.0+", "devDependencies": { "babel-core": "^6.25.0", + "babel-loader": "^7.1.1", "babel-plugin-transform-object-rest-spread": "^6.23.0", "babel-preset-env": "^1.5.2", "chalk": "^2.0.1", "codecov": "^2.2.0", "glob": "^7.1.2", - "jest": "^20.0.4", - "lerna": "^2.0.0", + "jest": "^22.0.3", + "lerna": "^2.5.1", "mkdirp": "^0.5.1", - "rimraf": "^2.6.1", - "babel-loader": "^7.1.1" + "rimraf": "^2.6.1" }, "jest": { "collectCoverageFrom": [ @@ -25,7 +25,7 @@ "scripts": { "build-clean": "rimraf ./packages/*/build ./packages/*/build-module", "build": "node ./scripts/build.js", - "postinstall": "lerna bootstrap --hoist && npm run build", + "postinstall": "lerna bootstrap && npm run build", "test": "jest", "test:coverage": "jest --coverage", "test:coverage-ci": "jest --coverage && codecov", From b99fb2888e4b0b96f842b3cd4454fd61d7c793dd Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Fri, 15 Dec 2017 11:19:16 -0500 Subject: [PATCH 237/393] Implement autop package --- packages/autop/README.md | 30 ++ packages/autop/package-lock.json | 5 + packages/autop/package.json | 16 + packages/autop/src/index.js | 262 ++++++++++++++ packages/autop/src/test/index.test.js | 499 ++++++++++++++++++++++++++ 5 files changed, 812 insertions(+) create mode 100644 packages/autop/README.md create mode 100644 packages/autop/package-lock.json create mode 100644 packages/autop/package.json create mode 100644 packages/autop/src/index.js create mode 100644 packages/autop/src/test/index.test.js diff --git a/packages/autop/README.md b/packages/autop/README.md new file mode 100644 index 0000000000000..60fef6edf813f --- /dev/null +++ b/packages/autop/README.md @@ -0,0 +1,30 @@ +# @wordpress/autop + +JavaScript port of WordPress's automatic paragraph function `autop` and the `removep` reverse behavior. + +## Installation + +Install the module + +```bash +npm install @wordpress/autop --save +``` + +### Usage + +Import the desired function(s) from `@wordpress/autop`: + +```js +import { autop, removep } from '@wordpress/autop'; + +autop( 'my text' ); +// "

my text

" + +removep( '

my text

' ); +// "my text" +``` + +### API Usage + +* `autop( text: string ): string` +* `remove( text: string ): string` diff --git a/packages/autop/package-lock.json b/packages/autop/package-lock.json new file mode 100644 index 0000000000000..498a3fda91c3b --- /dev/null +++ b/packages/autop/package-lock.json @@ -0,0 +1,5 @@ +{ + "name": "@wordpress/autop", + "version": "1.0.0", + "lockfileVersion": 1 +} diff --git a/packages/autop/package.json b/packages/autop/package.json new file mode 100644 index 0000000000000..1be6c2c71c661 --- /dev/null +++ b/packages/autop/package.json @@ -0,0 +1,16 @@ +{ + "name": "@wordpress/autop", + "version": "1.0.0", + "repository": { + "type": "git", + "url": "https://github.com/WordPress/packages.git" + }, + "description": "WordPress's automatic paragraph functions `autop` and `removep`", + "main": "build/index.js", + "module": "build-module/index.js", + "author": "WordPress", + "license": "GPL-2.0+", + "publishConfig": { + "access": "public" + } +} diff --git a/packages/autop/src/index.js b/packages/autop/src/index.js new file mode 100644 index 0000000000000..23ec46165daf5 --- /dev/null +++ b/packages/autop/src/index.js @@ -0,0 +1,262 @@ +/** + * Replaces two line breaks with a paragraph tag and one line break with a
. + * + * Similar to `wpautop()` in formatting.php. + * + * @param {string} text The text input. + * @returns {string} The formatted text. + */ +export function autop( text ) { + const blocklist = ( + 'table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre' + + '|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section' + + '|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary' + ); + + let preserveLinebreaks = false; + let preserveBr = false; + + // Normalize line breaks. + text = text.replace( /\r\n|\r/g, '\n' ); + + // Remove line breaks from . + if ( text.indexOf( '/g, function( a ) { + return a.replace( /\n+/g, '' ); + } ); + } + + // Remove line breaks from tags. + text = text.replace( /<[^<>]+>/g, function( a ) { + return a.replace( /[\n\t ]+/g, ' ' ); + } ); + + // Preserve line breaks in
 and