Dependencies added
This commit is contained in:
1 parent
94aad2ea07
commit
39d9c0de99
64 files changed
+8665
No files matched your search
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
"$basedir/node" "$basedir/../atob/bin/atob.js" "$@"
|
||||
ret=$?
|
||||
else
|
||||
node "$basedir/../atob/bin/atob.js" "$@"
|
||||
ret=$?
|
||||
fi
|
||||
exit $ret
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
@IF EXIST "%~dp0\node.exe" (
|
||||
"%~dp0\node.exe" "%~dp0\..\atob\bin\atob.js" %*
|
||||
) ELSE (
|
||||
@SETLOCAL
|
||||
@SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
node "%~dp0\..\atob\bin\atob.js" %*
|
||||
)
|
||||
+230
@@ -0,0 +1,230 @@
|
||||
At your option you may choose either of the following licenses:
|
||||
|
||||
* The MIT License (MIT)
|
||||
* The Apache License 2.0 (Apache-2.0)
|
||||
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 AJ ONeal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2015 AJ ONeal
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+319
@@ -0,0 +1,319 @@
|
||||
Creative Commons Legal Code
|
||||
|
||||
Attribution 3.0 Unported
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR
|
||||
DAMAGES RESULTING FROM ITS USE.
|
||||
|
||||
License
|
||||
|
||||
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
|
||||
COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
|
||||
COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
|
||||
AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
|
||||
|
||||
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
|
||||
TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY
|
||||
BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS
|
||||
CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND
|
||||
CONDITIONS.
|
||||
|
||||
1. Definitions
|
||||
|
||||
a. "Adaptation" means a work based upon the Work, or upon the Work and
|
||||
other pre-existing works, such as a translation, adaptation,
|
||||
derivative work, arrangement of music or other alterations of a
|
||||
literary or artistic work, or phonogram or performance and includes
|
||||
cinematographic adaptations or any other form in which the Work may be
|
||||
recast, transformed, or adapted including in any form recognizably
|
||||
derived from the original, except that a work that constitutes a
|
||||
Collection will not be considered an Adaptation for the purpose of
|
||||
this License. For the avoidance of doubt, where the Work is a musical
|
||||
work, performance or phonogram, the synchronization of the Work in
|
||||
timed-relation with a moving image ("synching") will be considered an
|
||||
Adaptation for the purpose of this License.
|
||||
b. "Collection" means a collection of literary or artistic works, such as
|
||||
encyclopedias and anthologies, or performances, phonograms or
|
||||
broadcasts, or other works or subject matter other than works listed
|
||||
in Section 1(f) below, which, by reason of the selection and
|
||||
arrangement of their contents, constitute intellectual creations, in
|
||||
which the Work is included in its entirety in unmodified form along
|
||||
with one or more other contributions, each constituting separate and
|
||||
independent works in themselves, which together are assembled into a
|
||||
collective whole. A work that constitutes a Collection will not be
|
||||
considered an Adaptation (as defined above) for the purposes of this
|
||||
License.
|
||||
c. "Distribute" means to make available to the public the original and
|
||||
copies of the Work or Adaptation, as appropriate, through sale or
|
||||
other transfer of ownership.
|
||||
d. "Licensor" means the individual, individuals, entity or entities that
|
||||
offer(s) the Work under the terms of this License.
|
||||
e. "Original Author" means, in the case of a literary or artistic work,
|
||||
the individual, individuals, entity or entities who created the Work
|
||||
or if no individual or entity can be identified, the publisher; and in
|
||||
addition (i) in the case of a performance the actors, singers,
|
||||
musicians, dancers, and other persons who act, sing, deliver, declaim,
|
||||
play in, interpret or otherwise perform literary or artistic works or
|
||||
expressions of folklore; (ii) in the case of a phonogram the producer
|
||||
being the person or legal entity who first fixes the sounds of a
|
||||
performance or other sounds; and, (iii) in the case of broadcasts, the
|
||||
organization that transmits the broadcast.
|
||||
f. "Work" means the literary and/or artistic work offered under the terms
|
||||
of this License including without limitation any production in the
|
||||
literary, scientific and artistic domain, whatever may be the mode or
|
||||
form of its expression including digital form, such as a book,
|
||||
pamphlet and other writing; a lecture, address, sermon or other work
|
||||
of the same nature; a dramatic or dramatico-musical work; a
|
||||
choreographic work or entertainment in dumb show; a musical
|
||||
composition with or without words; a cinematographic work to which are
|
||||
assimilated works expressed by a process analogous to cinematography;
|
||||
a work of drawing, painting, architecture, sculpture, engraving or
|
||||
lithography; a photographic work to which are assimilated works
|
||||
expressed by a process analogous to photography; a work of applied
|
||||
art; an illustration, map, plan, sketch or three-dimensional work
|
||||
relative to geography, topography, architecture or science; a
|
||||
performance; a broadcast; a phonogram; a compilation of data to the
|
||||
extent it is protected as a copyrightable work; or a work performed by
|
||||
a variety or circus performer to the extent it is not otherwise
|
||||
considered a literary or artistic work.
|
||||
g. "You" means an individual or entity exercising rights under this
|
||||
License who has not previously violated the terms of this License with
|
||||
respect to the Work, or who has received express permission from the
|
||||
Licensor to exercise rights under this License despite a previous
|
||||
violation.
|
||||
h. "Publicly Perform" means to perform public recitations of the Work and
|
||||
to communicate to the public those public recitations, by any means or
|
||||
process, including by wire or wireless means or public digital
|
||||
performances; to make available to the public Works in such a way that
|
||||
members of the public may access these Works from a place and at a
|
||||
place individually chosen by them; to perform the Work to the public
|
||||
by any means or process and the communication to the public of the
|
||||
performances of the Work, including by public digital performance; to
|
||||
broadcast and rebroadcast the Work by any means including signs,
|
||||
sounds or images.
|
||||
i. "Reproduce" means to make copies of the Work by any means including
|
||||
without limitation by sound or visual recordings and the right of
|
||||
fixation and reproducing fixations of the Work, including storage of a
|
||||
protected performance or phonogram in digital form or other electronic
|
||||
medium.
|
||||
|
||||
2. Fair Dealing Rights. Nothing in this License is intended to reduce,
|
||||
limit, or restrict any uses free from copyright or rights arising from
|
||||
limitations or exceptions that are provided for in connection with the
|
||||
copyright protection under copyright law or other applicable laws.
|
||||
|
||||
3. License Grant. Subject to the terms and conditions of this License,
|
||||
Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
|
||||
perpetual (for the duration of the applicable copyright) license to
|
||||
exercise the rights in the Work as stated below:
|
||||
|
||||
a. to Reproduce the Work, to incorporate the Work into one or more
|
||||
Collections, and to Reproduce the Work as incorporated in the
|
||||
Collections;
|
||||
b. to create and Reproduce Adaptations provided that any such Adaptation,
|
||||
including any translation in any medium, takes reasonable steps to
|
||||
clearly label, demarcate or otherwise identify that changes were made
|
||||
to the original Work. For example, a translation could be marked "The
|
||||
original work was translated from English to Spanish," or a
|
||||
modification could indicate "The original work has been modified.";
|
||||
c. to Distribute and Publicly Perform the Work including as incorporated
|
||||
in Collections; and,
|
||||
d. to Distribute and Publicly Perform Adaptations.
|
||||
e. For the avoidance of doubt:
|
||||
|
||||
i. Non-waivable Compulsory License Schemes. In those jurisdictions in
|
||||
which the right to collect royalties through any statutory or
|
||||
compulsory licensing scheme cannot be waived, the Licensor
|
||||
reserves the exclusive right to collect such royalties for any
|
||||
exercise by You of the rights granted under this License;
|
||||
ii. Waivable Compulsory License Schemes. In those jurisdictions in
|
||||
which the right to collect royalties through any statutory or
|
||||
compulsory licensing scheme can be waived, the Licensor waives the
|
||||
exclusive right to collect such royalties for any exercise by You
|
||||
of the rights granted under this License; and,
|
||||
iii. Voluntary License Schemes. The Licensor waives the right to
|
||||
collect royalties, whether individually or, in the event that the
|
||||
Licensor is a member of a collecting society that administers
|
||||
voluntary licensing schemes, via that society, from any exercise
|
||||
by You of the rights granted under this License.
|
||||
|
||||
The above rights may be exercised in all media and formats whether now
|
||||
known or hereafter devised. The above rights include the right to make
|
||||
such modifications as are technically necessary to exercise the rights in
|
||||
other media and formats. Subject to Section 8(f), all rights not expressly
|
||||
granted by Licensor are hereby reserved.
|
||||
|
||||
4. Restrictions. The license granted in Section 3 above is expressly made
|
||||
subject to and limited by the following restrictions:
|
||||
|
||||
a. You may Distribute or Publicly Perform the Work only under the terms
|
||||
of this License. You must include a copy of, or the Uniform Resource
|
||||
Identifier (URI) for, this License with every copy of the Work You
|
||||
Distribute or Publicly Perform. You may not offer or impose any terms
|
||||
on the Work that restrict the terms of this License or the ability of
|
||||
the recipient of the Work to exercise the rights granted to that
|
||||
recipient under the terms of the License. You may not sublicense the
|
||||
Work. You must keep intact all notices that refer to this License and
|
||||
to the disclaimer of warranties with every copy of the Work You
|
||||
Distribute or Publicly Perform. When You Distribute or Publicly
|
||||
Perform the Work, You may not impose any effective technological
|
||||
measures on the Work that restrict the ability of a recipient of the
|
||||
Work from You to exercise the rights granted to that recipient under
|
||||
the terms of the License. This Section 4(a) applies to the Work as
|
||||
incorporated in a Collection, but this does not require the Collection
|
||||
apart from the Work itself to be made subject to the terms of this
|
||||
License. If You create a Collection, upon notice from any Licensor You
|
||||
must, to the extent practicable, remove from the Collection any credit
|
||||
as required by Section 4(b), as requested. If You create an
|
||||
Adaptation, upon notice from any Licensor You must, to the extent
|
||||
practicable, remove from the Adaptation any credit as required by
|
||||
Section 4(b), as requested.
|
||||
b. If You Distribute, or Publicly Perform the Work or any Adaptations or
|
||||
Collections, You must, unless a request has been made pursuant to
|
||||
Section 4(a), keep intact all copyright notices for the Work and
|
||||
provide, reasonable to the medium or means You are utilizing: (i) the
|
||||
name of the Original Author (or pseudonym, if applicable) if supplied,
|
||||
and/or if the Original Author and/or Licensor designate another party
|
||||
or parties (e.g., a sponsor institute, publishing entity, journal) for
|
||||
attribution ("Attribution Parties") in Licensor's copyright notice,
|
||||
terms of service or by other reasonable means, the name of such party
|
||||
or parties; (ii) the title of the Work if supplied; (iii) to the
|
||||
extent reasonably practicable, the URI, if any, that Licensor
|
||||
specifies to be associated with the Work, unless such URI does not
|
||||
refer to the copyright notice or licensing information for the Work;
|
||||
and (iv) , consistent with Section 3(b), in the case of an Adaptation,
|
||||
a credit identifying the use of the Work in the Adaptation (e.g.,
|
||||
"French translation of the Work by Original Author," or "Screenplay
|
||||
based on original Work by Original Author"). The credit required by
|
||||
this Section 4 (b) may be implemented in any reasonable manner;
|
||||
provided, however, that in the case of a Adaptation or Collection, at
|
||||
a minimum such credit will appear, if a credit for all contributing
|
||||
authors of the Adaptation or Collection appears, then as part of these
|
||||
credits and in a manner at least as prominent as the credits for the
|
||||
other contributing authors. For the avoidance of doubt, You may only
|
||||
use the credit required by this Section for the purpose of attribution
|
||||
in the manner set out above and, by exercising Your rights under this
|
||||
License, You may not implicitly or explicitly assert or imply any
|
||||
connection with, sponsorship or endorsement by the Original Author,
|
||||
Licensor and/or Attribution Parties, as appropriate, of You or Your
|
||||
use of the Work, without the separate, express prior written
|
||||
permission of the Original Author, Licensor and/or Attribution
|
||||
Parties.
|
||||
c. Except as otherwise agreed in writing by the Licensor or as may be
|
||||
otherwise permitted by applicable law, if You Reproduce, Distribute or
|
||||
Publicly Perform the Work either by itself or as part of any
|
||||
Adaptations or Collections, You must not distort, mutilate, modify or
|
||||
take other derogatory action in relation to the Work which would be
|
||||
prejudicial to the Original Author's honor or reputation. Licensor
|
||||
agrees that in those jurisdictions (e.g. Japan), in which any exercise
|
||||
of the right granted in Section 3(b) of this License (the right to
|
||||
make Adaptations) would be deemed to be a distortion, mutilation,
|
||||
modification or other derogatory action prejudicial to the Original
|
||||
Author's honor and reputation, the Licensor will waive or not assert,
|
||||
as appropriate, this Section, to the fullest extent permitted by the
|
||||
applicable national law, to enable You to reasonably exercise Your
|
||||
right under Section 3(b) of this License (right to make Adaptations)
|
||||
but not otherwise.
|
||||
|
||||
5. Representations, Warranties and Disclaimer
|
||||
|
||||
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
|
||||
OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
|
||||
KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
|
||||
INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
|
||||
LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
|
||||
WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION
|
||||
OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
|
||||
|
||||
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
|
||||
LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR
|
||||
ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
|
||||
ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS
|
||||
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
7. Termination
|
||||
|
||||
a. This License and the rights granted hereunder will terminate
|
||||
automatically upon any breach by You of the terms of this License.
|
||||
Individuals or entities who have received Adaptations or Collections
|
||||
from You under this License, however, will not have their licenses
|
||||
terminated provided such individuals or entities remain in full
|
||||
compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will
|
||||
survive any termination of this License.
|
||||
b. Subject to the above terms and conditions, the license granted here is
|
||||
perpetual (for the duration of the applicable copyright in the Work).
|
||||
Notwithstanding the above, Licensor reserves the right to release the
|
||||
Work under different license terms or to stop distributing the Work at
|
||||
any time; provided, however that any such election will not serve to
|
||||
withdraw this License (or any other license that has been, or is
|
||||
required to be, granted under the terms of this License), and this
|
||||
License will continue in full force and effect unless terminated as
|
||||
stated above.
|
||||
|
||||
8. Miscellaneous
|
||||
|
||||
a. Each time You Distribute or Publicly Perform the Work or a Collection,
|
||||
the Licensor offers to the recipient a license to the Work on the same
|
||||
terms and conditions as the license granted to You under this License.
|
||||
b. Each time You Distribute or Publicly Perform an Adaptation, Licensor
|
||||
offers to the recipient a license to the original Work on the same
|
||||
terms and conditions as the license granted to You under this License.
|
||||
c. If any provision of this License is invalid or unenforceable under
|
||||
applicable law, it shall not affect the validity or enforceability of
|
||||
the remainder of the terms of this License, and without further action
|
||||
by the parties to this agreement, such provision shall be reformed to
|
||||
the minimum extent necessary to make such provision valid and
|
||||
enforceable.
|
||||
d. No term or provision of this License shall be deemed waived and no
|
||||
breach consented to unless such waiver or consent shall be in writing
|
||||
and signed by the party to be charged with such waiver or consent.
|
||||
e. This License constitutes the entire agreement between the parties with
|
||||
respect to the Work licensed here. There are no understandings,
|
||||
agreements or representations with respect to the Work not specified
|
||||
here. Licensor shall not be bound by any additional provisions that
|
||||
may appear in any communication from You. This License may not be
|
||||
modified without the mutual written agreement of the Licensor and You.
|
||||
f. The rights granted under, and the subject matter referenced, in this
|
||||
License were drafted utilizing the terminology of the Berne Convention
|
||||
for the Protection of Literary and Artistic Works (as amended on
|
||||
September 28, 1979), the Rome Convention of 1961, the WIPO Copyright
|
||||
Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996
|
||||
and the Universal Copyright Convention (as revised on July 24, 1971).
|
||||
These rights and subject matter take effect in the relevant
|
||||
jurisdiction in which the License terms are sought to be enforced
|
||||
according to the corresponding provisions of the implementation of
|
||||
those treaty provisions in the applicable national law. If the
|
||||
standard suite of rights granted under applicable copyright law
|
||||
includes additional rights not granted under this License, such
|
||||
additional rights are deemed to be included in the License; this
|
||||
License is not intended to restrict the license of any rights under
|
||||
applicable law.
|
||||
|
||||
|
||||
Creative Commons Notice
|
||||
|
||||
Creative Commons is not a party to this License, and makes no warranty
|
||||
whatsoever in connection with the Work. Creative Commons will not be
|
||||
liable to You or any party on any legal theory for any damages
|
||||
whatsoever, including without limitation any general, special,
|
||||
incidental or consequential damages arising in connection to this
|
||||
license. Notwithstanding the foregoing two (2) sentences, if Creative
|
||||
Commons has expressly identified itself as the Licensor hereunder, it
|
||||
shall have all rights and obligations of Licensor.
|
||||
|
||||
Except for the limited purpose of indicating to the public that the
|
||||
Work is licensed under the CCPL, Creative Commons does not authorize
|
||||
the use by either party of the trademark "Creative Commons" or any
|
||||
related trademark or logo of Creative Commons without the prior
|
||||
written consent of Creative Commons. Any permitted use will be in
|
||||
compliance with Creative Commons' then-current trademark usage
|
||||
guidelines, as may be published on its website or otherwise made
|
||||
available upon request from time to time. For the avoidance of doubt,
|
||||
this trademark restriction does not form part of this License.
|
||||
|
||||
Creative Commons may be contacted at http://creativecommons.org/.
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
atob
|
||||
===
|
||||
|
||||
Uses `Buffer` to emulate the exact functionality of the browser's atob.
|
||||
|
||||
Note: Unicode may be handled incorrectly (like the browser).
|
||||
|
||||
It turns base64-encoded <strong>a</strong>scii data back **to** <strong>b</strong>inary.
|
||||
|
||||
```javascript
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var atob = require('atob');
|
||||
var b64 = "SGVsbG8gV29ybGQ=";
|
||||
var bin = atob(b64);
|
||||
|
||||
console.log(bin); // "Hello World"
|
||||
}());
|
||||
```
|
||||
|
||||
### Need Unicode and Binary Support in the Browser?
|
||||
|
||||
Check out [unibabel.js](https://github.com/coolaj86/unibabel-js)
|
||||
|
||||
Changelog
|
||||
=======
|
||||
|
||||
* v2.0.0 provide browser version for ios web workers
|
||||
* v1.2.0 provide (empty) browser version
|
||||
* v1.1.3 add MIT license (see [#4](https://github.com/node-browser-compat/atob/issues/4))
|
||||
* v1.1.2 node only
|
||||
|
||||
LICENSE
|
||||
=======
|
||||
|
||||
Code copyright 2012-2015 AJ ONeal
|
||||
|
||||
Dual-licensed MIT and Apache-2.0
|
||||
|
||||
Docs copyright 2012-2015 AJ ONeal
|
||||
|
||||
Docs released under [Creative Commons](https://github.com/node-browser-compat/atob/blob/master/LICENSE.DOCS).
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
|
||||
var atob = require('../node-atob');
|
||||
var str = process.argv[2];
|
||||
console.log(atob(str));
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "atob",
|
||||
"description": "atob for isomorphic environments",
|
||||
"main": "browser-atob.js",
|
||||
"authors": [
|
||||
"AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com)"
|
||||
],
|
||||
"license": "(MIT OR Apache-2.0)",
|
||||
"keywords": [
|
||||
"atob",
|
||||
"browser"
|
||||
],
|
||||
"homepage": "https://github.com/node-browser-compat/atob",
|
||||
"moduleType": [
|
||||
"globals"
|
||||
],
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"version": "2.0.3"
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
(function (w) {
|
||||
"use strict";
|
||||
|
||||
var a2b = w.atob;
|
||||
|
||||
function atob(str) {
|
||||
// normal window
|
||||
if ('function' === typeof a2b) {
|
||||
return a2b(str);
|
||||
}
|
||||
// browserify (web worker)
|
||||
else if ('function' === typeof Buffer) {
|
||||
return new Buffer(str, 'base64').toString('binary');
|
||||
}
|
||||
// ios web worker with base64js
|
||||
else if ('object' === typeof w.base64js) {
|
||||
// bufferToBinaryString
|
||||
// https://github.com/coolaj86/unibabel-js/blob/master/index.js#L50
|
||||
var buf = w.base64js.b64ToByteArray(str);
|
||||
|
||||
return Array.prototype.map.call(buf, function (ch) {
|
||||
return String.fromCharCode(ch);
|
||||
}).join('');
|
||||
}
|
||||
// ios web worker without base64js
|
||||
else {
|
||||
throw new Error("you're probably in an ios webworker. please include use beatgammit's base64-js");
|
||||
}
|
||||
}
|
||||
|
||||
w.atob = atob;
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = atob;
|
||||
}
|
||||
}(window));
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
function atob(str) {
|
||||
return new Buffer(str, 'base64').toString('binary');
|
||||
}
|
||||
|
||||
module.exports = atob.atob = atob;
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"_from": "atob",
|
||||
"_id": "atob@2.0.3",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-GcenYEc3dEaPILLS0DNyrX1Mv10=",
|
||||
"_location": "/atob",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "tag",
|
||||
"registry": true,
|
||||
"raw": "atob",
|
||||
"name": "atob",
|
||||
"escapedName": "atob",
|
||||
"rawSpec": "",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "latest"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/atob/-/atob-2.0.3.tgz",
|
||||
"_shasum": "19c7a760473774468f20b2d2d03372ad7d4cbf5d",
|
||||
"_spec": "atob",
|
||||
"_where": "C:\\Users\\Luis\\source\\repos\\AAWebPlatform",
|
||||
"author": {
|
||||
"name": "AJ ONeal",
|
||||
"email": "coolaj86@gmail.com",
|
||||
"url": "https://coolaj86.com"
|
||||
},
|
||||
"bin": {
|
||||
"atob": "bin/atob.js"
|
||||
},
|
||||
"browser": "browser-atob.js",
|
||||
"bundleDependencies": false,
|
||||
"deprecated": false,
|
||||
"description": "atob for Node.JS and Linux / Mac / Windows CLI (it's a one-liner)",
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
},
|
||||
"homepage": "https://github.com/coolaj86/node-browser-compat",
|
||||
"keywords": [
|
||||
"atob",
|
||||
"browser"
|
||||
],
|
||||
"license": "(MIT OR Apache-2.0)",
|
||||
"main": "node-atob.js",
|
||||
"name": "atob",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/coolaj86/node-browser-compat/atob.git"
|
||||
},
|
||||
"version": "2.0.3"
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*jshint strict:true node:true es5:true onevar:true laxcomma:true laxbreak:true eqeqeq:true immed:true latedef:true*/
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var atob = require('.')
|
||||
, encoded = "SGVsbG8gV29ybGQ="
|
||||
, unencoded = "Hello World"
|
||||
/*
|
||||
, encoded = "SGVsbG8sIBZM"
|
||||
, unencoded = "Hello, 世界"
|
||||
*/
|
||||
;
|
||||
|
||||
if (unencoded !== atob(encoded)) {
|
||||
console.log('[FAIL]', unencoded, atob(encoded));
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('[PASS] all tests pass');
|
||||
}());
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
# master
|
||||
|
||||
# 2.0.4
|
||||
|
||||
* Fix npm package
|
||||
|
||||
# 2.0.3
|
||||
|
||||
* Fix useSetTimeout bug
|
||||
|
||||
# 2.0.2
|
||||
|
||||
* Adding RSVP#rethrow
|
||||
* add pre-built AMD link to README
|
||||
* adding promise#fail
|
||||
|
||||
# 2.0.1
|
||||
* misc IE fixes, including IE array detection
|
||||
* upload passing builds to s3
|
||||
* async: use three args for addEventListener
|
||||
* satisfy both 1.0 and 1.1 specs
|
||||
* Run reduce tests only in node
|
||||
* RSVP.resolve now simply uses the internal resolution procedure
|
||||
* prevent multiple promise resolutions
|
||||
* simplify thenable handling
|
||||
* pre-allocate the deferred's shape
|
||||
* Moved from Rake-based builds to Grunt
|
||||
* Fix Promise subclassing bug
|
||||
* Add RSVP.configure('onerror')
|
||||
* Throw exception when RSVP.all is called without an array
|
||||
* refactor RSVP.all to just use a promise directly
|
||||
* Make `RSVP.denodeify` pass along `thisArg`
|
||||
* add RSVP.reject
|
||||
* Reject promise if resolver function throws an exception
|
||||
* add travis build-status
|
||||
* correctly test and fix self fulfillment
|
||||
* remove promise coercion.
|
||||
* Fix infinite recursion with deep self fulfilling promises
|
||||
* doc fixes
|
||||
|
||||
# 2.0.0
|
||||
|
||||
* No changelog beyond this point. Here be dragons.
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
# ES6-Promises (subset of [rsvp.js](https://github.com/tildeio/rsvp.js))
|
||||
|
||||
This is a polyfill of [ES6 Promises](https://github.com/domenic/promises-unwrapping). The implementation is a subset of [rsvp.js](https://github.com/tildeio/rsvp.js), if you're wanting extra features and more debugging options, check out the [full library](https://github.com/tildeio/rsvp.js).
|
||||
|
||||
For API details and how to use promises, see the <a href="http://www.html5rocks.com/en/tutorials/es6/promises/">JavaScript Promises HTML5Rocks article</a>.
|
||||
|
||||
## Downloads
|
||||
|
||||
* [promise](http://s3.amazonaws.com/es6-promises/promise-0.1.2.js)
|
||||
* [promise-min](http://s3.amazonaws.com/es6-promises/promise-0.1.2.min.js) (~2k gzipped)
|
||||
|
||||
## Node.js
|
||||
|
||||
To install:
|
||||
|
||||
```sh
|
||||
npm install es6-promise
|
||||
```
|
||||
|
||||
To use:
|
||||
|
||||
```js
|
||||
var Promise = require('es6-promise').Promise;
|
||||
```
|
||||
|
||||
## Usage in IE<10
|
||||
|
||||
`catch` is a reserved word in IE<10, meaning `promise.catch(func)` throws a syntax error. To work around this, to a string to access the property:
|
||||
|
||||
```js
|
||||
promise['catch'](function(err) {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
Or use `.then` instead:
|
||||
|
||||
```js
|
||||
promise.then(undefined, function(err) {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
## Building & Testing
|
||||
|
||||
This package uses the [grunt-microlib](https://github.com/thomasboyt/grunt-microlib) package for building.
|
||||
|
||||
Custom tasks:
|
||||
|
||||
* `grunt test` - Run Mocha tests through Node and PhantomJS.
|
||||
* `grunt test:phantom` - Run Mocha tests through PhantomJS (browser build).
|
||||
* `grunt test:node` - Run Mocha tests through Node (CommonJS build).
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
"use strict";
|
||||
var Promise = require("./promise/promise").Promise;
|
||||
var polyfill = require("./promise/polyfill").polyfill;
|
||||
exports.Promise = Promise;
|
||||
exports.polyfill = polyfill;
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
"use strict";
|
||||
/* global toString */
|
||||
|
||||
var isArray = require("./utils").isArray;
|
||||
var isFunction = require("./utils").isFunction;
|
||||
|
||||
/**
|
||||
Returns a promise that is fulfilled when all the given promises have been
|
||||
fulfilled, or rejected if any of them become rejected. The return promise
|
||||
is fulfilled with an array that gives all the values in the order they were
|
||||
passed in the `promises` array argument.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var promise1 = RSVP.resolve(1);
|
||||
var promise2 = RSVP.resolve(2);
|
||||
var promise3 = RSVP.resolve(3);
|
||||
var promises = [ promise1, promise2, promise3 ];
|
||||
|
||||
RSVP.all(promises).then(function(array){
|
||||
// The array here would be [ 1, 2, 3 ];
|
||||
});
|
||||
```
|
||||
|
||||
If any of the `promises` given to `RSVP.all` are rejected, the first promise
|
||||
that is rejected will be given as an argument to the returned promises's
|
||||
rejection handler. For example:
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var promise1 = RSVP.resolve(1);
|
||||
var promise2 = RSVP.reject(new Error("2"));
|
||||
var promise3 = RSVP.reject(new Error("3"));
|
||||
var promises = [ promise1, promise2, promise3 ];
|
||||
|
||||
RSVP.all(promises).then(function(array){
|
||||
// Code here never runs because there are rejected promises!
|
||||
}, function(error) {
|
||||
// error.message === "2"
|
||||
});
|
||||
```
|
||||
|
||||
@method all
|
||||
@for RSVP
|
||||
@param {Array} promises
|
||||
@param {String} label
|
||||
@return {Promise} promise that is fulfilled when all `promises` have been
|
||||
fulfilled, or rejected if any of them become rejected.
|
||||
*/
|
||||
function all(promises) {
|
||||
/*jshint validthis:true */
|
||||
var Promise = this;
|
||||
|
||||
if (!isArray(promises)) {
|
||||
throw new TypeError('You must pass an array to all.');
|
||||
}
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
var results = [], remaining = promises.length,
|
||||
promise;
|
||||
|
||||
if (remaining === 0) {
|
||||
resolve([]);
|
||||
}
|
||||
|
||||
function resolver(index) {
|
||||
return function(value) {
|
||||
resolveAll(index, value);
|
||||
};
|
||||
}
|
||||
|
||||
function resolveAll(index, value) {
|
||||
results[index] = value;
|
||||
if (--remaining === 0) {
|
||||
resolve(results);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < promises.length; i++) {
|
||||
promise = promises[i];
|
||||
|
||||
if (promise && isFunction(promise.then)) {
|
||||
promise.then(resolver(i), reject);
|
||||
} else {
|
||||
resolveAll(i, promise);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
exports.all = all;
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
"use strict";
|
||||
var browserGlobal = (typeof window !== 'undefined') ? window : {};
|
||||
var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
|
||||
var local = (typeof global !== 'undefined') ? global : (this === undefined? window:this);
|
||||
|
||||
// node
|
||||
function useNextTick() {
|
||||
return function() {
|
||||
process.nextTick(flush);
|
||||
};
|
||||
}
|
||||
|
||||
function useMutationObserver() {
|
||||
var iterations = 0;
|
||||
var observer = new BrowserMutationObserver(flush);
|
||||
var node = document.createTextNode('');
|
||||
observer.observe(node, { characterData: true });
|
||||
|
||||
return function() {
|
||||
node.data = (iterations = ++iterations % 2);
|
||||
};
|
||||
}
|
||||
|
||||
function useSetTimeout() {
|
||||
return function() {
|
||||
local.setTimeout(flush, 1);
|
||||
};
|
||||
}
|
||||
|
||||
var queue = [];
|
||||
function flush() {
|
||||
for (var i = 0; i < queue.length; i++) {
|
||||
var tuple = queue[i];
|
||||
var callback = tuple[0], arg = tuple[1];
|
||||
callback(arg);
|
||||
}
|
||||
queue = [];
|
||||
}
|
||||
|
||||
var scheduleFlush;
|
||||
|
||||
// Decide what async method to use to triggering processing of queued callbacks:
|
||||
if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
|
||||
scheduleFlush = useNextTick();
|
||||
} else if (BrowserMutationObserver) {
|
||||
scheduleFlush = useMutationObserver();
|
||||
} else {
|
||||
scheduleFlush = useSetTimeout();
|
||||
}
|
||||
|
||||
function asap(callback, arg) {
|
||||
var length = queue.push([callback, arg]);
|
||||
if (length === 1) {
|
||||
// If length is 1, that means that we need to schedule an async flush.
|
||||
// If additional callbacks are queued before the queue is flushed, they
|
||||
// will be processed by this flush that we are scheduling.
|
||||
scheduleFlush();
|
||||
}
|
||||
}
|
||||
|
||||
exports.asap = asap;
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
"use strict";
|
||||
/**
|
||||
`RSVP.Promise.cast` returns the same promise if that promise shares a constructor
|
||||
with the promise being casted.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var promise = RSVP.resolve(1);
|
||||
var casted = RSVP.Promise.cast(promise);
|
||||
|
||||
console.log(promise === casted); // true
|
||||
```
|
||||
|
||||
In the case of a promise whose constructor does not match, it is assimilated.
|
||||
The resulting promise will fulfill or reject based on the outcome of the
|
||||
promise being casted.
|
||||
|
||||
In the case of a non-promise, a promise which will fulfill with that value is
|
||||
returned.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var value = 1; // could be a number, boolean, string, undefined...
|
||||
var casted = RSVP.Promise.cast(value);
|
||||
|
||||
console.log(value === casted); // false
|
||||
console.log(casted instanceof RSVP.Promise) // true
|
||||
|
||||
casted.then(function(val) {
|
||||
val === value // => true
|
||||
});
|
||||
```
|
||||
|
||||
`RSVP.Promise.cast` is similar to `RSVP.resolve`, but `RSVP.Promise.cast` differs in the
|
||||
following ways:
|
||||
* `RSVP.Promise.cast` serves as a memory-efficient way of getting a promise, when you
|
||||
have something that could either be a promise or a value. RSVP.resolve
|
||||
will have the same effect but will create a new promise wrapper if the
|
||||
argument is a promise.
|
||||
* `RSVP.Promise.cast` is a way of casting incoming thenables or promise subclasses to
|
||||
promises of the exact class specified, so that the resulting object's `then` is
|
||||
ensured to have the behavior of the constructor you are calling cast on (i.e., RSVP.Promise).
|
||||
|
||||
@method cast
|
||||
@for RSVP
|
||||
@param {Object} object to be casted
|
||||
@return {Promise} promise that is fulfilled when all properties of `promises`
|
||||
have been fulfilled, or rejected if any of them become rejected.
|
||||
*/
|
||||
|
||||
|
||||
function cast(object) {
|
||||
/*jshint validthis:true */
|
||||
if (object && typeof object === 'object' && object.constructor === this) {
|
||||
return object;
|
||||
}
|
||||
|
||||
var Promise = this;
|
||||
|
||||
return new Promise(function(resolve) {
|
||||
resolve(object);
|
||||
});
|
||||
}
|
||||
|
||||
exports.cast = cast;
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
"use strict";
|
||||
var config = {
|
||||
instrument: false
|
||||
};
|
||||
|
||||
function configure(name, value) {
|
||||
if (arguments.length === 2) {
|
||||
config[name] = value;
|
||||
} else {
|
||||
return config[name];
|
||||
}
|
||||
}
|
||||
|
||||
exports.config = config;
|
||||
exports.configure = configure;
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
"use strict";
|
||||
/*global self*/
|
||||
var RSVPPromise = require("./promise").Promise;
|
||||
var isFunction = require("./utils").isFunction;
|
||||
|
||||
function polyfill() {
|
||||
var local;
|
||||
|
||||
if (typeof global !== 'undefined') {
|
||||
local = global;
|
||||
} else if (typeof window !== 'undefined' && window.document) {
|
||||
local = window;
|
||||
} else {
|
||||
local = self;
|
||||
}
|
||||
|
||||
var es6PromiseSupport =
|
||||
"Promise" in local &&
|
||||
// Some of these methods are missing from
|
||||
// Firefox/Chrome experimental implementations
|
||||
"cast" in local.Promise &&
|
||||
"resolve" in local.Promise &&
|
||||
"reject" in local.Promise &&
|
||||
"all" in local.Promise &&
|
||||
"race" in local.Promise &&
|
||||
// Older version of the spec had a resolver object
|
||||
// as the arg rather than a function
|
||||
(function() {
|
||||
var resolve;
|
||||
new local.Promise(function(r) { resolve = r; });
|
||||
return isFunction(resolve);
|
||||
}());
|
||||
|
||||
if (!es6PromiseSupport) {
|
||||
local.Promise = RSVPPromise;
|
||||
}
|
||||
}
|
||||
|
||||
exports.polyfill = polyfill;
|
||||
+213
@@ -0,0 +1,213 @@
|
||||
"use strict";
|
||||
var config = require("./config").config;
|
||||
var configure = require("./config").configure;
|
||||
var objectOrFunction = require("./utils").objectOrFunction;
|
||||
var isFunction = require("./utils").isFunction;
|
||||
var now = require("./utils").now;
|
||||
var cast = require("./cast").cast;
|
||||
var all = require("./all").all;
|
||||
var race = require("./race").race;
|
||||
var staticResolve = require("./resolve").resolve;
|
||||
var staticReject = require("./reject").reject;
|
||||
var asap = require("./asap").asap;
|
||||
|
||||
var counter = 0;
|
||||
|
||||
config.async = asap; // default async is asap;
|
||||
|
||||
function Promise(resolver) {
|
||||
if (!isFunction(resolver)) {
|
||||
throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
|
||||
}
|
||||
|
||||
if (!(this instanceof Promise)) {
|
||||
throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
|
||||
}
|
||||
|
||||
this._subscribers = [];
|
||||
|
||||
invokeResolver(resolver, this);
|
||||
}
|
||||
|
||||
function invokeResolver(resolver, promise) {
|
||||
function resolvePromise(value) {
|
||||
resolve(promise, value);
|
||||
}
|
||||
|
||||
function rejectPromise(reason) {
|
||||
reject(promise, reason);
|
||||
}
|
||||
|
||||
try {
|
||||
resolver(resolvePromise, rejectPromise);
|
||||
} catch(e) {
|
||||
rejectPromise(e);
|
||||
}
|
||||
}
|
||||
|
||||
function invokeCallback(settled, promise, callback, detail) {
|
||||
var hasCallback = isFunction(callback),
|
||||
value, error, succeeded, failed;
|
||||
|
||||
if (hasCallback) {
|
||||
try {
|
||||
value = callback(detail);
|
||||
succeeded = true;
|
||||
} catch(e) {
|
||||
failed = true;
|
||||
error = e;
|
||||
}
|
||||
} else {
|
||||
value = detail;
|
||||
succeeded = true;
|
||||
}
|
||||
|
||||
if (handleThenable(promise, value)) {
|
||||
return;
|
||||
} else if (hasCallback && succeeded) {
|
||||
resolve(promise, value);
|
||||
} else if (failed) {
|
||||
reject(promise, error);
|
||||
} else if (settled === FULFILLED) {
|
||||
resolve(promise, value);
|
||||
} else if (settled === REJECTED) {
|
||||
reject(promise, value);
|
||||
}
|
||||
}
|
||||
|
||||
var PENDING = void 0;
|
||||
var SEALED = 0;
|
||||
var FULFILLED = 1;
|
||||
var REJECTED = 2;
|
||||
|
||||
function subscribe(parent, child, onFulfillment, onRejection) {
|
||||
var subscribers = parent._subscribers;
|
||||
var length = subscribers.length;
|
||||
|
||||
subscribers[length] = child;
|
||||
subscribers[length + FULFILLED] = onFulfillment;
|
||||
subscribers[length + REJECTED] = onRejection;
|
||||
}
|
||||
|
||||
function publish(promise, settled) {
|
||||
var child, callback, subscribers = promise._subscribers, detail = promise._detail;
|
||||
|
||||
for (var i = 0; i < subscribers.length; i += 3) {
|
||||
child = subscribers[i];
|
||||
callback = subscribers[i + settled];
|
||||
|
||||
invokeCallback(settled, child, callback, detail);
|
||||
}
|
||||
|
||||
promise._subscribers = null;
|
||||
}
|
||||
|
||||
Promise.prototype = {
|
||||
constructor: Promise,
|
||||
|
||||
_state: undefined,
|
||||
_detail: undefined,
|
||||
_subscribers: undefined,
|
||||
|
||||
then: function(onFulfillment, onRejection) {
|
||||
var promise = this;
|
||||
|
||||
var thenPromise = new this.constructor(function() {});
|
||||
|
||||
if (this._state) {
|
||||
var callbacks = arguments;
|
||||
config.async(function invokePromiseCallback() {
|
||||
invokeCallback(promise._state, thenPromise, callbacks[promise._state - 1], promise._detail);
|
||||
});
|
||||
} else {
|
||||
subscribe(this, thenPromise, onFulfillment, onRejection);
|
||||
}
|
||||
|
||||
return thenPromise;
|
||||
},
|
||||
|
||||
'catch': function(onRejection) {
|
||||
return this.then(null, onRejection);
|
||||
}
|
||||
};
|
||||
|
||||
Promise.all = all;
|
||||
Promise.cast = cast;
|
||||
Promise.race = race;
|
||||
Promise.resolve = staticResolve;
|
||||
Promise.reject = staticReject;
|
||||
|
||||
function handleThenable(promise, value) {
|
||||
var then = null,
|
||||
resolved;
|
||||
|
||||
try {
|
||||
if (promise === value) {
|
||||
throw new TypeError("A promises callback cannot return that same promise.");
|
||||
}
|
||||
|
||||
if (objectOrFunction(value)) {
|
||||
then = value.then;
|
||||
|
||||
if (isFunction(then)) {
|
||||
then.call(value, function(val) {
|
||||
if (resolved) { return true; }
|
||||
resolved = true;
|
||||
|
||||
if (value !== val) {
|
||||
resolve(promise, val);
|
||||
} else {
|
||||
fulfill(promise, val);
|
||||
}
|
||||
}, function(val) {
|
||||
if (resolved) { return true; }
|
||||
resolved = true;
|
||||
|
||||
reject(promise, val);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (resolved) { return true; }
|
||||
reject(promise, error);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function resolve(promise, value) {
|
||||
if (promise === value) {
|
||||
fulfill(promise, value);
|
||||
} else if (!handleThenable(promise, value)) {
|
||||
fulfill(promise, value);
|
||||
}
|
||||
}
|
||||
|
||||
function fulfill(promise, value) {
|
||||
if (promise._state !== PENDING) { return; }
|
||||
promise._state = SEALED;
|
||||
promise._detail = value;
|
||||
|
||||
config.async(publishFulfillment, promise);
|
||||
}
|
||||
|
||||
function reject(promise, reason) {
|
||||
if (promise._state !== PENDING) { return; }
|
||||
promise._state = SEALED;
|
||||
promise._detail = reason;
|
||||
|
||||
config.async(publishRejection, promise);
|
||||
}
|
||||
|
||||
function publishFulfillment(promise) {
|
||||
publish(promise, promise._state = FULFILLED);
|
||||
}
|
||||
|
||||
function publishRejection(promise) {
|
||||
publish(promise, promise._state = REJECTED);
|
||||
}
|
||||
|
||||
exports.Promise = Promise;
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
"use strict";
|
||||
/* global toString */
|
||||
var isArray = require("./utils").isArray;
|
||||
|
||||
/**
|
||||
`RSVP.race` allows you to watch a series of promises and act as soon as the
|
||||
first promise given to the `promises` argument fulfills or rejects.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var promise1 = new RSVP.Promise(function(resolve, reject){
|
||||
setTimeout(function(){
|
||||
resolve("promise 1");
|
||||
}, 200);
|
||||
});
|
||||
|
||||
var promise2 = new RSVP.Promise(function(resolve, reject){
|
||||
setTimeout(function(){
|
||||
resolve("promise 2");
|
||||
}, 100);
|
||||
});
|
||||
|
||||
RSVP.race([promise1, promise2]).then(function(result){
|
||||
// result === "promise 2" because it was resolved before promise1
|
||||
// was resolved.
|
||||
});
|
||||
```
|
||||
|
||||
`RSVP.race` is deterministic in that only the state of the first completed
|
||||
promise matters. For example, even if other promises given to the `promises`
|
||||
array argument are resolved, but the first completed promise has become
|
||||
rejected before the other promises became fulfilled, the returned promise
|
||||
will become rejected:
|
||||
|
||||
```javascript
|
||||
var promise1 = new RSVP.Promise(function(resolve, reject){
|
||||
setTimeout(function(){
|
||||
resolve("promise 1");
|
||||
}, 200);
|
||||
});
|
||||
|
||||
var promise2 = new RSVP.Promise(function(resolve, reject){
|
||||
setTimeout(function(){
|
||||
reject(new Error("promise 2"));
|
||||
}, 100);
|
||||
});
|
||||
|
||||
RSVP.race([promise1, promise2]).then(function(result){
|
||||
// Code here never runs because there are rejected promises!
|
||||
}, function(reason){
|
||||
// reason.message === "promise2" because promise 2 became rejected before
|
||||
// promise 1 became fulfilled
|
||||
});
|
||||
```
|
||||
|
||||
@method race
|
||||
@for RSVP
|
||||
@param {Array} promises array of promises to observe
|
||||
@param {String} label optional string for describing the promise returned.
|
||||
Useful for tooling.
|
||||
@return {Promise} a promise that becomes fulfilled with the value the first
|
||||
completed promises is resolved with if the first completed promise was
|
||||
fulfilled, or rejected with the reason that the first completed promise
|
||||
was rejected with.
|
||||
*/
|
||||
function race(promises) {
|
||||
/*jshint validthis:true */
|
||||
var Promise = this;
|
||||
|
||||
if (!isArray(promises)) {
|
||||
throw new TypeError('You must pass an array to race.');
|
||||
}
|
||||
return new Promise(function(resolve, reject) {
|
||||
var results = [], promise;
|
||||
|
||||
for (var i = 0; i < promises.length; i++) {
|
||||
promise = promises[i];
|
||||
|
||||
if (promise && typeof promise.then === 'function') {
|
||||
promise.then(resolve, reject);
|
||||
} else {
|
||||
resolve(promise);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
exports.race = race;
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
"use strict";
|
||||
/**
|
||||
`RSVP.reject` returns a promise that will become rejected with the passed
|
||||
`reason`. `RSVP.reject` is essentially shorthand for the following:
|
||||
|
||||
```javascript
|
||||
var promise = new RSVP.Promise(function(resolve, reject){
|
||||
reject(new Error('WHOOPS'));
|
||||
});
|
||||
|
||||
promise.then(function(value){
|
||||
// Code here doesn't run because the promise is rejected!
|
||||
}, function(reason){
|
||||
// reason.message === 'WHOOPS'
|
||||
});
|
||||
```
|
||||
|
||||
Instead of writing the above, your code now simply becomes the following:
|
||||
|
||||
```javascript
|
||||
var promise = RSVP.reject(new Error('WHOOPS'));
|
||||
|
||||
promise.then(function(value){
|
||||
// Code here doesn't run because the promise is rejected!
|
||||
}, function(reason){
|
||||
// reason.message === 'WHOOPS'
|
||||
});
|
||||
```
|
||||
|
||||
@method reject
|
||||
@for RSVP
|
||||
@param {Any} reason value that the returned promise will be rejected with.
|
||||
@param {String} label optional string for identifying the returned promise.
|
||||
Useful for tooling.
|
||||
@return {Promise} a promise that will become rejected with the given
|
||||
`reason`.
|
||||
*/
|
||||
function reject(reason) {
|
||||
/*jshint validthis:true */
|
||||
var Promise = this;
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
reject(reason);
|
||||
});
|
||||
}
|
||||
|
||||
exports.reject = reject;
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
"use strict";
|
||||
/**
|
||||
`RSVP.resolve` returns a promise that will become fulfilled with the passed
|
||||
`value`. `RSVP.resolve` is essentially shorthand for the following:
|
||||
|
||||
```javascript
|
||||
var promise = new RSVP.Promise(function(resolve, reject){
|
||||
resolve(1);
|
||||
});
|
||||
|
||||
promise.then(function(value){
|
||||
// value === 1
|
||||
});
|
||||
```
|
||||
|
||||
Instead of writing the above, your code now simply becomes the following:
|
||||
|
||||
```javascript
|
||||
var promise = RSVP.resolve(1);
|
||||
|
||||
promise.then(function(value){
|
||||
// value === 1
|
||||
});
|
||||
```
|
||||
|
||||
@method resolve
|
||||
@for RSVP
|
||||
@param {Any} value value that the returned promise will be resolved with
|
||||
@param {String} label optional string for identifying the returned promise.
|
||||
Useful for tooling.
|
||||
@return {Promise} a promise that will become fulfilled with the given
|
||||
`value`
|
||||
*/
|
||||
function resolve(value) {
|
||||
/*jshint validthis:true */
|
||||
var Promise = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
resolve(value);
|
||||
});
|
||||
}
|
||||
|
||||
exports.resolve = resolve;
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
"use strict";
|
||||
function objectOrFunction(x) {
|
||||
return isFunction(x) || (typeof x === "object" && x !== null);
|
||||
}
|
||||
|
||||
function isFunction(x) {
|
||||
return typeof x === "function";
|
||||
}
|
||||
|
||||
function isArray(x) {
|
||||
return Object.prototype.toString.call(x) === "[object Array]";
|
||||
}
|
||||
|
||||
// Date.now is not available in browsers < IE9
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now#Compatibility
|
||||
var now = Date.now || function() { return new Date().getTime(); };
|
||||
|
||||
|
||||
exports.objectOrFunction = objectOrFunction;
|
||||
exports.isFunction = isFunction;
|
||||
exports.isArray = isArray;
|
||||
exports.now = now;
|
||||
+732
@@ -0,0 +1,732 @@
|
||||
/**
|
||||
@class RSVP
|
||||
@module RSVP
|
||||
*/
|
||||
define("promise/all",
|
||||
["./utils","exports"],
|
||||
function(__dependency1__, __exports__) {
|
||||
"use strict";
|
||||
/* global toString */
|
||||
|
||||
var isArray = __dependency1__.isArray;
|
||||
var isFunction = __dependency1__.isFunction;
|
||||
|
||||
/**
|
||||
Returns a promise that is fulfilled when all the given promises have been
|
||||
fulfilled, or rejected if any of them become rejected. The return promise
|
||||
is fulfilled with an array that gives all the values in the order they were
|
||||
passed in the `promises` array argument.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var promise1 = RSVP.resolve(1);
|
||||
var promise2 = RSVP.resolve(2);
|
||||
var promise3 = RSVP.resolve(3);
|
||||
var promises = [ promise1, promise2, promise3 ];
|
||||
|
||||
RSVP.all(promises).then(function(array){
|
||||
// The array here would be [ 1, 2, 3 ];
|
||||
});
|
||||
```
|
||||
|
||||
If any of the `promises` given to `RSVP.all` are rejected, the first promise
|
||||
that is rejected will be given as an argument to the returned promises's
|
||||
rejection handler. For example:
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var promise1 = RSVP.resolve(1);
|
||||
var promise2 = RSVP.reject(new Error("2"));
|
||||
var promise3 = RSVP.reject(new Error("3"));
|
||||
var promises = [ promise1, promise2, promise3 ];
|
||||
|
||||
RSVP.all(promises).then(function(array){
|
||||
// Code here never runs because there are rejected promises!
|
||||
}, function(error) {
|
||||
// error.message === "2"
|
||||
});
|
||||
```
|
||||
|
||||
@method all
|
||||
@for RSVP
|
||||
@param {Array} promises
|
||||
@param {String} label
|
||||
@return {Promise} promise that is fulfilled when all `promises` have been
|
||||
fulfilled, or rejected if any of them become rejected.
|
||||
*/
|
||||
function all(promises) {
|
||||
/*jshint validthis:true */
|
||||
var Promise = this;
|
||||
|
||||
if (!isArray(promises)) {
|
||||
throw new TypeError('You must pass an array to all.');
|
||||
}
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
var results = [], remaining = promises.length,
|
||||
promise;
|
||||
|
||||
if (remaining === 0) {
|
||||
resolve([]);
|
||||
}
|
||||
|
||||
function resolver(index) {
|
||||
return function(value) {
|
||||
resolveAll(index, value);
|
||||
};
|
||||
}
|
||||
|
||||
function resolveAll(index, value) {
|
||||
results[index] = value;
|
||||
if (--remaining === 0) {
|
||||
resolve(results);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < promises.length; i++) {
|
||||
promise = promises[i];
|
||||
|
||||
if (promise && isFunction(promise.then)) {
|
||||
promise.then(resolver(i), reject);
|
||||
} else {
|
||||
resolveAll(i, promise);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
__exports__.all = all;
|
||||
});
|
||||
define("promise/asap",
|
||||
["exports"],
|
||||
function(__exports__) {
|
||||
"use strict";
|
||||
var browserGlobal = (typeof window !== 'undefined') ? window : {};
|
||||
var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
|
||||
var local = (typeof global !== 'undefined') ? global : (this === undefined? window:this);
|
||||
|
||||
// node
|
||||
function useNextTick() {
|
||||
return function() {
|
||||
process.nextTick(flush);
|
||||
};
|
||||
}
|
||||
|
||||
function useMutationObserver() {
|
||||
var iterations = 0;
|
||||
var observer = new BrowserMutationObserver(flush);
|
||||
var node = document.createTextNode('');
|
||||
observer.observe(node, { characterData: true });
|
||||
|
||||
return function() {
|
||||
node.data = (iterations = ++iterations % 2);
|
||||
};
|
||||
}
|
||||
|
||||
function useSetTimeout() {
|
||||
return function() {
|
||||
local.setTimeout(flush, 1);
|
||||
};
|
||||
}
|
||||
|
||||
var queue = [];
|
||||
function flush() {
|
||||
for (var i = 0; i < queue.length; i++) {
|
||||
var tuple = queue[i];
|
||||
var callback = tuple[0], arg = tuple[1];
|
||||
callback(arg);
|
||||
}
|
||||
queue = [];
|
||||
}
|
||||
|
||||
var scheduleFlush;
|
||||
|
||||
// Decide what async method to use to triggering processing of queued callbacks:
|
||||
if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
|
||||
scheduleFlush = useNextTick();
|
||||
} else if (BrowserMutationObserver) {
|
||||
scheduleFlush = useMutationObserver();
|
||||
} else {
|
||||
scheduleFlush = useSetTimeout();
|
||||
}
|
||||
|
||||
function asap(callback, arg) {
|
||||
var length = queue.push([callback, arg]);
|
||||
if (length === 1) {
|
||||
// If length is 1, that means that we need to schedule an async flush.
|
||||
// If additional callbacks are queued before the queue is flushed, they
|
||||
// will be processed by this flush that we are scheduling.
|
||||
scheduleFlush();
|
||||
}
|
||||
}
|
||||
|
||||
__exports__.asap = asap;
|
||||
});
|
||||
define("promise/cast",
|
||||
["exports"],
|
||||
function(__exports__) {
|
||||
"use strict";
|
||||
/**
|
||||
`RSVP.Promise.cast` returns the same promise if that promise shares a constructor
|
||||
with the promise being casted.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var promise = RSVP.resolve(1);
|
||||
var casted = RSVP.Promise.cast(promise);
|
||||
|
||||
console.log(promise === casted); // true
|
||||
```
|
||||
|
||||
In the case of a promise whose constructor does not match, it is assimilated.
|
||||
The resulting promise will fulfill or reject based on the outcome of the
|
||||
promise being casted.
|
||||
|
||||
In the case of a non-promise, a promise which will fulfill with that value is
|
||||
returned.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var value = 1; // could be a number, boolean, string, undefined...
|
||||
var casted = RSVP.Promise.cast(value);
|
||||
|
||||
console.log(value === casted); // false
|
||||
console.log(casted instanceof RSVP.Promise) // true
|
||||
|
||||
casted.then(function(val) {
|
||||
val === value // => true
|
||||
});
|
||||
```
|
||||
|
||||
`RSVP.Promise.cast` is similar to `RSVP.resolve`, but `RSVP.Promise.cast` differs in the
|
||||
following ways:
|
||||
* `RSVP.Promise.cast` serves as a memory-efficient way of getting a promise, when you
|
||||
have something that could either be a promise or a value. RSVP.resolve
|
||||
will have the same effect but will create a new promise wrapper if the
|
||||
argument is a promise.
|
||||
* `RSVP.Promise.cast` is a way of casting incoming thenables or promise subclasses to
|
||||
promises of the exact class specified, so that the resulting object's `then` is
|
||||
ensured to have the behavior of the constructor you are calling cast on (i.e., RSVP.Promise).
|
||||
|
||||
@method cast
|
||||
@for RSVP
|
||||
@param {Object} object to be casted
|
||||
@return {Promise} promise that is fulfilled when all properties of `promises`
|
||||
have been fulfilled, or rejected if any of them become rejected.
|
||||
*/
|
||||
|
||||
|
||||
function cast(object) {
|
||||
/*jshint validthis:true */
|
||||
if (object && typeof object === 'object' && object.constructor === this) {
|
||||
return object;
|
||||
}
|
||||
|
||||
var Promise = this;
|
||||
|
||||
return new Promise(function(resolve) {
|
||||
resolve(object);
|
||||
});
|
||||
}
|
||||
|
||||
__exports__.cast = cast;
|
||||
});
|
||||
define("promise/config",
|
||||
["exports"],
|
||||
function(__exports__) {
|
||||
"use strict";
|
||||
var config = {
|
||||
instrument: false
|
||||
};
|
||||
|
||||
function configure(name, value) {
|
||||
if (arguments.length === 2) {
|
||||
config[name] = value;
|
||||
} else {
|
||||
return config[name];
|
||||
}
|
||||
}
|
||||
|
||||
__exports__.config = config;
|
||||
__exports__.configure = configure;
|
||||
});
|
||||
define("promise/polyfill",
|
||||
["./promise","./utils","exports"],
|
||||
function(__dependency1__, __dependency2__, __exports__) {
|
||||
"use strict";
|
||||
/*global self*/
|
||||
var RSVPPromise = __dependency1__.Promise;
|
||||
var isFunction = __dependency2__.isFunction;
|
||||
|
||||
function polyfill() {
|
||||
var local;
|
||||
|
||||
if (typeof global !== 'undefined') {
|
||||
local = global;
|
||||
} else if (typeof window !== 'undefined' && window.document) {
|
||||
local = window;
|
||||
} else {
|
||||
local = self;
|
||||
}
|
||||
|
||||
var es6PromiseSupport =
|
||||
"Promise" in local &&
|
||||
// Some of these methods are missing from
|
||||
// Firefox/Chrome experimental implementations
|
||||
"cast" in local.Promise &&
|
||||
"resolve" in local.Promise &&
|
||||
"reject" in local.Promise &&
|
||||
"all" in local.Promise &&
|
||||
"race" in local.Promise &&
|
||||
// Older version of the spec had a resolver object
|
||||
// as the arg rather than a function
|
||||
(function() {
|
||||
var resolve;
|
||||
new local.Promise(function(r) { resolve = r; });
|
||||
return isFunction(resolve);
|
||||
}());
|
||||
|
||||
if (!es6PromiseSupport) {
|
||||
local.Promise = RSVPPromise;
|
||||
}
|
||||
}
|
||||
|
||||
__exports__.polyfill = polyfill;
|
||||
});
|
||||
define("promise/promise",
|
||||
["./config","./utils","./cast","./all","./race","./resolve","./reject","./asap","exports"],
|
||||
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) {
|
||||
"use strict";
|
||||
var config = __dependency1__.config;
|
||||
var configure = __dependency1__.configure;
|
||||
var objectOrFunction = __dependency2__.objectOrFunction;
|
||||
var isFunction = __dependency2__.isFunction;
|
||||
var now = __dependency2__.now;
|
||||
var cast = __dependency3__.cast;
|
||||
var all = __dependency4__.all;
|
||||
var race = __dependency5__.race;
|
||||
var staticResolve = __dependency6__.resolve;
|
||||
var staticReject = __dependency7__.reject;
|
||||
var asap = __dependency8__.asap;
|
||||
|
||||
var counter = 0;
|
||||
|
||||
config.async = asap; // default async is asap;
|
||||
|
||||
function Promise(resolver) {
|
||||
if (!isFunction(resolver)) {
|
||||
throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
|
||||
}
|
||||
|
||||
if (!(this instanceof Promise)) {
|
||||
throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
|
||||
}
|
||||
|
||||
this._subscribers = [];
|
||||
|
||||
invokeResolver(resolver, this);
|
||||
}
|
||||
|
||||
function invokeResolver(resolver, promise) {
|
||||
function resolvePromise(value) {
|
||||
resolve(promise, value);
|
||||
}
|
||||
|
||||
function rejectPromise(reason) {
|
||||
reject(promise, reason);
|
||||
}
|
||||
|
||||
try {
|
||||
resolver(resolvePromise, rejectPromise);
|
||||
} catch(e) {
|
||||
rejectPromise(e);
|
||||
}
|
||||
}
|
||||
|
||||
function invokeCallback(settled, promise, callback, detail) {
|
||||
var hasCallback = isFunction(callback),
|
||||
value, error, succeeded, failed;
|
||||
|
||||
if (hasCallback) {
|
||||
try {
|
||||
value = callback(detail);
|
||||
succeeded = true;
|
||||
} catch(e) {
|
||||
failed = true;
|
||||
error = e;
|
||||
}
|
||||
} else {
|
||||
value = detail;
|
||||
succeeded = true;
|
||||
}
|
||||
|
||||
if (handleThenable(promise, value)) {
|
||||
return;
|
||||
} else if (hasCallback && succeeded) {
|
||||
resolve(promise, value);
|
||||
} else if (failed) {
|
||||
reject(promise, error);
|
||||
} else if (settled === FULFILLED) {
|
||||
resolve(promise, value);
|
||||
} else if (settled === REJECTED) {
|
||||
reject(promise, value);
|
||||
}
|
||||
}
|
||||
|
||||
var PENDING = void 0;
|
||||
var SEALED = 0;
|
||||
var FULFILLED = 1;
|
||||
var REJECTED = 2;
|
||||
|
||||
function subscribe(parent, child, onFulfillment, onRejection) {
|
||||
var subscribers = parent._subscribers;
|
||||
var length = subscribers.length;
|
||||
|
||||
subscribers[length] = child;
|
||||
subscribers[length + FULFILLED] = onFulfillment;
|
||||
subscribers[length + REJECTED] = onRejection;
|
||||
}
|
||||
|
||||
function publish(promise, settled) {
|
||||
var child, callback, subscribers = promise._subscribers, detail = promise._detail;
|
||||
|
||||
for (var i = 0; i < subscribers.length; i += 3) {
|
||||
child = subscribers[i];
|
||||
callback = subscribers[i + settled];
|
||||
|
||||
invokeCallback(settled, child, callback, detail);
|
||||
}
|
||||
|
||||
promise._subscribers = null;
|
||||
}
|
||||
|
||||
Promise.prototype = {
|
||||
constructor: Promise,
|
||||
|
||||
_state: undefined,
|
||||
_detail: undefined,
|
||||
_subscribers: undefined,
|
||||
|
||||
then: function(onFulfillment, onRejection) {
|
||||
var promise = this;
|
||||
|
||||
var thenPromise = new this.constructor(function() {});
|
||||
|
||||
if (this._state) {
|
||||
var callbacks = arguments;
|
||||
config.async(function invokePromiseCallback() {
|
||||
invokeCallback(promise._state, thenPromise, callbacks[promise._state - 1], promise._detail);
|
||||
});
|
||||
} else {
|
||||
subscribe(this, thenPromise, onFulfillment, onRejection);
|
||||
}
|
||||
|
||||
return thenPromise;
|
||||
},
|
||||
|
||||
'catch': function(onRejection) {
|
||||
return this.then(null, onRejection);
|
||||
}
|
||||
};
|
||||
|
||||
Promise.all = all;
|
||||
Promise.cast = cast;
|
||||
Promise.race = race;
|
||||
Promise.resolve = staticResolve;
|
||||
Promise.reject = staticReject;
|
||||
|
||||
function handleThenable(promise, value) {
|
||||
var then = null,
|
||||
resolved;
|
||||
|
||||
try {
|
||||
if (promise === value) {
|
||||
throw new TypeError("A promises callback cannot return that same promise.");
|
||||
}
|
||||
|
||||
if (objectOrFunction(value)) {
|
||||
then = value.then;
|
||||
|
||||
if (isFunction(then)) {
|
||||
then.call(value, function(val) {
|
||||
if (resolved) { return true; }
|
||||
resolved = true;
|
||||
|
||||
if (value !== val) {
|
||||
resolve(promise, val);
|
||||
} else {
|
||||
fulfill(promise, val);
|
||||
}
|
||||
}, function(val) {
|
||||
if (resolved) { return true; }
|
||||
resolved = true;
|
||||
|
||||
reject(promise, val);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (resolved) { return true; }
|
||||
reject(promise, error);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function resolve(promise, value) {
|
||||
if (promise === value) {
|
||||
fulfill(promise, value);
|
||||
} else if (!handleThenable(promise, value)) {
|
||||
fulfill(promise, value);
|
||||
}
|
||||
}
|
||||
|
||||
function fulfill(promise, value) {
|
||||
if (promise._state !== PENDING) { return; }
|
||||
promise._state = SEALED;
|
||||
promise._detail = value;
|
||||
|
||||
config.async(publishFulfillment, promise);
|
||||
}
|
||||
|
||||
function reject(promise, reason) {
|
||||
if (promise._state !== PENDING) { return; }
|
||||
promise._state = SEALED;
|
||||
promise._detail = reason;
|
||||
|
||||
config.async(publishRejection, promise);
|
||||
}
|
||||
|
||||
function publishFulfillment(promise) {
|
||||
publish(promise, promise._state = FULFILLED);
|
||||
}
|
||||
|
||||
function publishRejection(promise) {
|
||||
publish(promise, promise._state = REJECTED);
|
||||
}
|
||||
|
||||
__exports__.Promise = Promise;
|
||||
});
|
||||
define("promise/race",
|
||||
["./utils","exports"],
|
||||
function(__dependency1__, __exports__) {
|
||||
"use strict";
|
||||
/* global toString */
|
||||
var isArray = __dependency1__.isArray;
|
||||
|
||||
/**
|
||||
`RSVP.race` allows you to watch a series of promises and act as soon as the
|
||||
first promise given to the `promises` argument fulfills or rejects.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var promise1 = new RSVP.Promise(function(resolve, reject){
|
||||
setTimeout(function(){
|
||||
resolve("promise 1");
|
||||
}, 200);
|
||||
});
|
||||
|
||||
var promise2 = new RSVP.Promise(function(resolve, reject){
|
||||
setTimeout(function(){
|
||||
resolve("promise 2");
|
||||
}, 100);
|
||||
});
|
||||
|
||||
RSVP.race([promise1, promise2]).then(function(result){
|
||||
// result === "promise 2" because it was resolved before promise1
|
||||
// was resolved.
|
||||
});
|
||||
```
|
||||
|
||||
`RSVP.race` is deterministic in that only the state of the first completed
|
||||
promise matters. For example, even if other promises given to the `promises`
|
||||
array argument are resolved, but the first completed promise has become
|
||||
rejected before the other promises became fulfilled, the returned promise
|
||||
will become rejected:
|
||||
|
||||
```javascript
|
||||
var promise1 = new RSVP.Promise(function(resolve, reject){
|
||||
setTimeout(function(){
|
||||
resolve("promise 1");
|
||||
}, 200);
|
||||
});
|
||||
|
||||
var promise2 = new RSVP.Promise(function(resolve, reject){
|
||||
setTimeout(function(){
|
||||
reject(new Error("promise 2"));
|
||||
}, 100);
|
||||
});
|
||||
|
||||
RSVP.race([promise1, promise2]).then(function(result){
|
||||
// Code here never runs because there are rejected promises!
|
||||
}, function(reason){
|
||||
// reason.message === "promise2" because promise 2 became rejected before
|
||||
// promise 1 became fulfilled
|
||||
});
|
||||
```
|
||||
|
||||
@method race
|
||||
@for RSVP
|
||||
@param {Array} promises array of promises to observe
|
||||
@param {String} label optional string for describing the promise returned.
|
||||
Useful for tooling.
|
||||
@return {Promise} a promise that becomes fulfilled with the value the first
|
||||
completed promises is resolved with if the first completed promise was
|
||||
fulfilled, or rejected with the reason that the first completed promise
|
||||
was rejected with.
|
||||
*/
|
||||
function race(promises) {
|
||||
/*jshint validthis:true */
|
||||
var Promise = this;
|
||||
|
||||
if (!isArray(promises)) {
|
||||
throw new TypeError('You must pass an array to race.');
|
||||
}
|
||||
return new Promise(function(resolve, reject) {
|
||||
var results = [], promise;
|
||||
|
||||
for (var i = 0; i < promises.length; i++) {
|
||||
promise = promises[i];
|
||||
|
||||
if (promise && typeof promise.then === 'function') {
|
||||
promise.then(resolve, reject);
|
||||
} else {
|
||||
resolve(promise);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
__exports__.race = race;
|
||||
});
|
||||
define("promise/reject",
|
||||
["exports"],
|
||||
function(__exports__) {
|
||||
"use strict";
|
||||
/**
|
||||
`RSVP.reject` returns a promise that will become rejected with the passed
|
||||
`reason`. `RSVP.reject` is essentially shorthand for the following:
|
||||
|
||||
```javascript
|
||||
var promise = new RSVP.Promise(function(resolve, reject){
|
||||
reject(new Error('WHOOPS'));
|
||||
});
|
||||
|
||||
promise.then(function(value){
|
||||
// Code here doesn't run because the promise is rejected!
|
||||
}, function(reason){
|
||||
// reason.message === 'WHOOPS'
|
||||
});
|
||||
```
|
||||
|
||||
Instead of writing the above, your code now simply becomes the following:
|
||||
|
||||
```javascript
|
||||
var promise = RSVP.reject(new Error('WHOOPS'));
|
||||
|
||||
promise.then(function(value){
|
||||
// Code here doesn't run because the promise is rejected!
|
||||
}, function(reason){
|
||||
// reason.message === 'WHOOPS'
|
||||
});
|
||||
```
|
||||
|
||||
@method reject
|
||||
@for RSVP
|
||||
@param {Any} reason value that the returned promise will be rejected with.
|
||||
@param {String} label optional string for identifying the returned promise.
|
||||
Useful for tooling.
|
||||
@return {Promise} a promise that will become rejected with the given
|
||||
`reason`.
|
||||
*/
|
||||
function reject(reason) {
|
||||
/*jshint validthis:true */
|
||||
var Promise = this;
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
reject(reason);
|
||||
});
|
||||
}
|
||||
|
||||
__exports__.reject = reject;
|
||||
});
|
||||
define("promise/resolve",
|
||||
["exports"],
|
||||
function(__exports__) {
|
||||
"use strict";
|
||||
/**
|
||||
`RSVP.resolve` returns a promise that will become fulfilled with the passed
|
||||
`value`. `RSVP.resolve` is essentially shorthand for the following:
|
||||
|
||||
```javascript
|
||||
var promise = new RSVP.Promise(function(resolve, reject){
|
||||
resolve(1);
|
||||
});
|
||||
|
||||
promise.then(function(value){
|
||||
// value === 1
|
||||
});
|
||||
```
|
||||
|
||||
Instead of writing the above, your code now simply becomes the following:
|
||||
|
||||
```javascript
|
||||
var promise = RSVP.resolve(1);
|
||||
|
||||
promise.then(function(value){
|
||||
// value === 1
|
||||
});
|
||||
```
|
||||
|
||||
@method resolve
|
||||
@for RSVP
|
||||
@param {Any} value value that the returned promise will be resolved with
|
||||
@param {String} label optional string for identifying the returned promise.
|
||||
Useful for tooling.
|
||||
@return {Promise} a promise that will become fulfilled with the given
|
||||
`value`
|
||||
*/
|
||||
function resolve(value) {
|
||||
/*jshint validthis:true */
|
||||
var Promise = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
resolve(value);
|
||||
});
|
||||
}
|
||||
|
||||
__exports__.resolve = resolve;
|
||||
});
|
||||
define("promise/utils",
|
||||
["exports"],
|
||||
function(__exports__) {
|
||||
"use strict";
|
||||
function objectOrFunction(x) {
|
||||
return isFunction(x) || (typeof x === "object" && x !== null);
|
||||
}
|
||||
|
||||
function isFunction(x) {
|
||||
return typeof x === "function";
|
||||
}
|
||||
|
||||
function isArray(x) {
|
||||
return Object.prototype.toString.call(x) === "[object Array]";
|
||||
}
|
||||
|
||||
// Date.now is not available in browsers < IE9
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now#Compatibility
|
||||
var now = Date.now || function() { return new Date().getTime(); };
|
||||
|
||||
|
||||
__exports__.objectOrFunction = objectOrFunction;
|
||||
__exports__.isFunction = isFunction;
|
||||
__exports__.isArray = isArray;
|
||||
__exports__.now = now;
|
||||
});
|
||||
+785
@@ -0,0 +1,785 @@
|
||||
(function() {
|
||||
var define, requireModule, require, requirejs;
|
||||
|
||||
(function() {
|
||||
var registry = {}, seen = {};
|
||||
|
||||
define = function(name, deps, callback) {
|
||||
registry[name] = { deps: deps, callback: callback };
|
||||
};
|
||||
|
||||
requirejs = require = requireModule = function(name) {
|
||||
requirejs._eak_seen = registry;
|
||||
|
||||
if (seen[name]) { return seen[name]; }
|
||||
seen[name] = {};
|
||||
|
||||
if (!registry[name]) {
|
||||
throw new Error("Could not find module " + name);
|
||||
}
|
||||
|
||||
var mod = registry[name],
|
||||
deps = mod.deps,
|
||||
callback = mod.callback,
|
||||
reified = [],
|
||||
exports;
|
||||
|
||||
for (var i=0, l=deps.length; i<l; i++) {
|
||||
if (deps[i] === 'exports') {
|
||||
reified.push(exports = {});
|
||||
} else {
|
||||
reified.push(requireModule(resolve(deps[i])));
|
||||
}
|
||||
}
|
||||
|
||||
var value = callback.apply(this, reified);
|
||||
return seen[name] = exports || value;
|
||||
|
||||
function resolve(child) {
|
||||
if (child.charAt(0) !== '.') { return child; }
|
||||
var parts = child.split("/");
|
||||
var parentBase = name.split("/").slice(0, -1);
|
||||
|
||||
for (var i=0, l=parts.length; i<l; i++) {
|
||||
var part = parts[i];
|
||||
|
||||
if (part === '..') { parentBase.pop(); }
|
||||
else if (part === '.') { continue; }
|
||||
else { parentBase.push(part); }
|
||||
}
|
||||
|
||||
return parentBase.join("/");
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
define("promise/all",
|
||||
["./utils","exports"],
|
||||
function(__dependency1__, __exports__) {
|
||||
"use strict";
|
||||
/* global toString */
|
||||
|
||||
var isArray = __dependency1__.isArray;
|
||||
var isFunction = __dependency1__.isFunction;
|
||||
|
||||
/**
|
||||
Returns a promise that is fulfilled when all the given promises have been
|
||||
fulfilled, or rejected if any of them become rejected. The return promise
|
||||
is fulfilled with an array that gives all the values in the order they were
|
||||
passed in the `promises` array argument.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var promise1 = RSVP.resolve(1);
|
||||
var promise2 = RSVP.resolve(2);
|
||||
var promise3 = RSVP.resolve(3);
|
||||
var promises = [ promise1, promise2, promise3 ];
|
||||
|
||||
RSVP.all(promises).then(function(array){
|
||||
// The array here would be [ 1, 2, 3 ];
|
||||
});
|
||||
```
|
||||
|
||||
If any of the `promises` given to `RSVP.all` are rejected, the first promise
|
||||
that is rejected will be given as an argument to the returned promises's
|
||||
rejection handler. For example:
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var promise1 = RSVP.resolve(1);
|
||||
var promise2 = RSVP.reject(new Error("2"));
|
||||
var promise3 = RSVP.reject(new Error("3"));
|
||||
var promises = [ promise1, promise2, promise3 ];
|
||||
|
||||
RSVP.all(promises).then(function(array){
|
||||
// Code here never runs because there are rejected promises!
|
||||
}, function(error) {
|
||||
// error.message === "2"
|
||||
});
|
||||
```
|
||||
|
||||
@method all
|
||||
@for RSVP
|
||||
@param {Array} promises
|
||||
@param {String} label
|
||||
@return {Promise} promise that is fulfilled when all `promises` have been
|
||||
fulfilled, or rejected if any of them become rejected.
|
||||
*/
|
||||
function all(promises) {
|
||||
/*jshint validthis:true */
|
||||
var Promise = this;
|
||||
|
||||
if (!isArray(promises)) {
|
||||
throw new TypeError('You must pass an array to all.');
|
||||
}
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
var results = [], remaining = promises.length,
|
||||
promise;
|
||||
|
||||
if (remaining === 0) {
|
||||
resolve([]);
|
||||
}
|
||||
|
||||
function resolver(index) {
|
||||
return function(value) {
|
||||
resolveAll(index, value);
|
||||
};
|
||||
}
|
||||
|
||||
function resolveAll(index, value) {
|
||||
results[index] = value;
|
||||
if (--remaining === 0) {
|
||||
resolve(results);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < promises.length; i++) {
|
||||
promise = promises[i];
|
||||
|
||||
if (promise && isFunction(promise.then)) {
|
||||
promise.then(resolver(i), reject);
|
||||
} else {
|
||||
resolveAll(i, promise);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
__exports__.all = all;
|
||||
});
|
||||
define("promise/asap",
|
||||
["exports"],
|
||||
function(__exports__) {
|
||||
"use strict";
|
||||
var browserGlobal = (typeof window !== 'undefined') ? window : {};
|
||||
var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
|
||||
var local = (typeof global !== 'undefined') ? global : (this === undefined? window:this);
|
||||
|
||||
// node
|
||||
function useNextTick() {
|
||||
return function() {
|
||||
process.nextTick(flush);
|
||||
};
|
||||
}
|
||||
|
||||
function useMutationObserver() {
|
||||
var iterations = 0;
|
||||
var observer = new BrowserMutationObserver(flush);
|
||||
var node = document.createTextNode('');
|
||||
observer.observe(node, { characterData: true });
|
||||
|
||||
return function() {
|
||||
node.data = (iterations = ++iterations % 2);
|
||||
};
|
||||
}
|
||||
|
||||
function useSetTimeout() {
|
||||
return function() {
|
||||
local.setTimeout(flush, 1);
|
||||
};
|
||||
}
|
||||
|
||||
var queue = [];
|
||||
function flush() {
|
||||
for (var i = 0; i < queue.length; i++) {
|
||||
var tuple = queue[i];
|
||||
var callback = tuple[0], arg = tuple[1];
|
||||
callback(arg);
|
||||
}
|
||||
queue = [];
|
||||
}
|
||||
|
||||
var scheduleFlush;
|
||||
|
||||
// Decide what async method to use to triggering processing of queued callbacks:
|
||||
if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
|
||||
scheduleFlush = useNextTick();
|
||||
} else if (BrowserMutationObserver) {
|
||||
scheduleFlush = useMutationObserver();
|
||||
} else {
|
||||
scheduleFlush = useSetTimeout();
|
||||
}
|
||||
|
||||
function asap(callback, arg) {
|
||||
var length = queue.push([callback, arg]);
|
||||
if (length === 1) {
|
||||
// If length is 1, that means that we need to schedule an async flush.
|
||||
// If additional callbacks are queued before the queue is flushed, they
|
||||
// will be processed by this flush that we are scheduling.
|
||||
scheduleFlush();
|
||||
}
|
||||
}
|
||||
|
||||
__exports__.asap = asap;
|
||||
});
|
||||
define("promise/cast",
|
||||
["exports"],
|
||||
function(__exports__) {
|
||||
"use strict";
|
||||
/**
|
||||
`RSVP.Promise.cast` returns the same promise if that promise shares a constructor
|
||||
with the promise being casted.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var promise = RSVP.resolve(1);
|
||||
var casted = RSVP.Promise.cast(promise);
|
||||
|
||||
console.log(promise === casted); // true
|
||||
```
|
||||
|
||||
In the case of a promise whose constructor does not match, it is assimilated.
|
||||
The resulting promise will fulfill or reject based on the outcome of the
|
||||
promise being casted.
|
||||
|
||||
In the case of a non-promise, a promise which will fulfill with that value is
|
||||
returned.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var value = 1; // could be a number, boolean, string, undefined...
|
||||
var casted = RSVP.Promise.cast(value);
|
||||
|
||||
console.log(value === casted); // false
|
||||
console.log(casted instanceof RSVP.Promise) // true
|
||||
|
||||
casted.then(function(val) {
|
||||
val === value // => true
|
||||
});
|
||||
```
|
||||
|
||||
`RSVP.Promise.cast` is similar to `RSVP.resolve`, but `RSVP.Promise.cast` differs in the
|
||||
following ways:
|
||||
* `RSVP.Promise.cast` serves as a memory-efficient way of getting a promise, when you
|
||||
have something that could either be a promise or a value. RSVP.resolve
|
||||
will have the same effect but will create a new promise wrapper if the
|
||||
argument is a promise.
|
||||
* `RSVP.Promise.cast` is a way of casting incoming thenables or promise subclasses to
|
||||
promises of the exact class specified, so that the resulting object's `then` is
|
||||
ensured to have the behavior of the constructor you are calling cast on (i.e., RSVP.Promise).
|
||||
|
||||
@method cast
|
||||
@for RSVP
|
||||
@param {Object} object to be casted
|
||||
@return {Promise} promise that is fulfilled when all properties of `promises`
|
||||
have been fulfilled, or rejected if any of them become rejected.
|
||||
*/
|
||||
|
||||
|
||||
function cast(object) {
|
||||
/*jshint validthis:true */
|
||||
if (object && typeof object === 'object' && object.constructor === this) {
|
||||
return object;
|
||||
}
|
||||
|
||||
var Promise = this;
|
||||
|
||||
return new Promise(function(resolve) {
|
||||
resolve(object);
|
||||
});
|
||||
}
|
||||
|
||||
__exports__.cast = cast;
|
||||
});
|
||||
define("promise/config",
|
||||
["exports"],
|
||||
function(__exports__) {
|
||||
"use strict";
|
||||
var config = {
|
||||
instrument: false
|
||||
};
|
||||
|
||||
function configure(name, value) {
|
||||
if (arguments.length === 2) {
|
||||
config[name] = value;
|
||||
} else {
|
||||
return config[name];
|
||||
}
|
||||
}
|
||||
|
||||
__exports__.config = config;
|
||||
__exports__.configure = configure;
|
||||
});
|
||||
define("promise/polyfill",
|
||||
["./promise","./utils","exports"],
|
||||
function(__dependency1__, __dependency2__, __exports__) {
|
||||
"use strict";
|
||||
/*global self*/
|
||||
var RSVPPromise = __dependency1__.Promise;
|
||||
var isFunction = __dependency2__.isFunction;
|
||||
|
||||
function polyfill() {
|
||||
var local;
|
||||
|
||||
if (typeof global !== 'undefined') {
|
||||
local = global;
|
||||
} else if (typeof window !== 'undefined' && window.document) {
|
||||
local = window;
|
||||
} else {
|
||||
local = self;
|
||||
}
|
||||
|
||||
var es6PromiseSupport =
|
||||
"Promise" in local &&
|
||||
// Some of these methods are missing from
|
||||
// Firefox/Chrome experimental implementations
|
||||
"cast" in local.Promise &&
|
||||
"resolve" in local.Promise &&
|
||||
"reject" in local.Promise &&
|
||||
"all" in local.Promise &&
|
||||
"race" in local.Promise &&
|
||||
// Older version of the spec had a resolver object
|
||||
// as the arg rather than a function
|
||||
(function() {
|
||||
var resolve;
|
||||
new local.Promise(function(r) { resolve = r; });
|
||||
return isFunction(resolve);
|
||||
}());
|
||||
|
||||
if (!es6PromiseSupport) {
|
||||
local.Promise = RSVPPromise;
|
||||
}
|
||||
}
|
||||
|
||||
__exports__.polyfill = polyfill;
|
||||
});
|
||||
define("promise/promise",
|
||||
["./config","./utils","./cast","./all","./race","./resolve","./reject","./asap","exports"],
|
||||
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) {
|
||||
"use strict";
|
||||
var config = __dependency1__.config;
|
||||
var configure = __dependency1__.configure;
|
||||
var objectOrFunction = __dependency2__.objectOrFunction;
|
||||
var isFunction = __dependency2__.isFunction;
|
||||
var now = __dependency2__.now;
|
||||
var cast = __dependency3__.cast;
|
||||
var all = __dependency4__.all;
|
||||
var race = __dependency5__.race;
|
||||
var staticResolve = __dependency6__.resolve;
|
||||
var staticReject = __dependency7__.reject;
|
||||
var asap = __dependency8__.asap;
|
||||
|
||||
var counter = 0;
|
||||
|
||||
config.async = asap; // default async is asap;
|
||||
|
||||
function Promise(resolver) {
|
||||
if (!isFunction(resolver)) {
|
||||
throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
|
||||
}
|
||||
|
||||
if (!(this instanceof Promise)) {
|
||||
throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
|
||||
}
|
||||
|
||||
this._subscribers = [];
|
||||
|
||||
invokeResolver(resolver, this);
|
||||
}
|
||||
|
||||
function invokeResolver(resolver, promise) {
|
||||
function resolvePromise(value) {
|
||||
resolve(promise, value);
|
||||
}
|
||||
|
||||
function rejectPromise(reason) {
|
||||
reject(promise, reason);
|
||||
}
|
||||
|
||||
try {
|
||||
resolver(resolvePromise, rejectPromise);
|
||||
} catch(e) {
|
||||
rejectPromise(e);
|
||||
}
|
||||
}
|
||||
|
||||
function invokeCallback(settled, promise, callback, detail) {
|
||||
var hasCallback = isFunction(callback),
|
||||
value, error, succeeded, failed;
|
||||
|
||||
if (hasCallback) {
|
||||
try {
|
||||
value = callback(detail);
|
||||
succeeded = true;
|
||||
} catch(e) {
|
||||
failed = true;
|
||||
error = e;
|
||||
}
|
||||
} else {
|
||||
value = detail;
|
||||
succeeded = true;
|
||||
}
|
||||
|
||||
if (handleThenable(promise, value)) {
|
||||
return;
|
||||
} else if (hasCallback && succeeded) {
|
||||
resolve(promise, value);
|
||||
} else if (failed) {
|
||||
reject(promise, error);
|
||||
} else if (settled === FULFILLED) {
|
||||
resolve(promise, value);
|
||||
} else if (settled === REJECTED) {
|
||||
reject(promise, value);
|
||||
}
|
||||
}
|
||||
|
||||
var PENDING = void 0;
|
||||
var SEALED = 0;
|
||||
var FULFILLED = 1;
|
||||
var REJECTED = 2;
|
||||
|
||||
function subscribe(parent, child, onFulfillment, onRejection) {
|
||||
var subscribers = parent._subscribers;
|
||||
var length = subscribers.length;
|
||||
|
||||
subscribers[length] = child;
|
||||
subscribers[length + FULFILLED] = onFulfillment;
|
||||
subscribers[length + REJECTED] = onRejection;
|
||||
}
|
||||
|
||||
function publish(promise, settled) {
|
||||
var child, callback, subscribers = promise._subscribers, detail = promise._detail;
|
||||
|
||||
for (var i = 0; i < subscribers.length; i += 3) {
|
||||
child = subscribers[i];
|
||||
callback = subscribers[i + settled];
|
||||
|
||||
invokeCallback(settled, child, callback, detail);
|
||||
}
|
||||
|
||||
promise._subscribers = null;
|
||||
}
|
||||
|
||||
Promise.prototype = {
|
||||
constructor: Promise,
|
||||
|
||||
_state: undefined,
|
||||
_detail: undefined,
|
||||
_subscribers: undefined,
|
||||
|
||||
then: function(onFulfillment, onRejection) {
|
||||
var promise = this;
|
||||
|
||||
var thenPromise = new this.constructor(function() {});
|
||||
|
||||
if (this._state) {
|
||||
var callbacks = arguments;
|
||||
config.async(function invokePromiseCallback() {
|
||||
invokeCallback(promise._state, thenPromise, callbacks[promise._state - 1], promise._detail);
|
||||
});
|
||||
} else {
|
||||
subscribe(this, thenPromise, onFulfillment, onRejection);
|
||||
}
|
||||
|
||||
return thenPromise;
|
||||
},
|
||||
|
||||
'catch': function(onRejection) {
|
||||
return this.then(null, onRejection);
|
||||
}
|
||||
};
|
||||
|
||||
Promise.all = all;
|
||||
Promise.cast = cast;
|
||||
Promise.race = race;
|
||||
Promise.resolve = staticResolve;
|
||||
Promise.reject = staticReject;
|
||||
|
||||
function handleThenable(promise, value) {
|
||||
var then = null,
|
||||
resolved;
|
||||
|
||||
try {
|
||||
if (promise === value) {
|
||||
throw new TypeError("A promises callback cannot return that same promise.");
|
||||
}
|
||||
|
||||
if (objectOrFunction(value)) {
|
||||
then = value.then;
|
||||
|
||||
if (isFunction(then)) {
|
||||
then.call(value, function(val) {
|
||||
if (resolved) { return true; }
|
||||
resolved = true;
|
||||
|
||||
if (value !== val) {
|
||||
resolve(promise, val);
|
||||
} else {
|
||||
fulfill(promise, val);
|
||||
}
|
||||
}, function(val) {
|
||||
if (resolved) { return true; }
|
||||
resolved = true;
|
||||
|
||||
reject(promise, val);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (resolved) { return true; }
|
||||
reject(promise, error);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function resolve(promise, value) {
|
||||
if (promise === value) {
|
||||
fulfill(promise, value);
|
||||
} else if (!handleThenable(promise, value)) {
|
||||
fulfill(promise, value);
|
||||
}
|
||||
}
|
||||
|
||||
function fulfill(promise, value) {
|
||||
if (promise._state !== PENDING) { return; }
|
||||
promise._state = SEALED;
|
||||
promise._detail = value;
|
||||
|
||||
config.async(publishFulfillment, promise);
|
||||
}
|
||||
|
||||
function reject(promise, reason) {
|
||||
if (promise._state !== PENDING) { return; }
|
||||
promise._state = SEALED;
|
||||
promise._detail = reason;
|
||||
|
||||
config.async(publishRejection, promise);
|
||||
}
|
||||
|
||||
function publishFulfillment(promise) {
|
||||
publish(promise, promise._state = FULFILLED);
|
||||
}
|
||||
|
||||
function publishRejection(promise) {
|
||||
publish(promise, promise._state = REJECTED);
|
||||
}
|
||||
|
||||
__exports__.Promise = Promise;
|
||||
});
|
||||
define("promise/race",
|
||||
["./utils","exports"],
|
||||
function(__dependency1__, __exports__) {
|
||||
"use strict";
|
||||
/* global toString */
|
||||
var isArray = __dependency1__.isArray;
|
||||
|
||||
/**
|
||||
`RSVP.race` allows you to watch a series of promises and act as soon as the
|
||||
first promise given to the `promises` argument fulfills or rejects.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
var promise1 = new RSVP.Promise(function(resolve, reject){
|
||||
setTimeout(function(){
|
||||
resolve("promise 1");
|
||||
}, 200);
|
||||
});
|
||||
|
||||
var promise2 = new RSVP.Promise(function(resolve, reject){
|
||||
setTimeout(function(){
|
||||
resolve("promise 2");
|
||||
}, 100);
|
||||
});
|
||||
|
||||
RSVP.race([promise1, promise2]).then(function(result){
|
||||
// result === "promise 2" because it was resolved before promise1
|
||||
// was resolved.
|
||||
});
|
||||
```
|
||||
|
||||
`RSVP.race` is deterministic in that only the state of the first completed
|
||||
promise matters. For example, even if other promises given to the `promises`
|
||||
array argument are resolved, but the first completed promise has become
|
||||
rejected before the other promises became fulfilled, the returned promise
|
||||
will become rejected:
|
||||
|
||||
```javascript
|
||||
var promise1 = new RSVP.Promise(function(resolve, reject){
|
||||
setTimeout(function(){
|
||||
resolve("promise 1");
|
||||
}, 200);
|
||||
});
|
||||
|
||||
var promise2 = new RSVP.Promise(function(resolve, reject){
|
||||
setTimeout(function(){
|
||||
reject(new Error("promise 2"));
|
||||
}, 100);
|
||||
});
|
||||
|
||||
RSVP.race([promise1, promise2]).then(function(result){
|
||||
// Code here never runs because there are rejected promises!
|
||||
}, function(reason){
|
||||
// reason.message === "promise2" because promise 2 became rejected before
|
||||
// promise 1 became fulfilled
|
||||
});
|
||||
```
|
||||
|
||||
@method race
|
||||
@for RSVP
|
||||
@param {Array} promises array of promises to observe
|
||||
@param {String} label optional string for describing the promise returned.
|
||||
Useful for tooling.
|
||||
@return {Promise} a promise that becomes fulfilled with the value the first
|
||||
completed promises is resolved with if the first completed promise was
|
||||
fulfilled, or rejected with the reason that the first completed promise
|
||||
was rejected with.
|
||||
*/
|
||||
function race(promises) {
|
||||
/*jshint validthis:true */
|
||||
var Promise = this;
|
||||
|
||||
if (!isArray(promises)) {
|
||||
throw new TypeError('You must pass an array to race.');
|
||||
}
|
||||
return new Promise(function(resolve, reject) {
|
||||
var results = [], promise;
|
||||
|
||||
for (var i = 0; i < promises.length; i++) {
|
||||
promise = promises[i];
|
||||
|
||||
if (promise && typeof promise.then === 'function') {
|
||||
promise.then(resolve, reject);
|
||||
} else {
|
||||
resolve(promise);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
__exports__.race = race;
|
||||
});
|
||||
define("promise/reject",
|
||||
["exports"],
|
||||
function(__exports__) {
|
||||
"use strict";
|
||||
/**
|
||||
`RSVP.reject` returns a promise that will become rejected with the passed
|
||||
`reason`. `RSVP.reject` is essentially shorthand for the following:
|
||||
|
||||
```javascript
|
||||
var promise = new RSVP.Promise(function(resolve, reject){
|
||||
reject(new Error('WHOOPS'));
|
||||
});
|
||||
|
||||
promise.then(function(value){
|
||||
// Code here doesn't run because the promise is rejected!
|
||||
}, function(reason){
|
||||
// reason.message === 'WHOOPS'
|
||||
});
|
||||
```
|
||||
|
||||
Instead of writing the above, your code now simply becomes the following:
|
||||
|
||||
```javascript
|
||||
var promise = RSVP.reject(new Error('WHOOPS'));
|
||||
|
||||
promise.then(function(value){
|
||||
// Code here doesn't run because the promise is rejected!
|
||||
}, function(reason){
|
||||
// reason.message === 'WHOOPS'
|
||||
});
|
||||
```
|
||||
|
||||
@method reject
|
||||
@for RSVP
|
||||
@param {Any} reason value that the returned promise will be rejected with.
|
||||
@param {String} label optional string for identifying the returned promise.
|
||||
Useful for tooling.
|
||||
@return {Promise} a promise that will become rejected with the given
|
||||
`reason`.
|
||||
*/
|
||||
function reject(reason) {
|
||||
/*jshint validthis:true */
|
||||
var Promise = this;
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
reject(reason);
|
||||
});
|
||||
}
|
||||
|
||||
__exports__.reject = reject;
|
||||
});
|
||||
define("promise/resolve",
|
||||
["exports"],
|
||||
function(__exports__) {
|
||||
"use strict";
|
||||
/**
|
||||
`RSVP.resolve` returns a promise that will become fulfilled with the passed
|
||||
`value`. `RSVP.resolve` is essentially shorthand for the following:
|
||||
|
||||
```javascript
|
||||
var promise = new RSVP.Promise(function(resolve, reject){
|
||||
resolve(1);
|
||||
});
|
||||
|
||||
promise.then(function(value){
|
||||
// value === 1
|
||||
});
|
||||
```
|
||||
|
||||
Instead of writing the above, your code now simply becomes the following:
|
||||
|
||||
```javascript
|
||||
var promise = RSVP.resolve(1);
|
||||
|
||||
promise.then(function(value){
|
||||
// value === 1
|
||||
});
|
||||
```
|
||||
|
||||
@method resolve
|
||||
@for RSVP
|
||||
@param {Any} value value that the returned promise will be resolved with
|
||||
@param {String} label optional string for identifying the returned promise.
|
||||
Useful for tooling.
|
||||
@return {Promise} a promise that will become fulfilled with the given
|
||||
`value`
|
||||
*/
|
||||
function resolve(value) {
|
||||
/*jshint validthis:true */
|
||||
var Promise = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
resolve(value);
|
||||
});
|
||||
}
|
||||
|
||||
__exports__.resolve = resolve;
|
||||
});
|
||||
define("promise/utils",
|
||||
["exports"],
|
||||
function(__exports__) {
|
||||
"use strict";
|
||||
function objectOrFunction(x) {
|
||||
return isFunction(x) || (typeof x === "object" && x !== null);
|
||||
}
|
||||
|
||||
function isFunction(x) {
|
||||
return typeof x === "function";
|
||||
}
|
||||
|
||||
function isArray(x) {
|
||||
return Object.prototype.toString.call(x) === "[object Array]";
|
||||
}
|
||||
|
||||
// Date.now is not available in browsers < IE9
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now#Compatibility
|
||||
var now = Date.now || function() { return new Date().getTime(); };
|
||||
|
||||
|
||||
__exports__.objectOrFunction = objectOrFunction;
|
||||
__exports__.isFunction = isFunction;
|
||||
__exports__.isArray = isArray;
|
||||
__exports__.now = now;
|
||||
});
|
||||
requireModule('promise/polyfill').polyfill();
|
||||
}());
|
||||
+1
@@ -0,0 +1 @@
|
||||
!function(){var a,b,c,d;!function(){var e={},f={};a=function(a,b,c){e[a]={deps:b,callback:c}},d=c=b=function(a){function c(b){if("."!==b.charAt(0))return b;for(var c=b.split("/"),d=a.split("/").slice(0,-1),e=0,f=c.length;f>e;e++){var g=c[e];if(".."===g)d.pop();else{if("."===g)continue;d.push(g)}}return d.join("/")}if(d._eak_seen=e,f[a])return f[a];if(f[a]={},!e[a])throw new Error("Could not find module "+a);for(var g,h=e[a],i=h.deps,j=h.callback,k=[],l=0,m=i.length;m>l;l++)"exports"===i[l]?k.push(g={}):k.push(b(c(i[l])));var n=j.apply(this,k);return f[a]=g||n}}(),a("promise/all",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to all.");return new b(function(b,c){function d(a){return function(b){f(a,b)}}function f(a,c){h[a]=c,0===--i&&b(h)}var g,h=[],i=a.length;0===i&&b([]);for(var j=0;j<a.length;j++)g=a[j],g&&e(g.then)?g.then(d(j),c):f(j,g)})}var d=a.isArray,e=a.isFunction;b.all=c}),a("promise/asap",["exports"],function(a){"use strict";function b(){return function(){process.nextTick(e)}}function c(){var a=0,b=new i(e),c=document.createTextNode("");return b.observe(c,{characterData:!0}),function(){c.data=a=++a%2}}function d(){return function(){j.setTimeout(e,1)}}function e(){for(var a=0;a<k.length;a++){var b=k[a],c=b[0],d=b[1];c(d)}k=[]}function f(a,b){var c=k.push([a,b]);1===c&&g()}var g,h="undefined"!=typeof window?window:{},i=h.MutationObserver||h.WebKitMutationObserver,j="undefined"!=typeof global?global:void 0===this?window:this,k=[];g="undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?b():i?c():d(),a.asap=f}),a("promise/cast",["exports"],function(a){"use strict";function b(a){if(a&&"object"==typeof a&&a.constructor===this)return a;var b=this;return new b(function(b){b(a)})}a.cast=b}),a("promise/config",["exports"],function(a){"use strict";function b(a,b){return 2!==arguments.length?c[a]:(c[a]=b,void 0)}var c={instrument:!1};a.config=c,a.configure=b}),a("promise/polyfill",["./promise","./utils","exports"],function(a,b,c){"use strict";function d(){var a;a="undefined"!=typeof global?global:"undefined"!=typeof window&&window.document?window:self;var b="Promise"in a&&"cast"in a.Promise&&"resolve"in a.Promise&&"reject"in a.Promise&&"all"in a.Promise&&"race"in a.Promise&&function(){var b;return new a.Promise(function(a){b=a}),f(b)}();b||(a.Promise=e)}var e=a.Promise,f=b.isFunction;c.polyfill=d}),a("promise/promise",["./config","./utils","./cast","./all","./race","./resolve","./reject","./asap","exports"],function(a,b,c,d,e,f,g,h,i){"use strict";function j(a){if(!w(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof j))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");this._subscribers=[],k(a,this)}function k(a,b){function c(a){p(b,a)}function d(a){r(b,a)}try{a(c,d)}catch(e){d(e)}}function l(a,b,c,d){var e,f,g,h,i=w(c);if(i)try{e=c(d),g=!0}catch(j){h=!0,f=j}else e=d,g=!0;o(b,e)||(i&&g?p(b,e):h?r(b,f):a===F?p(b,e):a===G&&r(b,e))}function m(a,b,c,d){var e=a._subscribers,f=e.length;e[f]=b,e[f+F]=c,e[f+G]=d}function n(a,b){for(var c,d,e=a._subscribers,f=a._detail,g=0;g<e.length;g+=3)c=e[g],d=e[g+b],l(b,c,d,f);a._subscribers=null}function o(a,b){var c,d=null;try{if(a===b)throw new TypeError("A promises callback cannot return that same promise.");if(v(b)&&(d=b.then,w(d)))return d.call(b,function(d){return c?!0:(c=!0,b!==d?p(a,d):q(a,d),void 0)},function(b){return c?!0:(c=!0,r(a,b),void 0)}),!0}catch(e){return c?!0:(r(a,e),!0)}return!1}function p(a,b){a===b?q(a,b):o(a,b)||q(a,b)}function q(a,b){a._state===D&&(a._state=E,a._detail=b,u.async(s,a))}function r(a,b){a._state===D&&(a._state=E,a._detail=b,u.async(t,a))}function s(a){n(a,a._state=F)}function t(a){n(a,a._state=G)}var u=a.config,v=(a.configure,b.objectOrFunction),w=b.isFunction,x=(b.now,c.cast),y=d.all,z=e.race,A=f.resolve,B=g.reject,C=h.asap;u.async=C;var D=void 0,E=0,F=1,G=2;j.prototype={constructor:j,_state:void 0,_detail:void 0,_subscribers:void 0,then:function(a,b){var c=this,d=new this.constructor(function(){});if(this._state){var e=arguments;u.async(function(){l(c._state,d,e[c._state-1],c._detail)})}else m(this,d,a,b);return d},"catch":function(a){return this.then(null,a)}},j.all=y,j.cast=x,j.race=z,j.resolve=A,j.reject=B,i.Promise=j}),a("promise/race",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to race.");return new b(function(b,c){for(var d,e=0;e<a.length;e++)d=a[e],d&&"function"==typeof d.then?d.then(b,c):b(d)})}var d=a.isArray;b.race=c}),a("promise/reject",["exports"],function(a){"use strict";function b(a){var b=this;return new b(function(b,c){c(a)})}a.reject=b}),a("promise/resolve",["exports"],function(a){"use strict";function b(a){var b=this;return new b(function(b){b(a)})}a.resolve=b}),a("promiseLine truncated
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"_from": "es6-promise@~0.1.1",
|
||||
"_id": "es6-promise@0.1.2",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-8RLCn+paCZhTn8tqL9IUQ9KPBfc=",
|
||||
"_location": "/es6-promise",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "es6-promise@~0.1.1",
|
||||
"name": "es6-promise",
|
||||
"escapedName": "es6-promise",
|
||||
"rawSpec": "~0.1.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "~0.1.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/octokit"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-0.1.2.tgz",
|
||||
"_shasum": "f112c29fea5a0998539fcb6a2fd21443d28f05f7",
|
||||
"_spec": "es6-promise@~0.1.1",
|
||||
"_where": "C:\\Users\\Luis\\source\\repos\\AAWebPlatform\\node_modules\\octokit",
|
||||
"author": {
|
||||
"name": "Tilde, Inc.",
|
||||
"url": "Conversion to ES6 API by Jake Archibald"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jakearchibald/ES6-Promises/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"deprecated": false,
|
||||
"description": "A polyfill for ES6-style Promises, tracking rsvp",
|
||||
"devDependencies": {
|
||||
"brfs": "0.0.8",
|
||||
"connect-redirection": "0.0.1",
|
||||
"grunt": "~0.4.2",
|
||||
"grunt-browserify": "~1.2.11",
|
||||
"grunt-cli": "~0.1.11",
|
||||
"grunt-contrib-clean": "~0.5.0",
|
||||
"grunt-contrib-concat": "~0.3.0",
|
||||
"grunt-contrib-connect": "~0.5.0",
|
||||
"grunt-contrib-jshint": "~0.7.0",
|
||||
"grunt-contrib-uglify": "~0.2.4",
|
||||
"grunt-contrib-watch": "~0.5.3",
|
||||
"grunt-contrib-yuidoc": "~0.5.0",
|
||||
"grunt-es6-module-transpiler": "~0.6.0",
|
||||
"grunt-mocha-phantomjs": "~0.3.1",
|
||||
"grunt-mocha-test": "~0.5.0",
|
||||
"grunt-s3": "~0.2.0-alpha.2",
|
||||
"jshint": "~0.9",
|
||||
"load-grunt-config": "~0.5.0",
|
||||
"load-grunt-tasks": "~0.2.0",
|
||||
"mocha-phantomjs": "~3.1.6",
|
||||
"promises-aplus-tests": "git://github.com/stefanpenner/promises-tests.git"
|
||||
},
|
||||
"directories": {
|
||||
"lib": "lib"
|
||||
},
|
||||
"homepage": "https://github.com/jakearchibald/ES6-Promises#readme",
|
||||
"keywords": [
|
||||
"promises",
|
||||
"futures",
|
||||
"events"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "dist/commonjs/main.js",
|
||||
"name": "es6-promise",
|
||||
"namespace": "Promise",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/jakearchibald/ES6-Promises.git"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "jshint lib",
|
||||
"prepublish": "grunt build",
|
||||
"test": "grunt test"
|
||||
},
|
||||
"version": "0.1.2"
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
bower_components
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
# Drop multiple versions because there were interleavings on Travis
|
||||
# - "0.8"
|
||||
|
||||
before_script:
|
||||
- npm install -g grunt-cli
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
module.exports = (grunt) ->
|
||||
|
||||
fs = require('fs')
|
||||
pkg = require('./package.json')
|
||||
|
||||
# Project configuration.
|
||||
grunt.initConfig
|
||||
pkg: pkg
|
||||
|
||||
# Lint
|
||||
# ----
|
||||
|
||||
# CoffeeLint
|
||||
coffeelint:
|
||||
options:
|
||||
arrow_spacing:
|
||||
level: 'error'
|
||||
line_endings:
|
||||
level: 'error'
|
||||
value: 'unix'
|
||||
max_line_length:
|
||||
level: 'error'
|
||||
value: 150
|
||||
no_unnecessary_fat_arrows:
|
||||
level: "ignore"
|
||||
|
||||
source: ['octokit.coffee']
|
||||
grunt: 'Gruntfile.coffee'
|
||||
|
||||
|
||||
# Dist
|
||||
# ----
|
||||
|
||||
|
||||
# Clean
|
||||
clean:
|
||||
files:
|
||||
src: [
|
||||
'octokit.js'
|
||||
'octokit.js.map'
|
||||
]
|
||||
filter: 'isFile'
|
||||
|
||||
|
||||
# Compile CoffeeScript to JavaScript
|
||||
coffee:
|
||||
compile:
|
||||
options:
|
||||
sourceMap: false # true
|
||||
files:
|
||||
'octokit.js': ['octokit.coffee']
|
||||
|
||||
# Release a new version and push upstream
|
||||
bump:
|
||||
options:
|
||||
commit: true
|
||||
push: true
|
||||
pushTo: ''
|
||||
commitFiles: ['package.json', 'component.json', 'bower.json', 'octokit.js']
|
||||
# Files to bump the version number of
|
||||
files: ['package.json', 'bower.json', 'component.json']
|
||||
|
||||
mochaTest:
|
||||
test:
|
||||
options:
|
||||
reporter: 'spec'
|
||||
require: 'coffee-script'
|
||||
src: ['test/**/node*.coffee']
|
||||
|
||||
# Used for coveralls.io code coverage
|
||||
mochacov:
|
||||
options:
|
||||
coverage: true # use blanket
|
||||
reporter: 'spec'
|
||||
require: ['coffee-script']
|
||||
compilers: ['coffee:coffee-script']
|
||||
all: ['test/**/node*.coffee']
|
||||
|
||||
# Code coverage in PhantomJS requires commenting out the following in
|
||||
# node_modules/mocha/mocha.js:
|
||||
# - `self.suiteURL(suite)`
|
||||
# - `self.testURL(test)`
|
||||
blanket_mocha:
|
||||
all: [ 'test/index.html' ]
|
||||
options:
|
||||
threshold: 54
|
||||
log: true
|
||||
reporter: 'Dot'
|
||||
|
||||
watch:
|
||||
files: 'octokit.coffee'
|
||||
tasks: ['default']
|
||||
|
||||
|
||||
# Dependencies
|
||||
# ============
|
||||
for name of pkg.dependencies when name.substring(0, 6) is 'grunt-'
|
||||
grunt.loadNpmTasks(name)
|
||||
for name of pkg.devDependencies when name.substring(0, 6) is 'grunt-'
|
||||
if grunt.file.exists("./node_modules/#{name}")
|
||||
grunt.loadNpmTasks(name)
|
||||
|
||||
# Tasks
|
||||
# =====
|
||||
|
||||
# Travis CI
|
||||
# -----
|
||||
grunt.registerTask 'test', [
|
||||
'coffeelint'
|
||||
'clean'
|
||||
'coffee'
|
||||
'mochaTest'
|
||||
#'blanket_mocha' NOTE: Uncomment once the `suiteURL` problem noted above is fixed
|
||||
]
|
||||
|
||||
# Dist
|
||||
# -----
|
||||
grunt.registerTask 'release', [
|
||||
'clean'
|
||||
'coffeelint'
|
||||
'coffee'
|
||||
# 'mochaTest'
|
||||
#'blanket_mocha'
|
||||
'bump'
|
||||
]
|
||||
|
||||
grunt.registerTask 'release-minor', [
|
||||
'clean'
|
||||
'coffeelint'
|
||||
'coffee'
|
||||
'mochaTest'
|
||||
#'blanket_mocha'
|
||||
'bump:minor'
|
||||
]
|
||||
|
||||
# Default
|
||||
# -----
|
||||
grunt.registerTask 'default', [
|
||||
'coffeelint'
|
||||
'clean'
|
||||
'coffee'
|
||||
]
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
Copyright (c) 2012 Michael Aufreiter, Development Seed
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
- Neither the name "Development Seed" nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+565
@@ -0,0 +1,565 @@
|
||||
# octokit.js [](https://travis-ci.org/philschatz/octokit.js)
|
||||
|
||||
octokit.js provides a minimal higher-level wrapper around git's [plumbing commands](http://git-scm.com/book/en/Git-Internals-Plumbing-and-Porcelain),
|
||||
exposing an API for manipulating GitHub repositories, users, groups, and gists.
|
||||
It is being developed in the context of [github-bookeditor](https://github.com/oerpub/github-bookeditor), an EPUB3 editor for GitHub.
|
||||
|
||||
This package can also be used in `nodejs` or as an AMD module in the browser.
|
||||
|
||||
## Key Features
|
||||
|
||||
- Works in `nodejs`, an AMD module in the browser, and as a [bower](https://github.com/bower/bower) library
|
||||
- Simple `read` and `write` methods for text _and_ binary files
|
||||
- Creating gists, Pull Requests, forks, and new Repositories
|
||||
- `ETag` Caching
|
||||
- Promises instead of callbacks (for better error-handling and progress updating)
|
||||
- Progress Notifications for multistep operations
|
||||
- Starring and Following repositories, users, and organizations
|
||||
- Editing Team and Organization Membership
|
||||
- User/Org/Repo events and notifications
|
||||
- Listeners for rate limit changes
|
||||
- Public Keys
|
||||
- Hooks (commit, comment, etc)
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
All asynchronous methods return a [Common-JS Promise](http://wiki.commonjs.org/wiki/Promises/A).
|
||||
|
||||
### In a browser without requirejs
|
||||
|
||||
Create an Octokit instance.
|
||||
|
||||
```js
|
||||
var gh = new Octokit({
|
||||
username: "USER_NAME",
|
||||
password: "PASSWORD"
|
||||
});
|
||||
```
|
||||
|
||||
Or if you prefer OAuth, it looks like this:
|
||||
|
||||
```js
|
||||
var gh = new Octokit({
|
||||
token: "OAUTH_TOKEN"
|
||||
});
|
||||
```
|
||||
|
||||
### In a browser using requirejs
|
||||
|
||||
```js
|
||||
define(['octokit'], function(Octokit) {
|
||||
var gh = new Octokit({
|
||||
username: "YOU_USER",
|
||||
password: "YOUR_PASSWORD"
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### In NodeJS
|
||||
|
||||
Install instructions:
|
||||
|
||||
npm install octokit --save
|
||||
|
||||
```js
|
||||
var Octokit = require('octokit');
|
||||
var gh = Octokit.new({
|
||||
username: "YOU_USER",
|
||||
password: "YOUR_PASSWORD"
|
||||
});
|
||||
```
|
||||
|
||||
### Using Generators in NodeJS 0.11 (or EcmaScript 6 browsers)
|
||||
|
||||
This requires NodeJS 0.11 with the `--harmony-generators` flag:
|
||||
|
||||
```js
|
||||
var co = require('co');
|
||||
var Octokit = require('octokit');
|
||||
var gh = Octokit.new();
|
||||
|
||||
var fn = function *() {
|
||||
var zen = yield gh.getZen();
|
||||
var info = yield gh.getRepo('philschatz', 'octokit.js').getInfo();
|
||||
|
||||
console.log(zen);
|
||||
console.log(info);
|
||||
};
|
||||
|
||||
co(fn)();
|
||||
```
|
||||
|
||||
### Using bower
|
||||
|
||||
This file can be included using the bower package manager:
|
||||
|
||||
bower install octokit --save
|
||||
|
||||
## Development
|
||||
|
||||
Mocha tests are run on NodeJS by running `npm test`. Mocha tests in the browser and code coverage are run by going to [./test/index.html](http://philschatz.github.io/octokit.js/test).
|
||||
|
||||
|
||||
## Repository API
|
||||
|
||||
|
||||
```js
|
||||
var repo = gh.getRepo(username, reponame);
|
||||
```
|
||||
|
||||
Show repository information
|
||||
|
||||
```js
|
||||
repo.getInfo()
|
||||
.then(function(repo) {})
|
||||
```
|
||||
|
||||
List all branches in a Repository
|
||||
|
||||
```js
|
||||
repo.getBranches()
|
||||
.then(function(branches) {});
|
||||
```
|
||||
|
||||
Fork a repository
|
||||
|
||||
```js
|
||||
repo.fork()
|
||||
.then(function() {});
|
||||
```
|
||||
|
||||
Create a Pull Request
|
||||
|
||||
```js
|
||||
repo.createPullRequest()
|
||||
.then(function() {});
|
||||
```
|
||||
|
||||
Get recent commits to the repository
|
||||
|
||||
```js
|
||||
var options = {};
|
||||
repo.getCommits(options)
|
||||
.then(function(commits) {});
|
||||
```
|
||||
|
||||
List Repository events
|
||||
|
||||
```js
|
||||
repo.getEvents()
|
||||
.then(function(events) {});
|
||||
```
|
||||
|
||||
List Issue events for the repository
|
||||
|
||||
```js
|
||||
repo.getIssueEvents()
|
||||
.then(function(events) {});
|
||||
```
|
||||
|
||||
List events for a network of Repositories
|
||||
|
||||
```js
|
||||
repo.getNetworkEvents()
|
||||
.then(function(events) {});
|
||||
```
|
||||
|
||||
List unread notifications for authenticated user pertaining to this repository
|
||||
|
||||
```js
|
||||
var options = {};
|
||||
repo.getNotifications(options)
|
||||
.then(function(events) {});
|
||||
```
|
||||
|
||||
Get programming language counts (CoffeeScript, Ruby, Shell)
|
||||
|
||||
```js
|
||||
repo.getLanguages()
|
||||
.then(function(events) {});
|
||||
```
|
||||
|
||||
Get releases
|
||||
```js
|
||||
repo.getReleases()
|
||||
.then(function(releases) {});
|
||||
```
|
||||
|
||||
### Branch API
|
||||
|
||||
Additional methods are available for a specific branch in a repository
|
||||
|
||||
Get the Default branch of a repository
|
||||
|
||||
```js
|
||||
var branch = repo.getBranch();
|
||||
```
|
||||
|
||||
Get a specific branch of a repository
|
||||
|
||||
```js
|
||||
var branch = repo.getBranch("BRANCH_NAME");
|
||||
```
|
||||
|
||||
Read a file from the branch
|
||||
|
||||
```js
|
||||
var isBinary = false;
|
||||
branch.read('PATH/TO/FILE.txt', isBinary)
|
||||
.then(function(contents) {})
|
||||
```
|
||||
|
||||
Remove a file from the branch
|
||||
|
||||
```js
|
||||
var message = "OPTIONAL COMMIT MESSAGE";
|
||||
branch.remove('PATH/TO/FILE.txt', message)
|
||||
.then(function() {});
|
||||
```
|
||||
|
||||
Read the contents (raw) of a file or directory
|
||||
|
||||
```js
|
||||
branch.contents('DIRECTORY/PATH')
|
||||
.then(function(contents) {});
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```js
|
||||
branch.contents('DIRECTORY/PATH/FILE.txt')
|
||||
.then(function(contents) {});
|
||||
```
|
||||
|
||||
Move a file
|
||||
|
||||
```js
|
||||
var message = "OPTIONAL COMMIT MESSAGE";
|
||||
branch.move('PATH/TO/FILE.txt', 'NEW/PATH/TO/FILE.txt', message)
|
||||
.then(function() {});
|
||||
```
|
||||
|
||||
Write a file (update or add)
|
||||
|
||||
```js
|
||||
var content = "Contents of the file";
|
||||
var message = "OPTIONAL COMMIT MESSAGE";
|
||||
var isBinary = false;
|
||||
branch.write('PATH/TO/FILE.txt', content, message, isBinary)
|
||||
.then(function() {});
|
||||
```
|
||||
|
||||
Write multiple files (update or add) in one commit
|
||||
|
||||
```js
|
||||
var contents = {
|
||||
"FILE1.txt": "Contents of the file",
|
||||
"FILE2.txt": {isBase64: true, content: "BASE_64_ENCODED_STRING"}
|
||||
}
|
||||
branch.writeMany(contents, message)
|
||||
.then(function() {});
|
||||
```
|
||||
|
||||
Get recent commits to a branch
|
||||
|
||||
```js
|
||||
var options = {};
|
||||
branch.getCommits(options)
|
||||
.then(function(commits) {});
|
||||
```
|
||||
|
||||
Create a new branch
|
||||
|
||||
```js
|
||||
branch.createBranch("new-branch-name")
|
||||
.then(function() {});
|
||||
```
|
||||
|
||||
|
||||
### Low-level Repo API
|
||||
|
||||
The methods on a branch or repo use the following low-level methods.
|
||||
|
||||
```js
|
||||
repo.git.getRef(...) .then(function(result) {});
|
||||
repo.git.createRef(...) .then(function(result) {});
|
||||
repo.git.deleteRef(...) .then(function(result) {});
|
||||
repo.git.getBranches() .then(function(result) {});
|
||||
repo.git.getBlob(...) .then(function(result) {});
|
||||
repo.git.getSha(...) .then(function(result) {});
|
||||
repo.git.getTree(...) .then(function(result) {});
|
||||
repo.git.postBlob(...) .then(function(result) {});
|
||||
repo.git.updateTree(...) .then(function(result) {});
|
||||
repo.git.postTree(...) .then(function(result) {});
|
||||
repo.git.commit(...) .then(function(result) {});
|
||||
repo.git.updateHead(...) .then(function(result) {});
|
||||
repo.git.getCommits(...) .then(function(result) {});
|
||||
```
|
||||
|
||||
|
||||
## User API
|
||||
|
||||
|
||||
```js
|
||||
var user = gh.getUser(GITHUB_USERNAME);
|
||||
```
|
||||
|
||||
Show user information for a particular user. Also works for organizations.
|
||||
|
||||
```js
|
||||
user.getInfo()
|
||||
.then(function(user) {})
|
||||
```
|
||||
|
||||
List public repositories for a particular user.
|
||||
_options described [here](http://developer.github.com/v3/repos/#list-user-repositories)_
|
||||
|
||||
```js
|
||||
user.getRepos(type='all', sort='pushed', direction='desc')
|
||||
.then(function(repos) {});
|
||||
```
|
||||
|
||||
List organizations the user is in.
|
||||
|
||||
```js
|
||||
user.getOrgs()
|
||||
.then(function(orgs) {});
|
||||
```
|
||||
|
||||
List all gists of a particular user.
|
||||
|
||||
```js
|
||||
user.getGists()
|
||||
.then(function(gists) {});
|
||||
```
|
||||
|
||||
List users following this user.
|
||||
|
||||
```js
|
||||
user.getFollowers()
|
||||
.then(function(users) {});
|
||||
```
|
||||
|
||||
List users this user is following.
|
||||
|
||||
```js
|
||||
user.getFollowing()
|
||||
.then(function(users) {});
|
||||
```
|
||||
|
||||
Get Received events for this user.
|
||||
|
||||
```js
|
||||
user.getReceivedEvents()
|
||||
.then(function(events) {});
|
||||
```
|
||||
|
||||
Get all events for this user.
|
||||
|
||||
```js
|
||||
user.getEvents()
|
||||
.then(function(events) {});
|
||||
```
|
||||
|
||||
|
||||
## Authenticated User API
|
||||
|
||||
The Authenticated User contains the following methods in addition to all the methods in the **User API**.
|
||||
|
||||
Get the authenticated user.
|
||||
|
||||
```js
|
||||
var user = gh.getUser();
|
||||
```
|
||||
|
||||
List unread notifications for the user.
|
||||
|
||||
```js
|
||||
gh.getNotifications()
|
||||
.then(function(notifications) {})
|
||||
```
|
||||
|
||||
List private and public repositories of the current authenticated user.
|
||||
|
||||
```js
|
||||
user.getRepos()
|
||||
.then(function(repos) {});
|
||||
```
|
||||
|
||||
Follow another user.
|
||||
|
||||
```js
|
||||
user.follow("OTHER_USERNAME")
|
||||
.then(function(orgs) {});
|
||||
```
|
||||
|
||||
Stop following another user.
|
||||
|
||||
```js
|
||||
user.unfollow("OTHER_USERNAME")
|
||||
.then(function(orgs) {});
|
||||
```
|
||||
|
||||
|
||||
## Gist API
|
||||
|
||||
```js
|
||||
var gist = gh.getGist(3165654);
|
||||
```
|
||||
|
||||
Read the contents of a Gist.
|
||||
|
||||
```js
|
||||
gist.read()
|
||||
.then(function(gist) {});
|
||||
```
|
||||
|
||||
Update the contents of a Gist. Please consult the documentation on [GitHub](http://developer.github.com/v3/gists/).
|
||||
|
||||
```js
|
||||
var delta = {
|
||||
"description": "the description for this gist",
|
||||
"files": {
|
||||
"file1.txt": {
|
||||
"content": "updated file contents"
|
||||
},
|
||||
"old_name.txt": {
|
||||
"filename": "new_name.txt",
|
||||
"content": "modified contents"
|
||||
},
|
||||
"new_file.txt": {
|
||||
"content": "a new file"
|
||||
},
|
||||
"delete_this_file.txt": null
|
||||
}
|
||||
};
|
||||
|
||||
gist.update(delta)
|
||||
.then(function(gist) {});
|
||||
```
|
||||
|
||||
Create a Gist
|
||||
|
||||
```js
|
||||
var files = {
|
||||
'file1.txt': {content: 'String file contents'}
|
||||
};
|
||||
|
||||
gh.getGist().create(files)
|
||||
.then(function(gist) {});
|
||||
```
|
||||
|
||||
Delete the Gist
|
||||
|
||||
```js
|
||||
gist.delete()
|
||||
.then(function(gist) {});
|
||||
```
|
||||
|
||||
Fork the Gist
|
||||
|
||||
```js
|
||||
gist.fork()
|
||||
.then(function(gist) {});
|
||||
```
|
||||
|
||||
Star the Gist
|
||||
|
||||
```js
|
||||
gist.star()
|
||||
.then(function() {});
|
||||
```
|
||||
|
||||
Unstar the Gist
|
||||
|
||||
```js
|
||||
gist.unstar()
|
||||
.then(function() {});
|
||||
```
|
||||
|
||||
Check if the Gist is starred
|
||||
|
||||
```js
|
||||
gist.isStarred()
|
||||
.then(function() {});
|
||||
```
|
||||
|
||||
|
||||
## Miscellaneous methods
|
||||
|
||||
Retreive a zen message (to test the API works).
|
||||
|
||||
```js
|
||||
gh.getZen()
|
||||
.then(function(msg) {});
|
||||
```
|
||||
|
||||
Add a listener for `rateLimit` changes
|
||||
|
||||
```js
|
||||
function listener(rateLimitRemaining, rateLimit, method, path, data, raw, isBase64) {
|
||||
// ...
|
||||
};
|
||||
gh.onRateLimitChanged(listener);
|
||||
```
|
||||
|
||||
List repositories for a particular organization. Includes private repositories if you are authorized.
|
||||
|
||||
```js
|
||||
gh.getOrgRepos(orgname)
|
||||
.then(function(repos) {});
|
||||
```
|
||||
|
||||
## Progress Notifications
|
||||
|
||||
For multistep operations users can listen to updates by registering a listener at `promise.progress(function(obj) {})`.
|
||||
|
||||
|
||||
|
||||
## Setup
|
||||
|
||||
`octokit.js` has the following dependencies when used in a browser:
|
||||
|
||||
- A Promise API (supports jQuery, AngularJS, or a Promise Polyfill)
|
||||
|
||||
If you are already using [jQuery](https://api.jquery.com/jQuery.Deferred/) or [AngularJS](https://docs.angularjs.org/api/ng/service/$q) in your project just be sure to include them before octokit and it will
|
||||
use their Promise API.
|
||||
|
||||
Otherwise, you can include a Promise polyfill like [jakearchibald/es6-promise](https://github.com/jakearchibald/es6-promise):
|
||||
|
||||
```
|
||||
<script src="./node_modules/es6-promise/dist/promise-0.1.1.js"></script>
|
||||
<script src="./octokit.js">
|
||||
```
|
||||
|
||||
## Change Log
|
||||
|
||||
|
||||
### 0.7.X
|
||||
|
||||
Switched to a native `request` implementation (thanks @mattpass). Adds support for GitHub gists, forks and pull requests.
|
||||
|
||||
### 0.6.X
|
||||
|
||||
Adds support for organizations and fixes an encoding issue.
|
||||
|
||||
### 0.5.X
|
||||
|
||||
Smart caching of latest commit sha.
|
||||
|
||||
### 0.4.X
|
||||
|
||||
Added support for [OAuth](http://developer.github.com/v3/oauth/).
|
||||
|
||||
### 0.3.X
|
||||
|
||||
Support for Moving and removing files.
|
||||
|
||||
### 0.2.X
|
||||
|
||||
Consider commit messages.
|
||||
|
||||
### 0.1.X
|
||||
|
||||
Initial version.
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "octokit",
|
||||
"version": "0.10.4",
|
||||
"description": "Javascript github client for nodejs or a web browser using promises",
|
||||
"main": "octokit.js",
|
||||
"dependencies": {
|
||||
"blanket": "#development",
|
||||
"mocha": "~1.16.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"coffee-script": ">=1.3"
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "octokit",
|
||||
"version": "0.10.4",
|
||||
"description": "Javascript github client for nodejs or a web browser using promises",
|
||||
"main": "octokit.js",
|
||||
"scripts": [
|
||||
"octokit.js"
|
||||
],
|
||||
"repository": "philschatz/octokit"
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
module.exports = require('./octokit');
|
||||
+1545
File diff suppressed because it is too large.
Load diff
+1476
File diff suppressed because it is too large.
Load diff
+84
@@ -0,0 +1,84 @@
|
||||
{
|
||||
"_from": "octokit",
|
||||
"_id": "octokit@0.10.4",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-vthU2JxGEGKtXFbL4YZ4Tu61pOs=",
|
||||
"_location": "/octokit",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "tag",
|
||||
"registry": true,
|
||||
"raw": "octokit",
|
||||
"name": "octokit",
|
||||
"escapedName": "octokit",
|
||||
"rawSpec": "",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "latest"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/octokit/-/octokit-0.10.4.tgz",
|
||||
"_shasum": "bed854d89c461062ad5c56cbe186784eeeb5a4eb",
|
||||
"_spec": "octokit",
|
||||
"_where": "C:\\Users\\Luis\\source\\repos\\AAWebPlatform",
|
||||
"author": {
|
||||
"name": "Philip Schatz"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/philschatz/octokit.js/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"es6-promise": "~0.1.1",
|
||||
"xmlhttprequest": "~1.6.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Javascript github client for nodejs or a web browser using promises",
|
||||
"devDependencies": {
|
||||
"blanket": "~1.1.5",
|
||||
"bower": "~1.0",
|
||||
"chai": "~1.8.1",
|
||||
"coffee-script": "~1.6.3",
|
||||
"docco": "~0.4.0",
|
||||
"grunt": "~0.4.2",
|
||||
"grunt-blanket-mocha": "git://github.com/philschatz/grunt-blanket-mocha.git#fixes-for-octokit.js",
|
||||
"grunt-bump": "~0.0.10",
|
||||
"grunt-coffeelint": "~0.0.7",
|
||||
"grunt-contrib-clean": "~0.5",
|
||||
"grunt-contrib-coffee": "~0.7",
|
||||
"grunt-contrib-watch": "~0.6.1",
|
||||
"grunt-mocha-cov": "0.0.7",
|
||||
"grunt-mocha-test": "~0.8.0",
|
||||
"jamjs": "~0.2.17",
|
||||
"mocha": "~1.14.0"
|
||||
},
|
||||
"homepage": "https://github.com/philschatz/octokit.js#readme",
|
||||
"jam": {
|
||||
"dependencies": {
|
||||
"jquery": ">=1.8",
|
||||
"lodash": ">=1.0"
|
||||
}
|
||||
},
|
||||
"keywords": [
|
||||
"javascript",
|
||||
"github",
|
||||
"client",
|
||||
"promise",
|
||||
"ender"
|
||||
],
|
||||
"main": "octokit.js",
|
||||
"name": "octokit",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/philschatz/octokit.js.git"
|
||||
},
|
||||
"scripts": {
|
||||
"dist": "grunt dist --verbose",
|
||||
"prepublish": "bower install",
|
||||
"test": "grunt test --verbose",
|
||||
"update": "bower update"
|
||||
},
|
||||
"version": "0.10.4"
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<link rel="stylesheet" href="../bower_components/mocha/mocha.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>This is a test page. Mocha tests should run below.</p>
|
||||
|
||||
<div id="mocha"></div>
|
||||
|
||||
<script src="../node_modules/es6-promise/dist/promise-0.1.1.js"></script>
|
||||
<script src="../bower_components/jquery/dist/jquery.js"></script>
|
||||
<script src="../bower_components/coffee-script/extras/coffee-script.js"></script>
|
||||
|
||||
<script data-cover src="../octokit.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
# TODO: Use requirejs and require('chai')
|
||||
assert = @chai.assert
|
||||
expect = @chai.expect
|
||||
|
||||
@makeTests(assert, expect, btoa, @Octokit)
|
||||
|
||||
|
||||
# from http://www.geekdave.com/2013/08/02/automated-code-coverage-enforcement-for-mocha-using-grunt-and-blanket/
|
||||
if @PHANTOMJS
|
||||
@blanket.options('reporter', '../node_modules/grunt-blanket-mocha/support/grunt-reporter.js')
|
||||
|
||||
mocha.checkLeaks()
|
||||
mocha.globals(['jQuery'])
|
||||
|
||||
|
||||
# Needs to run once this file is loaded
|
||||
mocha.run()
|
||||
+325
@@ -0,0 +1,325 @@
|
||||
makeTests = (assert, expect, btoa, Octokit) ->
|
||||
|
||||
USERNAME = 'octokit-test'
|
||||
TOKEN = 'dca7f85a5911df8e9b7aeb4c5be8f5f50806ac49'
|
||||
|
||||
ORG_NAME = 'octokit-test-org'
|
||||
|
||||
REPO_USER = USERNAME
|
||||
REPO_NAME = 'octokit-test-repo' # Cannot use '.' because najax does not like it
|
||||
|
||||
REPO_HOMEPAGE = 'https:/github.com/philschatz/octokit.js'
|
||||
OTHER_HOMEPAGE = 'http://example.com'
|
||||
|
||||
OTHER_USERNAME = 'octokit-test2'
|
||||
|
||||
DEFAULT_BRANCH = 'master'
|
||||
|
||||
LONG_TIMEOUT = 10 * 1000 # 10 seconds
|
||||
SHORT_TIMEOUT = 5 * 1000 # 5 seconds
|
||||
|
||||
|
||||
IS_NODE = !! module?
|
||||
|
||||
some = (arr, fn) ->
|
||||
for entry in arr
|
||||
do (entry) ->
|
||||
if fn(entry) == true
|
||||
return true
|
||||
return false
|
||||
|
||||
trapFail = (promise) ->
|
||||
onError = (err) ->
|
||||
console.error(JSON.stringify(err))
|
||||
assert.catch(err)
|
||||
# Depending on the Promise implementation the fail method could be:
|
||||
# - `.catch` (native Promise)
|
||||
# - `.fail` (jQuery or angularjs)
|
||||
promise.catch?(onError) or promise.fail(onError)
|
||||
return promise
|
||||
|
||||
helper1 = (done, promise, func) ->
|
||||
return trapFail(promise)
|
||||
.then(func)
|
||||
.then () -> done()
|
||||
|
||||
helper2 = (promise, func) ->
|
||||
return trapFail(promise)
|
||||
.then(func)
|
||||
|
||||
arrayContainsKey = (arr, key, value) ->
|
||||
some arr, (entry) ->
|
||||
return entry[key] == value
|
||||
|
||||
describe 'Octokit', () ->
|
||||
@timeout(LONG_TIMEOUT)
|
||||
|
||||
GH = 'GH'
|
||||
REPO = 'REPO'
|
||||
USER = 'USER'
|
||||
BRANCH = 'BRANCH'
|
||||
ANOTHER_USER = 'ANOTHER_USER'
|
||||
|
||||
STATE = {}
|
||||
|
||||
itIsOk = (obj, funcName) ->
|
||||
it "##{funcName}()", (done) ->
|
||||
helper1 done, STATE[obj][funcName](), (val) ->
|
||||
expect(val).to.be.ok
|
||||
|
||||
before () ->
|
||||
options =
|
||||
token: TOKEN
|
||||
# PhantomJS does not support the `PATCH` verb yet.
|
||||
# See https://github.com/ariya/phantomjs/issues/11384 for updates
|
||||
usePostInsteadOfPatch:true
|
||||
|
||||
options.useETags = false if IS_NODE
|
||||
|
||||
STATE[GH] = new Octokit(options)
|
||||
STATE[USER] = STATE[GH].getUser()
|
||||
|
||||
itIsOk(GH, 'getZen')
|
||||
itIsOk(GH, 'getAllUsers')
|
||||
#(GH, 'getOrgRepos(orgName, type='all')')
|
||||
itIsOk(GH, 'getPublicGists')
|
||||
itIsOk(GH, 'getPublicEvents')
|
||||
#(GH, 'onRateLimitChanged(listener)')
|
||||
|
||||
describe 'Repo:', () ->
|
||||
@timeout(LONG_TIMEOUT)
|
||||
PREV_SHA = null
|
||||
|
||||
before (done) ->
|
||||
STATE[REPO] = STATE[GH].getRepo(REPO_USER, REPO_NAME)
|
||||
STATE[BRANCH] = STATE[REPO].getDefaultBranch()
|
||||
createRepo = () ->
|
||||
console.log('BEFORE: Creating test repo')
|
||||
options =
|
||||
description: 'Test Repository for https:/github.com/philschatz/octokit.js'
|
||||
homepage: REPO_HOMEPAGE
|
||||
# private: false
|
||||
# has_issues: false
|
||||
# has_wiki: false
|
||||
# has_downloads: false
|
||||
auto_init: true # Make an initial `master` branch and commit
|
||||
|
||||
trapFail(STATE[USER].createRepo(REPO_NAME, options))
|
||||
.then () ->
|
||||
console.log('BEFORE: Done Creating test repo')
|
||||
setTimeout(done, SHORT_TIMEOUT)
|
||||
|
||||
resetRepoToFirstCommit = (repoInfo) ->
|
||||
findLastCommits = (commits, options) ->
|
||||
console.log('BEFORE: Found commits')
|
||||
if options?.next
|
||||
trapFail(options.next())
|
||||
.then(findLastCommits)
|
||||
else
|
||||
console.log('BEFORE: Finding master branch')
|
||||
initialCommit = commits[commits.length-1]
|
||||
sha = initialCommit.sha
|
||||
|
||||
masterBranch = repoInfo.default_branch
|
||||
console.log('BEFORE: Found master branch')
|
||||
console.log("BEFORE: Updating #{masterBranch} to #{sha}")
|
||||
trapFail(STATE[REPO].git.updateHead(masterBranch, sha, true)) # true == force
|
||||
.then () =>
|
||||
console.log('BEFORE: Updated HEAD')
|
||||
done()
|
||||
|
||||
console.log('BEFORE: Resetting test repo name and homepage')
|
||||
trapFail(STATE[REPO].updateInfo({name: REPO_NAME, homepage: REPO_HOMEPAGE}))
|
||||
.then () ->
|
||||
console.log('BEFORE: Getting recent commits')
|
||||
trapFail(STATE[REPO].getCommits())
|
||||
.then(findLastCommits)
|
||||
|
||||
# Make sure the repo is empty by deleting it and creating a new one
|
||||
console.log('BEFORE: Checking if repo exists')
|
||||
promise = STATE[REPO].getInfo()
|
||||
.then (val) ->
|
||||
# STATE[REPO].git.deleteRepo()
|
||||
# .catch(() -> resetRepoToFirstCommit)
|
||||
# .then () -> createRepo()
|
||||
|
||||
# Send the repoInfo so we do not rely on cached results (najax does not like that for now)
|
||||
resetRepoToFirstCommit(val)
|
||||
|
||||
# Depending on the Promise implementation the fail method could be:
|
||||
# - `.catch` (native Promise)
|
||||
# - `.fail` (jQuery or angularjs)
|
||||
promise.catch?(createRepo) or promise.fail(createRepo)
|
||||
|
||||
describe 'Initially:', () ->
|
||||
it 'has one commit', (done) ->
|
||||
trapFail(STATE[REPO].getCommits())
|
||||
.then (val) ->
|
||||
expect(val).to.have.length(1)
|
||||
done()
|
||||
|
||||
it 'has one branch', (done) ->
|
||||
trapFail(STATE[REPO].getBranches())
|
||||
.then (branches) ->
|
||||
expect(branches).to.have.length(1)
|
||||
done()
|
||||
|
||||
describe 'Writing file(s):', () ->
|
||||
it 'commits a single text file', (done) ->
|
||||
FILE_PATH = 'test.txt'
|
||||
FILE_TEXT = 'Hello there'
|
||||
|
||||
trapFail(STATE[BRANCH].write(FILE_PATH, FILE_TEXT))
|
||||
.then (sha) ->
|
||||
# Read the file back
|
||||
trapFail(STATE[BRANCH].read(FILE_PATH))
|
||||
.then (val) ->
|
||||
expect(val.content).to.equal(FILE_TEXT)
|
||||
PREV_SHA = val.sha
|
||||
done()
|
||||
|
||||
it 'removes a single file', (done) ->
|
||||
FILE_PATH = 'test.txt'
|
||||
trapFail(STATE[BRANCH].remove(FILE_PATH))
|
||||
.then () ->
|
||||
done()
|
||||
|
||||
it 'commits multiple files at once (including binary ones)', (done) ->
|
||||
FILE1 = 'testdir/test1.txt'
|
||||
FILE2 = 'testdir/test2.txt'
|
||||
BINARY_DATA = 'Ahoy!'
|
||||
contents = {}
|
||||
contents[FILE1] = 'Hello World!'
|
||||
contents[FILE2] = {content:btoa(BINARY_DATA), isBase64:true}
|
||||
|
||||
trapFail(STATE[BRANCH].writeMany(contents))
|
||||
.then () ->
|
||||
# Read the files and verify they were added
|
||||
trapFail(STATE[BRANCH].read(FILE1))
|
||||
.then (val) ->
|
||||
expect(val.content).to.equal(contents[FILE1])
|
||||
trapFail(STATE[BRANCH].read(FILE2))
|
||||
.then (val) ->
|
||||
expect(val.content).to.equal(contents[FILE2].content)
|
||||
done()
|
||||
|
||||
it 'should have created 4 commits (3 + the initial)', (done) ->
|
||||
helper1 done, STATE[REPO].getCommits(), (commits) ->
|
||||
expect(commits).to.have.length(4)
|
||||
|
||||
describe 'Collaborators:', () ->
|
||||
it 'initially should have only 1 collaborator', (done) ->
|
||||
helper1 done, STATE[REPO].getCollaborators(), (collaborators) ->
|
||||
expect(collaborators).to.have.length(1)
|
||||
|
||||
it 'initially the collaborator should be [USERNAME]', (done) ->
|
||||
helper1 done, STATE[REPO].isCollaborator(USERNAME), (canCollaborate) ->
|
||||
expect(canCollaborate).to.be.true
|
||||
|
||||
it 'the current user should be able to collaborate', (done) ->
|
||||
helper1 done, STATE[REPO].canCollaborate(), (canCollaborate) ->
|
||||
expect(canCollaborate).to.be.true
|
||||
|
||||
it 'should be able to add and remove a collaborator', (done) ->
|
||||
helper2 STATE[REPO].addCollaborator(OTHER_USERNAME), (added) ->
|
||||
expect(added).to.be.true
|
||||
|
||||
helper2 STATE[REPO].isCollaborator(OTHER_USERNAME), (canCollaborate) ->
|
||||
expect(canCollaborate).to.be.true
|
||||
|
||||
helper2 STATE[REPO].removeCollaborator(OTHER_USERNAME), (removed) ->
|
||||
expect(removed).to.be.true
|
||||
|
||||
helper1 done, STATE[REPO].isCollaborator(OTHER_USERNAME), (canCollaborate) ->
|
||||
expect(canCollaborate).to.be.false
|
||||
|
||||
describe 'Editing Repository:', () ->
|
||||
it 'initially the repository homepage should be [REPO_HOMEPAGE]', (done) ->
|
||||
helper1 done, STATE[REPO].getInfo(), (info) ->
|
||||
expect(info.homepage).to.equal(REPO_HOMEPAGE)
|
||||
|
||||
it 'should be able to edit the repo homepage', (done) ->
|
||||
helper2 STATE[REPO].updateInfo({name: REPO_NAME, homepage: OTHER_HOMEPAGE}), ->
|
||||
|
||||
helper1 done, STATE[REPO].getInfo(), (info) ->
|
||||
expect(info.homepage).to.equal(OTHER_HOMEPAGE)
|
||||
|
||||
it 'changing the default branch should not explode', (done) ->
|
||||
helper1 done, STATE[REPO].setDefaultBranch(DEFAULT_BRANCH), (result) ->
|
||||
expect(result.default_branch).to.equal(DEFAULT_BRANCH)
|
||||
|
||||
describe 'fetch organization', () ->
|
||||
it 'should be able to fetch organization info', (done) ->
|
||||
|
||||
helper1 done, STATE[GH].getOrg(ORG_NAME).getInfo(), (info) ->
|
||||
expect(info.login).to.equal(ORG_NAME)
|
||||
|
||||
describe 'Releases', () ->
|
||||
it 'should be able to get releases', (done) ->
|
||||
|
||||
helper1 done, STATE[REPO].getReleases(), (releases) ->
|
||||
expect(releases).to.have.length(0)
|
||||
|
||||
describe 'Events:', () ->
|
||||
itIsOk(REPO, 'getEvents')
|
||||
itIsOk(REPO, 'getIssueEvents')
|
||||
itIsOk(REPO, 'getNetworkEvents')
|
||||
#itIsOk(REPO, 'getNotifications')
|
||||
|
||||
describe 'Misc:', () ->
|
||||
itIsOk(REPO, 'getHooks')
|
||||
itIsOk(REPO, 'getLanguages')
|
||||
itIsOk(REPO, 'getInfo')
|
||||
|
||||
|
||||
describe 'Users:', () ->
|
||||
|
||||
describe 'Current User:', () ->
|
||||
|
||||
describe 'Methods for all Users:', () ->
|
||||
#itIsOk(USER, 'getNotifications')
|
||||
itIsOk(USER, 'getInfo')
|
||||
itIsOk(USER, 'getRepos')
|
||||
itIsOk(USER, 'getOrgs')
|
||||
itIsOk(USER, 'getGists')
|
||||
itIsOk(USER, 'getFollowers')
|
||||
itIsOk(USER, 'getFollowing')
|
||||
#(USER, 'isFollowing')
|
||||
# itIsOk(USER, 'getPublicKeys')
|
||||
itIsOk(USER, 'getReceivedEvents')
|
||||
# itIsOk(USER, 'getEvents')
|
||||
|
||||
describe 'Methods only for authenticated user:', () ->
|
||||
#(USER, 'updateInfo(options')
|
||||
itIsOk(USER, 'getGists')
|
||||
#(USER, 'follow(username)')
|
||||
#(USER, 'unfollow(username)')
|
||||
itIsOk(USER, 'getEmails')
|
||||
#(USER, 'addEmail(emails)')
|
||||
#(USER, 'removeEmail(emails)')
|
||||
#(USER, 'getPublicKey(id)')
|
||||
#(USER, 'addPublicKey(title, key)')
|
||||
#(USER, 'updatePublicKey(id, options)')
|
||||
itIsOk(USER, 'getReceivedEvents')
|
||||
|
||||
describe 'Another User:', () ->
|
||||
before () ->
|
||||
STATE[ANOTHER_USER] = STATE[GH].getUser(OTHER_USERNAME)
|
||||
|
||||
# itIsOk(user, 'getNotifications')
|
||||
itIsOk(ANOTHER_USER, 'getInfo')
|
||||
itIsOk(ANOTHER_USER, 'getRepos')
|
||||
itIsOk(ANOTHER_USER, 'getOrgs')
|
||||
itIsOk(ANOTHER_USER, 'getGists')
|
||||
itIsOk(ANOTHER_USER, 'getFollowers')
|
||||
itIsOk(ANOTHER_USER, 'getFollowing')
|
||||
#(ANOTHER_USER, 'isFollowing')
|
||||
itIsOk(ANOTHER_USER, 'getPublicKeys')
|
||||
itIsOk(ANOTHER_USER, 'getReceivedEvents')
|
||||
itIsOk(ANOTHER_USER, 'getEvents')
|
||||
|
||||
|
||||
if exports?
|
||||
exports.makeTests = makeTests
|
||||
else
|
||||
@makeTests = makeTests
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<link rel="stylesheet" href="../bower_components/mocha/mocha.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>This is a test page. Mocha tests should run below.</p>
|
||||
|
||||
<div id="mocha"></div>
|
||||
|
||||
<script src="../node_modules/es6-promise/dist/promise-0.1.1.js"></script>
|
||||
<script src="../bower_components/jquery/dist/jquery.js"></script>
|
||||
<script src="../bower_components/coffee-script/extras/coffee-script.js"></script>
|
||||
<script src="../bower_components/mocha/mocha.js"></script>
|
||||
<script src="../node_modules/chai/chai.js"></script>
|
||||
<script src="../bower_components/blanket/dist/mocha/blanket_mocha.js"></script>
|
||||
<script type="text/javascript" src="../node_modules/grunt-blanket-mocha/support/mocha-blanket.js"></script>
|
||||
<script>
|
||||
mocha.setup('bdd');
|
||||
</script>
|
||||
|
||||
<script data-cover src="../octokit.js"></script>
|
||||
<script type="text/coffeescript" src="common.coffee"></script>
|
||||
<script type="text/coffeescript" src="browser.coffee"></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
chai = require('chai')
|
||||
Octokit = require('../octokit').new
|
||||
makeTests = require('./common').makeTests
|
||||
|
||||
assert = chai.assert
|
||||
expect = chai.expect
|
||||
|
||||
# NodeJS does not have a btoa
|
||||
btoa = (str) ->
|
||||
buffer = new Buffer str, 'binary'
|
||||
buffer.toString 'base64'
|
||||
|
||||
makeTests(assert, expect, btoa, Octokit)
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2010 passive.ly LLC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
# node-XMLHttpRequest #
|
||||
|
||||
node-XMLHttpRequest is a wrapper for the built-in http client to emulate the
|
||||
browser XMLHttpRequest object.
|
||||
|
||||
This can be used with JS designed for browsers to improve reuse of code and
|
||||
allow the use of existing libraries.
|
||||
|
||||
Note: This library currently conforms to [XMLHttpRequest 1](http://www.w3.org/TR/XMLHttpRequest/). Version 2.0 will target [XMLHttpRequest Level 2](http://www.w3.org/TR/XMLHttpRequest2/).
|
||||
|
||||
## Usage ##
|
||||
|
||||
Here's how to include the module in your project and use as the browser-based
|
||||
XHR object.
|
||||
|
||||
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
Note: use the lowercase string "xmlhttprequest" in your require(). On
|
||||
case-sensitive systems (eg Linux) using uppercase letters won't work.
|
||||
|
||||
## Versions ##
|
||||
|
||||
Prior to 1.4.0 version numbers were arbitrary. From 1.4.0 on they conform to
|
||||
the standard major.minor.bugfix. 1.x shouldn't necessarily be considered
|
||||
stable just because it's above 0.x.
|
||||
|
||||
Since the XMLHttpRequest API is stable this library's API is stable as
|
||||
well. Major version numbers indicate significant core code changes.
|
||||
Minor versions indicate minor core code changes or better conformity to
|
||||
the W3C spec.
|
||||
|
||||
## License ##
|
||||
|
||||
MIT license. See LICENSE for full details.
|
||||
|
||||
## Supports ##
|
||||
|
||||
* Async and synchronous requests
|
||||
* GET, POST, PUT, and DELETE requests
|
||||
* All spec methods (open, send, abort, getRequestHeader,
|
||||
getAllRequestHeaders, event methods)
|
||||
* Requests to all domains
|
||||
|
||||
## Known Issues / Missing Features ##
|
||||
|
||||
For a list of open issues or to report your own visit the [github issues
|
||||
page](https://github.com/driverdan/node-XMLHttpRequest/issues).
|
||||
|
||||
* Local file access may have unexpected results for non-UTF8 files
|
||||
* Synchronous requests don't set headers properly
|
||||
* Synchronous requests freeze node while waiting for response (But that's what you want, right? Stick with async!).
|
||||
* Some events are missing, such as abort
|
||||
* getRequestHeader is case-sensitive
|
||||
* Cookies aren't persisted between requests
|
||||
* Missing XML support
|
||||
* Missing basic auth
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
def run_all_tests
|
||||
puts `clear`
|
||||
puts `node tests/test-constants.js`
|
||||
puts `node tests/test-headers.js`
|
||||
puts `node tests/test-request.js`
|
||||
end
|
||||
watch('.*.js') { run_all_tests }
|
||||
run_all_tests
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
var sys = require('util');
|
||||
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
sys.puts("State: " + this.readyState);
|
||||
|
||||
if (this.readyState == 4) {
|
||||
sys.puts("Complete.\nBody length: " + this.responseText.length);
|
||||
sys.puts("Body:\n" + this.responseText);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.open("GET", "http://driverdan.com");
|
||||
xhr.send();
|
||||
+599
@@ -0,0 +1,599 @@
|
||||
/**
|
||||
* Wrapper for built-in http.js to emulate the browser XMLHttpRequest object.
|
||||
*
|
||||
* This can be used with JS designed for browsers to improve reuse of code and
|
||||
* allow the use of existing libraries.
|
||||
*
|
||||
* Usage: include("XMLHttpRequest.js") and use XMLHttpRequest per W3C specs.
|
||||
*
|
||||
* @author Dan DeFelippi <dan@driverdan.com>
|
||||
* @contributor David Ellis <d.f.ellis@ieee.org>
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
var Url = require("url")
|
||||
, spawn = require("child_process").spawn
|
||||
, fs = require('fs');
|
||||
|
||||
exports.XMLHttpRequest = function() {
|
||||
/**
|
||||
* Private variables
|
||||
*/
|
||||
var self = this;
|
||||
var http = require('http');
|
||||
var https = require('https');
|
||||
|
||||
// Holds http.js objects
|
||||
var request;
|
||||
var response;
|
||||
|
||||
// Request settings
|
||||
var settings = {};
|
||||
|
||||
// Disable header blacklist.
|
||||
// Not part of XHR specs.
|
||||
var disableHeaderCheck = false;
|
||||
|
||||
// Set some default headers
|
||||
var defaultHeaders = {
|
||||
"User-Agent": "node-XMLHttpRequest",
|
||||
"Accept": "*/*",
|
||||
};
|
||||
|
||||
var headers = defaultHeaders;
|
||||
|
||||
// These headers are not user setable.
|
||||
// The following are allowed but banned in the spec:
|
||||
// * user-agent
|
||||
var forbiddenRequestHeaders = [
|
||||
"accept-charset",
|
||||
"accept-encoding",
|
||||
"access-control-request-headers",
|
||||
"access-control-request-method",
|
||||
"connection",
|
||||
"content-length",
|
||||
"content-transfer-encoding",
|
||||
"cookie",
|
||||
"cookie2",
|
||||
"date",
|
||||
"expect",
|
||||
"host",
|
||||
"keep-alive",
|
||||
"origin",
|
||||
"referer",
|
||||
"te",
|
||||
"trailer",
|
||||
"transfer-encoding",
|
||||
"upgrade",
|
||||
"via"
|
||||
];
|
||||
|
||||
// These request methods are not allowed
|
||||
var forbiddenRequestMethods = [
|
||||
"TRACE",
|
||||
"TRACK",
|
||||
"CONNECT"
|
||||
];
|
||||
|
||||
// Send flag
|
||||
var sendFlag = false;
|
||||
// Error flag, used when errors occur or abort is called
|
||||
var errorFlag = false;
|
||||
|
||||
// Event listeners
|
||||
var listeners = {};
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
this.UNSENT = 0;
|
||||
this.OPENED = 1;
|
||||
this.HEADERS_RECEIVED = 2;
|
||||
this.LOADING = 3;
|
||||
this.DONE = 4;
|
||||
|
||||
/**
|
||||
* Public vars
|
||||
*/
|
||||
|
||||
// Current state
|
||||
this.readyState = this.UNSENT;
|
||||
|
||||
// default ready state change handler in case one is not set or is set late
|
||||
this.onreadystatechange = null;
|
||||
|
||||
// Result & response
|
||||
this.responseText = "";
|
||||
this.responseXML = "";
|
||||
this.status = null;
|
||||
this.statusText = null;
|
||||
|
||||
/**
|
||||
* Private methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check if the specified header is allowed.
|
||||
*
|
||||
* @param string header Header to validate
|
||||
* @return boolean False if not allowed, otherwise true
|
||||
*/
|
||||
var isAllowedHttpHeader = function(header) {
|
||||
return disableHeaderCheck || (header && forbiddenRequestHeaders.indexOf(header.toLowerCase()) === -1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the specified method is allowed.
|
||||
*
|
||||
* @param string method Request method to validate
|
||||
* @return boolean False if not allowed, otherwise true
|
||||
*/
|
||||
var isAllowedHttpMethod = function(method) {
|
||||
return (method && forbiddenRequestMethods.indexOf(method) === -1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Public methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Open the connection. Currently supports local server requests.
|
||||
*
|
||||
* @param string method Connection method (eg GET, POST)
|
||||
* @param string url URL for the connection.
|
||||
* @param boolean async Asynchronous connection. Default is true.
|
||||
* @param string user Username for basic authentication (optional)
|
||||
* @param string password Password for basic authentication (optional)
|
||||
*/
|
||||
this.open = function(method, url, async, user, password) {
|
||||
this.abort();
|
||||
errorFlag = false;
|
||||
|
||||
// Check for valid request method
|
||||
if (!isAllowedHttpMethod(method)) {
|
||||
throw "SecurityError: Request method not allowed";
|
||||
}
|
||||
|
||||
settings = {
|
||||
"method": method,
|
||||
"url": url.toString(),
|
||||
"async": (typeof async !== "boolean" ? true : async),
|
||||
"user": user || null,
|
||||
"password": password || null
|
||||
};
|
||||
|
||||
setState(this.OPENED);
|
||||
};
|
||||
|
||||
/**
|
||||
* Disables or enables isAllowedHttpHeader() check the request. Enabled by default.
|
||||
* This does not conform to the W3C spec.
|
||||
*
|
||||
* @param boolean state Enable or disable header checking.
|
||||
*/
|
||||
this.setDisableHeaderCheck = function(state) {
|
||||
disableHeaderCheck = state;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets a header for the request.
|
||||
*
|
||||
* @param string header Header name
|
||||
* @param string value Header value
|
||||
*/
|
||||
this.setRequestHeader = function(header, value) {
|
||||
if (this.readyState != this.OPENED) {
|
||||
throw "INVALID_STATE_ERR: setRequestHeader can only be called when state is OPEN";
|
||||
}
|
||||
if (!isAllowedHttpHeader(header)) {
|
||||
console.warn('Refused to set unsafe header "' + header + '"');
|
||||
return;
|
||||
}
|
||||
if (sendFlag) {
|
||||
throw "INVALID_STATE_ERR: send flag is true";
|
||||
}
|
||||
headers[header] = value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a header from the server response.
|
||||
*
|
||||
* @param string header Name of header to get.
|
||||
* @return string Text of the header or null if it doesn't exist.
|
||||
*/
|
||||
this.getResponseHeader = function(header) {
|
||||
if (typeof header === "string"
|
||||
&& this.readyState > this.OPENED
|
||||
&& response.headers[header.toLowerCase()]
|
||||
&& !errorFlag
|
||||
) {
|
||||
return response.headers[header.toLowerCase()];
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets all the response headers.
|
||||
*
|
||||
* @return string A string with all response headers separated by CR+LF
|
||||
*/
|
||||
this.getAllResponseHeaders = function() {
|
||||
if (this.readyState < this.HEADERS_RECEIVED || errorFlag) {
|
||||
return "";
|
||||
}
|
||||
var result = "";
|
||||
|
||||
for (var i in response.headers) {
|
||||
// Cookie headers are excluded
|
||||
if (i !== "set-cookie" && i !== "set-cookie2") {
|
||||
result += i + ": " + response.headers[i] + "\r\n";
|
||||
}
|
||||
}
|
||||
return result.substr(0, result.length - 2);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a request header
|
||||
*
|
||||
* @param string name Name of header to get
|
||||
* @return string Returns the request header or empty string if not set
|
||||
*/
|
||||
this.getRequestHeader = function(name) {
|
||||
// @TODO Make this case insensitive
|
||||
if (typeof name === "string" && headers[name]) {
|
||||
return headers[name];
|
||||
}
|
||||
|
||||
return "";
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends the request to the server.
|
||||
*
|
||||
* @param string data Optional data to send as request body.
|
||||
*/
|
||||
this.send = function(data) {
|
||||
if (this.readyState != this.OPENED) {
|
||||
throw "INVALID_STATE_ERR: connection must be opened before send() is called";
|
||||
}
|
||||
|
||||
if (sendFlag) {
|
||||
throw "INVALID_STATE_ERR: send has already been called";
|
||||
}
|
||||
|
||||
var ssl = false, local = false;
|
||||
var url = Url.parse(settings.url);
|
||||
var host;
|
||||
// Determine the server
|
||||
switch (url.protocol) {
|
||||
case 'https:':
|
||||
ssl = true;
|
||||
// SSL & non-SSL both need host, no break here.
|
||||
case 'http:':
|
||||
host = url.hostname;
|
||||
break;
|
||||
|
||||
case 'file:':
|
||||
local = true;
|
||||
break;
|
||||
|
||||
case undefined:
|
||||
case '':
|
||||
host = "localhost";
|
||||
break;
|
||||
|
||||
default:
|
||||
throw "Protocol not supported.";
|
||||
}
|
||||
|
||||
// Load files off the local filesystem (file://)
|
||||
if (local) {
|
||||
if (settings.method !== "GET") {
|
||||
throw "XMLHttpRequest: Only GET method is supported";
|
||||
}
|
||||
|
||||
if (settings.async) {
|
||||
fs.readFile(url.pathname, 'utf8', function(error, data) {
|
||||
if (error) {
|
||||
self.handleError(error);
|
||||
} else {
|
||||
self.status = 200;
|
||||
self.responseText = data;
|
||||
setState(self.DONE);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
this.responseText = fs.readFileSync(url.pathname, 'utf8');
|
||||
this.status = 200;
|
||||
setState(self.DONE);
|
||||
} catch(e) {
|
||||
this.handleError(e);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Default to port 80. If accessing localhost on another port be sure
|
||||
// to use http://localhost:port/path
|
||||
var port = url.port || (ssl ? 443 : 80);
|
||||
// Add query string if one is used
|
||||
var uri = url.pathname + (url.search ? url.search : '');
|
||||
|
||||
// Set the Host header or the server may reject the request
|
||||
headers["Host"] = host;
|
||||
if (!((ssl && port === 443) || port === 80)) {
|
||||
headers["Host"] += ':' + url.port;
|
||||
}
|
||||
|
||||
// Set Basic Auth if necessary
|
||||
if (settings.user) {
|
||||
if (typeof settings.password == "undefined") {
|
||||
settings.password = "";
|
||||
}
|
||||
var authBuf = new Buffer(settings.user + ":" + settings.password);
|
||||
headers["Authorization"] = "Basic " + authBuf.toString("base64");
|
||||
}
|
||||
|
||||
// Set content length header
|
||||
if (settings.method === "GET" || settings.method === "HEAD") {
|
||||
data = null;
|
||||
} else if (data) {
|
||||
headers["Content-Length"] = Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data);
|
||||
|
||||
if (!headers["Content-Type"]) {
|
||||
headers["Content-Type"] = "text/plain;charset=UTF-8";
|
||||
}
|
||||
} else if (settings.method === "POST") {
|
||||
// For a post with no data set Content-Length: 0.
|
||||
// This is required by buggy servers that don't meet the specs.
|
||||
headers["Content-Length"] = 0;
|
||||
}
|
||||
|
||||
var options = {
|
||||
host: host,
|
||||
port: port,
|
||||
path: uri,
|
||||
method: settings.method,
|
||||
headers: headers,
|
||||
agent: false
|
||||
};
|
||||
|
||||
// Reset error flag
|
||||
errorFlag = false;
|
||||
|
||||
// Handle async requests
|
||||
if (settings.async) {
|
||||
// Use the proper protocol
|
||||
var doRequest = ssl ? https.request : http.request;
|
||||
|
||||
// Request is being sent, set send flag
|
||||
sendFlag = true;
|
||||
|
||||
// As per spec, this is called here for historical reasons.
|
||||
self.dispatchEvent("readystatechange");
|
||||
|
||||
// Handler for the response
|
||||
function responseHandler(resp) {
|
||||
// Set response var to the response we got back
|
||||
// This is so it remains accessable outside this scope
|
||||
response = resp;
|
||||
// Check for redirect
|
||||
// @TODO Prevent looped redirects
|
||||
if (response.statusCode === 302 || response.statusCode === 303 || response.statusCode === 307) {
|
||||
// Change URL to the redirect location
|
||||
settings.url = response.headers.location;
|
||||
var url = Url.parse(settings.url);
|
||||
// Set host var in case it's used later
|
||||
host = url.hostname;
|
||||
// Options for the new request
|
||||
var newOptions = {
|
||||
hostname: url.hostname,
|
||||
port: url.port,
|
||||
path: url.path,
|
||||
method: response.statusCode === 303 ? 'GET' : settings.method,
|
||||
headers: headers
|
||||
};
|
||||
|
||||
// Issue the new request
|
||||
request = doRequest(newOptions, responseHandler).on('error', errorHandler);
|
||||
request.end();
|
||||
// @TODO Check if an XHR event needs to be fired here
|
||||
return;
|
||||
}
|
||||
|
||||
response.setEncoding("utf8");
|
||||
|
||||
setState(self.HEADERS_RECEIVED);
|
||||
self.status = response.statusCode;
|
||||
|
||||
response.on('data', function(chunk) {
|
||||
// Make sure there's some data
|
||||
if (chunk) {
|
||||
self.responseText += chunk;
|
||||
}
|
||||
// Don't emit state changes if the connection has been aborted.
|
||||
if (sendFlag) {
|
||||
setState(self.LOADING);
|
||||
}
|
||||
});
|
||||
|
||||
response.on('end', function() {
|
||||
if (sendFlag) {
|
||||
// Discard the 'end' event if the connection has been aborted
|
||||
setState(self.DONE);
|
||||
sendFlag = false;
|
||||
}
|
||||
});
|
||||
|
||||
response.on('error', function(error) {
|
||||
self.handleError(error);
|
||||
});
|
||||
}
|
||||
|
||||
// Error handler for the request
|
||||
function errorHandler(error) {
|
||||
self.handleError(error);
|
||||
}
|
||||
|
||||
// Create the request
|
||||
request = doRequest(options, responseHandler).on('error', errorHandler);
|
||||
|
||||
// Node 0.4 and later won't accept empty data. Make sure it's needed.
|
||||
if (data) {
|
||||
request.write(data);
|
||||
}
|
||||
|
||||
request.end();
|
||||
|
||||
self.dispatchEvent("loadstart");
|
||||
} else { // Synchronous
|
||||
// Create a temporary file for communication with the other Node process
|
||||
var contentFile = ".node-xmlhttprequest-content-" + process.pid;
|
||||
var syncFile = ".node-xmlhttprequest-sync-" + process.pid;
|
||||
fs.writeFileSync(syncFile, "", "utf8");
|
||||
// The async request the other Node process executes
|
||||
var execString = "var http = require('http'), https = require('https'), fs = require('fs');"
|
||||
+ "var doRequest = http" + (ssl ? "s" : "") + ".request;"
|
||||
+ "var options = " + JSON.stringify(options) + ";"
|
||||
+ "var responseText = '';"
|
||||
+ "var req = doRequest(options, function(response) {"
|
||||
+ "response.setEncoding('utf8');"
|
||||
+ "response.on('data', function(chunk) {"
|
||||
+ " responseText += chunk;"
|
||||
+ "});"
|
||||
+ "response.on('end', function() {"
|
||||
+ "fs.writeFileSync('" + contentFile + "', 'NODE-XMLHTTPREQUEST-STATUS:' + response.statusCode + ',' + responseText, 'utf8');"
|
||||
+ "fs.unlinkSync('" + syncFile + "');"
|
||||
+ "});"
|
||||
+ "response.on('error', function(error) {"
|
||||
+ "fs.writeFileSync('" + contentFile + "', 'NODE-XMLHTTPREQUEST-ERROR:' + JSON.stringify(error), 'utf8');"
|
||||
+ "fs.unlinkSync('" + syncFile + "');"
|
||||
+ "});"
|
||||
+ "}).on('error', function(error) {"
|
||||
+ "fs.writeFileSync('" + contentFile + "', 'NODE-XMLHTTPREQUEST-ERROR:' + JSON.stringify(error), 'utf8');"
|
||||
+ "fs.unlinkSync('" + syncFile + "');"
|
||||
+ "});"
|
||||
+ (data ? "req.write('" + data.replace(/'/g, "\\'") + "');":"")
|
||||
+ "req.end();";
|
||||
// Start the other Node Process, executing this string
|
||||
var syncProc = spawn(process.argv[0], ["-e", execString]);
|
||||
var statusText;
|
||||
while(fs.existsSync(syncFile)) {
|
||||
// Wait while the sync file is empty
|
||||
}
|
||||
self.responseText = fs.readFileSync(contentFile, 'utf8');
|
||||
// Kill the child process once the file has data
|
||||
syncProc.stdin.end();
|
||||
// Remove the temporary file
|
||||
fs.unlinkSync(contentFile);
|
||||
if (self.responseText.match(/^NODE-XMLHTTPREQUEST-ERROR:/)) {
|
||||
// If the file returned an error, handle it
|
||||
var errorObj = self.responseText.replace(/^NODE-XMLHTTPREQUEST-ERROR:/, "");
|
||||
self.handleError(errorObj);
|
||||
} else {
|
||||
// If the file returned okay, parse its data and move to the DONE state
|
||||
self.status = self.responseText.replace(/^NODE-XMLHTTPREQUEST-STATUS:([0-9]*),.*/, "$1");
|
||||
self.responseText = self.responseText.replace(/^NODE-XMLHTTPREQUEST-STATUS:[0-9]*,(.*)/, "$1");
|
||||
setState(self.DONE);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when an error is encountered to deal with it.
|
||||
*/
|
||||
this.handleError = function(error) {
|
||||
this.status = 503;
|
||||
this.statusText = error;
|
||||
this.responseText = error.stack;
|
||||
errorFlag = true;
|
||||
setState(this.DONE);
|
||||
};
|
||||
|
||||
/**
|
||||
* Aborts a request.
|
||||
*/
|
||||
this.abort = function() {
|
||||
if (request) {
|
||||
request.abort();
|
||||
request = null;
|
||||
}
|
||||
|
||||
headers = defaultHeaders;
|
||||
this.responseText = "";
|
||||
this.responseXML = "";
|
||||
|
||||
errorFlag = true;
|
||||
|
||||
if (this.readyState !== this.UNSENT
|
||||
&& (this.readyState !== this.OPENED || sendFlag)
|
||||
&& this.readyState !== this.DONE) {
|
||||
sendFlag = false;
|
||||
setState(this.DONE);
|
||||
}
|
||||
this.readyState = this.UNSENT;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds an event listener. Preferred method of binding to events.
|
||||
*/
|
||||
this.addEventListener = function(event, callback) {
|
||||
if (!(event in listeners)) {
|
||||
listeners[event] = [];
|
||||
}
|
||||
// Currently allows duplicate callbacks. Should it?
|
||||
listeners[event].push(callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove an event callback that has already been bound.
|
||||
* Only works on the matching funciton, cannot be a copy.
|
||||
*/
|
||||
this.removeEventListener = function(event, callback) {
|
||||
if (event in listeners) {
|
||||
// Filter will return a new array with the callback removed
|
||||
listeners[event] = listeners[event].filter(function(ev) {
|
||||
return ev !== callback;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispatch any events, including both "on" methods and events attached using addEventListener.
|
||||
*/
|
||||
this.dispatchEvent = function(event) {
|
||||
if (typeof self["on" + event] === "function") {
|
||||
self["on" + event]();
|
||||
}
|
||||
if (event in listeners) {
|
||||
for (var i = 0, len = listeners[event].length; i < len; i++) {
|
||||
listeners[event][i].call(self);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Changes readyState and calls onreadystatechange.
|
||||
*
|
||||
* @param int state New state
|
||||
*/
|
||||
var setState = function(state) {
|
||||
if (self.readyState !== state) {
|
||||
self.readyState = state;
|
||||
|
||||
if (settings.async || self.readyState < self.OPENED || self.readyState === self.DONE) {
|
||||
self.dispatchEvent("readystatechange");
|
||||
}
|
||||
|
||||
if (self.readyState === self.DONE && !errorFlag) {
|
||||
self.dispatchEvent("load");
|
||||
// @TODO figure out InspectorInstrumentation::didLoadXHR(cookie)
|
||||
self.dispatchEvent("loadend");
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"_from": "xmlhttprequest@~1.6.0",
|
||||
"_id": "xmlhttprequest@1.6.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-ST0oX1kmb9y41P79JTRae2k8lmw=",
|
||||
"_location": "/xmlhttprequest",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "xmlhttprequest@~1.6.0",
|
||||
"name": "xmlhttprequest",
|
||||
"escapedName": "xmlhttprequest",
|
||||
"rawSpec": "~1.6.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "~1.6.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/octokit"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.6.0.tgz",
|
||||
"_shasum": "493d285f59266fdcb8d4fefd25345a7b693c966c",
|
||||
"_spec": "xmlhttprequest@~1.6.0",
|
||||
"_where": "C:\\Users\\Luis\\source\\repos\\AAWebPlatform\\node_modules\\octokit",
|
||||
"author": {
|
||||
"name": "Dan DeFelippi",
|
||||
"url": "http://driverdan.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "http://github.com/driverdan/node-XMLHttpRequest/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"deprecated": false,
|
||||
"description": "XMLHttpRequest for Node",
|
||||
"directories": {
|
||||
"lib": "./lib",
|
||||
"example": "./example"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
},
|
||||
"homepage": "https://github.com/driverdan/node-XMLHttpRequest#readme",
|
||||
"keywords": [
|
||||
"xhr",
|
||||
"ajax"
|
||||
],
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT",
|
||||
"url": "http://creativecommons.org/licenses/MIT/"
|
||||
}
|
||||
],
|
||||
"main": "./lib/XMLHttpRequest.js",
|
||||
"name": "xmlhttprequest",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/driverdan/node-XMLHttpRequest.git"
|
||||
},
|
||||
"version": "1.6.0"
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
var sys = require("util")
|
||||
, assert = require("assert")
|
||||
, XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest
|
||||
, xhr = new XMLHttpRequest();
|
||||
|
||||
// Test constant values
|
||||
assert.equal(0, xhr.UNSENT);
|
||||
assert.equal(1, xhr.OPENED);
|
||||
assert.equal(2, xhr.HEADERS_RECEIVED);
|
||||
assert.equal(3, xhr.LOADING);
|
||||
assert.equal(4, xhr.DONE);
|
||||
|
||||
sys.puts("done");
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
var sys = require("util")
|
||||
, assert = require("assert")
|
||||
, http = require("http")
|
||||
, XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest
|
||||
, xhr;
|
||||
|
||||
// Test server
|
||||
var server = http.createServer(function (req, res) {
|
||||
var body = (req.method != "HEAD" ? "Hello World" : "");
|
||||
|
||||
res.writeHead(200, {
|
||||
"Content-Type": "text/plain",
|
||||
"Content-Length": Buffer.byteLength(body)
|
||||
});
|
||||
// HEAD has no body
|
||||
if (req.method != "HEAD") {
|
||||
res.write(body);
|
||||
}
|
||||
res.end();
|
||||
assert.equal(onreadystatechange, true);
|
||||
assert.equal(readystatechange, true);
|
||||
assert.equal(removed, true);
|
||||
sys.puts("done");
|
||||
this.close();
|
||||
}).listen(8000);
|
||||
|
||||
xhr = new XMLHttpRequest();
|
||||
|
||||
// Track event calls
|
||||
var onreadystatechange = false;
|
||||
var readystatechange = false;
|
||||
var removed = true;
|
||||
var removedEvent = function() {
|
||||
removed = false;
|
||||
};
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
onreadystatechange = true;
|
||||
};
|
||||
|
||||
xhr.addEventListener("readystatechange", function() {
|
||||
readystatechange = true;
|
||||
});
|
||||
|
||||
// This isn't perfect, won't guarantee it was added in the first place
|
||||
xhr.addEventListener("readystatechange", removedEvent);
|
||||
xhr.removeEventListener("readystatechange", removedEvent);
|
||||
|
||||
xhr.open("GET", "http://localhost:8000");
|
||||
xhr.send();
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
var sys = require("util")
|
||||
, assert = require("assert")
|
||||
, XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest
|
||||
, xhr = new XMLHttpRequest();
|
||||
|
||||
// Test request methods that aren't allowed
|
||||
try {
|
||||
xhr.open("TRACK", "http://localhost:8000/");
|
||||
console.log("ERROR: TRACK should have thrown exception");
|
||||
} catch(e) {}
|
||||
try {
|
||||
xhr.open("TRACE", "http://localhost:8000/");
|
||||
console.log("ERROR: TRACE should have thrown exception");
|
||||
} catch(e) {}
|
||||
try {
|
||||
xhr.open("CONNECT", "http://localhost:8000/");
|
||||
console.log("ERROR: CONNECT should have thrown exception");
|
||||
} catch(e) {}
|
||||
// Test valid request method
|
||||
try {
|
||||
xhr.open("GET", "http://localhost:8000/");
|
||||
} catch(e) {
|
||||
console.log("ERROR: Invalid exception for GET", e);
|
||||
}
|
||||
|
||||
// Test forbidden headers
|
||||
var forbiddenRequestHeaders = [
|
||||
"accept-charset",
|
||||
"accept-encoding",
|
||||
"access-control-request-headers",
|
||||
"access-control-request-method",
|
||||
"connection",
|
||||
"content-length",
|
||||
"content-transfer-encoding",
|
||||
"cookie",
|
||||
"cookie2",
|
||||
"date",
|
||||
"expect",
|
||||
"host",
|
||||
"keep-alive",
|
||||
"origin",
|
||||
"referer",
|
||||
"te",
|
||||
"trailer",
|
||||
"transfer-encoding",
|
||||
"upgrade",
|
||||
"user-agent",
|
||||
"via"
|
||||
];
|
||||
|
||||
for (var i in forbiddenRequestHeaders) {
|
||||
try {
|
||||
xhr.setRequestHeader(forbiddenRequestHeaders[i], "Test");
|
||||
console.log("ERROR: " + forbiddenRequestHeaders[i] + " should have thrown exception");
|
||||
} catch(e) {
|
||||
}
|
||||
}
|
||||
|
||||
// Try valid header
|
||||
xhr.setRequestHeader("X-Foobar", "Test");
|
||||
|
||||
console.log("Done");
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
var sys = require("util")
|
||||
, assert = require("assert")
|
||||
, XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest
|
||||
, xhr = new XMLHttpRequest()
|
||||
, http = require("http");
|
||||
|
||||
// Test server
|
||||
var server = http.createServer(function (req, res) {
|
||||
// Test setRequestHeader
|
||||
assert.equal("Foobar", req.headers["x-test"]);
|
||||
// Test non-conforming allowed header
|
||||
assert.equal("node-XMLHttpRequest-test", req.headers["user-agent"]);
|
||||
// Test header set with blacklist disabled
|
||||
assert.equal("http://github.com", req.headers["referer"]);
|
||||
|
||||
var body = "Hello World";
|
||||
res.writeHead(200, {
|
||||
"Content-Type": "text/plain",
|
||||
"Content-Length": Buffer.byteLength(body),
|
||||
// Set cookie headers to see if they're correctly suppressed
|
||||
// Actual values don't matter
|
||||
"Set-Cookie": "foo=bar",
|
||||
"Set-Cookie2": "bar=baz",
|
||||
"Date": "Thu, 30 Aug 2012 18:17:53 GMT",
|
||||
"Connection": "close"
|
||||
});
|
||||
res.write("Hello World");
|
||||
res.end();
|
||||
|
||||
this.close();
|
||||
}).listen(8000);
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
if (this.readyState == 4) {
|
||||
// Test getAllResponseHeaders()
|
||||
var headers = "content-type: text/plain\r\ncontent-length: 11\r\ndate: Thu, 30 Aug 2012 18:17:53 GMT\r\nconnection: close";
|
||||
assert.equal(headers, this.getAllResponseHeaders());
|
||||
|
||||
// Test case insensitivity
|
||||
assert.equal('text/plain', this.getResponseHeader('Content-Type'));
|
||||
assert.equal('text/plain', this.getResponseHeader('Content-type'));
|
||||
assert.equal('text/plain', this.getResponseHeader('content-Type'));
|
||||
assert.equal('text/plain', this.getResponseHeader('content-type'));
|
||||
|
||||
// Test aborted getAllResponseHeaders
|
||||
this.abort();
|
||||
assert.equal("", this.getAllResponseHeaders());
|
||||
assert.equal(null, this.getResponseHeader("Connection"));
|
||||
|
||||
sys.puts("done");
|
||||
}
|
||||
};
|
||||
|
||||
assert.equal(null, xhr.getResponseHeader("Content-Type"));
|
||||
try {
|
||||
xhr.open("GET", "http://localhost:8000/");
|
||||
// Valid header
|
||||
xhr.setRequestHeader("X-Test", "Foobar");
|
||||
// Invalid header
|
||||
xhr.setRequestHeader("Content-Length", 0);
|
||||
// Allowed header outside of specs
|
||||
xhr.setRequestHeader("user-agent", "node-XMLHttpRequest-test");
|
||||
// Test getRequestHeader
|
||||
assert.equal("Foobar", xhr.getRequestHeader("X-Test"));
|
||||
// Test invalid header
|
||||
assert.equal("", xhr.getRequestHeader("Content-Length"));
|
||||
|
||||
// Test allowing all headers
|
||||
xhr.setDisableHeaderCheck(true);
|
||||
xhr.setRequestHeader("Referer", "http://github.com");
|
||||
assert.equal("http://github.com", xhr.getRequestHeader("Referer"));
|
||||
|
||||
xhr.send();
|
||||
} catch(e) {
|
||||
console.log("ERROR: Exception raised", e);
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
var sys = require("util")
|
||||
, assert = require("assert")
|
||||
, XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest
|
||||
, xhr = new XMLHttpRequest()
|
||||
, http = require("http");
|
||||
|
||||
// Test server
|
||||
var server = http.createServer(function (req, res) {
|
||||
if (req.url === '/redirectingResource') {
|
||||
res.writeHead(302, {'Location': 'http://localhost:8000/'});
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
var body = "Hello World";
|
||||
res.writeHead(200, {
|
||||
"Content-Type": "text/plain",
|
||||
"Content-Length": Buffer.byteLength(body),
|
||||
"Date": "Thu, 30 Aug 2012 18:17:53 GMT",
|
||||
"Connection": "close"
|
||||
});
|
||||
res.write("Hello World");
|
||||
res.end();
|
||||
|
||||
this.close();
|
||||
}).listen(8000);
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
if (this.readyState == 4) {
|
||||
assert.equal(xhr.getRequestHeader('Location'), '');
|
||||
assert.equal(xhr.responseText, "Hello World");
|
||||
sys.puts("done");
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
xhr.open("GET", "http://localhost:8000/redirectingResource");
|
||||
xhr.send();
|
||||
} catch(e) {
|
||||
console.log("ERROR: Exception raised", e);
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
var sys = require("util")
|
||||
, assert = require("assert")
|
||||
, XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest
|
||||
, xhr = new XMLHttpRequest()
|
||||
, http = require("http");
|
||||
|
||||
// Test server
|
||||
var server = http.createServer(function (req, res) {
|
||||
if (req.url === '/redirectingResource') {
|
||||
res.writeHead(303, {'Location': 'http://localhost:8000/'});
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
var body = "Hello World";
|
||||
res.writeHead(200, {
|
||||
"Content-Type": "text/plain",
|
||||
"Content-Length": Buffer.byteLength(body),
|
||||
"Date": "Thu, 30 Aug 2012 18:17:53 GMT",
|
||||
"Connection": "close"
|
||||
});
|
||||
res.write("Hello World");
|
||||
res.end();
|
||||
|
||||
this.close();
|
||||
}).listen(8000);
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
if (this.readyState == 4) {
|
||||
assert.equal(xhr.getRequestHeader('Location'), '');
|
||||
assert.equal(xhr.responseText, "Hello World");
|
||||
sys.puts("done");
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
xhr.open("POST", "http://localhost:8000/redirectingResource");
|
||||
xhr.send();
|
||||
} catch(e) {
|
||||
console.log("ERROR: Exception raised", e);
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
var sys = require("util")
|
||||
, assert = require("assert")
|
||||
, XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest
|
||||
, xhr = new XMLHttpRequest()
|
||||
, http = require("http");
|
||||
|
||||
// Test server
|
||||
var server = http.createServer(function (req, res) {
|
||||
if (req.url === '/redirectingResource') {
|
||||
res.writeHead(307, {'Location': 'http://localhost:8000/'});
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
assert.equal(req.method, 'POST');
|
||||
|
||||
var body = "Hello World";
|
||||
res.writeHead(200, {
|
||||
"Content-Type": "text/plain",
|
||||
"Content-Length": Buffer.byteLength(body),
|
||||
"Date": "Thu, 30 Aug 2012 18:17:53 GMT",
|
||||
"Connection": "close"
|
||||
});
|
||||
res.write("Hello World");
|
||||
res.end();
|
||||
|
||||
this.close();
|
||||
}).listen(8000);
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
if (this.readyState == 4) {
|
||||
assert.equal(xhr.getRequestHeader('Location'), '');
|
||||
assert.equal(xhr.responseText, "Hello World");
|
||||
sys.puts("done");
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
xhr.open("POST", "http://localhost:8000/redirectingResource");
|
||||
xhr.send();
|
||||
} catch(e) {
|
||||
console.log("ERROR: Exception raised", e);
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
var sys = require("util")
|
||||
, assert = require("assert")
|
||||
, XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest
|
||||
, http = require("http")
|
||||
, xhr;
|
||||
|
||||
// Test server
|
||||
var server = http.createServer(function (req, res) {
|
||||
// Check request method and URL
|
||||
assert.equal(methods[curMethod], req.method);
|
||||
assert.equal("/" + methods[curMethod], req.url);
|
||||
|
||||
var body = (req.method != "HEAD" ? "Hello World" : "");
|
||||
|
||||
res.writeHead(200, {
|
||||
"Content-Type": "text/plain",
|
||||
"Content-Length": Buffer.byteLength(body)
|
||||
});
|
||||
// HEAD has no body
|
||||
if (req.method != "HEAD") {
|
||||
res.write(body);
|
||||
}
|
||||
res.end();
|
||||
|
||||
if (curMethod == methods.length - 1) {
|
||||
this.close();
|
||||
sys.puts("done");
|
||||
}
|
||||
}).listen(8000);
|
||||
|
||||
// Test standard methods
|
||||
var methods = ["GET", "POST", "HEAD", "PUT", "DELETE"];
|
||||
var curMethod = 0;
|
||||
|
||||
function start(method) {
|
||||
// Reset each time
|
||||
xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
if (this.readyState == 4) {
|
||||
if (method == "HEAD") {
|
||||
assert.equal("", this.responseText);
|
||||
} else {
|
||||
assert.equal("Hello World", this.responseText);
|
||||
}
|
||||
|
||||
curMethod++;
|
||||
|
||||
if (curMethod < methods.length) {
|
||||
sys.puts("Testing " + methods[curMethod]);
|
||||
start(methods[curMethod]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var url = "http://localhost:8000/" + method;
|
||||
xhr.open(method, url);
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
sys.puts("Testing " + methods[curMethod]);
|
||||
start(methods[curMethod]);
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
var sys = require("util")
|
||||
, assert = require("assert")
|
||||
, XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest
|
||||
, xhr;
|
||||
|
||||
xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
if (this.readyState == 4) {
|
||||
assert.equal("Hello World", this.responseText);
|
||||
this.close();
|
||||
runSync();
|
||||
}
|
||||
};
|
||||
|
||||
// Async
|
||||
var url = "file://" + __dirname + "/testdata.txt";
|
||||
xhr.open("GET", url);
|
||||
xhr.send();
|
||||
|
||||
// Sync
|
||||
var runSync = function() {
|
||||
xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
if (this.readyState == 4) {
|
||||
assert.equal("Hello World", this.responseText);
|
||||
this.close();
|
||||
sys.puts("done");
|
||||
}
|
||||
};
|
||||
xhr.open("GET", url, false);
|
||||
xhr.send();
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
Hello World
|
||||
Reference in new issue
Block a user