Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2f128c9619 | |||
| f7a5f1788a | |||
| b3ed7a8a7a | |||
| 62d34e1437 | |||
| 855971c385 | |||
| 2d489ff936 | |||
| fc5cda2f72 | |||
| 05ad1ce90c | |||
| 5703984d4d | |||
| ea8952177e | |||
| 90ca6f983e | |||
| 57030bb6b4 | |||
| 710a27030e | |||
| 19aa16c8d5 | |||
| 4a1972c71b | |||
| 6aa04b1db4 | |||
| ac6e1306ec | |||
| e004378d10 | |||
| 4ec1d8ee86 | |||
| c37bfde9eb | |||
| f6bcbb53f0 | |||
| 53a4580d95 | |||
| 4c8eaa1eb0 | |||
| 4ba35eb97e | |||
| 6fb4bf4c54 | |||
| cc604b6e26 | |||
| 99ee6f275a | |||
| 21c4919a5b | |||
| 714759100c | |||
| ee8e981c47 | |||
| 05e2c3196c | |||
| 718ebf1fcf | |||
| 2f5d17f3b6 | |||
| fd792de9e8 | |||
| a01cf6d39e | |||
| f93e9bfa81 | |||
| 590cd14ae0 | |||
| 74db92cd9f |
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType">
|
||||
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED" value="true"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:<?xml version="1.0" encoding="UTF-8"?> <launchConfigurationWorkingSet editPageId="org.eclipse.ui.resourceWorkingSetPage" factoryID="org.eclipse.ui.internal.WorkingSetFactory" id="1262905463390_2" label="workingSet" name="workingSet"> <item factoryID="org.eclipse.ui.internal.model.ResourceFactory" path="/angular.js/test" type="2"/> <item factoryID="org.eclipse.ui.internal.model.ResourceFactory" path="/angular.js/src" type="2"/> </launchConfigurationWorkingSet>}"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/angular.js}/test.sh"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,"/>
|
||||
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/angular.js}"/>
|
||||
</launchConfiguration>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType">
|
||||
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED" value="false"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:<?xml version="1.0" encoding="UTF-8"?> <resources> <item path="/angular.js/perf" type="2"/> <item path="/angular.js/src" type="2"/> </resources>}"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/angular.js/perf.sh}"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,"/>
|
||||
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/angular.js}"/>
|
||||
</launchConfiguration>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType">
|
||||
<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:<?xml version="1.0" encoding="UTF-8"?> <resources> <item path="/angular.js/build" type="2"/> </resources>}"/>
|
||||
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED" value="true"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:<?xml version="1.0" encoding="UTF-8"?> <resources> <item path="/angular.js/docs" type="2"/> <item path="/angular.js/src" type="2"/> </resources>}"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/angular.js/gen_docs.sh}"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,"/>
|
||||
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/angular.js}"/>
|
||||
</launchConfiguration>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType">
|
||||
<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:<?xml version="1.0" encoding="UTF-8"?> <resources> <item path="/angular.js/docs" type="2"/> </resources>}"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LAUNCH_CONFIGURATION_BUILD_SCOPE" value="${none}"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/angular.js/gen_docs.sh}"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/angular.js}"/>
|
||||
</launchConfiguration>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType">
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/angular.js/lib/jsl/jsl}"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-conf lib/jsl/jsl.default.conf"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/angular.js}"/>
|
||||
</launchConfiguration>
|
||||
+4
-11
@@ -1,4 +1,6 @@
|
||||
/build/
|
||||
build/
|
||||
angularjs.netrc
|
||||
jstd.log
|
||||
.DS_Store
|
||||
gen_docs.disable
|
||||
test.disable
|
||||
@@ -6,14 +8,5 @@ regression/temp*.html
|
||||
performance/temp*.html
|
||||
.idea/workspace.xml
|
||||
*~
|
||||
*.swp
|
||||
angular.js.tmproj
|
||||
/node_modules/
|
||||
/components/
|
||||
/bower_components/
|
||||
angular.xcodeproj
|
||||
.idea
|
||||
.agignore
|
||||
libpeerconnection.log
|
||||
npm-debug.log
|
||||
/tmp/
|
||||
node_modules
|
||||
|
||||
Generated
+67
@@ -0,0 +1,67 @@
|
||||
IMPORTANT: THIS IS TO CERTIFY THE RIGHT TO USE THE JETBRAINS SOFTWARE PRODUCT, GRANTED BY JETBRAINS S.R.O. UNDER THE TERMS AND CONDITIONS OF THE LICENSE AGREEMENT INCLUDED WITH THE SOFTWARE. PLEASE SAVE A COPY OF THIS EMAIL FOR FUTURE REFERENCES.
|
||||
|
||||
========LICENSE DETAILS========
|
||||
|
||||
Type: Open Source License
|
||||
Reference No*: LC-93161-D352729080
|
||||
Date of Issue: 3 November 2010
|
||||
Expiration Date: 3 November 2011
|
||||
Number of Authorized Users: not limited
|
||||
|
||||
* Please quote this reference when contacting JetBrains
|
||||
|
||||
===========LICENSEE============
|
||||
|
||||
Name: angularjs
|
||||
Customer ID: 93161
|
||||
Address:
|
||||
|
||||
=======SOFTWARE PRODUCT========
|
||||
|
||||
Product Name: WebStorm
|
||||
Licensed Version: 1.0 and any new product release which is made generally available before 3 November 2011
|
||||
|
||||
The software is shipped electronically and is available for download from:
|
||||
http://www.jetbrains.com/webstorm/download/
|
||||
|
||||
Your WebStorm license includes a 1-year upgrade subscription qualifying you for free upgrades to any new versions of WebStorm released by JetBrains during your upgrade subscription period starting on your license issue date and ending on 3 November 2011. To check availability of the new versions of WebStorm, please visit http://www.jetbrains.com.
|
||||
|
||||
For running any new version of WebStorm released by JetBrains during your upgrade subscription period, please use the included below licensing details.
|
||||
|
||||
You can renew your upgrade subscription before or after its expiration. Your new subscription period will start on the date following the expiration date of your current upgrade subscription.
|
||||
|
||||
=========INSTALLATION==========
|
||||
|
||||
Run WebStorm and follow the Installation Wizard's instructions. To register for use of the software or change your existing registration details, go to Help/Register menu of the software and enter the included below the User Name and License Key(s) into the registration dialog:
|
||||
|
||||
User Name: angularjs
|
||||
|
||||
===== LICENSE BEGIN =====
|
||||
93161-03112010
|
||||
00000jBsEx59XVlc79fV"aAqWXQ09e
|
||||
jQsg5TNp5X4HGhc10LNBdu!!ejRcFG
|
||||
7h3S6T09YcRWs23TH0RgaM87!HqmQo
|
||||
===== LICENSE END =====
|
||||
|
||||
===DOCUMENTATION AND SUPPORT===
|
||||
|
||||
WebStorm documentation:
|
||||
http://www.jetbrains.com/webstorm/documentation/
|
||||
|
||||
Available support resources:
|
||||
http://www.jetbrains.com/support/
|
||||
|
||||
Technical support contact:
|
||||
support@jetbrains.com
|
||||
|
||||
Contact for the license renewal requests:
|
||||
opensource@jetbrains.com
|
||||
|
||||
For questions, please contact:
|
||||
sales@jetbrains.com
|
||||
|
||||
|
||||
JetBrains Sales Team
|
||||
http://www.jetbrains.com
|
||||
"Develop with pleasure!"
|
||||
|
||||
Generated
+9
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
Generated
+5
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
|
||||
</project>
|
||||
|
||||
Generated
+11
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DependencyValidationManager">
|
||||
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" />
|
||||
<component name="SvnBranchConfigurationManager">
|
||||
<option name="mySupportsUserInfoFilter" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
|
||||
Generated
+9
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/angular.js.iml" filepath="$PROJECT_DIR$/.idea/angular.js.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
|
||||
Generated
+68
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CodeStyleSettingsManager">
|
||||
<option name="PER_PROJECT_SETTINGS">
|
||||
<value>
|
||||
<option name="USE_SAME_INDENTS" value="true" />
|
||||
<option name="OTHER_INDENT_OPTIONS">
|
||||
<value>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
<option name="USE_TAB_CHARACTER" value="false" />
|
||||
<option name="SMART_TABS" value="false" />
|
||||
<option name="LABEL_INDENT_SIZE" value="0" />
|
||||
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
|
||||
</value>
|
||||
</option>
|
||||
<ADDITIONAL_INDENT_OPTIONS fileType="js">
|
||||
<option name="INDENT_SIZE" value="4" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="8" />
|
||||
<option name="TAB_SIZE" value="4" />
|
||||
<option name="USE_TAB_CHARACTER" value="false" />
|
||||
<option name="SMART_TABS" value="false" />
|
||||
<option name="LABEL_INDENT_SIZE" value="0" />
|
||||
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
|
||||
</ADDITIONAL_INDENT_OPTIONS>
|
||||
<ADDITIONAL_INDENT_OPTIONS fileType="jsp">
|
||||
<option name="INDENT_SIZE" value="4" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="8" />
|
||||
<option name="TAB_SIZE" value="4" />
|
||||
<option name="USE_TAB_CHARACTER" value="false" />
|
||||
<option name="SMART_TABS" value="false" />
|
||||
<option name="LABEL_INDENT_SIZE" value="0" />
|
||||
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
|
||||
</ADDITIONAL_INDENT_OPTIONS>
|
||||
<ADDITIONAL_INDENT_OPTIONS fileType="sass">
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="8" />
|
||||
<option name="TAB_SIZE" value="4" />
|
||||
<option name="USE_TAB_CHARACTER" value="false" />
|
||||
<option name="SMART_TABS" value="false" />
|
||||
<option name="LABEL_INDENT_SIZE" value="0" />
|
||||
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
|
||||
</ADDITIONAL_INDENT_OPTIONS>
|
||||
<ADDITIONAL_INDENT_OPTIONS fileType="xml">
|
||||
<option name="INDENT_SIZE" value="4" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="8" />
|
||||
<option name="TAB_SIZE" value="4" />
|
||||
<option name="USE_TAB_CHARACTER" value="false" />
|
||||
<option name="SMART_TABS" value="false" />
|
||||
<option name="LABEL_INDENT_SIZE" value="0" />
|
||||
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
|
||||
</ADDITIONAL_INDENT_OPTIONS>
|
||||
<ADDITIONAL_INDENT_OPTIONS fileType="yml">
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="8" />
|
||||
<option name="TAB_SIZE" value="4" />
|
||||
<option name="USE_TAB_CHARACTER" value="false" />
|
||||
<option name="SMART_TABS" value="false" />
|
||||
<option name="LABEL_INDENT_SIZE" value="0" />
|
||||
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
|
||||
</ADDITIONAL_INDENT_OPTIONS>
|
||||
</value>
|
||||
</option>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
|
||||
Generated
+15
@@ -0,0 +1,15 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="gen_docs" type="BashConfigurationType" factoryName="Bash">
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="INTERPRETER_PATH" value="/bin/bash" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs />
|
||||
<module name="angular.js" />
|
||||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/gen_docs.sh" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<RunnerSettings RunnerId="BashRunner" />
|
||||
<ConfigurationWrapper RunnerId="BashRunner" />
|
||||
<method />
|
||||
</configuration>
|
||||
</component>
|
||||
Generated
+15
@@ -0,0 +1,15 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="rake compile" type="BashConfigurationType" factoryName="Bash">
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="INTERPRETER_PATH" value="/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs />
|
||||
<module name="angular.js" />
|
||||
<option name="SCRIPT_NAME" value="/usr/bin/rake" />
|
||||
<option name="PARAMETERS" value="compile" />
|
||||
<RunnerSettings RunnerId="BashRunner" />
|
||||
<ConfigurationWrapper RunnerId="BashRunner" />
|
||||
<method />
|
||||
</configuration>
|
||||
</component>
|
||||
Generated
+7
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>angular.js</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>auto,full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/docs.launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>auto,full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/JSTD_Tests.launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>auto,full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/JSTD_perf.launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry excluding="test/" kind="src" path="src"/>
|
||||
<classpathentry excluding="docs-data.js|docs-scenario.js" kind="src" path="docs"/>
|
||||
<classpathentry excluding="test/" kind="src" path="test"/>
|
||||
<classpathentry kind="src" path="test/test"/>
|
||||
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
|
||||
<classpathentry kind="output" path=""/>
|
||||
</classpath>
|
||||
@@ -0,0 +1,16 @@
|
||||
#Mon Jan 24 10:31:47 PST 2011
|
||||
activeContentFilterList=*.makefile,makefile,*.Makefile,Makefile,Makefile.*,*.mk,MANIFEST.MF
|
||||
addNewLine=true
|
||||
convertActionOnSaave=AnyEdit.CnvrtTabToSpaces
|
||||
eclipse.preferences.version=1
|
||||
inActiveContentFilterList=
|
||||
javaTabWidthForJava=true
|
||||
org.eclipse.jdt.ui.editor.tab.width=2
|
||||
projectPropsEnabled=false
|
||||
removeTrailingSpaces=true
|
||||
replaceAllSpaces=false
|
||||
replaceAllTabs=false
|
||||
saveAndAddLine=true
|
||||
saveAndConvert=true
|
||||
saveAndTrim=true
|
||||
useModulo4Tabs=false
|
||||
@@ -0,0 +1 @@
|
||||
org.eclipse.wst.jsdt.launching.JRE_CONTAINER
|
||||
@@ -0,0 +1 @@
|
||||
Global
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.10
|
||||
|
||||
env:
|
||||
global:
|
||||
- SAUCE_USERNAME=angular-ci
|
||||
- SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987
|
||||
- SAUCE_CONNECT_READY_FILE=/tmp/sauce-connect-ready
|
||||
- LOGS_DIR=/tmp/angular-build/logs
|
||||
|
||||
before_script:
|
||||
- mkdir -p $LOGS_DIR
|
||||
- ./lib/sauce/sauce_connect_setup.sh
|
||||
- npm install -g grunt-cli
|
||||
- grunt bower
|
||||
- grunt bower
|
||||
- grunt package-without-bower
|
||||
- grunt ci-checks
|
||||
- ./lib/sauce/sauce_connect_block.sh
|
||||
|
||||
script:
|
||||
- ./travis_build.sh
|
||||
|
||||
after_script:
|
||||
- ./travis_print_logs.sh
|
||||
+42
-3562
File diff suppressed because it is too large
Load Diff
-216
@@ -1,216 +0,0 @@
|
||||
#Contributing to AngularJS
|
||||
|
||||
We'd love for you to contribute to our source code and to make AngularJS even better than it is
|
||||
today! Here are the guidelines we'd like you to follow:
|
||||
|
||||
## Got a Question or Problem?
|
||||
|
||||
If you have questions about how to use AngularJS, please direct these to the [Google Group][groups]
|
||||
discussion list or [StackOverflow][stackoverflow]. We are also available on [IRC][irc].
|
||||
|
||||
## Found an Issue?
|
||||
If you find a bug in the source code or a mistake in the documentation, you can help us by
|
||||
submitting and issue to our [GitHub Repository][github]. Even better you can submit a Pull Request
|
||||
with a fix.
|
||||
|
||||
***Localization Issue:*** *Angular.js uses the [Google Closure I18N library], to generate its own I18N files. This means that
|
||||
any changes to these files would be lost the next time that we import the library. The recommended
|
||||
approach is to submit a patch to the I18N project directly, instead of submitting it here.*
|
||||
|
||||
**Please see the Submission Guidelines below**.
|
||||
|
||||
## Want a Feature?
|
||||
You can request a new feature by submitting an issue to our [GitHub Repository][github]. If you
|
||||
would like to implement a new feature then consider what kind of change it is:
|
||||
|
||||
* **Major Changes** that you wish to contribute to the project should be discussed first on our
|
||||
[dev mailing list][angular-dev] or [IRC][irc] so that we can better coordinate our efforts, prevent
|
||||
duplication of work, and help you to craft the change so that it is successfully accepted into the
|
||||
project.
|
||||
* **Small Changes** can be crafted and submitted to [GitHub Repository][github] as a Pull Request.
|
||||
|
||||
## Submission Guidelines
|
||||
|
||||
### Submitting an Issue
|
||||
Before you submit your issue follow the following guidelines:
|
||||
|
||||
* Search the archive first, it's likely that your question was already answered.
|
||||
* A live example demonstrating the issue, will get an answer faster.
|
||||
* Create one using [Plunker][plunker] or [JSFiddle][jsfiddle].
|
||||
* If you get help, help others. Good karma rulez!
|
||||
|
||||
If your issue appears to be a bug, and hasn't been reported, open a new issue.
|
||||
Help us to maximize the effort we can spend fixing issues and adding new
|
||||
features, by not reporting duplicate issues.
|
||||
|
||||
### Submitting a Pull Request
|
||||
Before you submit your pull request follow the following guidelines:
|
||||
|
||||
* Search GitHub for an open or closed Pull Request that relates to your submission. You don't want
|
||||
to duplicate effort.
|
||||
* Make your changes in a new git branch
|
||||
* Follow our Coding Rules
|
||||
* Follow our Git Commit Guidelines
|
||||
* Build your changes locally and on Travis (by pushing to GitHub) to ensure all the tests pass.
|
||||
* Sign the Contributor License Agreement (CLA). We cannot accept code without this.
|
||||
* If we suggest changes then you can modify your branch, rebase and force a new push to your GitHub
|
||||
repository to update the Pull Request.
|
||||
|
||||
## Coding Rules
|
||||
To ensure consistency throughout the source code, keep these rules in mind as you are working:
|
||||
|
||||
* All features or bug fixes **must be tested** by one or more [specs][unit-testing].
|
||||
* All public API methods **must be documented** with ngdoc, an extended version of jsdoc (we added
|
||||
support for markdown and templating via @ngdoc tag). To see how we document our APIs, please check
|
||||
out the existing ngdocs and see [this wiki page][ngDocs].
|
||||
* With the exceptions listed below, we follow the rules contained in
|
||||
[Google's JavaScript Style Guide][js-style-guide]:
|
||||
* **Do not use namespaces**: Instead, wrap the entire angular code base in an anonymous closure and
|
||||
export our API explicitly rather than implicitly.
|
||||
* Wrap all code at **100 characters**.
|
||||
* Instead of complex inheritance hierarchies, we **prefer simple objects**. We use prototypical
|
||||
inheritance only when absolutely necessary.
|
||||
* We **love functions and closures** and, whenever possible, prefer them over objects.
|
||||
* To write concise code that can be better minified, we **use aliases internally** that map to the
|
||||
external API. See our existing code to see what we mean.
|
||||
* We **don't go crazy with type annotations** for private internal APIs unless it's an internal API
|
||||
that is used throughout AngularJS. The best guidance is to do what makes the most sense.
|
||||
|
||||
## Git Commit Guidelines
|
||||
|
||||
We have very precise rules over how our git commit messages can be formatted. This leads to **more
|
||||
readable messages** that are easy to follow when looking through the **project history**. But also,
|
||||
we use the git commit messages to **generate the AngularJS change log**.
|
||||
|
||||
### Commit Message Format
|
||||
Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
|
||||
format that includes a **type**, a **scope** and a **subject**:
|
||||
|
||||
```
|
||||
<type>(<scope>): <subject>
|
||||
<BLANK LINE>
|
||||
<body>
|
||||
<BLANK LINE>
|
||||
<footer>
|
||||
```
|
||||
|
||||
Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
|
||||
to read on github as well as in various git tools.
|
||||
|
||||
### Type
|
||||
Must be one of the following:
|
||||
|
||||
* **feat**: A new feature
|
||||
* **fix**: A bug fix
|
||||
* **docs**: Documentation only changes
|
||||
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing
|
||||
semi-colons, etc)
|
||||
* **refactor**: A code change that neither fixes a bug or adds a feature
|
||||
* **test**: Adding missing tests
|
||||
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
|
||||
generation
|
||||
|
||||
### Scope
|
||||
The scope could be anything specifying place of the commit change. For example `$location`,
|
||||
`$browser`, `$compile`, `$rootScope`, `ngHref`, `ngClick`, `ngView`, etc...
|
||||
|
||||
### Subject
|
||||
The subject contains succinct description of the change:
|
||||
|
||||
* use the imperative, present tense: "change" not "changed" nor "changes"
|
||||
* don't capitalize first letter
|
||||
* no dot (.) at the end
|
||||
|
||||
###Body
|
||||
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes"
|
||||
The body should include the motivation for the change and contrast this with previous behavior.
|
||||
|
||||
###Footer
|
||||
The footer should contain any information about **Breaking Changes** and is also the place to
|
||||
reference GitHub issues that this commit **Closes**.
|
||||
|
||||
|
||||
A detailed explanation can be found in this [document][commit-message-format].
|
||||
|
||||
## Signing the CLA
|
||||
|
||||
Please sign our Contributor License Agreement (CLA) before sending pull requests. For any code
|
||||
changes to be accepted, the CLA must be signed. It's a quick process, we promise!
|
||||
|
||||
* For individuals we have a [simple click-through form][individual-cla].
|
||||
* For corporations we'll need you to
|
||||
[print, sign and one of scan+email, fax or mail the form][corporate-cla].
|
||||
|
||||
## Further Information
|
||||
You can find out more detailed information about contributing in the
|
||||
[AngularJS documentation][contributing].
|
||||
|
||||
|
||||
## Submitting Your Changes
|
||||
|
||||
To create and submit a change:
|
||||
|
||||
1. Please sign our [Contributor License Agreement (CLA)](#signing-the-cla) before sending pull
|
||||
requests.
|
||||
|
||||
2. Create and checkout a new branch off the master branch for your changes:
|
||||
|
||||
```shell
|
||||
git checkout -b my-fix-branch master
|
||||
```
|
||||
|
||||
3. Create your patch, including appropriate test cases.
|
||||
|
||||
4. Commit your changes and create a descriptive commit message (the commit message is used to
|
||||
generate release notes, please check out our [commit message conventions](#commit-message-format)
|
||||
and our commit message presubmit hook `validate-commit-msg.js`):
|
||||
|
||||
```shell
|
||||
git commit -a
|
||||
```
|
||||
|
||||
5. Push your branch to Github:
|
||||
|
||||
```shell
|
||||
git push origin my-fix-branch
|
||||
```
|
||||
|
||||
6. In Github, send a pull request to `angular:master`.
|
||||
|
||||
That's it! Thank you for your contribution!
|
||||
|
||||
When the patch is reviewed and merged, you can safely delete your branch and pull the changes
|
||||
from the main (upstream) repository:
|
||||
|
||||
```shell
|
||||
# Delete the remote branch on Github:
|
||||
git push origin :my-fix-branch
|
||||
|
||||
# Check out the master branch:
|
||||
git checkout master
|
||||
|
||||
# Delete the local branch:
|
||||
git branch -D my-fix-branch
|
||||
|
||||
# Update your master with the latest upstream version:
|
||||
git pull --ff upstream master
|
||||
```
|
||||
|
||||
|
||||
[github]: https://github.com/angular/angular.js
|
||||
[Google Closure I18N library]: https://code.google.com/p/closure-library/source/browse/closure/goog/i18n/
|
||||
[list]: https://groups.google.com/forum/?fromgroups#!forum/angular
|
||||
[contribute]: http://docs.angularjs.org/misc/contribute
|
||||
[stackoverflow]: http://stackoverflow.com/questions/tagged/angularjs
|
||||
[groups]: https://groups.google.com/forum/?fromgroups#!forum/angular
|
||||
[angular-dev]: https://groups.google.com/forum/?fromgroups#!forum/angular-dev
|
||||
[irc]: http://webchat.freenode.net/?channels=angularjs&uio=d4
|
||||
[plunker]: http://plnkr.co/edit
|
||||
[jsfiddle]: http://jsfiddle.net/
|
||||
[ngDocs]: https://github.com/angular/angular.js/wiki/Writing-AngularJS-Documentation
|
||||
[unit-testing]: http://docs.angularjs.org/guide/dev_guide.unit-testing
|
||||
[js-style-guide]: http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
|
||||
[contributing]: http://docs.angularjs.org/misc/contribute
|
||||
[individual-cla]: http://code.google.com/legal/individual-cla-v1.0.html
|
||||
[corporate-cla]: http://code.google.com/legal/corporate-cla-v1.0.html
|
||||
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
|
||||
-299
@@ -1,299 +0,0 @@
|
||||
var files = require('./angularFiles').files;
|
||||
var util = require('./lib/grunt/utils.js');
|
||||
var path = require('path');
|
||||
|
||||
module.exports = function(grunt) {
|
||||
//grunt plugins
|
||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
||||
grunt.loadNpmTasks('grunt-contrib-copy');
|
||||
grunt.loadNpmTasks('grunt-contrib-connect');
|
||||
grunt.loadNpmTasks('grunt-contrib-compress');
|
||||
grunt.loadNpmTasks('grunt-jasmine-node');
|
||||
grunt.loadNpmTasks('grunt-ddescribe-iit');
|
||||
grunt.loadNpmTasks('grunt-merge-conflict');
|
||||
grunt.loadNpmTasks('grunt-parallel');
|
||||
grunt.loadNpmTasks('grunt-shell');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadTasks('lib/grunt');
|
||||
|
||||
var NG_VERSION = util.getVersion();
|
||||
var dist = 'angular-'+ NG_VERSION.full;
|
||||
|
||||
|
||||
//global beforeEach
|
||||
util.init();
|
||||
|
||||
|
||||
//config
|
||||
grunt.initConfig({
|
||||
NG_VERSION: NG_VERSION,
|
||||
|
||||
parallel: {
|
||||
travis: {
|
||||
tasks: [
|
||||
util.parallelTask(['test:unit', 'test:docgen', 'test:promises-aplus', 'tests:docs'], {stream: true}),
|
||||
util.parallelTask(['test:e2e'])
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
connect: {
|
||||
devserver: {
|
||||
options: {
|
||||
port: 8000,
|
||||
hostname: '0.0.0.0',
|
||||
base: '.',
|
||||
keepalive: true,
|
||||
middleware: function(connect, options){
|
||||
return [
|
||||
//uncomment to enable CSP
|
||||
// util.csp(),
|
||||
util.rewrite(),
|
||||
connect.favicon('images/favicon.ico'),
|
||||
connect.static(options.base),
|
||||
connect.directory(options.base)
|
||||
];
|
||||
}
|
||||
}
|
||||
},
|
||||
testserver: {
|
||||
options: {
|
||||
// We use end2end task (which does not start the webserver)
|
||||
// and start the webserver as a separate process (in travis_build.sh)
|
||||
// to avoid https://github.com/joyent/libuv/issues/826
|
||||
port: 8000,
|
||||
hostname: '0.0.0.0',
|
||||
middleware: function(connect, options){
|
||||
return [
|
||||
function(req, resp, next) {
|
||||
// cache get requests to speed up tests on travis
|
||||
if (req.method === 'GET') {
|
||||
resp.setHeader('Cache-control', 'public, max-age=3600');
|
||||
}
|
||||
|
||||
next();
|
||||
},
|
||||
connect.favicon('images/favicon.ico'),
|
||||
connect.static(options.base)
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
tests: {
|
||||
jqlite: 'karma-jqlite.conf.js',
|
||||
jquery: 'karma-jquery.conf.js',
|
||||
docs: 'karma-docs.conf.js',
|
||||
modules: 'karma-modules.conf.js',
|
||||
//NOTE run grunt test:e2e instead and it will start a webserver for you
|
||||
end2end: 'karma-e2e.conf.js'
|
||||
},
|
||||
|
||||
|
||||
autotest: {
|
||||
jqlite: 'karma-jqlite.conf.js',
|
||||
jquery: 'karma-jquery.conf.js',
|
||||
modules: 'karma-modules.conf.js',
|
||||
docs: 'karma-docs.conf.js'
|
||||
},
|
||||
|
||||
|
||||
clean: {
|
||||
build: ['build'],
|
||||
tmp: ['tmp']
|
||||
},
|
||||
|
||||
jshint: {
|
||||
ng: {
|
||||
files: { src: files['angularSrc'] },
|
||||
options: { jshintrc: 'src/.jshintrc' }
|
||||
},
|
||||
ngAnimate: {
|
||||
files: { src: 'src/ngAnimate/**/*.js' },
|
||||
options: { jshintrc: 'src/ngAnimate/.jshintrc' }
|
||||
},
|
||||
ngCookies: {
|
||||
files: { src: 'src/ngCookies/**/*.js' },
|
||||
options: { jshintrc: 'src/ngCookies/.jshintrc' }
|
||||
},
|
||||
ngLocale: {
|
||||
files: { src: 'src/ngLocale/**/*.js' },
|
||||
options: { jshintrc: 'src/ngLocale/.jshintrc' }
|
||||
},
|
||||
ngMock: {
|
||||
files: { src: 'src/ngMock/**/*.js' },
|
||||
options: { jshintrc: 'src/ngMock/.jshintrc' }
|
||||
},
|
||||
ngResource: {
|
||||
files: { src: 'src/ngResource/**/*.js' },
|
||||
options: { jshintrc: 'src/ngResource/.jshintrc' }
|
||||
},
|
||||
ngRoute: {
|
||||
files: { src: 'src/ngRoute/**/*.js' },
|
||||
options: { jshintrc: 'src/ngRoute/.jshintrc' }
|
||||
},
|
||||
ngSanitize: {
|
||||
files: { src: 'src/ngSanitize/**/*.js' },
|
||||
options: { jshintrc: 'src/ngSanitize/.jshintrc' }
|
||||
},
|
||||
ngScenario: {
|
||||
files: { src: 'src/ngScenario/**/*.js' },
|
||||
options: { jshintrc: 'src/ngScenario/.jshintrc' }
|
||||
},
|
||||
ngTouch: {
|
||||
files: { src: 'src/ngTouch/**/*.js' },
|
||||
options: { jshintrc: 'src/ngTouch/.jshintrc' }
|
||||
}
|
||||
},
|
||||
|
||||
build: {
|
||||
scenario: {
|
||||
dest: 'build/angular-scenario.js',
|
||||
src: [
|
||||
'bower_components/jquery/jquery.js',
|
||||
util.wrap([files['angularSrc'], files['angularScenario']], 'ngScenario/angular')
|
||||
],
|
||||
styles: {
|
||||
css: ['css/angular.css', 'css/angular-scenario.css']
|
||||
}
|
||||
},
|
||||
angular: {
|
||||
dest: 'build/angular.js',
|
||||
src: util.wrap([files['angularSrc']], 'angular'),
|
||||
styles: {
|
||||
css: ['css/angular.css'],
|
||||
generateCspCssFile: true,
|
||||
minify: true
|
||||
}
|
||||
},
|
||||
loader: {
|
||||
dest: 'build/angular-loader.js',
|
||||
src: util.wrap(files['angularLoader'], 'loader')
|
||||
},
|
||||
touch: {
|
||||
dest: 'build/angular-touch.js',
|
||||
src: util.wrap(files['angularModules']['ngTouch'], 'module')
|
||||
},
|
||||
mocks: {
|
||||
dest: 'build/angular-mocks.js',
|
||||
src: files['angularModules']['ngMock'],
|
||||
strict: false
|
||||
},
|
||||
sanitize: {
|
||||
dest: 'build/angular-sanitize.js',
|
||||
src: util.wrap(files['angularModules']['ngSanitize'], 'module')
|
||||
},
|
||||
resource: {
|
||||
dest: 'build/angular-resource.js',
|
||||
src: util.wrap(files['angularModules']['ngResource'], 'module')
|
||||
},
|
||||
animate: {
|
||||
dest: 'build/angular-animate.js',
|
||||
src: util.wrap(files['angularModules']['ngAnimate'], 'module')
|
||||
},
|
||||
route: {
|
||||
dest: 'build/angular-route.js',
|
||||
src: util.wrap(files['angularModules']['ngRoute'], 'module')
|
||||
},
|
||||
cookies: {
|
||||
dest: 'build/angular-cookies.js',
|
||||
src: util.wrap(files['angularModules']['ngCookies'], 'module')
|
||||
},
|
||||
"promises-aplus-adapter": {
|
||||
dest:'tmp/promises-aplus-adapter++.js',
|
||||
src:['src/ng/q.js','lib/promises-aplus/promises-aplus-test-adapter.js']
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
min: {
|
||||
angular: 'build/angular.js',
|
||||
animate: 'build/angular-animate.js',
|
||||
cookies: 'build/angular-cookies.js',
|
||||
loader: 'build/angular-loader.js',
|
||||
touch: 'build/angular-touch.js',
|
||||
resource: 'build/angular-resource.js',
|
||||
route: 'build/angular-route.js',
|
||||
sanitize: 'build/angular-sanitize.js'
|
||||
},
|
||||
|
||||
|
||||
docs: {
|
||||
process: ['build/docs/*.html', 'build/docs/.htaccess']
|
||||
},
|
||||
|
||||
"jasmine_node": {
|
||||
projectRoot: 'docs/spec'
|
||||
},
|
||||
|
||||
"ddescribe-iit": {
|
||||
files: [
|
||||
'test/**/*.js',
|
||||
'!test/ngScenario/DescribeSpec.js'
|
||||
]
|
||||
},
|
||||
|
||||
"merge-conflict": {
|
||||
files: [
|
||||
'src/**/*',
|
||||
'test/**/*',
|
||||
'docs/**/*',
|
||||
'css/**/*'
|
||||
]
|
||||
},
|
||||
|
||||
copy: {
|
||||
i18n: {
|
||||
files: [
|
||||
{ src: 'src/ngLocale/**', dest: 'build/i18n/', expand: true, flatten: true }
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
compress: {
|
||||
build: {
|
||||
options: {archive: 'build/' + dist +'.zip', mode: 'zip'},
|
||||
src: ['**'], cwd: 'build', expand: true, dot: true, dest: dist + '/'
|
||||
}
|
||||
},
|
||||
|
||||
shell:{
|
||||
"promises-aplus-tests":{
|
||||
options:{
|
||||
//stdout:true,
|
||||
stderr:true,
|
||||
failOnError:true
|
||||
},
|
||||
command:path.normalize('./node_modules/.bin/promises-aplus-tests tmp/promises-aplus-adapter++.js')
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
write: {
|
||||
versionTXT: {file: 'build/version.txt', val: NG_VERSION.full},
|
||||
versionJSON: {file: 'build/version.json', val: JSON.stringify(NG_VERSION)}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//alias tasks
|
||||
grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', ['jshint', 'package','test:unit','test:promises-aplus', 'tests:docs', 'test:e2e']);
|
||||
grunt.registerTask('test:jqlite', 'Run the unit tests with Karma' , ['tests:jqlite']);
|
||||
grunt.registerTask('test:jquery', 'Run the jQuery unit tests with Karma', ['tests:jquery']);
|
||||
grunt.registerTask('test:modules', 'Run the Karma module tests with Karma', ['tests:modules']);
|
||||
grunt.registerTask('test:docs', 'Run the doc-page tests with Karma', ['package', 'tests:docs']);
|
||||
grunt.registerTask('test:unit', 'Run unit, jQuery and Karma module tests with Karma', ['tests:jqlite', 'tests:jquery', 'tests:modules']);
|
||||
grunt.registerTask('test:e2e', 'Run the end to end tests with Karma and keep a test server running in the background', ['connect:testserver', 'tests:end2end']);
|
||||
grunt.registerTask('test:docgen', ['jasmine_node']);
|
||||
grunt.registerTask('test:promises-aplus',['build:promises-aplus-adapter','shell:promises-aplus-tests']);
|
||||
|
||||
grunt.registerTask('minify', ['bower','clean', 'build', 'minall']);
|
||||
grunt.registerTask('webserver', ['connect:devserver']);
|
||||
grunt.registerTask('package', ['bower','clean', 'buildall', 'minall', 'collect-errors', 'docs', 'copy', 'write', 'compress']);
|
||||
grunt.registerTask('package-without-bower', ['clean', 'buildall', 'minall', 'collect-errors', 'docs', 'copy', 'write', 'compress']);
|
||||
grunt.registerTask('ci-checks', ['ddescribe-iit', 'merge-conflict', 'jshint', 'test:docgen']);
|
||||
grunt.registerTask('default', ['package']);
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2010-2012 Google, Inc. http://angularjs.org
|
||||
Copyright (c) 2010 Adam Abrons and Misko Hevery http://getangular.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,40 +1,12 @@
|
||||
AngularJS [](https://travis-ci.org/angular/angular.js)
|
||||
=========
|
||||
Angular
|
||||
======
|
||||
|
||||
AngularJS lets you write client-side web applications as if you had a smarter browser. It lets you
|
||||
use good old HTML (or HAML, Jade and friends!) as your template language and lets you extend HTML’s
|
||||
syntax to express your application’s components clearly and succinctly. It automatically
|
||||
synchronizes data from your UI (view) with your JavaScript objects (model) through 2-way data
|
||||
binding. To help you structure your application better and make it easy to test, AngularJS teaches
|
||||
the browser how to do dependency injection and inversion of control. Oh yeah and it also helps with
|
||||
server-side communication, taming async callbacks with promises and deferreds; and make client-side
|
||||
navigation and deeplinking with hashbang urls or HTML5 pushState a piece of cake. The best of all:
|
||||
it makes development fun!
|
||||
|
||||
* Web site: http://angularjs.org
|
||||
* Tutorial: http://docs.angularjs.org/tutorial
|
||||
* API Docs: http://docs.angularjs.org/api
|
||||
* Developer Guide: http://docs.angularjs.org/guide
|
||||
* Contribution guidelines: http://docs.angularjs.org/misc/contribute
|
||||
* Dashboard: http://dashboard.angularjs.org
|
||||
|
||||
Building AngularJS
|
||||
Compiling
|
||||
---------
|
||||
[Once you have your environment setup](http://docs.angularjs.org/misc/contribute) just run:
|
||||
|
||||
grunt package
|
||||
|
||||
rake compile
|
||||
|
||||
Running Tests
|
||||
-------------
|
||||
To execute all unit tests, use:
|
||||
rake server:start
|
||||
rake test
|
||||
|
||||
grunt test:unit
|
||||
|
||||
To execute end-to-end (e2e) tests, use:
|
||||
|
||||
grunt package
|
||||
grunt test:e2e
|
||||
|
||||
To learn more about the grunt tasks, run `grunt --help` and also read our
|
||||
[contribution guidelines](http://docs.angularjs.org/misc/contribute).
|
||||
|
||||
@@ -0,0 +1,393 @@
|
||||
require 'yaml'
|
||||
include FileUtils
|
||||
|
||||
ANGULAR = [
|
||||
'src/Angular.js',
|
||||
'src/JSON.js',
|
||||
'src/Compiler.js',
|
||||
'src/Scope.js',
|
||||
'src/Injector.js',
|
||||
'src/parser.js',
|
||||
'src/Resource.js',
|
||||
'src/Browser.js',
|
||||
'src/sanitizer.js',
|
||||
'src/jqLite.js',
|
||||
'src/apis.js',
|
||||
'src/filters.js',
|
||||
'src/formatters.js',
|
||||
'src/validators.js',
|
||||
'src/service/cookieStore.js',
|
||||
'src/service/cookies.js',
|
||||
'src/service/defer.js',
|
||||
'src/service/document.js',
|
||||
'src/service/exceptionHandler.js',
|
||||
'src/service/hover.js',
|
||||
'src/service/invalidWidgets.js',
|
||||
'src/service/location.js',
|
||||
'src/service/log.js',
|
||||
'src/service/resource.js',
|
||||
'src/service/route.js',
|
||||
'src/service/updateView.js',
|
||||
'src/service/window.js',
|
||||
'src/service/xhr.bulk.js',
|
||||
'src/service/xhr.cache.js',
|
||||
'src/service/xhr.error.js',
|
||||
'src/service/xhr.js',
|
||||
'src/directives.js',
|
||||
'src/markups.js',
|
||||
'src/widgets.js',
|
||||
'src/AngularPublic.js',
|
||||
]
|
||||
|
||||
ANGULAR_SCENARIO = [
|
||||
'src/scenario/Scenario.js',
|
||||
'src/scenario/Application.js',
|
||||
'src/scenario/Describe.js',
|
||||
'src/scenario/Future.js',
|
||||
'src/scenario/ObjectModel.js',
|
||||
'src/scenario/Describe.js',
|
||||
'src/scenario/Runner.js',
|
||||
'src/scenario/SpecRunner.js',
|
||||
'src/scenario/dsl.js',
|
||||
'src/scenario/matchers.js',
|
||||
'src/scenario/output/Html.js',
|
||||
'src/scenario/output/Json.js',
|
||||
'src/scenario/output/Xml.js',
|
||||
'src/scenario/output/Object.js'
|
||||
]
|
||||
|
||||
BUILD_DIR = 'build'
|
||||
|
||||
task :default => [:compile, :test]
|
||||
|
||||
|
||||
desc 'Init the build workspace'
|
||||
task :init do
|
||||
FileUtils.mkdir(BUILD_DIR) unless File.directory?(BUILD_DIR)
|
||||
|
||||
v = YAML::load( File.open( 'version.yaml' ) )
|
||||
match = v['version'].match(/^([^-]*)(-snapshot)?$/)
|
||||
|
||||
NG_VERSION = Struct.new(:full, :major, :minor, :dot, :codename).
|
||||
new(match[1] + (match[2] ? ('-' + %x(git rev-parse HEAD)[0..7]) : ''),
|
||||
match[1].split('.')[0],
|
||||
match[1].split('.')[1],
|
||||
match[1].split('.')[2],
|
||||
v['codename'])
|
||||
end
|
||||
|
||||
|
||||
desc 'Clean Generated Files'
|
||||
task :clean do
|
||||
FileUtils.rm_r(BUILD_DIR, :force => true)
|
||||
FileUtils.mkdir(BUILD_DIR)
|
||||
end
|
||||
|
||||
|
||||
desc 'Compile Scenario'
|
||||
task :compile_scenario => :init do
|
||||
|
||||
deps = [
|
||||
'lib/jquery/jquery-1.4.2.js',
|
||||
'src/scenario/angular.prefix',
|
||||
ANGULAR,
|
||||
ANGULAR_SCENARIO,
|
||||
'src/scenario/angular.suffix',
|
||||
]
|
||||
|
||||
concat = 'cat ' + deps.flatten.join(' ')
|
||||
|
||||
File.open(path_to('angular-scenario.js'), 'w') do |f|
|
||||
f.write(%x{#{concat}}.gsub('"NG_VERSION_FULL"', NG_VERSION.full))
|
||||
f.write(gen_css('css/angular.css') + "\n")
|
||||
f.write(gen_css('css/angular-scenario.css'))
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Compile JSTD Scenario Adapter'
|
||||
task :compile_jstd_scenario_adapter => :init do
|
||||
|
||||
deps = [
|
||||
'src/jstd-scenario-adapter/angular.prefix',
|
||||
'src/jstd-scenario-adapter/Adapter.js',
|
||||
'src/jstd-scenario-adapter/angular.suffix',
|
||||
]
|
||||
|
||||
concat = 'cat ' + deps.flatten.join(' ')
|
||||
|
||||
File.open(path_to('jstd-scenario-adapter.js'), 'w') do |f|
|
||||
f.write(%x{#{concat}}.gsub('"NG_VERSION_FULL"', NG_VERSION.full))
|
||||
end
|
||||
|
||||
# TODO(vojta) use jstd configuration when implemented
|
||||
# (instead of including jstd-adapter-config.js)
|
||||
File.open(path_to('jstd-scenario-adapter-config.js'), 'w') do |f|
|
||||
f.write("/**\r\n" +
|
||||
" * Configuration for jstd scenario adapter \n */\n" +
|
||||
"var jstdScenarioAdapter = {\n relativeUrlPrefix: '/build/docs/'\n};\n")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
desc 'Generate IE css js patch'
|
||||
task :generate_ie_compat => :init do
|
||||
css = File.open('css/angular.css', 'r') {|f| f.read }
|
||||
|
||||
# finds all css rules that contain backround images and extracts the rule name(s), content type of
|
||||
# the image and base64 encoded image data
|
||||
r = /\n([^\{\n]+)\s*\{[^\}]*background-image:\s*url\("data:([^;]+);base64,([^"]+)"\);[^\}]*\}/
|
||||
|
||||
images = css.scan(r)
|
||||
|
||||
# create a js file with multipart header containing the extracted images. the entire file *must*
|
||||
# be CRLF (\r\n) delimited
|
||||
File.open(path_to('angular-ie-compat.js'), 'w') do |f|
|
||||
f.write("/*\r\n" +
|
||||
"Content-Type: multipart/related; boundary=\"_\"\r\n" +
|
||||
"\r\n")
|
||||
|
||||
images.each_index do |idx|
|
||||
f.write("--_\r\n" +
|
||||
"Content-Location:img#{idx}\r\n" +
|
||||
"Content-Transfer-Encoding:base64\r\n" +
|
||||
"\r\n" +
|
||||
images[idx][2] + "\r\n")
|
||||
end
|
||||
|
||||
f.write("--_--\r\n" +
|
||||
"*/\r\n")
|
||||
|
||||
# generate a css string containing *background-image rules for IE that point to the mime type
|
||||
# images in the header
|
||||
cssString = ''
|
||||
images.each_index do |idx|
|
||||
cssString += "#{images[idx][0]}{*background-image:url(\"mhtml:' + jsUri + '!img#{idx}\")}"
|
||||
end
|
||||
|
||||
# generate a javascript closure that contains a function which will append the generated css
|
||||
# string as a stylesheet to the current html document
|
||||
jsString = "(function(){ \r\n" +
|
||||
" var jsUri = document.location.href.replace(/\\/[^\\\/]+(#.*)?$/, '/') + \r\n" +
|
||||
" document.getElementById('ng-ie-compat').src,\r\n" +
|
||||
" css = '#{cssString}',\r\n" +
|
||||
" s = document.createElement('style'); \r\n" +
|
||||
"\r\n" +
|
||||
" s.setAttribute('type', 'text/css'); \r\n" +
|
||||
"\r\n" +
|
||||
" if (s.styleSheet) { \r\n" +
|
||||
" s.styleSheet.cssText = css; \r\n" +
|
||||
" } else { \r\n" +
|
||||
" s.appendChild(document.createTextNode(css)); \r\n" +
|
||||
" } \r\n" +
|
||||
" document.getElementsByTagName('head')[0].appendChild(s); \r\n" +
|
||||
"})();\r\n"
|
||||
|
||||
f.write(jsString)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
desc 'Compile JavaScript'
|
||||
task :compile => [:init, :compile_scenario, :compile_jstd_scenario_adapter, :generate_ie_compat] do
|
||||
|
||||
deps = [
|
||||
'src/angular.prefix',
|
||||
ANGULAR,
|
||||
'src/angular.suffix',
|
||||
]
|
||||
|
||||
File.open(path_to('angular.js'), 'w') do |f|
|
||||
concat = 'cat ' + deps.flatten.join(' ')
|
||||
|
||||
content = %x{#{concat}}.
|
||||
gsub('"NG_VERSION_FULL"', NG_VERSION.full).
|
||||
gsub('"NG_VERSION_MAJOR"', NG_VERSION.major).
|
||||
gsub('"NG_VERSION_MINOR"', NG_VERSION.minor).
|
||||
gsub('"NG_VERSION_DOT"', NG_VERSION.dot).
|
||||
gsub('"NG_VERSION_CODENAME"', NG_VERSION.codename).
|
||||
gsub(/^\s*['"]use strict['"];?\s*$/, ''). # remove all file-specific strict mode flags
|
||||
gsub(/'USE STRICT'/, "'use strict'") # rename the placeholder in angular.prefix
|
||||
|
||||
f.write(content)
|
||||
f.write(gen_css('css/angular.css', true))
|
||||
end
|
||||
|
||||
%x(java -jar lib/closure-compiler/compiler.jar \
|
||||
--compilation_level SIMPLE_OPTIMIZATIONS \
|
||||
--language_in ECMASCRIPT5_STRICT \
|
||||
--js #{path_to('angular.js')} \
|
||||
--js_output_file #{path_to('angular.min.js')})
|
||||
end
|
||||
|
||||
|
||||
desc 'Generate docs'
|
||||
task :docs => [:init] do
|
||||
`node docs/src/gen-docs.js`
|
||||
File.open(path_to('docs/.htaccess'), File::RDWR) do |f|
|
||||
text = f.read
|
||||
f.truncate 0
|
||||
f.rewind
|
||||
f.write text.sub('"NG_VERSION_FULL"', NG_VERSION.full)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
desc 'Create angular distribution'
|
||||
task :package => [:clean, :compile, :docs] do
|
||||
tarball = "angular-#{NG_VERSION.full}.tgz"
|
||||
|
||||
pkg_dir = path_to("pkg/angular-#{NG_VERSION.full}")
|
||||
FileUtils.rm_r(path_to('pkg'), :force => true)
|
||||
FileUtils.mkdir_p(pkg_dir)
|
||||
|
||||
['src/angular-mocks.js',
|
||||
path_to('angular.js'),
|
||||
path_to('angular.min.js'),
|
||||
path_to('angular-ie-compat.js'),
|
||||
path_to('angular-scenario.js'),
|
||||
path_to('jstd-scenario-adapter.js'),
|
||||
path_to('jstd-scenario-adapter-config.js'),
|
||||
].each do |src|
|
||||
dest = src.gsub(/^[^\/]+\//, '').gsub(/((\.min)?\.js)$/, "-#{NG_VERSION.full}\\1")
|
||||
FileUtils.cp(src, pkg_dir + '/' + dest)
|
||||
end
|
||||
|
||||
FileUtils.cp_r path_to('docs'), "#{pkg_dir}/docs-#{NG_VERSION.full}"
|
||||
|
||||
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/index.html", File::RDWR) do |f|
|
||||
text = f.read
|
||||
f.truncate 0
|
||||
f.rewind
|
||||
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js")
|
||||
end
|
||||
|
||||
|
||||
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/index-jq.html", File::RDWR) do |f|
|
||||
text = f.read
|
||||
f.truncate 0
|
||||
f.rewind
|
||||
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js")
|
||||
end
|
||||
|
||||
|
||||
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/index-nocache.html", File::RDWR) do |f|
|
||||
text = f.read
|
||||
f.truncate 0
|
||||
f.rewind
|
||||
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js")
|
||||
end
|
||||
|
||||
|
||||
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/index-jq-nocache.html", File::RDWR) do |f|
|
||||
text = f.read
|
||||
f.truncate 0
|
||||
f.rewind
|
||||
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js")
|
||||
end
|
||||
|
||||
|
||||
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/docs-scenario.html", File::RDWR) do |f|
|
||||
text = f.read
|
||||
f.truncate 0
|
||||
f.rewind
|
||||
f.write text.sub('angular-scenario.js', "angular-scenario-#{NG_VERSION.full}.js")
|
||||
end
|
||||
|
||||
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/appcache.manifest", File::RDWR) do |f|
|
||||
text = f.read
|
||||
f.truncate 0
|
||||
f.rewind
|
||||
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js")
|
||||
end
|
||||
|
||||
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/appcache-offline.manifest", File::RDWR) do |f|
|
||||
text = f.read
|
||||
f.truncate 0
|
||||
f.rewind
|
||||
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js")
|
||||
end
|
||||
|
||||
|
||||
%x(tar -czf #{path_to(tarball)} -C #{path_to('pkg')} .)
|
||||
|
||||
FileUtils.cp path_to(tarball), pkg_dir
|
||||
FileUtils.mv pkg_dir, path_to(['pkg', NG_VERSION.full])
|
||||
|
||||
puts "Package created: #{path_to(tarball)}"
|
||||
end
|
||||
|
||||
|
||||
namespace :server do
|
||||
|
||||
desc 'Run JsTestDriver Server'
|
||||
task :start do
|
||||
sh %x(java -jar lib/jstestdriver/JsTestDriver.jar --browser open --port 9876)
|
||||
end
|
||||
|
||||
desc 'Run JavaScript tests against the server'
|
||||
task :test do
|
||||
sh %(java -jar lib/jstestdriver/JsTestDriver.jar --tests all)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
desc 'Run JavaScript tests'
|
||||
task :test do
|
||||
sh %(java -jar lib/jstestdriver/JsTestDriver.jar --tests all --browser open --port 9876)
|
||||
end
|
||||
|
||||
|
||||
desc 'Lint'
|
||||
task :lint do
|
||||
out = %x(lib/jsl/jsl -conf lib/jsl/jsl.default.conf)
|
||||
print out
|
||||
end
|
||||
|
||||
|
||||
desc 'push_angularjs'
|
||||
task :push_angularjs => :compile do
|
||||
sh %(cat angularjs.ftp | ftp -N angularjs.netrc angularjs.org)
|
||||
end
|
||||
|
||||
|
||||
|
||||
###################
|
||||
# utility methods #
|
||||
###################
|
||||
|
||||
|
||||
##
|
||||
# generates css snippet from a given files and optionally applies simple minification rules
|
||||
#
|
||||
def gen_css(cssFile, minify = false)
|
||||
css = ''
|
||||
File.open(cssFile, 'r') do |f|
|
||||
css = f.read
|
||||
end
|
||||
|
||||
if minify
|
||||
css.gsub! /\n/, ''
|
||||
css.gsub! /\/\*.*?\*\//, ''
|
||||
css.gsub! /:\s+/, ':'
|
||||
css.gsub! /\s*\{\s*/, '{'
|
||||
css.gsub! /\s*\}\s*/, '}'
|
||||
css.gsub! /\s*\,\s*/, ','
|
||||
css.gsub! /\s*\;\s*/, ';'
|
||||
end
|
||||
|
||||
#escape for js
|
||||
css.gsub! /\\/, "\\\\\\"
|
||||
css.gsub! /'/, "\\\\'"
|
||||
css.gsub! /\n/, "\\n"
|
||||
|
||||
return %Q{angular.element(document).find('head').append('<style type="text/css">#{css}</style>');}
|
||||
end
|
||||
|
||||
|
||||
##
|
||||
# returns path to the file in the build directory
|
||||
#
|
||||
def path_to(filename)
|
||||
return File.join(BUILD_DIR, *filename)
|
||||
end
|
||||
Vendored
-221
@@ -1,221 +0,0 @@
|
||||
angularFiles = {
|
||||
'angularSrc': [
|
||||
'src/minErr.js',
|
||||
'src/Angular.js',
|
||||
'src/loader.js',
|
||||
'src/AngularPublic.js',
|
||||
'src/jqLite.js',
|
||||
'src/apis.js',
|
||||
|
||||
'src/auto/injector.js',
|
||||
|
||||
'src/ng/anchorScroll.js',
|
||||
'src/ng/animate.js',
|
||||
'src/ng/browser.js',
|
||||
'src/ng/cacheFactory.js',
|
||||
'src/ng/compile.js',
|
||||
'src/ng/controller.js',
|
||||
'src/ng/document.js',
|
||||
'src/ng/exceptionHandler.js',
|
||||
'src/ng/http.js',
|
||||
'src/ng/httpBackend.js',
|
||||
'src/ng/interpolate.js',
|
||||
'src/ng/interval.js',
|
||||
'src/ng/locale.js',
|
||||
'src/ng/location.js',
|
||||
'src/ng/log.js',
|
||||
'src/ng/parse.js',
|
||||
'src/ng/q.js',
|
||||
'src/ng/rootScope.js',
|
||||
'src/ng/sce.js',
|
||||
'src/ng/sniffer.js',
|
||||
'src/ng/timeout.js',
|
||||
'src/ng/urlUtils.js',
|
||||
'src/ng/window.js',
|
||||
|
||||
'src/ng/filter.js',
|
||||
'src/ng/filter/filter.js',
|
||||
'src/ng/filter/filters.js',
|
||||
'src/ng/filter/limitTo.js',
|
||||
'src/ng/filter/orderBy.js',
|
||||
|
||||
'src/ng/directive/directives.js',
|
||||
'src/ng/directive/a.js',
|
||||
'src/ng/directive/booleanAttrs.js',
|
||||
'src/ng/directive/form.js',
|
||||
'src/ng/directive/input.js',
|
||||
'src/ng/directive/ngBind.js',
|
||||
'src/ng/directive/ngClass.js',
|
||||
'src/ng/directive/ngCloak.js',
|
||||
'src/ng/directive/ngController.js',
|
||||
'src/ng/directive/ngCsp.js',
|
||||
'src/ng/directive/ngEventDirs.js',
|
||||
'src/ng/directive/ngIf.js',
|
||||
'src/ng/directive/ngInclude.js',
|
||||
'src/ng/directive/ngInit.js',
|
||||
'src/ng/directive/ngNonBindable.js',
|
||||
'src/ng/directive/ngPluralize.js',
|
||||
'src/ng/directive/ngRepeat.js',
|
||||
'src/ng/directive/ngShowHide.js',
|
||||
'src/ng/directive/ngStyle.js',
|
||||
'src/ng/directive/ngSwitch.js',
|
||||
'src/ng/directive/ngTransclude.js',
|
||||
'src/ng/directive/script.js',
|
||||
'src/ng/directive/select.js',
|
||||
'src/ng/directive/style.js'
|
||||
],
|
||||
|
||||
'angularLoader': [
|
||||
'src/minErr.js',
|
||||
'src/loader.js'
|
||||
],
|
||||
|
||||
'angularModules': {
|
||||
'ngAnimate': [
|
||||
'src/ngAnimate/animate.js'
|
||||
],
|
||||
'ngCookies': [
|
||||
'src/ngCookies/cookies.js'
|
||||
],
|
||||
'ngResource': [
|
||||
'src/ngResource/resource.js'
|
||||
],
|
||||
'ngRoute': [
|
||||
'src/ngRoute/route.js',
|
||||
'src/ngRoute/routeParams.js',
|
||||
'src/ngRoute/directive/ngView.js'
|
||||
],
|
||||
'ngSanitize': [
|
||||
'src/ngSanitize/sanitize.js',
|
||||
'src/ngSanitize/filter/linky.js'
|
||||
],
|
||||
'ngMock': [
|
||||
'src/ngMock/angular-mocks.js'
|
||||
],
|
||||
'ngTouch': [
|
||||
'src/ngTouch/touch.js',
|
||||
'src/ngTouch/swipe.js',
|
||||
'src/ngTouch/directive/ngClick.js',
|
||||
'src/ngTouch/directive/ngSwipe.js'
|
||||
],
|
||||
},
|
||||
|
||||
'angularScenario': [
|
||||
'src/ngScenario/Scenario.js',
|
||||
'src/ngScenario/browserTrigger.js',
|
||||
'src/ngScenario/Application.js',
|
||||
'src/ngScenario/Describe.js',
|
||||
'src/ngScenario/Future.js',
|
||||
'src/ngScenario/ObjectModel.js',
|
||||
'src/ngScenario/Runner.js',
|
||||
'src/ngScenario/SpecRunner.js',
|
||||
'src/ngScenario/dsl.js',
|
||||
'src/ngScenario/matchers.js',
|
||||
'src/ngScenario/output/Html.js',
|
||||
'src/ngScenario/output/Json.js',
|
||||
'src/ngScenario/output/Xml.js',
|
||||
'src/ngScenario/output/Object.js'
|
||||
],
|
||||
|
||||
'angularTest': [
|
||||
'test/helpers/*.js',
|
||||
'test/ngScenario/*.js',
|
||||
'test/ngScenario/output/*.js',
|
||||
'test/*.js',
|
||||
'test/auto/*.js',
|
||||
'test/ng/**/*.js',
|
||||
'test/ngAnimate/*.js',
|
||||
'test/ngCookies/*.js',
|
||||
'test/ngResource/*.js',
|
||||
'test/ngRoute/**/*.js',
|
||||
'test/ngSanitize/**/*.js',
|
||||
'test/ngMock/*.js',
|
||||
'test/ngTouch/**/*.js'
|
||||
],
|
||||
|
||||
'karma': [
|
||||
'bower_components/jquery/jquery.js',
|
||||
'test/jquery_remove.js',
|
||||
'@angularSrc',
|
||||
'src/publishExternalApis.js',
|
||||
'@angularSrcModules',
|
||||
'@angularScenario',
|
||||
'@angularTest',
|
||||
'example/personalLog/*.js',
|
||||
'example/personalLog/test/*.js'
|
||||
],
|
||||
|
||||
'karmaExclude': [
|
||||
'test/jquery_alias.js',
|
||||
'src/angular-bootstrap.js',
|
||||
'src/ngScenario/angular-bootstrap.js'
|
||||
],
|
||||
|
||||
'karmaScenario': [
|
||||
'build/angular-scenario.js',
|
||||
'build/docs/docs-scenario.js'
|
||||
],
|
||||
|
||||
"karmaModules": [
|
||||
'build/angular.js',
|
||||
'@angularSrcModules',
|
||||
'src/ngScenario/browserTrigger.js',
|
||||
'test/helpers/*.js',
|
||||
'test/ngMock/*.js',
|
||||
'test/ngCookies/*.js',
|
||||
'test/ngRoute/**/*.js',
|
||||
'test/ngResource/*.js',
|
||||
'test/ngSanitize/**/*.js',
|
||||
'test/ngTouch/**/*.js'
|
||||
],
|
||||
|
||||
'karmaJquery': [
|
||||
'bower_components/jquery/jquery.js',
|
||||
'test/jquery_alias.js',
|
||||
'@angularSrc',
|
||||
'src/publishExternalApis.js',
|
||||
'@angularSrcModules',
|
||||
'@angularScenario',
|
||||
'@angularTest',
|
||||
'example/personalLog/*.js',
|
||||
|
||||
'example/personalLog/test/*.js'
|
||||
],
|
||||
|
||||
'karmaJqueryExclude': [
|
||||
'src/angular-bootstrap.js',
|
||||
'src/ngScenario/angular-bootstrap.js',
|
||||
'test/jquery_remove.js'
|
||||
]
|
||||
};
|
||||
|
||||
angularFiles['angularSrcModules'] = [].concat(
|
||||
angularFiles['angularModules']['ngAnimate'],
|
||||
angularFiles['angularModules']['ngCookies'],
|
||||
angularFiles['angularModules']['ngResource'],
|
||||
angularFiles['angularModules']['ngRoute'],
|
||||
angularFiles['angularModules']['ngSanitize'],
|
||||
angularFiles['angularModules']['ngMock'],
|
||||
angularFiles['angularModules']['ngTouch']
|
||||
);
|
||||
|
||||
if (exports) {
|
||||
exports.files = angularFiles;
|
||||
exports.mergeFilesFor = function() {
|
||||
var files = [];
|
||||
|
||||
Array.prototype.slice.call(arguments, 0).forEach(function(filegroup) {
|
||||
angularFiles[filegroup].forEach(function(file) {
|
||||
// replace @ref
|
||||
var match = file.match(/^\@(.*)/);
|
||||
if (match) {
|
||||
files = files.concat(angularFiles[match[1]]);
|
||||
} else {
|
||||
files.push(file);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return files;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
bin
|
||||
cd angularjs.org/ng
|
||||
put angular-debug.js js/angular-debug.js
|
||||
put angular-minified.js js/angular-minified.js
|
||||
put angular-scenario.js js/angular-scenario.js
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"name": "AngularJS",
|
||||
"devDependencies": {
|
||||
"jquery": "1.10.2",
|
||||
"lunr.js": "0.4.0",
|
||||
"google-code-prettify": "1.0.0",
|
||||
"components-font-awesome": "3.1.0",
|
||||
"bootstrap": "https://raw.github.com/twbs/bootstrap/v2.0.2/docs/assets/bootstrap.zip",
|
||||
"closure-compiler": "https://closure-compiler.googlecode.com/files/compiler-20130603.zip",
|
||||
"ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.2.2/assets/ng-closure-runner.zip"
|
||||
}
|
||||
}
|
||||
-204
@@ -1,204 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// TODO(vojta): pre-commit hook for validating messages
|
||||
// TODO(vojta): report errors, currently Q silence everything which really sucks
|
||||
|
||||
var child = require('child_process');
|
||||
var fs = require('fs');
|
||||
var util = require('util');
|
||||
var q = require('qq');
|
||||
|
||||
var GIT_LOG_CMD = 'git log --grep="%s" -E --format=%s %s..HEAD';
|
||||
var GIT_TAG_CMD = 'git describe --tags --abbrev=0';
|
||||
|
||||
var HEADER_TPL = '<a name="%s"></a>\n# %s (%s)\n\n';
|
||||
var LINK_ISSUE = '[#%s](https://github.com/angular/angular.js/issues/%s)';
|
||||
var LINK_COMMIT = '[%s](https://github.com/angular/angular.js/commit/%s)';
|
||||
|
||||
var EMPTY_COMPONENT = '$$';
|
||||
|
||||
|
||||
var warn = function() {
|
||||
console.log('WARNING:', util.format.apply(null, arguments));
|
||||
};
|
||||
|
||||
|
||||
var parseRawCommit = function(raw) {
|
||||
if (!raw) return null;
|
||||
|
||||
var lines = raw.split('\n');
|
||||
var msg = {}, match;
|
||||
|
||||
msg.hash = lines.shift();
|
||||
msg.subject = lines.shift();
|
||||
msg.closes = [];
|
||||
msg.breaks = [];
|
||||
|
||||
lines.forEach(function(line) {
|
||||
match = line.match(/(?:Closes|Fixes)\s#(\d+)/);
|
||||
if (match) msg.closes.push(parseInt(match[1]));
|
||||
});
|
||||
|
||||
match = raw.match(/BREAKING CHANGE:([\s\S]*)/);
|
||||
if (match) {
|
||||
msg.breaking = match[1];
|
||||
}
|
||||
|
||||
|
||||
msg.body = lines.join('\n');
|
||||
match = msg.subject.match(/^(.*)\((.*)\)\:\s(.*)$/);
|
||||
|
||||
if (!match || !match[1] || !match[3]) {
|
||||
warn('Incorrect message: %s %s', msg.hash, msg.subject);
|
||||
return null;
|
||||
}
|
||||
|
||||
msg.type = match[1];
|
||||
msg.component = match[2];
|
||||
msg.subject = match[3];
|
||||
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
var linkToIssue = function(issue) {
|
||||
return util.format(LINK_ISSUE, issue, issue);
|
||||
};
|
||||
|
||||
|
||||
var linkToCommit = function(hash) {
|
||||
return util.format(LINK_COMMIT, hash.substr(0, 8), hash);
|
||||
};
|
||||
|
||||
|
||||
var currentDate = function() {
|
||||
var now = new Date();
|
||||
var pad = function(i) {
|
||||
return ('0' + i).substr(-2);
|
||||
};
|
||||
|
||||
return util.format('%d-%s-%s', now.getFullYear(), pad(now.getMonth() + 1), pad(now.getDate()));
|
||||
};
|
||||
|
||||
|
||||
var printSection = function(stream, title, section, printCommitLinks) {
|
||||
printCommitLinks = printCommitLinks === undefined ? true : printCommitLinks;
|
||||
var components = Object.getOwnPropertyNames(section).sort();
|
||||
|
||||
if (!components.length) return;
|
||||
|
||||
stream.write(util.format('\n## %s\n\n', title));
|
||||
|
||||
components.forEach(function(name) {
|
||||
var prefix = '-';
|
||||
var nested = section[name].length > 1;
|
||||
|
||||
if (name !== EMPTY_COMPONENT) {
|
||||
if (nested) {
|
||||
stream.write(util.format('- **%s:**\n', name));
|
||||
prefix = ' -';
|
||||
} else {
|
||||
prefix = util.format('- **%s:**', name);
|
||||
}
|
||||
}
|
||||
|
||||
section[name].forEach(function(commit) {
|
||||
if (printCommitLinks) {
|
||||
stream.write(util.format('%s %s\n (%s', prefix, commit.subject, linkToCommit(commit.hash)));
|
||||
if (commit.closes.length) {
|
||||
stream.write(',\n ' + commit.closes.map(linkToIssue).join(', '));
|
||||
}
|
||||
stream.write(')\n');
|
||||
} else {
|
||||
stream.write(util.format('%s %s', prefix, commit.subject));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
stream.write('\n');
|
||||
};
|
||||
|
||||
|
||||
var readGitLog = function(grep, from) {
|
||||
var deferred = q.defer();
|
||||
|
||||
// TODO(vojta): if it's slow, use spawn and stream it instead
|
||||
child.exec(util.format(GIT_LOG_CMD, grep, '%H%n%s%n%b%n==END==', from), function(code, stdout, stderr) {
|
||||
var commits = [];
|
||||
|
||||
stdout.split('\n==END==\n').forEach(function(rawCommit) {
|
||||
var commit = parseRawCommit(rawCommit);
|
||||
if (commit) commits.push(commit);
|
||||
});
|
||||
|
||||
deferred.resolve(commits);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
|
||||
var writeChangelog = function(stream, commits, version) {
|
||||
var sections = {
|
||||
fix: {},
|
||||
feat: {},
|
||||
breaks: {}
|
||||
};
|
||||
|
||||
sections.breaks[EMPTY_COMPONENT] = [];
|
||||
|
||||
commits.forEach(function(commit) {
|
||||
var section = sections[commit.type];
|
||||
var component = commit.component || EMPTY_COMPONENT;
|
||||
|
||||
if (section) {
|
||||
section[component] = section[component] || [];
|
||||
section[component].push(commit);
|
||||
}
|
||||
|
||||
if (commit.breaking) {
|
||||
sections.breaks[component] = sections.breaks[component] || [];
|
||||
sections.breaks[component].push({
|
||||
subject: util.format("due to %s,\n %s", linkToCommit(commit.hash), commit.breaking),
|
||||
hash: commit.hash,
|
||||
closes: []
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
stream.write(util.format(HEADER_TPL, version, version, currentDate()));
|
||||
printSection(stream, 'Bug Fixes', sections.fix);
|
||||
printSection(stream, 'Features', sections.feat);
|
||||
printSection(stream, 'Breaking Changes', sections.breaks, false);
|
||||
}
|
||||
|
||||
|
||||
var getPreviousTag = function() {
|
||||
var deferred = q.defer();
|
||||
child.exec(GIT_TAG_CMD, function(code, stdout, stderr) {
|
||||
if (code) deferred.reject('Cannot get the previous tag.');
|
||||
else deferred.resolve(stdout.replace('\n', ''));
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
|
||||
var generate = function(version, file) {
|
||||
getPreviousTag().then(function(tag) {
|
||||
console.log('Reading git log since', tag);
|
||||
readGitLog('^fix|^feat|BREAKING', tag).then(function(commits) {
|
||||
console.log('Parsed', commits.length, 'commits');
|
||||
console.log('Generating changelog to', file || 'stdout', '(', version, ')');
|
||||
writeChangelog(file ? fs.createWriteStream(file) : process.stdout, commits, version);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// publish for testing
|
||||
exports.parseRawCommit = parseRawCommit;
|
||||
|
||||
// hacky start if not run by jasmine :-D
|
||||
if (process.argv.join('').indexOf('jasmine-node') === -1) {
|
||||
generate(process.argv[2], process.argv[3]);
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
describe('changelog.js', function() {
|
||||
var ch = require('./changelog');
|
||||
|
||||
describe('parseRawCommit', function() {
|
||||
it('should parse raw commit', function() {
|
||||
var msg = ch.parseRawCommit(
|
||||
'9b1aff905b638aa274a5fc8f88662df446d374bd\n' +
|
||||
'feat(scope): broadcast $destroy event on scope destruction\n' +
|
||||
'perf testing shows that in chrome this change adds 5-15% overhead\n' +
|
||||
'when destroying 10k nested scopes where each scope has a $destroy listener\n');
|
||||
|
||||
expect(msg.type).toBe('feat');
|
||||
expect(msg.hash).toBe('9b1aff905b638aa274a5fc8f88662df446d374bd');
|
||||
expect(msg.subject).toBe('broadcast $destroy event on scope destruction');
|
||||
expect(msg.body).toBe('perf testing shows that in chrome this change adds 5-15% overhead\n' +
|
||||
'when destroying 10k nested scopes where each scope has a $destroy listener\n')
|
||||
expect(msg.component).toBe('scope');
|
||||
});
|
||||
|
||||
|
||||
it('should parse closed issues', function() {
|
||||
var msg = ch.parseRawCommit(
|
||||
'13f31602f396bc269076ab4d389cfd8ca94b20ba\n' +
|
||||
'feat(ng-list): Allow custom separator\n' +
|
||||
'bla bla bla\n\n' +
|
||||
'Closes #123\nCloses #25\n');
|
||||
|
||||
expect(msg.closes).toEqual([123, 25]);
|
||||
});
|
||||
|
||||
|
||||
it('should parse breaking changes', function() {
|
||||
var msg = ch.parseRawCommit(
|
||||
'13f31602f396bc269076ab4d389cfd8ca94b20ba\n' +
|
||||
'feat(ng-list): Allow custom separator\n' +
|
||||
'bla bla bla\n\n' +
|
||||
'BREAKING CHANGE: first breaking change\nsomething else\n' +
|
||||
'another line with more info\n');
|
||||
|
||||
expect(msg.breaking).toEqual(' first breaking change\nsomething else\nanother line with more info\n');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,80 +0,0 @@
|
||||
<a name="v1.0.0rc3"></a>
|
||||
# v1.0.0rc3 (2012-03-27)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$compile:**
|
||||
- create new (isolate) scopes for directives on root elements ([5390fb37](https://github.com/angular/angular.js/commit/5390fb37d2c01937922613fc57df4986af521787), closes [#817](https://github.com/angular/angular.js/issues/817))
|
||||
- don't touch static element attributes ([9cb2195e](https://github.com/angular/angular.js/commit/9cb2195e61a78e99020ec19d687a221ca88b5900))
|
||||
- Merge interpolated css class when replacing an element ([f49eaf8b](https://github.com/angular/angular.js/commit/f49eaf8bf2df5f4e0e82d6c89e849a4f82c8d414))
|
||||
- **$http:**
|
||||
- don't send Content-Type header when no data ([1a5bebd9](https://github.com/angular/angular.js/commit/1a5bebd927ecd22f9c34617642fdf58fe3f62efb), closes [#749](https://github.com/angular/angular.js/issues/749))
|
||||
- **$log:**
|
||||
- avoid console.log.apply calls in IE ([15213ec2](https://github.com/angular/angular.js/commit/15213ec212769837cb2b7e781ffc5bfd598d27ca), closes [#805](https://github.com/angular/angular.js/issues/805))
|
||||
- **$resource:**
|
||||
- support escaping of ':' in resource url ([6d6f8753](https://github.com/angular/angular.js/commit/6d6f875345e01f2c6c63ef95164f6f39e923da15))
|
||||
- **compiler:**
|
||||
- allow transclusion of root elements ([9918b748](https://github.com/angular/angular.js/commit/9918b748be01266eb10db39d51b4d3098d54ab66))
|
||||
- **e2e runner:**
|
||||
- fix typo that caused errors on IE8 ([ee5a5352](https://github.com/angular/angular.js/commit/ee5a5352fd4b94cedee6ef20d4bf2d43ce77e00b), closes [#806](https://github.com/angular/angular.js/issues/806))
|
||||
- **forEach:**
|
||||
- should ignore prototypically inherited properties ([8d7e6948](https://github.com/angular/angular.js/commit/8d7e6948496ff26ef1da8854ba02fcb8eebfed61), closes [#813](https://github.com/angular/angular.js/issues/813))
|
||||
- **forms:**
|
||||
- Remove double registering of form ([1faafa31](https://github.com/angular/angular.js/commit/1faafa31582c4e9413f48dc7d12f5b681f9fe9fd))
|
||||
- Set ng-valid/ng-invalid correctly ([08bfea18](https://github.com/angular/angular.js/commit/08bfea183a850b29da270eac47f80b598cbe600f))
|
||||
- **init:**
|
||||
- use jQuery#ready for init if available ([cb2ad9ab](https://github.com/angular/angular.js/commit/cb2ad9abf24e6f855cc749efe3155bd7987ece9d), closes [#818](https://github.com/angular/angular.js/issues/818))
|
||||
- **json:**
|
||||
- added support for iso8061 timezone ([5ac14f63](https://github.com/angular/angular.js/commit/5ac14f633a69f49973b5512780c6ec7752405967))
|
||||
- **matchers.toHaveClass:**
|
||||
- Correct reference to angular.mock.dump ([f701ce08](https://github.com/angular/angular.js/commit/f701ce08f9d63be05fc3b92f57ad473e1e749b2d))
|
||||
- **ng-switch:**
|
||||
- properly destroy child scopes ([2315d9b3](https://github.com/angular/angular.js/commit/2315d9b3610994b36c44e4a97fb1427d59471ce8))
|
||||
- **ngDocSpec:**
|
||||
- fix broken tests ([53b6f522](https://github.com/angular/angular.js/commit/53b6f522a56eea314cbd084816e08f24b2c7879f))
|
||||
- **ngForm:**
|
||||
- alias name||ngForm ([823adb23](https://github.com/angular/angular.js/commit/823adb231995e917bc060bfa49453e2a96bac2b6))
|
||||
- **ngRepeat:**
|
||||
- correct variable reference in error message ([935c1018](https://github.com/angular/angular.js/commit/935c1018da05dbf3124b2dd33619c4a3c82d7a2a))
|
||||
- **ngView:**
|
||||
- controller not published ([21e74c2d](https://github.com/angular/angular.js/commit/21e74c2d2e8e985b23711785287feb59965cbd90))
|
||||
- **q:**
|
||||
- resolve all of nothing to nothing ([ac75079e](https://github.com/angular/angular.js/commit/ac75079e2113949d5d64adbcf23d56f3cf295d41))
|
||||
- **select:**
|
||||
- multiselect failes to update view on selection insert ([6ecac8e7](https://github.com/angular/angular.js/commit/6ecac8e71a84792a434d21db2c245b3648c55f18))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **$compile:**
|
||||
- do not interpolate boolean attributes, rather evaluate them ([a08cbc02](https://github.com/angular/angular.js/commit/a08cbc02e78e789a66e9af771c410e8ad1646e25))
|
||||
- **$controller:**
|
||||
- support controller registration via $controllerProvider ([d54dfecb](https://github.com/angular/angular.js/commit/d54dfecb00fba41455536c5ddd55310592fdaf84))
|
||||
- **$route:**
|
||||
- when matching consider trailing slash as optional ([a4fe51da](https://github.com/angular/angular.js/commit/a4fe51da3ba0dc297ecd389e230d6664f250c9a6), closes [#784](https://github.com/angular/angular.js/issues/784))
|
||||
- **assertArgFn:**
|
||||
- should support array annotated fns ([4b8d9260](https://github.com/angular/angular.js/commit/4b8d926062eb4d4483555bdbdec4656f585ab40b))
|
||||
- **http:**
|
||||
- added params parameter ([73c85930](https://github.com/angular/angular.js/commit/73c8593077155a9f2e8ef42efd4c497eba0bef4f))
|
||||
- **injector:**
|
||||
- infer _foo_ as foo ([f13dd339](https://github.com/angular/angular.js/commit/f13dd3393dfb7a33565c9360342c193bc0bddcb6))
|
||||
- **input.radio:**
|
||||
- Allow value attribute to be interpolated ([ade6c452](https://github.com/angular/angular.js/commit/ade6c452753145c84884d17027a7865bf4b34b0c))
|
||||
- **jqLite:**
|
||||
- make injector() and scope() work with the document object ([5fdab52d](https://github.com/angular/angular.js/commit/5fdab52dd7c269f99839f4fa6b5854d9548269fa))
|
||||
- add .controller() method ([6c5a05ad](https://github.com/angular/angular.js/commit/6c5a05ad49a1e083570c3dfe331403398f899dbe))
|
||||
- **ngValue:**
|
||||
- allow radio inputs to have non string values ([09e175f0](https://github.com/angular/angular.js/commit/09e175f02cca0f4a295fd0c9b980cd8f432e722b), closes [#816](https://github.com/angular/angular.js/issues/816))
|
||||
- **scope:**
|
||||
- broadcast $destroy event on scope destruction ([9b1aff90](https://github.com/angular/angular.js/commit/9b1aff905b638aa274a5fc8f88662df446d374bd))
|
||||
- **scope.$eval:**
|
||||
- Allow passing locals to the expression ([192ff61f](https://github.com/angular/angular.js/commit/192ff61f5d61899e667c6dbce4d3e6e399429d8b))
|
||||
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- boolean attrs are evaluated rather than interpolated ([a08cbc02](https://github.com/angular/angular.js/commit/a08cbc02e78e789a66e9af771c410e8ad1646e25))
|
||||
- ng-bind-attr directive removed ([55027132](https://github.com/angular/angular.js/commit/55027132f3d57e5dcf94683e6e6bd7b0aae0087d))
|
||||
- any app that depends on this service and its fallback to Modernizr, please ([aaedefb9](https://github.com/angular/angular.js/commit/aaedefb92e6bec6626e173e5155072c91471596a))
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
grunt minify
|
||||
gzip -c < build/angular.min.js > build/angular.min.js.gzip
|
||||
ls -l build/angular.min.*
|
||||
@@ -1,17 +0,0 @@
|
||||
This file contains externs for use with the Closure compiler (aka JSCompiler).
|
||||
Passing these files to the --externs parameter of a compiler pass allows using
|
||||
type annotations for AngularJS objects. For example, Angular's $scope objects
|
||||
can be annotated as:
|
||||
```js
|
||||
/** @type {angular.Scope} */
|
||||
var scope = $scope;
|
||||
```
|
||||
|
||||
This allows JSCompiler to type check accesses to scope, give warnings about
|
||||
missing methods or incorrect arguments, and also prevents renaming of property
|
||||
accesses with advanced compilation.
|
||||
|
||||
The externs are incomplete and maintained on an as-needed basis, but strive to
|
||||
be correct. Externs for individual modules should be added in separate files.
|
||||
|
||||
See https://developers.google.com/closure/compiler/
|
||||
Vendored
-1912
File diff suppressed because it is too large
Load Diff
@@ -1,163 +0,0 @@
|
||||
#!/usr/local/bin/node
|
||||
|
||||
var util = require('util');
|
||||
var cp = require('child_process');
|
||||
|
||||
var Q = require('q');
|
||||
var _ = require('lodash');
|
||||
var semver = require('semver');
|
||||
|
||||
var exec = function (cmd) {
|
||||
return function () {
|
||||
var args = Array.prototype.slice.call(arguments, 0);
|
||||
args.unshift(cmd);
|
||||
var fullCmd = util.format.apply(util, args);
|
||||
return Q.nfcall(cp.exec, fullCmd).then(function (out) {
|
||||
return out[0].split('\n');
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var andThen = function (fn, after) {
|
||||
return function () {
|
||||
return fn.apply(this, arguments).then(after);
|
||||
};
|
||||
};
|
||||
|
||||
var oneArg = function (fn) {
|
||||
return function (arg) {
|
||||
return fn(arg);
|
||||
};
|
||||
};
|
||||
|
||||
var oneLine = function (lines) {
|
||||
return lines[0].trim();
|
||||
};
|
||||
|
||||
var noArgs = function (fn) {
|
||||
return function () {
|
||||
return fn();
|
||||
};
|
||||
};
|
||||
|
||||
var identity = function (i) { return i; };
|
||||
|
||||
// like Q.all, but runs the comands in series
|
||||
// useful for ensuring env state (like which branch is checked out)
|
||||
var allInSeries = function (fn) {
|
||||
return function (args) {
|
||||
var results = [];
|
||||
var def;
|
||||
while (args.length > 0) {
|
||||
(function (arg) {
|
||||
if (def) {
|
||||
def = def.then(function () {
|
||||
return fn(arg);
|
||||
});
|
||||
} else {
|
||||
def = fn(arg);
|
||||
}
|
||||
def = def.then(function (res) {
|
||||
results.push(res);
|
||||
});
|
||||
}(args.pop()));
|
||||
}
|
||||
return def.then(function () {
|
||||
return results;
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var compareBranches = function (left, right) {
|
||||
console.log('# These commits are in ' + left.name + ' but not in ' + right.name + '\n');
|
||||
console.log(_(left.log).
|
||||
difference(right.log).
|
||||
map(function (line) {
|
||||
return left.full[left.log.indexOf(line)]; // lol O(n^2)
|
||||
}).
|
||||
value().
|
||||
join('\n'));
|
||||
};
|
||||
|
||||
var checkout = oneArg(exec('git checkout %s'));
|
||||
|
||||
var getCurrentBranch = andThen(noArgs(exec('git rev-parse --abbrev-ref HEAD')), oneLine);
|
||||
var getTags = noArgs(exec('git tag'));
|
||||
var getShaOfTag = oneArg(exec('git rev-list %s | head -n 1'));
|
||||
var getTheLog = oneArg(exec('git log --pretty=oneline %s..HEAD | cat'));
|
||||
|
||||
// remember this so we can restore state
|
||||
var currentBranch;
|
||||
|
||||
getCurrentBranch().
|
||||
then(function (branch) {
|
||||
currentBranch = branch;
|
||||
}).
|
||||
then(getTags).
|
||||
then(function (tags) {
|
||||
return tags.
|
||||
filter(semver.valid).
|
||||
map(semver.clean).
|
||||
sort(semver.rcompare);
|
||||
}).
|
||||
then(function (tags) {
|
||||
var major = tags[0].split('.')[0] + '.x';
|
||||
return tags.
|
||||
filter(function (ver) {
|
||||
return semver.satisfies(ver, major);
|
||||
});
|
||||
}).
|
||||
then(function (tags) {
|
||||
return _(tags).
|
||||
groupBy(function (tag) {
|
||||
return tag.split('.')[1];
|
||||
}).
|
||||
map(function (group) {
|
||||
return _.first(group);
|
||||
}).
|
||||
map(function (tag) {
|
||||
return 'v' + tag;
|
||||
}).
|
||||
value();
|
||||
}).
|
||||
then(function (tags) {
|
||||
return [
|
||||
{ name: 'v1.0.x', tag: tags[0] },
|
||||
{ name: 'master', tag: tags[1] }
|
||||
];
|
||||
}).
|
||||
then(allInSeries(function (branch) {
|
||||
return checkout(branch.name).
|
||||
then(function () {
|
||||
return getTheLog(branch.tag);
|
||||
}).
|
||||
then(function (log) {
|
||||
return log.
|
||||
filter(identity);
|
||||
}).
|
||||
then(function (log) {
|
||||
branch.full = log.map(function (line) {
|
||||
line = line.split(' ');
|
||||
var sha = line.shift();
|
||||
var msg = line.join(' ');
|
||||
return sha + (msg.toLowerCase().indexOf('fix') === -1 ? ' ' : ' * ') + msg;
|
||||
});
|
||||
branch.log = log.map(function (line) {
|
||||
return line.substr(41)
|
||||
});
|
||||
return branch;
|
||||
});
|
||||
})).
|
||||
then(function (pairs) {
|
||||
compareBranches(pairs[0], pairs[1]);
|
||||
console.log('\n');
|
||||
compareBranches(pairs[1], pairs[0]);
|
||||
return pairs;
|
||||
}).
|
||||
then(function () {
|
||||
return checkout(currentBranch);
|
||||
}).
|
||||
catch(function (e) {
|
||||
console.log(e.stack);
|
||||
});
|
||||
|
||||
+81
-16
@@ -1,22 +1,87 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],
|
||||
.ng-cloak, .x-ng-cloak,
|
||||
.ng-hide {
|
||||
display: none !important;
|
||||
.ng-format-negative {
|
||||
color: red;
|
||||
}
|
||||
|
||||
ng\:form {
|
||||
display: block;
|
||||
.ng-exception {
|
||||
border: 2px solid #FF0000;
|
||||
font-family: "Courier New", Courier, monospace;
|
||||
font-size: smaller;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
/* The styles below ensure that the CSS transition will ALWAYS
|
||||
* animate and close. A nasty bug occurs with CSS transitions where
|
||||
* when the active class isn't set, or if the active class doesn't
|
||||
* contain any styles to transition to, then, if ngAnimate is used,
|
||||
* it will appear as if the webpage is broken due to the forever hanging
|
||||
* animations. The border-spacing (!ie) and zoom (ie) CSS properties are
|
||||
* used below since they trigger a transition without making the browser
|
||||
* animate anything and they're both highly underused CSS properties */
|
||||
.ng-animate-start { border-spacing:1px 1px; -ms-zoom:1.0001; }
|
||||
.ng-animate-active { border-spacing:0px 0px; -ms-zoom:1; }
|
||||
.ng-validation-error {
|
||||
border: 2px solid #FF0000;
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
* TIP
|
||||
*****************/
|
||||
#ng-callout {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
vertical-align: baseline;
|
||||
background: transparent;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#ng-callout .ng-arrow-left{
|
||||
background-image: url("data:image/gif;base64,R0lGODlhCwAXAKIAAMzMzO/v7/f39////////wAAAAAAAAAAACH5BAUUAAQALAAAAAALABcAAAMrSLoc/AG8FeUUIN+sGebWAnbKSJodqqlsOxJtqYooU9vvk+vcJIcTkg+QAAA7");
|
||||
background-repeat: no-repeat;
|
||||
background-position: left top;
|
||||
position: absolute;
|
||||
z-index:101;
|
||||
left:-12px;
|
||||
height:23px;
|
||||
width:10px;
|
||||
top:-3px;
|
||||
}
|
||||
|
||||
#ng-callout .ng-arrow-right{
|
||||
background-image: url("data:image/gif;base64,R0lGODlhCwAXAKIAAMzMzO/v7/f39////////wAAAAAAAAAAACH5BAUUAAQALAAAAAALABcAAAMrCLTcoM29yN6k9socs91e5X3EyJloipYrO4ohTMqA0Fn2XVNswJe+H+SXAAA7");
|
||||
background-repeat: no-repeat;
|
||||
background-position: left top;
|
||||
position: absolute;
|
||||
z-index:101;
|
||||
height:23px;
|
||||
width:11px;
|
||||
top:-2px;
|
||||
}
|
||||
|
||||
#ng-callout {
|
||||
position: absolute;
|
||||
z-index:100;
|
||||
border: 2px solid #CCCCCC;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
#ng-callout .ng-content{
|
||||
padding:10px 10px 10px 10px;
|
||||
color:#333333;
|
||||
}
|
||||
|
||||
#ng-callout .ng-title{
|
||||
background-color: #CCCCCC;
|
||||
text-align: left;
|
||||
padding-left: 8px;
|
||||
padding-bottom: 5px;
|
||||
padding-top: 2px;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
* indicators
|
||||
*****************/
|
||||
.ng-input-indicator-wait {
|
||||
background-image: url("data:image/png;base64,R0lGODlhEAAQAPQAAP///wAAAPDw8IqKiuDg4EZGRnp6egAAAFhYWCQkJKysrL6+vhQUFJycnAQEBDY2NmhoaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAAFdyAgAgIJIeWoAkRCCMdBkKtIHIngyMKsErPBYbADpkSCwhDmQCBethRB6Vj4kFCkQPG4IlWDgrNRIwnO4UKBXDufzQvDMaoSDBgFb886MiQadgNABAokfCwzBA8LCg0Egl8jAggGAA1kBIA1BAYzlyILczULC2UhACH5BAkKAAAALAAAAAAQABAAAAV2ICACAmlAZTmOREEIyUEQjLKKxPHADhEvqxlgcGgkGI1DYSVAIAWMx+lwSKkICJ0QsHi9RgKBwnVTiRQQgwF4I4UFDQQEwi6/3YSGWRRmjhEETAJfIgMFCnAKM0KDV4EEEAQLiF18TAYNXDaSe3x6mjidN1s3IQAh+QQJCgAAACwAAAAAEAAQAAAFeCAgAgLZDGU5jgRECEUiCI+yioSDwDJyLKsXoHFQxBSHAoAAFBhqtMJg8DgQBgfrEsJAEAg4YhZIEiwgKtHiMBgtpg3wbUZXGO7kOb1MUKRFMysCChAoggJCIg0GC2aNe4gqQldfL4l/Ag1AXySJgn5LcoE3QXI3IQAh+QQJCgAAACwAAAAAEAAQAAAFdiAgAgLZNGU5joQhCEjxIssqEo8bC9BRjy9Ag7GILQ4QEoE0gBAEBcOpcBA0DoxSK/e8LRIHn+i1cK0IyKdg0VAoljYIg+GgnRrwVS/8IAkICyosBIQpBAMoKy9dImxPhS+GKkFrkX+TigtLlIyKXUF+NjagNiEAIfkECQoAAAAsAAAAABAAEAAABWwgIAICaRhlOY4EIgjH8R7LKhKHGwsMvb4AAy3WODBIBBKCsYA9TjuhDNDKEVSERezQEL0WrhXucRUQGuik7bFlngzqVW9LMl9XWvLdjFaJtDFqZ1cEZUB0dUgvL3dgP4WJZn4jkomWNpSTIyEAIfkECQoAAAAsAAAAABAAEAAABX4gIAICuSxlOY6CIgiD8RrEKgqGOwxwUrMlAoSwIzAGpJpgoSDAGifDY5kopBYDlEpAQBwevxfBtRIUGi8xwWkDNBCIwmC9Vq0aiQQDQuK+VgQPDXV9hCJjBwcFYU5pLwwHXQcMKSmNLQcIAExlbH8JBwttaX0ABAcNbWVbKyEAIfkECQoAAAAsAAAAABAAEAAABXkgIAICSRBlOY7CIghN8zbEKsKoIjdFzZaEgUBHKChMJtRwcWpAWoWnifm6ESAMhO8lQK0EEAV3rFopIBCEcGwDKAqPh4HUrY4ICHH1dSoTFgcHUiZjBhAJB2AHDykpKAwHAwdzf19KkASIPl9cDgcnDkdtNwiMJCshACH5BAkKAAAALAAAAAAQABAAAAV3ICACAkkQZTmOAiosiyAoxCq+KPxCNVsSMRgBsiClWrLTSWFoIQZHl6pleBh6suxKMIhlvzbAwkBWfFWrBQTxNLq2RG2yhSUkDs2b63AYDAoJXAcFRwADeAkJDX0AQCsEfAQMDAIPBz0rCgcxky0JRWE1AmwpKyEAIfkECQoAAAAsAAAAABAAEAAABXkgIAICKZzkqJ4nQZxLqZKv4NqNLKK2/Q4Ek4lFXChsg5ypJjs1II3gEDUSRInEGYAw6B6zM4JhrDAtEosVkLUtHA7RHaHAGJQEjsODcEg0FBAFVgkQJQ1pAwcDDw8KcFtSInwJAowCCA6RIwqZAgkPNgVpWndjdyohACH5BAkKAAAALAAAAAAQABAAAAV5ICACAimc5KieLEuUKvm2xAKLqDCfC2GaO9eL0LABWTiBYmA06W6kHgvCqEJiAIJiu3gcvgUsscHUERm+kaCxyxa+zRPk0SgJEgfIvbAdIAQLCAYlCj4DBw0IBQsMCjIqBAcPAooCBg9pKgsJLwUFOhCZKyQDA3YqIQAh+QQJCgAAACwAAAAAEAAQAAAFdSAgAgIpnOSonmxbqiThCrJKEHFbo8JxDDOZYFFb+A41E4H4OhkOipXwBElYITDAckFEOBgMQ3arkMkUBdxIUGZpEb7kaQBRlASPg0FQQHAbEEMGDSVEAA1QBhAED1E0NgwFAooCDWljaQIQCE5qMHcNhCkjIQAh+QQJCgAAACwAAAAAEAAQAAAFeSAgAgIpnOSoLgxxvqgKLEcCC65KEAByKK8cSpA4DAiHQ/DkKhGKh4ZCtCyZGo6F6iYYPAqFgYy02xkSaLEMV34tELyRYNEsCQyHlvWkGCzsPgMCEAY7Cg04Uk48LAsDhRA8MVQPEF0GAgqYYwSRlycNcWskCkApIyEAOwAAAAAAAAAAAA==");
|
||||
background-position: right;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
describe("DocsNavigationCtrl", function() {
|
||||
|
||||
beforeEach(module('docsApp'));
|
||||
|
||||
var ctrl, $scope;
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
$provide.value('docsPages', []);
|
||||
$provide.factory('docsSearch', function() {
|
||||
return function(q) {
|
||||
return ['one','two','three'];
|
||||
};
|
||||
});
|
||||
});
|
||||
inject(function($controller, $rootScope, $location, docsSearch) {
|
||||
$scope = $rootScope.$new();
|
||||
ctrl = $controller('DocsNavigationCtrl', {
|
||||
$scope : $scope,
|
||||
$location : $location,
|
||||
docsSearch : docsSearch
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should search and return data from docsSearch", function() {
|
||||
$scope.search('1234')
|
||||
expect($scope.results.join(',')).toBe('one,two,three');
|
||||
expect($scope.hasResults).toBe(true);
|
||||
});
|
||||
|
||||
it("should avoid searching if the search term is too short", function() {
|
||||
$scope.search('1')
|
||||
expect($scope.results.length).toBe(0);
|
||||
expect($scope.hasResults).toBe(false);
|
||||
});
|
||||
|
||||
it("should set the columns classname based on the total grouped results", function() {
|
||||
$scope.search('1234');
|
||||
expect($scope.colClassName).toBe('cols-3');
|
||||
|
||||
$scope.search('1');
|
||||
expect($scope.colClassName).toBe(null);
|
||||
});
|
||||
|
||||
it("should hide and clear the results when called", function() {
|
||||
$scope.hasResults = true;
|
||||
$scope.results = ['one'];
|
||||
$scope.colClassName = '...';
|
||||
$scope.hideResults();
|
||||
expect($scope.hasResults).toBe(false);
|
||||
expect($scope.results.length).toBe(0);
|
||||
expect($scope.colClassName).toBe(null);
|
||||
});
|
||||
|
||||
it("should hide, clear and change the path of the page when submitted", inject(function($location) {
|
||||
$scope.hasResults = true;
|
||||
$scope.results = {
|
||||
api : [
|
||||
{url : '/home'}
|
||||
],
|
||||
tutorial : [
|
||||
{url : '/tutorial'}
|
||||
]
|
||||
};
|
||||
$scope.submit();
|
||||
expect($location.path()).toBe('/home');
|
||||
expect($scope.results.length).toBe(0);
|
||||
expect($scope.hasResults).toBe(false);
|
||||
}));
|
||||
|
||||
});
|
||||
@@ -1,195 +0,0 @@
|
||||
describe('Docs Annotations', function() {
|
||||
|
||||
beforeEach(module('docsApp'));
|
||||
|
||||
var body;
|
||||
beforeEach(function() {
|
||||
body = angular.element(document.body);
|
||||
body.html('');
|
||||
});
|
||||
|
||||
var normalizeHtml = function(html) {
|
||||
return html.toLowerCase().replace(/\s*$/, '');
|
||||
};
|
||||
|
||||
describe('popover directive', function() {
|
||||
|
||||
var $scope, element;
|
||||
beforeEach(inject(function($rootScope, $compile) {
|
||||
$scope = $rootScope.$new();
|
||||
element = angular.element(
|
||||
'<div style="margin:200px;" data-title="title_text" data-content="content_text" popover></div>'
|
||||
);
|
||||
element.attr('id','idx');
|
||||
body.append(element);
|
||||
$compile(element)($scope);
|
||||
$scope.$apply();
|
||||
}));
|
||||
|
||||
it('should be hidden by default', inject(function(popoverElement) {
|
||||
expect(popoverElement.visible()).toBe(false);
|
||||
}));
|
||||
|
||||
it('should capture the click event and set the title and content and position the tip', inject(function(popoverElement) {
|
||||
element.triggerHandler('click');
|
||||
expect(popoverElement.isSituatedAt(element)).toBe(true);
|
||||
expect(popoverElement.visible()).toBe(true);
|
||||
expect(popoverElement.title()).toBe('title_text');
|
||||
expect(popoverElement.content()).toContain('content_text');
|
||||
expect(popoverElement.besideElement.attr('id')).toBe('idx');
|
||||
}));
|
||||
|
||||
it('should hide and clear the title and content if the same element is clicked again', inject(function(popoverElement) {
|
||||
//show the element
|
||||
element.triggerHandler('click');
|
||||
expect(popoverElement.isSituatedAt(element)).toBe(true);
|
||||
|
||||
//hide the element
|
||||
element.triggerHandler('click');
|
||||
expect(popoverElement.isSituatedAt(element)).toBe(false);
|
||||
expect(popoverElement.visible()).toBe(false);
|
||||
expect(popoverElement.title()).toBe('');
|
||||
expect(popoverElement.content()).toBe('');
|
||||
}));
|
||||
|
||||
it('should parse markdown content', inject(function(popoverElement, $compile) {
|
||||
element = angular.element(
|
||||
'<div style="margin:200px;" data-title="#title_text" data-content="#heading" popover></div>'
|
||||
);
|
||||
body.append(element);
|
||||
$compile(element)($scope);
|
||||
$scope.$apply();
|
||||
element.triggerHandler('click');
|
||||
expect(popoverElement.title()).toBe('#title_text');
|
||||
expect(normalizeHtml(popoverElement.content())).toMatch('<h1>heading</h1>');
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('foldout directive', function() {
|
||||
|
||||
// Do not run this suite on Internet Explorer.
|
||||
if (msie < 10) return;
|
||||
|
||||
var $scope, parent, element, url;
|
||||
beforeEach(function() {
|
||||
module(function($provide, $animateProvider) {
|
||||
$animateProvider.register('.foldout', function($timeout) {
|
||||
return {
|
||||
enter : function(element, done) {
|
||||
$timeout(done, 1000);
|
||||
},
|
||||
removeClass : function(element, className, done) {
|
||||
$timeout(done, 500);
|
||||
},
|
||||
addClass : function(element, className, done) {
|
||||
$timeout(done, 200);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
inject(function($rootScope, $compile, $templateCache, $rootElement, $animate) {
|
||||
$animate.enabled(true);
|
||||
url = '/page.html';
|
||||
$scope = $rootScope.$new();
|
||||
parent = angular.element('<div class="parent"></div>');
|
||||
|
||||
//we're injecting the element to the $rootElement since the changes in
|
||||
//$animate only detect and perform animations if the root element has
|
||||
//animations enabled. If the element is not apart of the DOM
|
||||
//then animations are skipped.
|
||||
element = angular.element('<div data-url="' + url + '" class="foldout" foldout></div>');
|
||||
parent.append(element);
|
||||
$rootElement.append(parent);
|
||||
body.append($rootElement);
|
||||
|
||||
$compile(parent)($scope);
|
||||
$scope.$apply();
|
||||
});
|
||||
});
|
||||
|
||||
it('should inform that it is loading', inject(function($httpBackend) {
|
||||
$httpBackend.expect('GET', url).respond('hello');
|
||||
element.triggerHandler('click');
|
||||
|
||||
var kids = body.children();
|
||||
var foldout = angular.element(kids[kids.length-1]);
|
||||
expect(foldout.html()).toContain('loading');
|
||||
}));
|
||||
|
||||
//TODO(matias): this test is bad. it's not clear what is being tested and what the assertions are.
|
||||
// Additionally, now that promises get auto-flushed there are extra tasks in the deferred queue which screws up
|
||||
// these brittle tests.
|
||||
xit('should download a foldout HTML page and animate the contents', inject(function($httpBackend, $timeout, $sniffer) {
|
||||
$httpBackend.expect('GET', url).respond('hello');
|
||||
|
||||
element.triggerHandler('click');
|
||||
$httpBackend.flush();
|
||||
|
||||
$timeout.flushNext(0);
|
||||
$timeout.flushNext(1000);
|
||||
|
||||
var kids = body.children();
|
||||
var foldout = angular.element(kids[kids.length-1]);
|
||||
expect(foldout.text()).toContain('hello');
|
||||
}));
|
||||
|
||||
//TODO(matias): this test is bad. it's not clear what is being tested and what the assertions are.
|
||||
// Additionally, now that promises get auto-flushed there are extra tasks in the deferred queue which screws up
|
||||
// these brittle tests.
|
||||
xit('should hide then show when clicked again', inject(function($httpBackend, $timeout, $sniffer) {
|
||||
$httpBackend.expect('GET', url).respond('hello');
|
||||
|
||||
//enter
|
||||
element.triggerHandler('click');
|
||||
$httpBackend.flush();
|
||||
$timeout.flushNext(0);
|
||||
$timeout.flushNext(1000);
|
||||
|
||||
//hide
|
||||
element.triggerHandler('click');
|
||||
$timeout.flushNext(0);
|
||||
$timeout.flushNext(200);
|
||||
|
||||
//show
|
||||
element.triggerHandler('click');
|
||||
$timeout.flushNext(0);
|
||||
$timeout.flushNext(500);
|
||||
$timeout.flushNext(0);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe('DocsController fold', function() {
|
||||
|
||||
var $scope, ctrl;
|
||||
beforeEach(function() {
|
||||
inject(function($rootScope, $controller, $location, $cookies, sections) {
|
||||
$scope = $rootScope.$new();
|
||||
ctrl = $controller('DocsController',{
|
||||
$scope : $scope,
|
||||
$location : $location,
|
||||
$cookies : $cookies,
|
||||
sections : sections
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should download and reveal the foldover container', inject(function($compile, $httpBackend) {
|
||||
var url = '/page.html';
|
||||
var fullUrl = '/notes/' + url;
|
||||
$httpBackend.expect('GET', fullUrl).respond('hello');
|
||||
|
||||
var element = angular.element('<div ng-include="docs_fold"></div>');
|
||||
$compile(element)($scope);
|
||||
$scope.$apply();
|
||||
|
||||
$scope.fold(url);
|
||||
|
||||
$httpBackend.flush();
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
-157
@@ -1,157 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('bootstrap', function() {
|
||||
var $compile, $rootScope, element;
|
||||
|
||||
function clickTab(element, index) {
|
||||
browserTrigger(element.children().eq(0).children().eq(index));
|
||||
}
|
||||
|
||||
beforeEach(module('bootstrap'));
|
||||
beforeEach(inject(function(_$compile_, _$rootScope_) {
|
||||
$compile = _$compile_;
|
||||
$rootScope = _$rootScope_;
|
||||
}));
|
||||
beforeEach(function(){
|
||||
function findTab(element, index) {
|
||||
return _jQuery(element[0]).find('> .nav-tabs > li').eq(index);
|
||||
}
|
||||
function findTabPane(element, index) {
|
||||
return _jQuery(element[0]).find('> .tab-content > .tab-pane').eq(index);
|
||||
}
|
||||
|
||||
this.addMatchers({
|
||||
toHaveTab: function(index, title) {
|
||||
var tab = findTab(element, index);
|
||||
|
||||
this.message = function() {
|
||||
if (tab.length) {
|
||||
return 'Expect tab index ' + index + ' to be ' + toJson(title) + ' but was ' + toJson(tab.text());
|
||||
} else {
|
||||
return 'Expect tab index ' + index + ' to be ' + toJson(title) + ' but there are only ' +
|
||||
element.children().length + ' tabs.';
|
||||
}
|
||||
};
|
||||
|
||||
return tab.length && tab.text() == title;
|
||||
},
|
||||
|
||||
toHaveTabPane: function(index, title) {
|
||||
var tabPane = findTabPane(element, index);
|
||||
|
||||
this.message = function() {
|
||||
if (tabPane.length) {
|
||||
return 'Expect tab pane index ' + index + ' to be ' + toJson(title) + ' but was ' + toJson(tabPane.text());
|
||||
} else {
|
||||
return 'Expect tab pane index ' + index + ' to be ' + toJson(title) + ' but there are only ' +
|
||||
element.children().length + 'tab panes.';
|
||||
}
|
||||
};
|
||||
|
||||
return tabPane.length && tabPane.text() == title;
|
||||
},
|
||||
|
||||
toHaveSelected: function(index) {
|
||||
var tab = findTab(element, index);
|
||||
var tabPane = findTabPane(element, index);
|
||||
|
||||
this.message = function() {
|
||||
return 'Expect tab index ' + index + ' to be selected\n' +
|
||||
' TAB: ' + angular.mock.dump(tab) + '\n' +
|
||||
'TAB-PANE: ' + angular.mock.dump(tabPane);
|
||||
};
|
||||
|
||||
return tabPane.hasClass('active') && tab.hasClass('active');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
dealoc(element);
|
||||
});
|
||||
|
||||
describe('tabbable', function() {
|
||||
|
||||
it('should create the right structure', function() {
|
||||
element = $compile(
|
||||
'<div class="tabbable">' +
|
||||
'<div class="tab-pane" title="first">tab1</div>' +
|
||||
'<div class="tab-pane" title="second">tab2</div>' +
|
||||
'</div>')($rootScope);
|
||||
|
||||
$rootScope.$apply();
|
||||
|
||||
expect(element).toHaveTab(0, 'first');
|
||||
expect(element).toHaveTab(1, 'second');
|
||||
|
||||
expect(element).toHaveTabPane(0, 'tab1');
|
||||
expect(element).toHaveTabPane(1, 'tab2');
|
||||
|
||||
expect(element).toHaveSelected(0);
|
||||
});
|
||||
|
||||
|
||||
it('should respond to tab click', function(){
|
||||
element = $compile(
|
||||
'<div class="tabbable">' +
|
||||
'<div class="tab-pane" title="first">tab1</div>' +
|
||||
'<div class="tab-pane" title="second">tab2</div>' +
|
||||
'</div>')($rootScope);
|
||||
|
||||
expect(element).toHaveSelected(0);
|
||||
clickTab(element, 1);
|
||||
expect(element).toHaveSelected(1);
|
||||
});
|
||||
|
||||
|
||||
it('should select the first tab in repeater', function() {
|
||||
element = $compile(
|
||||
'<div class="tabbable">' +
|
||||
'<div class="tab-pane" ng-repeat="id in [1,2,3]" title="Tab {{id}}" value="tab-{{id}}">' +
|
||||
'Tab content {{id}}!' +
|
||||
'</div>' +
|
||||
'</div>')($rootScope);
|
||||
$rootScope.$apply();
|
||||
|
||||
expect(element).toHaveSelected(0);
|
||||
});
|
||||
|
||||
|
||||
describe('ngModel', function() {
|
||||
it('should bind to model', function() {
|
||||
$rootScope.tab = 'B';
|
||||
|
||||
element = $compile(
|
||||
'<div class="tabbable" ng-model="tab">' +
|
||||
'<div class="tab-pane" title="first" value="A">tab1</div>' +
|
||||
'<div class="tab-pane" title="second" value="B">tab2</div>' +
|
||||
'</div>')($rootScope);
|
||||
|
||||
$rootScope.$apply();
|
||||
expect(element).toHaveSelected(1);
|
||||
|
||||
$rootScope.tab = 'A';
|
||||
$rootScope.$apply();
|
||||
expect(element).toHaveSelected(0);
|
||||
|
||||
clickTab(element, 1);
|
||||
expect($rootScope.tab).toEqual('B');
|
||||
expect(element).toHaveSelected(1);
|
||||
});
|
||||
|
||||
|
||||
it('should not overwrite the model', function() {
|
||||
$rootScope.tab = 'tab-2';
|
||||
element = $compile(
|
||||
'<div class="tabbable" ng-model="tab">' +
|
||||
'<div class="tab-pane" ng-repeat="id in [1,2,3]" title="Tab {{id}}" value="tab-{{id}}">' +
|
||||
'Tab content {{id}}!' +
|
||||
'</div>' +
|
||||
'</div>')($rootScope);
|
||||
$rootScope.$apply();
|
||||
|
||||
expect(element).toHaveSelected(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,91 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../../src/angular-bootstrap.js"></script>
|
||||
<script type="text/javascript">
|
||||
$script('src/bootstrap/google-prettify/prettify', 'prettify');
|
||||
$script.ready('angular', function() {
|
||||
$script(['src/bootstrap/bootstrap-prettify', 'src/bootstrap/bootstrap'], 'myCode');
|
||||
angular.module('myApp', []).run(function($rootScope){ $rootScope.text = 'WORKS!' });
|
||||
});
|
||||
$script.ready(['myCode', 'prettify'], function() {
|
||||
angular.bootstrap(document, ['bootstrapPrettify', 'bootstrap']);
|
||||
});
|
||||
</script>
|
||||
<link rel="stylesheet" href="../../src/bootstrap/google-prettify/prettify.css" type="text/css">
|
||||
<link rel="stylesheet" href="../../src/bootstrap/css/bootstrap.css" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<h1>AngularJS is {{'working'}}</h1>
|
||||
|
||||
<h2>Directive: <code>prettify</code></h2>
|
||||
<pre class="prettyprint linenums">
|
||||
<p>Sample text here...</p>
|
||||
</pre>
|
||||
|
||||
|
||||
<h2>Directive: <code>ng-set-text</code></h2>
|
||||
<pre class="prettyprint linenums" ng-set-text="hello.html"></pre>
|
||||
<script type="text/html" id="hello.html">
|
||||
<h1>Hello World!</h1>
|
||||
</script>
|
||||
|
||||
<h2>Directive: <code>ng-html-wrap</code></h2>
|
||||
<pre class="prettyprint linenums" ng-set-text="hello.html" ng-html-wrap="angular.js angular-resource.js myApp abc.js abc.css"></pre>
|
||||
|
||||
<h2>Directive <code>ng-embed-app</code></h2>
|
||||
<div ng-embed-app="myApp">{{text}}</div>
|
||||
|
||||
<h1>Bootstrap</h1>
|
||||
|
||||
<h2>Directive <code>drop-down-toggle</code></h2>
|
||||
<div class="btn btn-primary dropdown">
|
||||
<a href="#ABC" class="dropdown-toggle">
|
||||
Account
|
||||
<b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li>One</li>
|
||||
<li>Two</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2 ng-init="state = 'tab-2' ">Directive <code>tabbable</code></h2>
|
||||
state = {{state}}
|
||||
|
||||
<div class="tabbable" ng-model="state">
|
||||
<div class="tab-pane" ng-repeat="id in [1,2,3]" title="Tab {{id}}" value='tab-{{id}}'>
|
||||
Tab content {{id}}!
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="tabbable" ng-model="state">
|
||||
<div class="tab-pane" ng-repeat="id in [1,2,3]" title="Tab {{id}}" value='tab-{{id}}'>
|
||||
Tab content {{id}}!
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="tabbable">
|
||||
<div class="tab-pane" ng-repeat="id in [1,2,3]" title="Tab {{id}}" value='tab-{{id}}'>
|
||||
Tab content {{id}}!
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,59 +0,0 @@
|
||||
describe("docsSearch", function() {
|
||||
|
||||
beforeEach(module('docsApp'));
|
||||
|
||||
var interceptedLunrResults;
|
||||
beforeEach(function() {
|
||||
interceptedLunrResults = [];
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
var results = [];
|
||||
results[0] = { section: 'tutorial', shortName: 'item one', keywords: 'item, one, 1' };
|
||||
results[1] = { section: 'tutorial', shortName: 'item man', keywords: 'item, man' };
|
||||
results[2] = { section: 'api', shortName: 'item other', keywords: 'item, other' };
|
||||
results[3] = { section: 'cookbook', shortName: 'item cookbook', keywords: 'item, other' };
|
||||
results[4] = { section: 'api', shortName: 'ngRepeat', keywords: 'item, other' };
|
||||
|
||||
$provide.value('NG_PAGES', results);
|
||||
$provide.factory('lunrSearch', function() {
|
||||
return function() {
|
||||
return {
|
||||
store : function(value) {
|
||||
interceptedLunrResults.push(value);
|
||||
},
|
||||
search : function(q) {
|
||||
var data = [];
|
||||
angular.forEach(results, function(res, i) {
|
||||
data.push({ ref : i });
|
||||
});
|
||||
return data;
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should lookup and organize values properly", inject(function(docsSearch) {
|
||||
var items = docsSearch('item');
|
||||
expect(items['api'].length).toBe(2);
|
||||
}));
|
||||
|
||||
it("should place cookbook items in the tutorial", inject(function(docsSearch) {
|
||||
var items = docsSearch('item');
|
||||
expect(items['tutorial'].length).toBe(3);
|
||||
}));
|
||||
|
||||
it("should return all results without a search", inject(function(docsSearch) {
|
||||
var items = docsSearch();
|
||||
expect(items['tutorial'].length).toBe(3);
|
||||
expect(items['api'].length).toBe(2);
|
||||
}));
|
||||
|
||||
it("should store values with and without a ng prefix", inject(function(docsSearch) {
|
||||
expect(interceptedLunrResults[4].title).toBe('ngRepeat repeat');
|
||||
}));
|
||||
|
||||
});
|
||||
@@ -1,76 +0,0 @@
|
||||
describe("errorDisplay", function () {
|
||||
|
||||
var $location, compileHTML;
|
||||
|
||||
beforeEach(module('docsApp'));
|
||||
|
||||
beforeEach(inject(function ($injector) {
|
||||
var $rootScope = $injector.get('$rootScope'),
|
||||
$compile = $injector.get('$compile');
|
||||
|
||||
$location = $injector.get('$location');
|
||||
|
||||
compileHTML = function (code) {
|
||||
var elm = angular.element(code);
|
||||
$compile(elm)($rootScope);
|
||||
$rootScope.$digest();
|
||||
return elm;
|
||||
};
|
||||
|
||||
this.addMatchers({
|
||||
toInterpolateTo: function (expected) {
|
||||
// Given a compiled DOM node with a minerr-display attribute,
|
||||
// assert that its interpolated string matches the expected text.
|
||||
return this.actual.text() === expected;
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
it('should interpolate a template with no parameters', function () {
|
||||
var elm;
|
||||
|
||||
spyOn($location, 'search').andReturn({});
|
||||
elm = compileHTML('<div error-display="This is a test"></div>');
|
||||
expect(elm).toInterpolateTo('This is a test');
|
||||
});
|
||||
|
||||
it('should interpolate a template with no parameters when search parameters are present', function () {
|
||||
var elm;
|
||||
|
||||
spyOn($location, 'search').andReturn({ p0: 'foobaz' });
|
||||
elm = compileHTML('<div error-display="This is a test"></div>');
|
||||
expect(elm).toInterpolateTo('This is a test');
|
||||
});
|
||||
|
||||
it('should correctly interpolate search parameters', function () {
|
||||
var elm;
|
||||
|
||||
spyOn($location, 'search').andReturn({ p0: '42' });
|
||||
elm = compileHTML('<div error-display="The answer is {0}"></div>');
|
||||
expect(elm).toInterpolateTo('The answer is 42');
|
||||
});
|
||||
|
||||
it('should interpolate parameters in the specified order', function () {
|
||||
var elm;
|
||||
|
||||
spyOn($location, 'search').andReturn({ p0: 'second', p1: 'first' });
|
||||
elm = compileHTML('<div error-display="{1} {0}"></div>');
|
||||
expect(elm).toInterpolateTo('first second');
|
||||
});
|
||||
|
||||
it('should preserve interpolation markers when fewer arguments than needed are provided', function () {
|
||||
var elm;
|
||||
|
||||
spyOn($location, 'search').andReturn({ p0: 'Fooooo' });
|
||||
elm = compileHTML('<div error-display="This {0} is {1} on {2}"></div>');
|
||||
expect(elm).toInterpolateTo('This Fooooo is {1} on {2}');
|
||||
});
|
||||
|
||||
it('should correctly handle the empty string as an interpolation parameter', function () {
|
||||
var elm;
|
||||
|
||||
spyOn($location, 'search').andReturn({ p0: 'test', p1: '' });
|
||||
elm = compileHTML('<div error-display="This {0} is a {1}"></div>');
|
||||
expect(elm).toInterpolateTo('This test is a ');
|
||||
});
|
||||
});
|
||||
@@ -1,52 +0,0 @@
|
||||
describe("errorLinkFilter", function () {
|
||||
|
||||
var errorLinkFilter;
|
||||
|
||||
beforeEach(module('docsApp'));
|
||||
|
||||
beforeEach(inject(function ($filter) {
|
||||
errorLinkFilter = $filter('errorLink');
|
||||
}));
|
||||
|
||||
it('should not change text that does not contain links', function () {
|
||||
expect(errorLinkFilter('This is a test')).toBe('This is a test');
|
||||
});
|
||||
|
||||
it('should find links in text and linkify them', function () {
|
||||
var output = errorLinkFilter("http://ab/ (http://a/) http://1.2/v:~-123. c");
|
||||
//temporary fix for IE8 sanitization whitespace bug
|
||||
output = output.replace('</a>(','</a> (');
|
||||
expect(output).
|
||||
toBe('<a href="http://ab/">http://ab/</a> ' +
|
||||
'(<a href="http://a/">http://a/</a>) ' +
|
||||
'<a href="http://1.2/v:~-123">http://1.2/v:~-123</a>. c');
|
||||
expect(errorLinkFilter(undefined)).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('should handle mailto', function () {
|
||||
expect(errorLinkFilter("mailto:me@example.com")).
|
||||
toBe('<a href="mailto:me@example.com">me@example.com</a>');
|
||||
expect(errorLinkFilter("me@example.com")).
|
||||
toBe('<a href="mailto:me@example.com">me@example.com</a>');
|
||||
expect(errorLinkFilter("send email to me@example.com, but")).
|
||||
toBe('send email to <a href="mailto:me@example.com">me@example.com</a>, but');
|
||||
});
|
||||
|
||||
it('should handle target', function () {
|
||||
expect(errorLinkFilter("http://example.com", "_blank")).
|
||||
toBe('<a target="_blank" href="http://example.com">http://example.com</a>')
|
||||
expect(errorLinkFilter("http://example.com", "someNamedIFrame")).
|
||||
toBe('<a target="someNamedIFrame" href="http://example.com">http://example.com</a>')
|
||||
});
|
||||
|
||||
it('should not linkify stack trace URLs', function () {
|
||||
expect(errorLinkFilter("http://example.com/angular.min.js:42:1337")).
|
||||
toBe("http://example.com/angular.min.js:42:1337");
|
||||
});
|
||||
|
||||
it('should truncate linked URLs at 60 characters', function () {
|
||||
expect(errorLinkFilter("http://errors.angularjs.org/very-long-version-string/$injector/nomod?p0=myApp")).
|
||||
toBe('<a href="http://errors.angularjs.org/very-long-version-string/$injector/nomod?p0=myApp">' +
|
||||
'http://errors.angularjs.org/very-long-version-string/$inj...</a>');
|
||||
});
|
||||
});
|
||||
@@ -1,32 +0,0 @@
|
||||
// Copy/pasted from src/Angular.js, so that we can disable specific tests on IE.
|
||||
var msie = parseInt((/msie (\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1], 10);
|
||||
|
||||
var createMockWindow = function() {
|
||||
var mockWindow = {};
|
||||
var setTimeoutQueue = [];
|
||||
|
||||
mockWindow.location = window.location;
|
||||
mockWindow.document = window.document;
|
||||
mockWindow.getComputedStyle = angular.bind(window, window.getComputedStyle);
|
||||
mockWindow.scrollTo = angular.bind(window, window.scrollTo);
|
||||
mockWindow.navigator = window.navigator;
|
||||
mockWindow.setTimeout = function(fn, delay) {
|
||||
setTimeoutQueue.push({fn: fn, delay: delay});
|
||||
};
|
||||
mockWindow.setTimeout.queue = setTimeoutQueue;
|
||||
mockWindow.setTimeout.expect = function(delay) {
|
||||
if (setTimeoutQueue.length > 0) {
|
||||
return {
|
||||
process: function() {
|
||||
var tick = setTimeoutQueue.shift();
|
||||
expect(tick.delay).toEqual(delay);
|
||||
tick.fn();
|
||||
}
|
||||
};
|
||||
} else {
|
||||
expect('SetTimoutQueue empty. Expecting delay of ').toEqual(delay);
|
||||
}
|
||||
};
|
||||
|
||||
return mockWindow;
|
||||
};
|
||||
@@ -1,50 +0,0 @@
|
||||
describe('Docs Syntax', function() {
|
||||
|
||||
beforeEach(module('bootstrap'));
|
||||
|
||||
describe('syntax', function() {
|
||||
|
||||
var id, element, document;
|
||||
|
||||
beforeEach(inject(function($compile, $rootScope, $document) {
|
||||
document = $document[0];
|
||||
//create the HTML elements missing in IE8 for this directive
|
||||
document.createElement('nav');
|
||||
|
||||
element = angular.element(
|
||||
'<div>' +
|
||||
'<pre syntax ' +
|
||||
'syntax-github="gh-url" ' +
|
||||
'syntax-plunkr="pl-url" ' +
|
||||
'syntax-fiddle="jf-url">' +
|
||||
'</pre>' +
|
||||
'</div>'
|
||||
);
|
||||
$compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
|
||||
element = element[0];
|
||||
document.body.appendChild(element);
|
||||
}));
|
||||
|
||||
it("should properly prepare a github link in the page", function() {
|
||||
var github = element.querySelector('.syntax-github');
|
||||
expect(github.innerHTML).toMatch(/View on Github/i);
|
||||
expect(github.getAttribute('href')).toBe('gh-url');
|
||||
});
|
||||
|
||||
it("should properly prepare a plunkr link in the page", function() {
|
||||
var plunkr = element.querySelector('.syntax-plunkr');
|
||||
expect(plunkr.innerHTML).toMatch(/View on Plunkr/i);
|
||||
expect(plunkr.getAttribute('href')).toBe('pl-url');
|
||||
});
|
||||
|
||||
it("should properly prepare a jsfiddle link in the page", function() {
|
||||
var jsfiddle = element.querySelector('.syntax-jsfiddle');
|
||||
expect(jsfiddle.innerHTML).toMatch(/View on JSFiddle/i);
|
||||
expect(jsfiddle.getAttribute('href')).toBe('jf-url');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,33 +0,0 @@
|
||||
describe('DocsApp', function() {
|
||||
|
||||
// Do not run this suite on Internet Explorer.
|
||||
if (msie < 10) return;
|
||||
|
||||
beforeEach(module('docsApp'));
|
||||
|
||||
describe('DocsVersionsCtrl', function() {
|
||||
var $scope, ctrl, window, version = '9.8.7';
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide) {
|
||||
$provide.value('$window', window = createMockWindow());
|
||||
});
|
||||
inject(function($controller, $rootScope) {
|
||||
$scope = $rootScope.$new();
|
||||
$scope.version = version;
|
||||
ctrl = $controller('DocsVersionsCtrl',{
|
||||
$scope : $scope,
|
||||
$window : window
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('changing the URL', function() {
|
||||
it('should jump to the url provided', function() {
|
||||
$scope.jumpToDocsVersion({ version: '1.0.1', url : 'page123'});
|
||||
expect(window.location).toBe('page123');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
Vendored
-227
@@ -1,227 +0,0 @@
|
||||
|
||||
/*!
|
||||
* $script.js Async loader & dependency manager
|
||||
* https://github.com/ded/script.js
|
||||
* (c) Dustin Diaz, Jacob Thornton 2011
|
||||
* License: MIT
|
||||
*/
|
||||
(function (name, definition, context) {
|
||||
if (typeof context['module'] != 'undefined' && context['module']['exports']) context['module']['exports'] = definition()
|
||||
else if (typeof context['define'] != 'undefined' && context['define'] == 'function' && context['define']['amd']) define(name, definition)
|
||||
else context[name] = definition()
|
||||
})('$script', function () {
|
||||
var doc = document
|
||||
, head = doc.getElementsByTagName('head')[0]
|
||||
, validBase = /^https?:\/\//
|
||||
, list = {}, ids = {}, delay = {}, scriptpath
|
||||
, scripts = {}, s = 'string', f = false
|
||||
, push = 'push', domContentLoaded = 'DOMContentLoaded', readyState = 'readyState'
|
||||
, addEventListener = 'addEventListener', onreadystatechange = 'onreadystatechange'
|
||||
|
||||
function every(ar, fn) {
|
||||
for (var i = 0, j = ar.length; i < j; ++i) if (!fn(ar[i])) return f
|
||||
return 1
|
||||
}
|
||||
function each(ar, fn) {
|
||||
every(ar, function(el) {
|
||||
return !fn(el)
|
||||
})
|
||||
}
|
||||
|
||||
if (!doc[readyState] && doc[addEventListener]) {
|
||||
doc[addEventListener](domContentLoaded, function fn() {
|
||||
doc.removeEventListener(domContentLoaded, fn, f)
|
||||
doc[readyState] = 'complete'
|
||||
}, f)
|
||||
doc[readyState] = 'loading'
|
||||
}
|
||||
|
||||
function $script(paths, idOrDone, optDone) {
|
||||
paths = paths[push] ? paths : [paths]
|
||||
var idOrDoneIsDone = idOrDone && idOrDone.call
|
||||
, done = idOrDoneIsDone ? idOrDone : optDone
|
||||
, id = idOrDoneIsDone ? paths.join('') : idOrDone
|
||||
, queue = paths.length
|
||||
function loopFn(item) {
|
||||
return item.call ? item() : list[item]
|
||||
}
|
||||
function callback() {
|
||||
if (!--queue) {
|
||||
list[id] = 1
|
||||
done && done()
|
||||
for (var dset in delay) {
|
||||
every(dset.split('|'), loopFn) && !each(delay[dset], loopFn) && (delay[dset] = [])
|
||||
}
|
||||
}
|
||||
}
|
||||
setTimeout(function () {
|
||||
each(paths, function (path) {
|
||||
if (scripts[path]) {
|
||||
id && (ids[id] = 1)
|
||||
return scripts[path] == 2 && callback()
|
||||
}
|
||||
scripts[path] = 1
|
||||
id && (ids[id] = 1)
|
||||
create(!validBase.test(path) && scriptpath ? scriptpath + path + '.js' : path, callback)
|
||||
})
|
||||
}, 0)
|
||||
return $script
|
||||
}
|
||||
|
||||
function create(path, fn) {
|
||||
var el = doc.createElement('script')
|
||||
, loaded = f
|
||||
el.onload = el.onerror = el[onreadystatechange] = function () {
|
||||
if ((el[readyState] && !(/^c|loade/.test(el[readyState]))) || loaded) return;
|
||||
el.onload = el[onreadystatechange] = null
|
||||
loaded = 1
|
||||
scripts[path] = 2
|
||||
fn()
|
||||
}
|
||||
el.async = 1
|
||||
el.src = path
|
||||
head.insertBefore(el, head.firstChild)
|
||||
}
|
||||
|
||||
$script.get = create
|
||||
|
||||
$script.order = function (scripts, id, done) {
|
||||
(function callback(s) {
|
||||
s = scripts.shift()
|
||||
if (!scripts.length) $script(s, id, done)
|
||||
else $script(s, callback)
|
||||
}())
|
||||
}
|
||||
|
||||
$script.path = function (p) {
|
||||
scriptpath = p
|
||||
}
|
||||
$script.ready = function (deps, ready, req) {
|
||||
deps = deps[push] ? deps : [deps]
|
||||
var missing = [];
|
||||
!each(deps, function (dep) {
|
||||
list[dep] || missing[push](dep);
|
||||
}) && every(deps, function (dep) {return list[dep]}) ?
|
||||
ready() : !function (key) {
|
||||
delay[key] = delay[key] || []
|
||||
delay[key][push](ready)
|
||||
req && req(missing)
|
||||
}(deps.join('|'))
|
||||
return $script
|
||||
}
|
||||
return $script
|
||||
}, this);
|
||||
|
||||
|
||||
/**
|
||||
* @license AngularJS
|
||||
* (c) 2010-2012 Google, Inc. http://angularjs.org
|
||||
* License: MIT
|
||||
*/
|
||||
(function(window, document) {
|
||||
|
||||
var filename = /^(.*\/)angular-bootstrap.js(#.*)?$/,
|
||||
scripts = document.getElementsByTagName("SCRIPT"),
|
||||
serverPath,
|
||||
match,
|
||||
globalVars = {},
|
||||
IGNORE = {
|
||||
innerHeight: true, innerWidth: true,
|
||||
onkeyup: true, onkeydown: true, onresize: true,
|
||||
event: true, frames: true, external: true,
|
||||
sessionStorage: true, clipboardData: true, localStorage: true};
|
||||
|
||||
for(var j = 0; j < scripts.length; j++) {
|
||||
match = (scripts[j].src || "").match(filename);
|
||||
if (match) {
|
||||
serverPath = match[1];
|
||||
}
|
||||
}
|
||||
|
||||
document.write('<link rel="stylesheet" type="text/css" href="' + serverPath + '../css/angular.css"/>');
|
||||
|
||||
$script.path(serverPath+'../');
|
||||
$script('angularFiles', function() {
|
||||
var index = 0,
|
||||
scripts = angularFiles.angularSrc;
|
||||
|
||||
try { delete window.angularFiles; } catch(e) { window.angularFiles = undefined; }
|
||||
// initialize the window property cache
|
||||
for (var prop in window) {
|
||||
if (IGNORE[prop] || prop.match(/^moz[A-Z]/)) { //skip special variables which keep on changing
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
globalVars[key(prop)] = window[prop];
|
||||
} catch(e) {} //ignore properties that throw exception when accessed (common in FF)
|
||||
}
|
||||
|
||||
(function next() {
|
||||
if (index < scripts.length) {
|
||||
var file = scripts[index++],
|
||||
last = index == scripts.length,
|
||||
name = last ? 'angular' : file;
|
||||
|
||||
$script(file.replace(/\.js$/, ''), name, function() {
|
||||
angularClobberTest(file);
|
||||
next();
|
||||
});
|
||||
} else {
|
||||
// empty the cache to prevent mem leaks
|
||||
globalVars = {};
|
||||
|
||||
bindJQuery();
|
||||
publishExternalAPI(window.angular);
|
||||
|
||||
angularInit(document, angular.bootstrap);
|
||||
}
|
||||
})();
|
||||
});
|
||||
|
||||
function key(prop) {
|
||||
return "ng-clobber_" + prop;
|
||||
}
|
||||
|
||||
function angularClobberTest(file) {
|
||||
var varKey, prop,
|
||||
clobbered = {};
|
||||
|
||||
for (prop in window) {
|
||||
varKey = key(prop);
|
||||
|
||||
if (IGNORE[prop] || prop.match(/^moz[A-Z]/)) { //skip special variables which keep on changing
|
||||
continue;
|
||||
} else if (!globalVars.hasOwnProperty(varKey)) {
|
||||
//console.log('new global variable found: ', prop);
|
||||
try {
|
||||
globalVars[varKey] = window[prop];
|
||||
} catch(e) {} //ignore properties that throw exception when accessed (common in FF)
|
||||
} else if (globalVars[varKey] !== window[prop] && !isActuallyNaN(window[prop]) && prop != 'jqLite') {
|
||||
clobbered[prop] = true;
|
||||
console.error("Global variable clobbered by script " + file + "! Variable name: " + prop);
|
||||
globalVars[varKey] = window[prop];
|
||||
}
|
||||
}
|
||||
for (varKey in globalVars) {
|
||||
prop = varKey.substr(11);
|
||||
if (prop === 'event' || prop.match(/^moz[A-Z]/)) { //skip special variables which keep on changing
|
||||
continue;
|
||||
}
|
||||
if (!clobbered[prop] &&
|
||||
prop != 'event' &&
|
||||
prop != 'jqLite' &&
|
||||
!isActuallyNaN(globalVars[varKey]) &&
|
||||
globalVars[varKey] !== window[prop]) {
|
||||
|
||||
delete globalVars[varKey];
|
||||
console.warn("Global variable unexpectedly deleted in script " + file + "! " +
|
||||
"Variable name: " + prop);
|
||||
}
|
||||
}
|
||||
|
||||
function isActuallyNaN(val) {
|
||||
return (typeof val === 'number') && isNaN(val);
|
||||
}
|
||||
}
|
||||
})(window, document);
|
||||
|
||||
@@ -1,317 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var directive = {};
|
||||
var service = { value: {} };
|
||||
|
||||
var DEPENDENCIES = {
|
||||
'angular.js': 'http://code.angularjs.org/' + angular.version.full + '/angular.min.js',
|
||||
'angular-resource.js': 'http://code.angularjs.org/' + angular.version.full + '/angular-resource.min.js',
|
||||
'angular-route.js': 'http://code.angularjs.org/' + angular.version.full + '/angular-route.min.js',
|
||||
'angular-animate.js': 'http://code.angularjs.org/' + angular.version.full + '/angular-animate.min.js',
|
||||
'angular-sanitize.js': 'http://code.angularjs.org/' + angular.version.full + '/angular-sanitize.min.js',
|
||||
'angular-cookies.js': 'http://code.angularjs.org/' + angular.version.full + '/angular-cookies.min.js'
|
||||
};
|
||||
|
||||
|
||||
function escape(text) {
|
||||
return text.
|
||||
replace(/\&/g, '&').
|
||||
replace(/\</g, '<').
|
||||
replace(/\>/g, '>').
|
||||
replace(/"/g, '"');
|
||||
}
|
||||
|
||||
/**
|
||||
* http://stackoverflow.com/questions/451486/pre-tag-loses-line-breaks-when-setting-innerhtml-in-ie
|
||||
* http://stackoverflow.com/questions/195363/inserting-a-newline-into-a-pre-tag-ie-javascript
|
||||
*/
|
||||
function setHtmlIe8SafeWay(element, html) {
|
||||
var newElement = angular.element('<pre>' + html + '</pre>');
|
||||
|
||||
element.html('');
|
||||
element.append(newElement.contents());
|
||||
return element;
|
||||
}
|
||||
|
||||
|
||||
directive.jsFiddle = function(getEmbeddedTemplate, escape, script) {
|
||||
return {
|
||||
terminal: true,
|
||||
link: function(scope, element, attr) {
|
||||
var name = '',
|
||||
stylesheet = '<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">\n',
|
||||
fields = {
|
||||
html: '',
|
||||
css: '',
|
||||
js: ''
|
||||
};
|
||||
|
||||
angular.forEach(attr.jsFiddle.split(' '), function(file, index) {
|
||||
var fileType = file.split('.')[1];
|
||||
|
||||
if (fileType == 'html') {
|
||||
if (index == 0) {
|
||||
fields[fileType] +=
|
||||
'<div ng-app' + (attr.module ? '="' + attr.module + '"' : '') + '>\n' +
|
||||
getEmbeddedTemplate(file, 2);
|
||||
} else {
|
||||
fields[fileType] += '\n\n\n <!-- CACHE FILE: ' + file + ' -->\n' +
|
||||
' <script type="text/ng-template" id="' + file + '">\n' +
|
||||
getEmbeddedTemplate(file, 4) +
|
||||
' </script>\n';
|
||||
}
|
||||
} else {
|
||||
fields[fileType] += getEmbeddedTemplate(file) + '\n';
|
||||
}
|
||||
});
|
||||
|
||||
fields.html += '</div>\n';
|
||||
|
||||
setHtmlIe8SafeWay(element,
|
||||
'<form class="jsfiddle" method="post" action="http://jsfiddle.net/api/post/library/pure/" target="_blank">' +
|
||||
hiddenField('title', 'AngularJS Example: ' + name) +
|
||||
hiddenField('css', '</style> <!-- Ugly Hack due to jsFiddle issue: http://goo.gl/BUfGZ --> \n' +
|
||||
stylesheet +
|
||||
script.angular +
|
||||
(attr.resource ? script.resource : '') +
|
||||
'<style>\n' +
|
||||
fields.css) +
|
||||
hiddenField('html', fields.html) +
|
||||
hiddenField('js', fields.js) +
|
||||
'<button class="btn btn-primary"><i class="icon-white icon-pencil"></i> Edit Me</button>' +
|
||||
'</form>');
|
||||
|
||||
function hiddenField(name, value) {
|
||||
return '<input type="hidden" name="' + name + '" value="' + escape(value) + '">';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
directive.code = function() {
|
||||
return {restrict: 'E', terminal: true};
|
||||
};
|
||||
|
||||
|
||||
directive.prettyprint = ['reindentCode', function(reindentCode) {
|
||||
return {
|
||||
restrict: 'C',
|
||||
compile: function(element) {
|
||||
var html = element.html();
|
||||
//ensure that angular won't compile {{ curly }} values
|
||||
html = html.replace(/\{\{/g, '<span>{{</span>')
|
||||
.replace(/\}\}/g, '<span>}}</span>');
|
||||
if (window.RUNNING_IN_NG_TEST_RUNNER) {
|
||||
element.html(html);
|
||||
}
|
||||
else {
|
||||
element.html(window.prettyPrintOne(reindentCode(html), undefined, true));
|
||||
}
|
||||
}
|
||||
};
|
||||
}];
|
||||
|
||||
|
||||
directive.ngSetText = ['getEmbeddedTemplate', function(getEmbeddedTemplate) {
|
||||
return {
|
||||
restrict: 'CA',
|
||||
priority: 10,
|
||||
compile: function(element, attr) {
|
||||
setHtmlIe8SafeWay(element, escape(getEmbeddedTemplate(attr.ngSetText)));
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
||||
|
||||
directive.ngHtmlWrap = ['reindentCode', 'templateMerge', function(reindentCode, templateMerge) {
|
||||
return {
|
||||
compile: function(element, attr) {
|
||||
var properties = {
|
||||
head: '',
|
||||
module: '',
|
||||
body: element.text()
|
||||
},
|
||||
html = "<!doctype html>\n<html ng-app{{module}}>\n <head>\n{{head:4}} </head>\n <body>\n{{body:4}} </body>\n</html>";
|
||||
|
||||
angular.forEach((attr.ngHtmlWrap || '').split(' '), function(dep) {
|
||||
if (!dep) return;
|
||||
dep = DEPENDENCIES[dep] || dep;
|
||||
|
||||
var ext = dep.split(/\./).pop();
|
||||
|
||||
if (ext == 'css') {
|
||||
properties.head += '<link rel="stylesheet" href="' + dep + '" type="text/css">\n';
|
||||
} else if(ext == 'js') {
|
||||
properties.head += '<script src="' + dep + '"></script>\n';
|
||||
} else {
|
||||
properties.module = '="' + dep + '"';
|
||||
}
|
||||
});
|
||||
|
||||
setHtmlIe8SafeWay(element, escape(templateMerge(html, properties)));
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
|
||||
directive.ngSetHtml = ['getEmbeddedTemplate', function(getEmbeddedTemplate) {
|
||||
return {
|
||||
restrict: 'CA',
|
||||
priority: 10,
|
||||
compile: function(element, attr) {
|
||||
setHtmlIe8SafeWay(element, getEmbeddedTemplate(attr.ngSetHtml));
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
|
||||
directive.ngEvalJavascript = ['getEmbeddedTemplate', function(getEmbeddedTemplate) {
|
||||
return {
|
||||
compile: function (element, attr) {
|
||||
var fileNames = attr.ngEvalJavascript.split(' ');
|
||||
angular.forEach(fileNames, function(fileName) {
|
||||
var script = getEmbeddedTemplate(fileName);
|
||||
try {
|
||||
if (window.execScript) { // IE
|
||||
window.execScript(script || '""'); // IE complains when evaling empty string
|
||||
} else {
|
||||
window.eval(script + '//@ sourceURL=' + fileName);
|
||||
}
|
||||
} catch (e) {
|
||||
if (window.console) {
|
||||
window.console.log(script, '\n', e);
|
||||
} else {
|
||||
window.alert(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}];
|
||||
|
||||
|
||||
directive.ngEmbedApp = ['$templateCache', '$browser', '$rootScope', '$location', '$sniffer', '$animate',
|
||||
function($templateCache, $browser, docsRootScope, $location, $sniffer, $animate) {
|
||||
return {
|
||||
terminal: true,
|
||||
link: function(scope, element, attrs) {
|
||||
var modules = ['ngAnimate'],
|
||||
embedRootScope,
|
||||
deregisterEmbedRootScope;
|
||||
|
||||
modules.push(['$provide', function($provide) {
|
||||
$provide.value('$templateCache', $templateCache);
|
||||
$provide.value('$anchorScroll', angular.noop);
|
||||
$provide.value('$browser', $browser);
|
||||
$provide.value('$sniffer', $sniffer);
|
||||
$provide.value('$animate', $animate);
|
||||
$provide.provider('$location', function() {
|
||||
this.$get = ['$rootScope', function($rootScope) {
|
||||
docsRootScope.$on('$locationChangeSuccess', function(event, oldUrl, newUrl) {
|
||||
$rootScope.$broadcast('$locationChangeSuccess', oldUrl, newUrl);
|
||||
});
|
||||
return $location;
|
||||
}];
|
||||
this.html5Mode = angular.noop;
|
||||
});
|
||||
$provide.decorator('$timeout', ['$rootScope', '$delegate', function($rootScope, $delegate) {
|
||||
return angular.extend(function(fn, delay) {
|
||||
if (delay && delay > 50) {
|
||||
return setTimeout(function() {
|
||||
$rootScope.$apply(fn);
|
||||
}, delay);
|
||||
} else {
|
||||
return $delegate.apply(this, arguments);
|
||||
}
|
||||
}, $delegate);
|
||||
}]);
|
||||
$provide.decorator('$rootScope', ['$delegate', function($delegate) {
|
||||
embedRootScope = $delegate;
|
||||
|
||||
// Since we are teleporting the $animate service, which relies on the $$postDigestQueue
|
||||
// we need the embedded scope to use the same $$postDigestQueue as the outer scope
|
||||
embedRootScope.$$postDigestQueue = docsRootScope.$$postDigestQueue;
|
||||
|
||||
deregisterEmbedRootScope = docsRootScope.$watch(function embedRootScopeDigestWatch() {
|
||||
embedRootScope.$digest();
|
||||
});
|
||||
|
||||
return embedRootScope;
|
||||
}]);
|
||||
}]);
|
||||
if (attrs.ngEmbedApp) modules.push(attrs.ngEmbedApp);
|
||||
|
||||
element.on('click', function(event) {
|
||||
if (event.target.attributes.getNamedItem('ng-click')) {
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
element.bind('$destroy', function() {
|
||||
deregisterEmbedRootScope();
|
||||
embedRootScope.$destroy();
|
||||
});
|
||||
|
||||
element.data('$injector', null);
|
||||
angular.bootstrap(element, modules);
|
||||
}
|
||||
};
|
||||
}];
|
||||
|
||||
service.reindentCode = function() {
|
||||
return function (text, spaces) {
|
||||
if (!text) return text;
|
||||
var lines = text.split(/\r?\n/);
|
||||
var prefix = ' '.substr(0, spaces || 0);
|
||||
var i;
|
||||
|
||||
// remove any leading blank lines
|
||||
while (lines.length && lines[0].match(/^\s*$/)) lines.shift();
|
||||
// remove any trailing blank lines
|
||||
while (lines.length && lines[lines.length - 1].match(/^\s*$/)) lines.pop();
|
||||
var minIndent = 999;
|
||||
for (i = 0; i < lines.length; i++) {
|
||||
var line = lines[0];
|
||||
var reindentCode = line.match(/^\s*/)[0];
|
||||
if (reindentCode !== line && reindentCode.length < minIndent) {
|
||||
minIndent = reindentCode.length;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < lines.length; i++) {
|
||||
lines[i] = prefix + lines[i].substring(minIndent);
|
||||
}
|
||||
lines.push('');
|
||||
return lines.join('\n');
|
||||
}
|
||||
};
|
||||
|
||||
service.templateMerge = ['reindentCode', function(indentCode) {
|
||||
return function(template, properties) {
|
||||
return template.replace(/\{\{(\w+)(?:\:(\d+))?\}\}/g, function(_, key, indent) {
|
||||
var value = properties[key];
|
||||
|
||||
if (indent) {
|
||||
value = indentCode(value, indent);
|
||||
}
|
||||
|
||||
return value == undefined ? '' : value;
|
||||
});
|
||||
};
|
||||
}];
|
||||
|
||||
service.getEmbeddedTemplate = ['reindentCode', function(reindentCode) {
|
||||
return function (id) {
|
||||
var element = document.getElementById(id);
|
||||
|
||||
if (!element) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return reindentCode(angular.element(element).html(), 0);
|
||||
}
|
||||
}];
|
||||
|
||||
|
||||
angular.module('bootstrapPrettify', []).directive(directive).factory(service);
|
||||
-392
@@ -1,392 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var directive = {};
|
||||
|
||||
directive.dropdownToggle =
|
||||
['$document', '$location', '$window',
|
||||
function ($document, $location, $window) {
|
||||
var openElement = null, close;
|
||||
return {
|
||||
restrict: 'C',
|
||||
link: function(scope, element, attrs) {
|
||||
scope.$watch(function dropdownTogglePathWatch(){return $location.path();}, function dropdownTogglePathWatchAction() {
|
||||
close && close();
|
||||
});
|
||||
|
||||
element.parent().on('click', function(event) {
|
||||
close && close();
|
||||
});
|
||||
|
||||
element.on('click', function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
var iWasOpen = false;
|
||||
|
||||
if (openElement) {
|
||||
iWasOpen = openElement === element;
|
||||
close();
|
||||
}
|
||||
|
||||
if (!iWasOpen){
|
||||
element.parent().addClass('open');
|
||||
openElement = element;
|
||||
|
||||
close = function (event) {
|
||||
event && event.preventDefault();
|
||||
event && event.stopPropagation();
|
||||
$document.off('click', close);
|
||||
element.parent().removeClass('open');
|
||||
close = null;
|
||||
openElement = null;
|
||||
}
|
||||
|
||||
$document.on('click', close);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}];
|
||||
|
||||
directive.syntax = function() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, element, attrs) {
|
||||
function makeLink(type, text, link, icon) {
|
||||
return '<a href="' + link + '" class="btn syntax-' + type + '" target="_blank" rel="nofollow">' +
|
||||
'<span class="' + icon + '"></span> ' + text +
|
||||
'</a>';
|
||||
};
|
||||
|
||||
var html = '';
|
||||
var types = {
|
||||
'github' : {
|
||||
text : 'View on Github',
|
||||
key : 'syntaxGithub',
|
||||
icon : 'icon-github'
|
||||
},
|
||||
'plunkr' : {
|
||||
text : 'View on Plunkr',
|
||||
key : 'syntaxPlunkr',
|
||||
icon : 'icon-arrow-down'
|
||||
},
|
||||
'jsfiddle' : {
|
||||
text : 'View on JSFiddle',
|
||||
key : 'syntaxFiddle',
|
||||
icon : 'icon-cloud'
|
||||
}
|
||||
};
|
||||
for(var type in types) {
|
||||
var data = types[type];
|
||||
var link = attrs[data.key];
|
||||
if(link) {
|
||||
html += makeLink(type, data.text, link, data.icon);
|
||||
}
|
||||
};
|
||||
|
||||
var nav = document.createElement('nav');
|
||||
nav.className = 'syntax-links';
|
||||
nav.innerHTML = html;
|
||||
|
||||
var node = element[0];
|
||||
var par = node.parentNode;
|
||||
par.insertBefore(nav, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
directive.tabbable = function() {
|
||||
return {
|
||||
restrict: 'C',
|
||||
compile: function(element) {
|
||||
var navTabs = angular.element('<ul class="nav nav-tabs"></ul>'),
|
||||
tabContent = angular.element('<div class="tab-content"></div>');
|
||||
|
||||
tabContent.append(element.contents());
|
||||
element.append(navTabs).append(tabContent);
|
||||
},
|
||||
controller: ['$scope', '$element', function($scope, $element) {
|
||||
var navTabs = $element.contents().eq(0),
|
||||
ngModel = $element.controller('ngModel') || {},
|
||||
tabs = [],
|
||||
selectedTab;
|
||||
|
||||
ngModel.$render = function() {
|
||||
var $viewValue = this.$viewValue;
|
||||
|
||||
if (selectedTab ? (selectedTab.value != $viewValue) : $viewValue) {
|
||||
if(selectedTab) {
|
||||
selectedTab.paneElement.removeClass('active');
|
||||
selectedTab.tabElement.removeClass('active');
|
||||
selectedTab = null;
|
||||
}
|
||||
if($viewValue) {
|
||||
for(var i = 0, ii = tabs.length; i < ii; i++) {
|
||||
if ($viewValue == tabs[i].value) {
|
||||
selectedTab = tabs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (selectedTab) {
|
||||
selectedTab.paneElement.addClass('active');
|
||||
selectedTab.tabElement.addClass('active');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
this.addPane = function(element, attr) {
|
||||
var li = angular.element('<li><a href></a></li>'),
|
||||
a = li.find('a'),
|
||||
tab = {
|
||||
paneElement: element,
|
||||
paneAttrs: attr,
|
||||
tabElement: li
|
||||
};
|
||||
|
||||
tabs.push(tab);
|
||||
|
||||
attr.$observe('value', update)();
|
||||
attr.$observe('title', function(){ update(); a.text(tab.title); })();
|
||||
|
||||
function update() {
|
||||
tab.title = attr.title;
|
||||
tab.value = attr.value || attr.title;
|
||||
if (!ngModel.$setViewValue && (!ngModel.$viewValue || tab == selectedTab)) {
|
||||
// we are not part of angular
|
||||
ngModel.$viewValue = tab.value;
|
||||
}
|
||||
ngModel.$render();
|
||||
}
|
||||
|
||||
navTabs.append(li);
|
||||
li.on('click', function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if (ngModel.$setViewValue) {
|
||||
$scope.$apply(function() {
|
||||
ngModel.$setViewValue(tab.value);
|
||||
ngModel.$render();
|
||||
});
|
||||
} else {
|
||||
// we are not part of angular
|
||||
ngModel.$viewValue = tab.value;
|
||||
ngModel.$render();
|
||||
}
|
||||
});
|
||||
|
||||
return function() {
|
||||
tab.tabElement.remove();
|
||||
for(var i = 0, ii = tabs.length; i < ii; i++ ) {
|
||||
if (tab == tabs[i]) {
|
||||
tabs.splice(i, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}]
|
||||
};
|
||||
};
|
||||
|
||||
directive.table = function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function(scope, element, attrs) {
|
||||
if (!attrs['class']) {
|
||||
element.addClass('table table-bordered table-striped code-table');
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var popoverElement = function() {
|
||||
var object = {
|
||||
init : function() {
|
||||
this.element = angular.element(
|
||||
'<div class="popover popover-incode top">' +
|
||||
'<div class="arrow"></div>' +
|
||||
'<div class="popover-inner">' +
|
||||
'<div class="popover-title"><code></code></div>' +
|
||||
'<div class="popover-content"></div>' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
this.node = this.element[0];
|
||||
this.element.css({
|
||||
'display':'block',
|
||||
'position':'absolute'
|
||||
});
|
||||
angular.element(document.body).append(this.element);
|
||||
|
||||
var inner = this.element.children()[1];
|
||||
this.titleElement = angular.element(inner.childNodes[0].firstChild);
|
||||
this.contentElement = angular.element(inner.childNodes[1]);
|
||||
|
||||
//stop the click on the tooltip
|
||||
this.element.bind('click', function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
var self = this;
|
||||
angular.element(document.body).bind('click',function(event) {
|
||||
if(self.visible()) self.hide();
|
||||
});
|
||||
},
|
||||
|
||||
show : function(x,y) {
|
||||
this.element.addClass('visible');
|
||||
this.position(x || 0, y || 0);
|
||||
},
|
||||
|
||||
hide : function() {
|
||||
this.element.removeClass('visible');
|
||||
this.position(-9999,-9999);
|
||||
},
|
||||
|
||||
visible : function() {
|
||||
return this.position().y >= 0;
|
||||
},
|
||||
|
||||
isSituatedAt : function(element) {
|
||||
return this.besideElement ? element[0] == this.besideElement[0] : false;
|
||||
},
|
||||
|
||||
title : function(value) {
|
||||
return this.titleElement.html(value);
|
||||
},
|
||||
|
||||
content : function(value) {
|
||||
if(value && value.length > 0) {
|
||||
value = marked(value);
|
||||
}
|
||||
return this.contentElement.html(value);
|
||||
},
|
||||
|
||||
positionArrow : function(position) {
|
||||
this.node.className = 'popover ' + position;
|
||||
},
|
||||
|
||||
positionAway : function() {
|
||||
this.besideElement = null;
|
||||
this.hide();
|
||||
},
|
||||
|
||||
positionBeside : function(element) {
|
||||
this.besideElement = element;
|
||||
|
||||
var elm = element[0];
|
||||
var x = elm.offsetLeft;
|
||||
var y = elm.offsetTop;
|
||||
x -= 30;
|
||||
y -= this.node.offsetHeight + 10;
|
||||
this.show(x,y);
|
||||
},
|
||||
|
||||
position : function(x,y) {
|
||||
if(x != null && y != null) {
|
||||
this.element.css('left',x + 'px');
|
||||
this.element.css('top', y + 'px');
|
||||
}
|
||||
else {
|
||||
return {
|
||||
x : this.node.offsetLeft,
|
||||
y : this.node.offsetTop
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
object.init();
|
||||
object.hide();
|
||||
|
||||
return object;
|
||||
};
|
||||
|
||||
directive.popover = ['popoverElement', function(popover) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
priority : 500,
|
||||
link: function(scope, element, attrs) {
|
||||
element.bind('click',function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if(popover.isSituatedAt(element) && popover.visible()) {
|
||||
popover.title('');
|
||||
popover.content('');
|
||||
popover.positionAway();
|
||||
}
|
||||
else {
|
||||
popover.title(attrs.title);
|
||||
popover.content(attrs.content);
|
||||
popover.positionBeside(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
directive.tabPane = function() {
|
||||
return {
|
||||
require: '^tabbable',
|
||||
restrict: 'C',
|
||||
link: function(scope, element, attrs, tabsCtrl) {
|
||||
element.on('$remove', tabsCtrl.addPane(element, attrs));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
directive.foldout = ['$http', '$animate','$window', function($http, $animate, $window) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
priority : 500,
|
||||
link: function(scope, element, attrs) {
|
||||
var container, loading, url = attrs.url;
|
||||
if(/\/build\//.test($window.location.href)) {
|
||||
url = '/build/docs' + url;
|
||||
}
|
||||
element.bind('click',function() {
|
||||
scope.$apply(function() {
|
||||
if(!container) {
|
||||
if(loading) return;
|
||||
|
||||
loading = true;
|
||||
var par = element.parent();
|
||||
container = angular.element('<div class="foldout">loading...</div>');
|
||||
$animate.enter(container, null, par);
|
||||
|
||||
$http.get(url, { cache : true }).success(function(html) {
|
||||
loading = false;
|
||||
|
||||
html = '<div class="foldout-inner">' +
|
||||
'<div calss="foldout-arrow"></div>' +
|
||||
html +
|
||||
'</div>';
|
||||
container.html(html);
|
||||
|
||||
//avoid showing the element if the user has already closed it
|
||||
if(container.css('display') == 'block') {
|
||||
container.css('display','none');
|
||||
$animate.addClass(container, 'ng-hide');
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
container.hasClass('ng-hide') ? $animate.removeClass(container, 'ng-hide') : $animate.addClass(container, 'ng-hide');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
angular.module('bootstrap', [])
|
||||
.directive(directive)
|
||||
.factory('popoverElement', popoverElement)
|
||||
.run(function() {
|
||||
marked.setOptions({
|
||||
gfm: true,
|
||||
tables: true
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
@workInProgress
|
||||
@ngdoc overview
|
||||
@name angular.service
|
||||
@description
|
||||
|
||||
The services API provides objects for carrying out common web app tasks. Service objects are
|
||||
managed by angular's {@link guide/dev_guide.di dependency injection system}.
|
||||
|
||||
* {@link angular.service.$browser $browser } - Provides an instance of a browser object
|
||||
* {@link angular.service.$cookieStore $cookieStore } - Provides key / value storage backed by
|
||||
session cookies
|
||||
* {@link angular.service.$cookies $cookies } - Provides read / write access to browser cookies
|
||||
* {@link angular.service.$defer $defer } - Defers function execution and try / catch block
|
||||
* {@link angular.service.$document $document } - Provides reference to `window.document` element
|
||||
* {@link angular.service.$exceptionHandler $exceptionHandler } - Receives uncaught angular
|
||||
exceptions
|
||||
* {@link angular.service.$hover $hover } -
|
||||
* {@link angular.service.$invalidWidgets $invalidWidgets } - Holds references to invalid widgets
|
||||
* {@link angular.service.$location $location } - Parses the browser location URL
|
||||
* {@link angular.service.$log $log } - Provides logging service
|
||||
* {@link angular.service.$resource $resource } - Creates objects for interacting with RESTful
|
||||
server-side data sources
|
||||
* {@link angular.service.$route $route } - Provides deep-linking services
|
||||
* {@link angular.service.$updateView $updateView } - Queues view updates
|
||||
* {@link angular.service.$window $window } - References the browsers `window` object
|
||||
* {@link angular.service.$xhr $xhr} - Generates an XHR request.
|
||||
|
||||
For information on how angular services work and how to write your own services, see {@link
|
||||
guide/dev_guide.services Angular Services} in the angular Developer Guide.
|
||||
+46
-270
@@ -2,297 +2,73 @@
|
||||
@name API Reference
|
||||
@description
|
||||
|
||||
# AngularJS API Docs
|
||||
Welcome to the AngularJS API docs page. These pages contain the AngularJS reference materials for version <strong ng-bind="version"></strong>.
|
||||
## Angular Compiler API
|
||||
|
||||
The documentation is organized into **modules** which contain various components of an AngularJS application.
|
||||
These components are directives, services, filters, providers, types, global APIs and testing mocks.
|
||||
* {@link angular.widget Widgets} - Angular custom DOM element
|
||||
* {@link angular.directive Directives} - Angular DOM element attributes
|
||||
* {@link angular.markup Markup} and {@link angular.attrMarkup Attribute Markup}
|
||||
* {@link angular.filter Filters} - Angular output filters
|
||||
* {@link angular.formatter Formatters} - Angular converters for form elements
|
||||
* {@link angular.validator Validators} - Angular input validators
|
||||
* {@link angular.compile angular.compile()} - Template compiler
|
||||
|
||||
<div class="alert alert-info">
|
||||
**Angular Namespaces `$` and `$$`**
|
||||
## Angular Scope API
|
||||
|
||||
To prevent accidental name collisions with your code,
|
||||
Angular prefixes names of public objects with `$` and names of private objects with `$$`.
|
||||
Please do not use the `$` or `$$` prefix in your code.
|
||||
</div>
|
||||
|
||||
## Angular Namespace
|
||||
* {@link angular.scope Scope Object} - Angular scope object
|
||||
|
||||
|
||||
## {@link ng ng (core module)}
|
||||
This module is provided by default and contains the core components of AngularJS.
|
||||
## Angular Services & Dependency Injection API
|
||||
|
||||
<table class="definition-table spaced">
|
||||
<tr>
|
||||
<td>{@link ng#directive Directives}</td>
|
||||
<td>
|
||||
<p>
|
||||
This is the core collection of directives you would use in your template code to build an AngularJS application.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Some examples include:
|
||||
{@link ng.directive:ngClick ngClick},
|
||||
{@link ng.directive:ngInclude ngInclude},
|
||||
{@link ng.directive:ngRepeat ngRepeat},
|
||||
etc… <br />
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{@link ng#service Services / Factories}
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
This is the core collection of services which are used within the DI of your application.
|
||||
</p>
|
||||
<p>
|
||||
Some examples include:
|
||||
{@link ng.$compile $compile},
|
||||
{@link ng.$http $http},
|
||||
{@link ngRoute.$routeParams $routeParams},
|
||||
{@link ng.$location $location},
|
||||
etc…
|
||||
<p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{@link ng#filter Filters}
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
The core filters available in the ng module are used to transform template data before it is renders within directives and expressions.
|
||||
</p>
|
||||
<p>
|
||||
Some examples include:
|
||||
{@link ng.filter:filter filter},
|
||||
{@link ng.filter:date date},
|
||||
{@link ng.filter:currency currency},
|
||||
{@link ng.filter:lowercase lowercase},
|
||||
{@link ng.filter:uppercase uppercase},
|
||||
etc...
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{@link ng#function Global APIs}
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
The core global API functions are attached to the angular object. These core functions are useful for low level JavaScript operations within your application.
|
||||
</p>
|
||||
<p>
|
||||
Some examples include:
|
||||
{@link angular.copy angular.copy()},
|
||||
{@link angular.equals angular.equals()},
|
||||
{@link angular.element angular.element()},
|
||||
etc...
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
* {@link angular.service Angular Services}
|
||||
* {@link angular.injector angular.injector() }
|
||||
|
||||
|
||||
## {@link ngRoute ngRoute}
|
||||
## Angular Testing API
|
||||
|
||||
Use ngRoute to enable URL routing to your application. The ngRoute module supports URL management via both hashbang and HTML5 pushState.
|
||||
|
||||
<div class="alert alert-info">Include the **angular-route.js** file and set **ngRoute** as a dependency for this to work in your application.</div>
|
||||
|
||||
<table class="definition-table spaced">
|
||||
<tr>
|
||||
<td>
|
||||
{@link ngRoute#service Services / Factories}
|
||||
</td>
|
||||
<td>
|
||||
The following services are used for route management:
|
||||
<ul>
|
||||
<li>{@link ngRoute.$routeParams $routeParams} is used to access the querystring values present in the URL.</li>
|
||||
<li>{@link ngRoute.$route $route} is used to access the details of the route that is currently being accessed.</li>
|
||||
<li>{@link ngRoute.$routeProvider $routeProvider} is used to register routes for the application.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{@link ngRoute#directive Directives}
|
||||
</td>
|
||||
<td>
|
||||
The {@link ngRoute.directive:ngView ngView} directive will display the template of the current route within the page.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
* {@link angular.mock Testing Mocks API} - Mock objects for testing
|
||||
* {@link
|
||||
https://docs.google.com/document/d/11L8htLKrh6c92foV71ytYpiKkeKpM4_a5-9c3HywfIc/edit?hl=en_US
|
||||
Angular Scenario Runner} - Automated scenario testing documentation
|
||||
|
||||
|
||||
## {@link ngAnimate ngAnimate}
|
||||
## Angular Utility Functions
|
||||
|
||||
Use ngAnimate to enable animation features into your application. Various core ng directives will provide
|
||||
animation hooks into your application when ngAnimate is included. Animations are defined by using CSS transitions/animations
|
||||
or JavaScript callbacks.
|
||||
### HTML & DOM Manipulation
|
||||
|
||||
<div class="alert alert-info">Include the **angular-animate.js** file and set **ngAnimate** as a dependency for this to work in your application.</div>
|
||||
* {@link angular.element angular.element()}
|
||||
|
||||
<table class="definition-table spaced">
|
||||
<tr>
|
||||
<td>
|
||||
{@link ngAnimate#service Services / Factories}
|
||||
</td>
|
||||
<td>
|
||||
Use {@link ngAnimate.$animate $animate} to trigger animation operations within your directive code.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{@link ngAnimate CSS-based animations}
|
||||
</td>
|
||||
<td>
|
||||
Follow ngAnimate’s CSS naming structure to reference CSS transitions / keyframe animations in AngularJS. Once defined the animation can be triggered by referencing the CSS class within the HTML template code.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{@link ngAnimate JS-based animations}
|
||||
</td>
|
||||
<td>
|
||||
Use {@link angular.Module#methods_animation module.animation()} to register a JavaScript animation. Once registered the animation can be triggered by referencing the CSS class within the HTML template code.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
### Misc
|
||||
|
||||
* {@link angular.bind angular.bind() }
|
||||
* {@link angular.extend angular.extend() }
|
||||
* {@link angular.forEach angular.forEach() }
|
||||
* {@link angular.identity angular.identity() }
|
||||
* {@link angular.noop angular.noop() }
|
||||
|
||||
|
||||
## {@link ngResource ngResource}
|
||||
## Type Identification
|
||||
|
||||
Use the ngResource module when querying and posting data to a REST API.
|
||||
* {@link angular.isArray angular.isArray() }
|
||||
* {@link angular.isDate angular.isDate() }
|
||||
* {@link angular.isDefined angular.isDefined() }
|
||||
* {@link angular.isFunction angular.isFunction() }
|
||||
* {@link angular.isNumber angular.isNumber() }
|
||||
* {@link angular.isObject angular.isObject() }
|
||||
* {@link angular.isString angular.isString() }
|
||||
* {@link angular.isUndefined angular.isUndefined() }
|
||||
|
||||
<div class="alert alert-info">Include the **angular-resource.js** file and set **ngResource** as a dependency for this to work in your application.</div>
|
||||
## Strings
|
||||
|
||||
<table class="definition-table spaced">
|
||||
<tr>
|
||||
<td>
|
||||
{@link ngResource#service Services / Factories}
|
||||
</td>
|
||||
<td>
|
||||
The {@link ngResource.$resource $resource} service is used to define RESTful objects which communicate with a REST API.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
* {@link angular.lowercase angular.lowercase() }
|
||||
* {@link angular.uppercase angular.uppercase() }
|
||||
|
||||
## {@link ngCookies ngCookies}
|
||||
### JSON
|
||||
|
||||
Use the ngCookies module to handle cookie management within your application.
|
||||
* {@link angular.fromJson angular.fromJson() }
|
||||
* {@link angular.toJson angular.toJson() }
|
||||
|
||||
<div class="alert alert-info">Include the **angular-cookies.js** file and set **ngCookies** as a dependency for this to work in your application.</div>
|
||||
|
||||
<table class="definition-table spaced">
|
||||
<tr>
|
||||
<td>
|
||||
{@link ngCookies#service Services / Factories}
|
||||
</td>
|
||||
<td>
|
||||
The following services are used for cookie management:
|
||||
<ul>
|
||||
<li>The {@link ngCookies.$cookies $cookie} service is a convenient wrapper to store simple data within browser cookies.</li>
|
||||
<li>{@link ngCookies.$cookieStore $cookieStore} is used to store more complex data using serialization.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## {@link ngTouch ngTouch}
|
||||
|
||||
Use ngTouch when developing for mobile browsers/devices.
|
||||
|
||||
<div class="alert alert-info">Include the **angular-touch.js** file and set **ngTouch** as a dependency for this to work in your application.</div>
|
||||
|
||||
<table class="definition-table spaced">
|
||||
<tr>
|
||||
<td>
|
||||
{@link ngTouch#service Services / Factories}
|
||||
</td>
|
||||
<td>
|
||||
The {@link ngTouch.$swipe $swipe} service is used to register and manage mobile DOM events.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{@link ngTouch#directive Directives}
|
||||
</td>
|
||||
<td>
|
||||
Various directives are available in ngTouch to emulate mobile DOM events.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## {@link ngSanitize ngSanitize}
|
||||
|
||||
Use ngSanitize to securely parse and manipulate HTML data in your application.
|
||||
|
||||
<div class="alert alert-info">Include the **angular-sanitize.js** file and set **ngSanitize** as a dependency for this to work in your application.</div>
|
||||
|
||||
<table class="definition-table spaced">
|
||||
<tr>
|
||||
<td>
|
||||
{@link ngSanitize#service Services / Factories}
|
||||
</td>
|
||||
<td>
|
||||
The {@link ngSanitize.$sanitize $sanitize} service is used to clean up dangerous HTML code in a quick and convenient way.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{@link ngTouch#filter Filters}
|
||||
</td>
|
||||
<td>
|
||||
The {@link ngSanitize.filter:linky linky filter} is used to turn URLs into HTML links within the provided string.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## {@link ngMock ngMock}
|
||||
|
||||
Use ngMock to inject and mock modules, factories, services and providers within your unit tests
|
||||
|
||||
<div class="alert alert-info">Include the **angular-mocks.js** file into your test runner for this to work.</div>
|
||||
|
||||
<table class="definition-table spaced">
|
||||
<tr>
|
||||
<td>
|
||||
{@link ngMock#service Services / Factories}
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
ngMock will extend the behavior of various core services to become testing aware and manageable in a synchronous manner.
|
||||
<p>
|
||||
|
||||
<p>
|
||||
Some examples include:
|
||||
{@link ngMock.$timeout $timeout},
|
||||
{@link ngMock.$interval $interval},
|
||||
{@link ngMock.$log $log},
|
||||
{@link ngMock.$httpBackend $httpBackend},
|
||||
etc...
|
||||
<p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{@link ngMock#function Global APIs}
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Various helper functions are available to inject and mock modules within unit test code.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Some examples
|
||||
{@link angular.mock.inject inject()},
|
||||
{@link angular.mock.module module()},
|
||||
{@link angular.mock.dump dump()},
|
||||
etc...
|
||||
<p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
## Utility methods for JavaScript types
|
||||
* {@link angular.Object Object API} - Utility functions for JavaScript objects
|
||||
* {@link angular.Array Array API} - Utility functions for JavaScript arrays
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
@ngdoc overview
|
||||
@name ng
|
||||
@description
|
||||
|
||||
# ng (core module)
|
||||
The ng module is loaded by default when an AngularJS application is started. The module itself contains the essential components to for an AngularJS application to function. The table below lists a high level breakdown of each of the services/factories, filters, directives and testing components available within this core module.
|
||||
|
||||
<div doc-module-components="ng"></div>
|
||||
@@ -1,3 +1,4 @@
|
||||
@workInProgress
|
||||
@ngdoc overview
|
||||
@name Cookbook: Advanced Form
|
||||
@description
|
||||
@@ -8,8 +9,12 @@ detection, and preventing invalid form submission.
|
||||
<doc:example>
|
||||
<doc:source>
|
||||
<script>
|
||||
function UserForm($scope) {
|
||||
var master = {
|
||||
UserForm.$inject = ['$invalidWidgets'];
|
||||
function UserForm($invalidWidgets){
|
||||
this.$invalidWidgets = $invalidWidgets;
|
||||
this.state = /^\w\w$/;
|
||||
this.zip = /^\d\d\d\d\d$/;
|
||||
this.master = {
|
||||
name: 'John Smith',
|
||||
address:{
|
||||
line1: '123 Main St.',
|
||||
@@ -21,76 +26,56 @@ detection, and preventing invalid form submission.
|
||||
{type:'phone', value:'1(234) 555-1212'}
|
||||
]
|
||||
};
|
||||
|
||||
$scope.state = /^\w\w$/;
|
||||
$scope.zip = /^\d\d\d\d\d$/;
|
||||
|
||||
$scope.cancel = function() {
|
||||
$scope.form = angular.copy(master);
|
||||
};
|
||||
|
||||
$scope.save = function() {
|
||||
master = $scope.form;
|
||||
$scope.cancel();
|
||||
};
|
||||
|
||||
$scope.addContact = function() {
|
||||
$scope.form.contacts.push({type:'', value:''});
|
||||
};
|
||||
|
||||
$scope.removeContact = function(index) {
|
||||
$scope.form.contacts.splice(index, 1);
|
||||
};
|
||||
|
||||
$scope.isCancelDisabled = function() {
|
||||
return angular.equals(master, $scope.form);
|
||||
};
|
||||
|
||||
$scope.isSaveDisabled = function() {
|
||||
return $scope.myForm.$invalid || angular.equals(master, $scope.form);
|
||||
};
|
||||
|
||||
$scope.cancel();
|
||||
this.cancel();
|
||||
}
|
||||
|
||||
UserForm.prototype = {
|
||||
cancel: function(){
|
||||
this.form = angular.copy(this.master);
|
||||
},
|
||||
|
||||
save: function(){
|
||||
this.master = this.form;
|
||||
this.cancel();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<div ng-controller="UserForm">
|
||||
<div ng:controller="UserForm">
|
||||
|
||||
<form name="myForm">
|
||||
<label>Name:</label><br/>
|
||||
<input type="text" name="form.name" ng:required/> <br/><br/>
|
||||
|
||||
<label>Name:</label><br/>
|
||||
<input type="text" ng-model="form.name" required/> <br/><br/>
|
||||
<label>Address:</label><br/>
|
||||
<input type="text" name="form.address.line1" size="33" ng:required/> <br/>
|
||||
<input type="text" name="form.address.city" size="12" ng:required/>,
|
||||
<input type="text" name="form.address.state" size="2" ng:required ng:validate="regexp:state"/>
|
||||
<input type="text" name="form.address.zip" size="5" ng:required
|
||||
ng:validate="regexp:zip"/><br/><br/>
|
||||
|
||||
<label>Address:</label> <br/>
|
||||
<input type="text" ng-model="form.address.line1" size="33" required/> <br/>
|
||||
<input type="text" ng-model="form.address.city" size="12" required/>,
|
||||
<input type="text" ng-model="form.address.state" size="2"
|
||||
ng-pattern="state" required/>
|
||||
<input type="text" ng-model="form.address.zip" size="5"
|
||||
ng-pattern="zip" required/><br/><br/>
|
||||
|
||||
<label>Contacts:</label>
|
||||
[ <a href="" ng-click="addContact()">add</a> ]
|
||||
<div ng-repeat="contact in form.contacts">
|
||||
<select ng-model="contact.type">
|
||||
<option>email</option>
|
||||
<option>phone</option>
|
||||
<option>pager</option>
|
||||
<option>IM</option>
|
||||
</select>
|
||||
<input type="text" ng-model="contact.value" required/>
|
||||
[ <a href="" ng-click="removeContact($index)">X</a> ]
|
||||
</div>
|
||||
<button ng-click="cancel()" ng-disabled="isCancelDisabled()">Cancel</button>
|
||||
<button ng-click="save()" ng-disabled="isSaveDisabled()">Save</button>
|
||||
</form>
|
||||
<label>Contacts:</label>
|
||||
[ <a href="" ng:click="form.contacts.$add()">add</a> ]
|
||||
<div ng:repeat="contact in form.contacts">
|
||||
<select name="contact.type">
|
||||
<option>email</option>
|
||||
<option>phone</option>
|
||||
<option>pager</option>
|
||||
<option>IM</option>
|
||||
</select>
|
||||
<input type="text" name="contact.value" ng:required/>
|
||||
[ <a href="" ng:click="form.contacts.$remove(contact)">X</a> ]
|
||||
</div>
|
||||
<button ng:click="cancel()" ng:disabled="{{master.$equals(form)}}">Cancel</button>
|
||||
<button ng:click="save()" ng:disabled="{{$invalidWidgets.visible() ||
|
||||
master.$equals(form)}}">Save</button>
|
||||
|
||||
<hr/>
|
||||
Debug View:
|
||||
<pre>form={{form}}</pre>
|
||||
<pre>form={{form}}
|
||||
master={{master}}</pre>
|
||||
</div>
|
||||
</doc:source>
|
||||
<doc:scenario>
|
||||
it('should enable save button', function() {
|
||||
it('should enable save button', function(){
|
||||
expect(element(':button:contains(Save)').attr('disabled')).toBeTruthy();
|
||||
input('form.name').enter('');
|
||||
expect(element(':button:contains(Save)').attr('disabled')).toBeTruthy();
|
||||
@@ -99,13 +84,13 @@ detection, and preventing invalid form submission.
|
||||
element(':button:contains(Save)').click();
|
||||
expect(element(':button:contains(Save)').attr('disabled')).toBeTruthy();
|
||||
});
|
||||
it('should enable cancel button', function() {
|
||||
it('should enable cancel button', function(){
|
||||
expect(element(':button:contains(Cancel)').attr('disabled')).toBeTruthy();
|
||||
input('form.name').enter('change');
|
||||
expect(element(':button:contains(Cancel)').attr('disabled')).toBeFalsy();
|
||||
element(':button:contains(Cancel)').click();
|
||||
expect(element(':button:contains(Cancel)').attr('disabled')).toBeTruthy();
|
||||
expect(element(':input[ng\\:model="form.name"]').val()).toEqual('John Smith');
|
||||
expect(element(':input[name=form.name]').val()).toEqual('John Smith');
|
||||
});
|
||||
</doc:scenario>
|
||||
</doc:example>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
@workInProgress
|
||||
@ngdoc overview
|
||||
@name Cookbook: Resources - Buzz
|
||||
@description
|
||||
|
||||
External resources are URLs that provide JSON data, which are then rendered with the help of
|
||||
templates. Angular has a resource factory that can be used to give names to the URLs and then
|
||||
templates. angular has a resource factory that can be used to give names to the URLs and then
|
||||
attach behavior to them. For example you can use the
|
||||
{@link http://code.google.com/apis/buzz/v1/getting_started.html#background-operations| Google Buzz
|
||||
API}
|
||||
@@ -12,41 +13,40 @@ to retrieve Buzz activity and comments.
|
||||
<doc:example>
|
||||
<doc:source>
|
||||
<script>
|
||||
BuzzController.$inject = ['$scope', '$resource'];
|
||||
function BuzzController($scope, $resource) {
|
||||
$scope.userId = 'googlebuzz';
|
||||
$scope.Activity = $resource(
|
||||
BuzzController.$inject = ['$resource'];
|
||||
function BuzzController($resource) {
|
||||
this.Activity = $resource(
|
||||
'https://www.googleapis.com/buzz/v1/activities/:userId/:visibility/:activityId/:comments',
|
||||
{alt: 'json', callback: 'JSON_CALLBACK'},
|
||||
{ get: {method: 'JSONP', params: {visibility: '@self'}},
|
||||
replies: {method: 'JSONP', params: {visibility: '@self', comments: '@comments'}}
|
||||
{ get: {method: 'JSON', params: {visibility: '@self'}},
|
||||
replies: {method: 'JSON', params: {visibility: '@self', comments: '@comments'}}
|
||||
});
|
||||
|
||||
$scope.fetch = function() {
|
||||
$scope.activities = $scope.Activity.get({userId:this.userId});
|
||||
}
|
||||
|
||||
$scope.expandReplies = function(activity) {
|
||||
activity.replies = $scope.Activity.replies({userId: this.userId, activityId: activity.id});
|
||||
}
|
||||
BuzzController.prototype = {
|
||||
fetch: function() {
|
||||
this.activities = this.Activity.get({userId:this.userId});
|
||||
},
|
||||
expandReplies: function(activity) {
|
||||
activity.replies = this.Activity.replies({userId: this.userId, activityId: activity.id});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<div ng-controller="BuzzController">
|
||||
<input ng-model="userId"/>
|
||||
<button ng-click="fetch()">fetch</button>
|
||||
<div ng:controller="BuzzController">
|
||||
<input name="userId" value="googlebuzz"/>
|
||||
<button ng:click="fetch()">fetch</button>
|
||||
<hr/>
|
||||
<div class="buzz" ng-repeat="item in activities.data.items">
|
||||
<div class="buzz" ng:repeat="item in activities.data.items">
|
||||
<h1 style="font-size: 15px;">
|
||||
<img ng-src="{{item.actor.thumbnailUrl}}" style="max-height:30px;max-width:30px;"/>
|
||||
<a ng-href="{{item.actor.profileUrl}}">{{item.actor.name}}</a>
|
||||
<a href ng-click="expandReplies(item)" style="float: right;">
|
||||
<img ng:src="{{item.actor.thumbnailUrl}}" style="max-height:30px;max-width:30px;"/>
|
||||
<a ng:href="{{item.actor.profileUrl}}">{{item.actor.name}}</a>
|
||||
<a href ng:click="expandReplies(item)" style="float: right;">
|
||||
Expand replies: {{item.links.replies[0].count}}
|
||||
</a>
|
||||
</h1>
|
||||
{{item.object.content | html}}
|
||||
<div class="reply" ng-repeat="reply in item.replies.data.items" style="margin-left: 20px;">
|
||||
<img ng-src="{{reply.actor.thumbnailUrl}}" style="max-height:30px;max-width:30px;"/>
|
||||
<a ng-href="{{reply.actor.profileUrl}}">{{reply.actor.name}}</a>:
|
||||
<div class="reply" ng:repeat="reply in item.replies.data.items" style="margin-left: 20px;">
|
||||
<img ng:src="{{reply.actor.thumbnailUrl}}" style="max-height:30px;max-width:30px;"/>
|
||||
<a ng:href="{{reply.actor.profileUrl}}">{{reply.actor.name}}</a>:
|
||||
{{reply.content | html}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@workInProgress
|
||||
@ngdoc overview
|
||||
@name Cookbook: Deep Linking
|
||||
@description
|
||||
@@ -5,7 +6,7 @@
|
||||
Deep linking allows you to encode the state of the application in the URL so that it can be
|
||||
bookmarked and the application can be restored from the URL to the same state.
|
||||
|
||||
While Angular does not force you to deal with bookmarks in any particular way, it has services
|
||||
While <angular/> does not force you to deal with bookmarks in any particular way, it has services
|
||||
which make the common case described here very easy to implement.
|
||||
|
||||
# Assumptions
|
||||
@@ -27,125 +28,88 @@ controller.
|
||||
|
||||
In this example we have a simple app which consist of two screens:
|
||||
|
||||
* Welcome: url `welcome` Show the user contact information.
|
||||
* Settings: url `settings` Show an edit screen for user contact information.
|
||||
* Welcome: url `#` Show the user contact information.
|
||||
* Settings: url `#/settings` Show an edit screen for user contact information.
|
||||
|
||||
<example module="deepLinking" deps="angular-route.js, angular-sanitize.js">
|
||||
<file name="script.js">
|
||||
angular.module('deepLinking', ['ngRoute', 'ngSanitize'])
|
||||
.config(function($routeProvider) {
|
||||
$routeProvider.
|
||||
when("/welcome", {templateUrl:'welcome.html', controller:WelcomeCntl}).
|
||||
when("/settings", {templateUrl:'settings.html', controller:SettingsCntl});
|
||||
});
|
||||
|
||||
AppCntl.$inject = ['$scope', '$route']
|
||||
function AppCntl($scope, $route) {
|
||||
$scope.$route = $route;
|
||||
The two partials are defined in the following URLs:
|
||||
|
||||
// initialize the model to something useful
|
||||
$scope.person = {
|
||||
name:'anonymous',
|
||||
contacts:[{type:'email', url:'anonymous@example.com'}]
|
||||
};
|
||||
}
|
||||
* {@link ./examples/settings.html}
|
||||
* {@link ./examples/welcome.html}
|
||||
|
||||
function WelcomeCntl($scope) {
|
||||
$scope.greet = function() {
|
||||
alert("Hello " + $scope.person.name);
|
||||
};
|
||||
}
|
||||
<doc:example>
|
||||
<doc:source>
|
||||
<script>
|
||||
AppCntl.$inject = ['$route']
|
||||
function AppCntl($route) {
|
||||
// define routes
|
||||
$route.when("", {template:'./examples/welcome.html', controller:WelcomeCntl});
|
||||
$route.when("/settings", {template:'./examples/settings.html', controller:SettingsCntl});
|
||||
$route.parent(this);
|
||||
|
||||
function SettingsCntl($scope, $location) {
|
||||
$scope.cancel = function() {
|
||||
$scope.form = angular.copy($scope.person);
|
||||
};
|
||||
// initialize the model to something useful
|
||||
this.person = {
|
||||
name:'anonymous',
|
||||
contacts:[{type:'email', url:'anonymous@example.com'}]
|
||||
};
|
||||
}
|
||||
|
||||
$scope.save = function() {
|
||||
angular.copy($scope.form, $scope.person);
|
||||
$location.path('/welcome');
|
||||
};
|
||||
function WelcomeCntl($route){}
|
||||
WelcomeCntl.prototype = {
|
||||
greet: function(){
|
||||
alert("Hello " + this.person.name);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.cancel();
|
||||
}
|
||||
</file>
|
||||
<file name="style.css">
|
||||
[ng-view] {
|
||||
border: 1px solid blue;
|
||||
margin: 0;
|
||||
padding:1em;
|
||||
}
|
||||
function SettingsCntl(){
|
||||
this.cancel();
|
||||
}
|
||||
SettingsCntl.prototype = {
|
||||
cancel: function(){
|
||||
this.form = angular.copy(this.person);
|
||||
},
|
||||
|
||||
.partial-info {
|
||||
background-color: blue;
|
||||
color: white;
|
||||
padding: 3px;
|
||||
}
|
||||
</file>
|
||||
<file name="index.html">
|
||||
<div ng-controller="AppCntl">
|
||||
save: function(){
|
||||
angular.copy(this.form, this.person);
|
||||
window.location.hash = "#";
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<div ng:controller="AppCntl">
|
||||
<h1>Your App Chrome</h1>
|
||||
[ <a href="welcome">Welcome</a> | <a href="settings">Settings</a> ]
|
||||
[ <a href="#">Welcome</a> | <a href="#/settings">Settings</a> ]
|
||||
<hr/>
|
||||
<span class="partial-info">
|
||||
<span style="background-color: blue; color: white; padding: 3px;">
|
||||
Partial: {{$route.current.template}}
|
||||
</span>
|
||||
<div ng-view></div>
|
||||
<ng:view style="border: 1px solid blue; margin: 0; display:block; padding:1em;"></ng:view>
|
||||
<small>Your app footer </small>
|
||||
</div>
|
||||
</file>
|
||||
<file name="settings.html">
|
||||
<label>Name:</label>
|
||||
<input type="text" ng:model="form.name" required>
|
||||
|
||||
<div ng:repeat="contact in form.contacts">
|
||||
<select ng:model="contact.type">
|
||||
<option>url</option>
|
||||
<option>email</option>
|
||||
<option>phone</option>
|
||||
</select>
|
||||
<input type="text" ng:model="contact.url">
|
||||
[ <a href="" ng:click="form.contacts.$remove(contact)">X</a> ]
|
||||
</div>
|
||||
<div>
|
||||
[ <a href="" ng:click="form.contacts.$add()">add</a> ]
|
||||
</div>
|
||||
|
||||
<button ng:click="cancel()">Cancel</button>
|
||||
<button ng:click="save()">Save</button>
|
||||
</file>
|
||||
<file name="welcome.html">
|
||||
Hello {{person.name}},
|
||||
<div>
|
||||
Your contact information:
|
||||
<div ng:repeat="contact in person.contacts">{{contact.type}}:
|
||||
<span ng-bind-html="contact.url|linky"></span>
|
||||
</div>
|
||||
</div>
|
||||
</file>
|
||||
<file name="scenario.js">
|
||||
it('should navigate to URL', function() {
|
||||
element('a:contains(Welcome)').click();
|
||||
expect(element('[ng-view]').text()).toMatch(/Hello anonymous/);
|
||||
element('a:contains(Settings)').click();
|
||||
input('form.name').enter('yourname');
|
||||
element(':button:contains(Save)').click();
|
||||
element('a:contains(Welcome)').click();
|
||||
expect(element('[ng-view]').text()).toMatch(/Hello yourname/);
|
||||
</doc:source>
|
||||
<doc:scenario>
|
||||
it('should navigate to URL', function(){
|
||||
element('a:contains(Welcome)').click();
|
||||
expect(element('ng\\:view').text()).toMatch(/Hello anonymous/);
|
||||
element('a:contains(Settings)').click();
|
||||
input('form.name').enter('yourname');
|
||||
element(':button:contains(Save)').click();
|
||||
element('a:contains(Welcome)').click();
|
||||
expect(element('ng\\:view').text()).toMatch(/Hello yourname/);
|
||||
});
|
||||
</file>
|
||||
</example>
|
||||
</doc:scenario>
|
||||
</doc:example>
|
||||
|
||||
|
||||
|
||||
# Things to notice
|
||||
|
||||
* Routes are defined in the `AppCntl` class. The initialization of the controller causes the
|
||||
initialization of the {@link api/ngRoute.$route $route} service with the proper URL
|
||||
routes.
|
||||
* The {@link api/ngRoute.$route $route} service then watches the URL and instantiates the
|
||||
initialization of the {@link api/angular.service.$route $route} service with the proper URL
|
||||
routes.
|
||||
* The {@link api/angular.service.$route $route} service then watches the URL and instantiates the
|
||||
appropriate controller when the URL changes.
|
||||
* The {@link api/ngRoute.directive:ngView ngView} widget loads the
|
||||
view when the URL changes. It also sets the view scope to the newly instantiated controller.
|
||||
* The {@link api/angular.widget.ng:view ng:view} widget loads the view when the URL changes. It
|
||||
also
|
||||
sets the view scope to the newly instantiated controller.
|
||||
* Changing the URL is sufficient to change the controller and view. It makes no difference whether
|
||||
the URL is changed programmatically or by the user.
|
||||
the URL is changed programatically or by the user.
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
@workInProgress
|
||||
@ngdoc overview
|
||||
@name Cookbook: Form
|
||||
@description
|
||||
|
||||
A web application's main purpose is to present and gather data. For this reason Angular strives
|
||||
A web application's main purpose is to present and gather data. For this reason angular strives
|
||||
to make both of these operations trivial. This example shows off how you can build a simple form to
|
||||
allow a user to enter data.
|
||||
|
||||
@@ -10,91 +11,76 @@ allow a user to enter data.
|
||||
<doc:example>
|
||||
<doc:source>
|
||||
<script>
|
||||
function FormController($scope) {
|
||||
var user = $scope.user = {
|
||||
function FormController(){
|
||||
this.user = {
|
||||
name: 'John Smith',
|
||||
address:{line1: '123 Main St.', city:'Anytown', state:'AA', zip:'12345'},
|
||||
contacts:[{type:'phone', value:'1(234) 555-1212'}]
|
||||
};
|
||||
$scope.state = /^\w\w$/;
|
||||
$scope.zip = /^\d\d\d\d\d$/;
|
||||
|
||||
$scope.addContact = function() {
|
||||
user.contacts.push({type:'email', value:''});
|
||||
};
|
||||
|
||||
$scope.removeContact = function(contact) {
|
||||
for (var i = 0, ii = user.contacts.length; i < ii; i++) {
|
||||
if (contact === user.contacts[i]) {
|
||||
$scope.user.contacts.splice(i, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
this.state = /^\w\w$/;
|
||||
this.zip = /^\d\d\d\d\d$/;
|
||||
}
|
||||
</script>
|
||||
<div ng-controller="FormController" class="example">
|
||||
<div ng:controller="FormController" class="example">
|
||||
|
||||
<label>Name:</label><br>
|
||||
<input type="text" ng-model="user.name" required/> <br><br>
|
||||
<label>Name:</label><br/>
|
||||
<input type="text" name="user.name" ng:required/> <br/><br/>
|
||||
|
||||
<label>Address:</label><br>
|
||||
<input type="text" ng-model="user.address.line1" size="33" required> <br>
|
||||
<input type="text" ng-model="user.address.city" size="12" required>,
|
||||
<input type="text" ng-model="user.address.state"
|
||||
ng-pattern="state" size="2" required>
|
||||
<input type="text" ng-model="user.address.zip" size="5"
|
||||
ng-pattern="zip" required><br><br>
|
||||
<label>Address:</label><br/>
|
||||
<input type="text" name="user.address.line1" size="33" ng:required/> <br/>
|
||||
<input type="text" name="user.address.city" size="12" ng:required/>,
|
||||
<input type="text" name="user.address.state" size="2" ng:required ng:validate="regexp:state"/>
|
||||
<input type="text" name="user.address.zip" size="5" ng:required
|
||||
ng:validate="regexp:zip"/><br/><br/>
|
||||
|
||||
<label>Phone:</label>
|
||||
[ <a href="" ng-click="addContact()">add</a> ]
|
||||
<div ng-repeat="contact in user.contacts">
|
||||
<select ng-model="contact.type">
|
||||
[ <a href="" ng:click="user.contacts.$add()">add</a> ]
|
||||
<div ng:repeat="contact in user.contacts">
|
||||
<select name="contact.type">
|
||||
<option>email</option>
|
||||
<option>phone</option>
|
||||
<option>pager</option>
|
||||
<option>IM</option>
|
||||
</select>
|
||||
<input type="text" ng-model="contact.value" required>
|
||||
[ <a href="" ng-click="removeContact(contact)">X</a> ]
|
||||
<input type="text" name="contact.value" ng:required/>
|
||||
[ <a href="" ng:click="user.contacts.$remove(contact)">X</a> ]
|
||||
</div>
|
||||
<hr/>
|
||||
Debug View:
|
||||
<pre>user={{user | json}}</pre>
|
||||
<pre>user={{user}}</pre>
|
||||
</div>
|
||||
|
||||
</doc:source>
|
||||
<doc:scenario>
|
||||
it('should show debug', function() {
|
||||
it('should show debug', function(){
|
||||
expect(binding('user')).toMatch(/John Smith/);
|
||||
});
|
||||
it('should add contact', function() {
|
||||
it('should add contact', function(){
|
||||
using('.example').element('a:contains(add)').click();
|
||||
using('.example div:last').input('contact.value').enter('you@example.org');
|
||||
expect(binding('user')).toMatch(/\(234\) 555\-1212/);
|
||||
expect(binding('user')).toMatch(/you@example.org/);
|
||||
});
|
||||
|
||||
it('should remove contact', function() {
|
||||
it('should remove contact', function(){
|
||||
using('.example').element('a:contains(X)').click();
|
||||
expect(binding('user')).not().toMatch(/\(234\) 555\-1212/);
|
||||
});
|
||||
|
||||
it('should validate zip', function() {
|
||||
expect(using('.example').
|
||||
element(':input[ng\\:model="user.address.zip"]').
|
||||
prop('className')).not().toMatch(/ng-invalid/);
|
||||
it('should validate zip', function(){
|
||||
expect(using('.example').element(':input[name=user.address.zip]').attr('className'))
|
||||
.not().toMatch(/ng-validation-error/);
|
||||
using('.example').input('user.address.zip').enter('abc');
|
||||
expect(using('.example').
|
||||
element(':input[ng\\:model="user.address.zip"]').
|
||||
prop('className')).toMatch(/ng-invalid/);
|
||||
expect(using('.example').element(':input[name=user.address.zip]').attr('className'))
|
||||
.toMatch(/ng-validation-error/);
|
||||
});
|
||||
|
||||
it('should validate state', function() {
|
||||
expect(using('.example').element(':input[ng\\:model="user.address.state"]').prop('className'))
|
||||
.not().toMatch(/ng-invalid/);
|
||||
it('should validate state', function(){
|
||||
expect(using('.example').element(':input[name=user.address.state]').attr('className'))
|
||||
.not().toMatch(/ng-validation-error/);
|
||||
using('.example').input('user.address.state').enter('XXX');
|
||||
expect(using('.example').element(':input[ng\\:model="user.address.state"]').prop('className'))
|
||||
.toMatch(/ng-invalid/);
|
||||
expect(using('.example').element(':input[name=user.address.state]').attr('className'))
|
||||
.toMatch(/ng-validation-error/);
|
||||
});
|
||||
</doc:scenario>
|
||||
</doc:example>
|
||||
@@ -102,13 +88,14 @@ allow a user to enter data.
|
||||
|
||||
# Things to notice
|
||||
|
||||
* The user data model is initialized {@link api/ng.directive:ngController controller} and is
|
||||
available in the {@link api/ng.$rootScope.Scope scope} with the initial data.
|
||||
* The user data model is initialized {@link api/angular.directive.ng:controller controller} and is
|
||||
available in
|
||||
the {@link api/angular.scope scope} with the initial data.
|
||||
* For debugging purposes we have included a debug view of the model to better understand what
|
||||
is going on.
|
||||
* The {@link api/ng.directive:input input directives} simply refer
|
||||
to the model and are data-bound.
|
||||
* The inputs validate. (Try leaving them blank or entering non digits in the zip field)
|
||||
* The {@link api/angular.widget.HTML input widgets} simply refer to the model and are auto bound.
|
||||
* The inputs {@link api/angular.validator validate}. (Try leaving them blank or entering non digits
|
||||
in the zip field)
|
||||
* In your application you can simply read from or write to the model and the form will be updated.
|
||||
* By clicking the 'add' link you are adding new items into the `user.contacts` array which are then
|
||||
reflected in the view.
|
||||
|
||||
@@ -1,22 +1,16 @@
|
||||
@workInProgress
|
||||
@ngdoc overview
|
||||
@name Cookbook: Hello World
|
||||
@description
|
||||
|
||||
<doc:example>
|
||||
<doc:source>
|
||||
<script>
|
||||
function HelloCntl($scope) {
|
||||
$scope.name = 'World';
|
||||
}
|
||||
</script>
|
||||
<div ng-controller="HelloCntl">
|
||||
Your name: <input type="text" ng-model="name"/>
|
||||
<hr/>
|
||||
Hello {{name || "World"}}!
|
||||
</div>
|
||||
Your name: <input type="text" name="name" value="World"/>
|
||||
<hr/>
|
||||
Hello {{name}}!
|
||||
</doc:source>
|
||||
<doc:scenario>
|
||||
it('should change the binding when user enters text', function() {
|
||||
it('should change the binding when user enters text', function(){
|
||||
expect(binding('name')).toEqual('World');
|
||||
input('name').enter('angular');
|
||||
expect(binding('name')).toEqual('angular');
|
||||
@@ -28,12 +22,11 @@
|
||||
|
||||
Take a look through the source and note:
|
||||
|
||||
* The script tag that {@link guide/bootstrap bootstraps} the Angular environment.
|
||||
* The text {@link api/ng.directive:input input form control} which is
|
||||
bound to the greeting name text.
|
||||
* There is no need for listener registration and event firing on change events.
|
||||
* The implicit presence of the `name` variable which is in the root {@link api/ng.$rootScope.Scope scope}.
|
||||
* The script tag that {@link guide/dev_guide.bootstrap bootstraps} the angular environment.
|
||||
* The text {@link api/angular.widget.HTML input widget} which is bound to the greeting name text.
|
||||
* No need for listener registration and event firing on change events.
|
||||
* The implicit presence of the `name` variable which is in the root {@link api/angular.scope scope}.
|
||||
* The double curly brace `{{markup}}`, which binds the name variable to the greeting text.
|
||||
* The concept of {@link guide/databinding data binding}, which reflects any
|
||||
* The concept of {@link guide/dev_guide.templates.databinding data binding}, which reflects any
|
||||
changes to the
|
||||
input field in the greeting text.
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
@workInProgress
|
||||
@ngdoc overview
|
||||
@name Cookbook
|
||||
@description
|
||||
|
||||
Welcome to the Angular cookbook. Here we will show you typical uses of Angular by example.
|
||||
Welcome to the angular cookbook. Here we will show you typical uses of angular by example.
|
||||
|
||||
|
||||
# Hello World
|
||||
@@ -44,8 +45,8 @@ allowing you to send links to specific screens in your app.
|
||||
|
||||
# Services
|
||||
|
||||
{@link api/ng Services}: Services are long lived objects in your applications that are
|
||||
available across controllers. A collection of useful services are pre-bundled with Angular but you
|
||||
{@link api/angular.service Services}: Services are long lived objects in your applications that are
|
||||
available across controllers. A collection of useful services are pre-bundled with angular but you
|
||||
will likely add your own. Services are initialized using dependency injection, which resolves the
|
||||
order of initialization. This safeguards you from the perils of global state (a common way to
|
||||
implement long lived objects).
|
||||
@@ -55,4 +56,4 @@ implement long lived objects).
|
||||
|
||||
{@link buzz Resources}: Web applications must be able to communicate with the external
|
||||
services to get and update data. Resources are the abstractions of external URLs which are
|
||||
specially tailored to Angular data binding.
|
||||
specially tailored to angular data binding.
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
@workInProgress
|
||||
@ngdoc overview
|
||||
@name Cookbook: MVC
|
||||
@description
|
||||
|
||||
MVC allows for a clean and testable separation between the behavior (controller) and the view
|
||||
MVC allows for a clean an testable separation between the behavior (controller) and the view
|
||||
(HTML template). A Controller is just a JavaScript class which is grafted onto the scope of the
|
||||
view. This makes it very easy for the controller and the view to share the model.
|
||||
|
||||
The model is a set of objects and primitives that are referenced from the Scope ($scope) object.
|
||||
This makes it very easy to test the controller in isolation since one can simply instantiate the
|
||||
controller and test without a view, because there is no connection between the controller and the
|
||||
view.
|
||||
The model is simply the controller's this. This makes it very easy to test the controller in
|
||||
isolation since one can simply instantiate the controller and test without a view, because there is
|
||||
no connection between the controller and the view.
|
||||
|
||||
|
||||
<doc:example>
|
||||
<doc:source>
|
||||
<script>
|
||||
function TicTacToeCntl($scope, $location) {
|
||||
$scope.cellStyle= {
|
||||
function TicTacToeCntl($location){
|
||||
this.$location = $location;
|
||||
this.cellStyle= {
|
||||
'height': '20px',
|
||||
'width': '20px',
|
||||
'border': '1px solid black',
|
||||
@@ -24,40 +25,30 @@ view.
|
||||
'vertical-align': 'middle',
|
||||
'cursor': 'pointer'
|
||||
};
|
||||
|
||||
$scope.reset = function() {
|
||||
$scope.board = [
|
||||
this.reset();
|
||||
this.$watch('$location.hashSearch.board', this.readUrl);
|
||||
}
|
||||
TicTacToeCntl.prototype = {
|
||||
dropPiece: function(row, col) {
|
||||
if (!this.winner && !this.board[row][col]) {
|
||||
this.board[row][col] = this.nextMove;
|
||||
this.nextMove = this.nextMove == 'X' ? 'O' : 'X';
|
||||
this.setUrl();
|
||||
}
|
||||
},
|
||||
reset: function(){
|
||||
this.board = [
|
||||
['', '', ''],
|
||||
['', '', ''],
|
||||
['', '', '']
|
||||
];
|
||||
$scope.nextMove = 'X';
|
||||
$scope.winner = '';
|
||||
setUrl();
|
||||
};
|
||||
|
||||
$scope.dropPiece = function(row, col) {
|
||||
if (!$scope.winner && !$scope.board[row][col]) {
|
||||
$scope.board[row][col] = $scope.nextMove;
|
||||
$scope.nextMove = $scope.nextMove == 'X' ? 'O' : 'X';
|
||||
setUrl();
|
||||
}
|
||||
};
|
||||
|
||||
$scope.reset();
|
||||
$scope.$watch(function() { return $location.search().board;}, readUrl);
|
||||
|
||||
function setUrl() {
|
||||
var rows = [];
|
||||
angular.forEach($scope.board, function(row) {
|
||||
rows.push(row.join(','));
|
||||
});
|
||||
$location.search({board: rows.join(';') + '/' + $scope.nextMove});
|
||||
}
|
||||
|
||||
function grade() {
|
||||
var b = $scope.board;
|
||||
$scope.winner =
|
||||
this.nextMove = 'X';
|
||||
this.winner = '';
|
||||
this.setUrl();
|
||||
},
|
||||
grade: function(){
|
||||
var b = this.board;
|
||||
this.winner =
|
||||
row(0) || row(1) || row(2) ||
|
||||
col(0) || col(1) || col(2) ||
|
||||
diagonal(-1) || diagonal(1);
|
||||
@@ -65,36 +56,44 @@ view.
|
||||
function col(col) { return same(b[0][col], b[1][col], b[2][col]);}
|
||||
function diagonal(i) { return same(b[0][1-i], b[1][1], b[2][1+i]);}
|
||||
function same(a, b, c) { return (a==b && b==c) ? a : '';};
|
||||
}
|
||||
|
||||
function readUrl(value) {
|
||||
},
|
||||
setUrl: function(){
|
||||
var rows = [];
|
||||
angular.forEach(this.board, function(row){
|
||||
rows.push(row.join(','));
|
||||
});
|
||||
this.$location.hashSearch.board = rows.join(';') + '/' + this.nextMove;
|
||||
},
|
||||
readUrl: function(value) {
|
||||
if (value) {
|
||||
value = value.split('/');
|
||||
$scope.nextMove = value[1];
|
||||
this.nextMove = value[1];
|
||||
angular.forEach(value[0].split(';'), function(row, col){
|
||||
$scope.board[col] = row.split(',');
|
||||
});
|
||||
grade();
|
||||
this.board[col] = row.split(',');
|
||||
}, this);
|
||||
this.grade();
|
||||
} else {
|
||||
this.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<h3>Tic-Tac-Toe</h3>
|
||||
<div ng-controller="TicTacToeCntl">
|
||||
<div ng:controller="TicTacToeCntl">
|
||||
Next Player: {{nextMove}}
|
||||
<div class="winner" ng-show="winner">Player {{winner}} has won!</div>
|
||||
<div class="winner" ng:show="winner">Player {{winner}} has won!</div>
|
||||
<table class="board">
|
||||
<tr ng-repeat="row in board track by $index" style="height:15px;">
|
||||
<td ng-repeat="cell in row track by $index" ng-style="cellStyle"
|
||||
ng-click="dropPiece($parent.$index, $index)">{{cell}}</td>
|
||||
<tr ng:repeat="row in board" style="height:15px;">
|
||||
<td ng:repeat="cell in row" ng:style="cellStyle"
|
||||
ng:click="dropPiece($parent.$index, $index)">{{cell}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button ng-click="reset()">reset board</button>
|
||||
<button ng:click="reset()">reset board</button>
|
||||
</div>
|
||||
</doc:source>
|
||||
<doc:scenario>
|
||||
it('should play a game', function() {
|
||||
xit('should play a game', function(){
|
||||
piece(1, 1);
|
||||
expect(binding('nextMove')).toEqual('O');
|
||||
piece(3, 1);
|
||||
@@ -115,7 +114,7 @@ view.
|
||||
# Things to notice
|
||||
|
||||
* The controller is defined in JavaScript and has no reference to the rendering logic.
|
||||
* The controller is instantiated by Angular and injected into the view.
|
||||
* The controller is instantiated by <angular/> and injected into the view.
|
||||
* The controller can be instantiated in isolation (without a view) and the code will still execute.
|
||||
This makes it very testable.
|
||||
* The HTML view is a projection of the model. In the above example, the model is stored in the
|
||||
@@ -125,4 +124,4 @@ board variable.
|
||||
* The view can call any controller function.
|
||||
* In this example, the `setUrl()` and `readUrl()` functions copy the game state to/from the URL's
|
||||
hash so the browser's back button will undo game steps. See deep-linking. This example calls {@link
|
||||
api/ng.$rootScope.Scope#methods_$watch $watch()} to set up a listener that invokes `readUrl()` when needed.
|
||||
api/angular.scope.$watch $watch()} to set up a listener that invokes `readUrl()` when needed.
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $animate:notcsel
|
||||
@fullName Not class CSS selector
|
||||
@description
|
||||
|
||||
Expecting a CSS selector for class. Class selectors must start with `.`, for example: `.my-class-name`.
|
||||
@@ -1,8 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $cacheFactory:iid
|
||||
@fullName Invalid ID
|
||||
@description
|
||||
|
||||
This error occurs when trying to create a new `cache` object via {@link api/ng.$cacheFactory} with an ID that was already used to create another cache object.
|
||||
|
||||
To resolve the error please use a different cache ID when calling `$cacheFactory`.
|
||||
@@ -1,49 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:ctreq
|
||||
@fullName Missing Required Controller
|
||||
@description
|
||||
|
||||
This error occurs when {@link api/ng.$compile HTML compiler} tries to process a directive that specifies the {@link api/ng.$compile#description_comprehensive-directive-api_directive-definition-object `require` option} in a {@link api/ng.$compile#description_comprehensive-directive-api directive definition},
|
||||
but the required directive controller is not present on the current DOM element (or its ancestor element, if `^` was specified).
|
||||
|
||||
To resolve this error ensure that there is no typo in the required controller name and that the required directive controller is present on the current element.
|
||||
|
||||
If the required controller is expected to be on a ancestor element, make ensure that you prefix the controller name in the `require` definition with `^`.
|
||||
|
||||
If the required controller is optionally requested, use `?` or `^?` to specify that.
|
||||
|
||||
|
||||
Example of a directive that requires {@link api/ng.directive:ngModel ngModel} controller:
|
||||
```
|
||||
myApp.directive('myDirective', function() {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This directive can then be used as:
|
||||
```
|
||||
<input ng-model="some.path" my-directive>
|
||||
```
|
||||
|
||||
|
||||
Example of a directive that optionally requires a {@link api/ng.directive:form form} controller from an ancestor:
|
||||
```
|
||||
myApp.directive('myDirective', function() {
|
||||
return {
|
||||
require: '^?form',
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This directive can then be used as:
|
||||
```
|
||||
<form name="myForm">
|
||||
<div>
|
||||
<span my-directive></span>
|
||||
</div>
|
||||
</form>
|
||||
```
|
||||
@@ -1,25 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:iscp
|
||||
@fullName Invalid Isolate Scope Definition
|
||||
@description
|
||||
|
||||
When declaring isolate scope the scope definition object must be in specific format which starts with mode character (`@&=`) with an optional local name.
|
||||
|
||||
```
|
||||
myModule.directive('directiveName', function factory() {
|
||||
return {
|
||||
...
|
||||
scope: {
|
||||
'attrName': '@', // OK
|
||||
'attrName2': '=localName', // OK
|
||||
'attrName3': 'name', // ERROR: missing mode @&=
|
||||
'attrName4': ' = name', // ERROR: extra spaces
|
||||
'attrName5': 'name=', // ERROR: must be prefixed with @&=
|
||||
}
|
||||
...
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Please refer to the {@link api/ng.$compile#description_comprehensive-directive-api_directive-definition-object
|
||||
`scope` option} of the directive definition documentation to learn more about the API.
|
||||
@@ -1,17 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:multidir
|
||||
@fullName Multiple Directive Resource Contention
|
||||
@description
|
||||
|
||||
This error occurs when multiple directives are applied to the same DOM element, and
|
||||
processing them would result in a collision or an unsupported configuration.
|
||||
|
||||
|
||||
To resolve this issue remove one of the directives which is causing the collision.
|
||||
|
||||
Example scenarios of multiple incompatible directives applied to the same element include:
|
||||
|
||||
* Multiple directives requesting `isolated scope`.
|
||||
* Multiple directives publishing a controller under the same name.
|
||||
* Multiple directives declared with the `transclusion` option.
|
||||
* Multiple directives attempting to define a `template` or `templateURL`.
|
||||
@@ -1,20 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:nodomevents
|
||||
@fullName Interpolated Event Attributes
|
||||
@description
|
||||
|
||||
This error occurs when one tries to create a binding for event handler attributes like `onclick`, `onload`, `onsubmit`, etc.
|
||||
|
||||
There is no practical value in binding to these attributes and doing so only exposes your application to security vulnerabilities like XSS.
|
||||
For these reasons binding to event handler attributes (all attributes that start with `on` and `formaction` attribute) is not supported.
|
||||
|
||||
|
||||
An example code that would allow XSS vulnerability by evaluating user input in the window context could look like this:
|
||||
```
|
||||
<input ng-mode="username">
|
||||
<div onclick="{{username}}">click me</div>
|
||||
```
|
||||
|
||||
Since the `onclick` evaluates the value as JavaScript code in the window context, setting the `username` model to a value like `javascript:alert('PWND')` would result in script injection when the `div` is clicked.
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:nonassign
|
||||
@fullName Non-Assignable Expression
|
||||
@description
|
||||
|
||||
This error occurs when a directive defines an isolate scope property
|
||||
(using the `=` mode in the {@link api/ng.$compile#description_comprehensive-directive-api_directive-definition-object
|
||||
`scope` option} of a directive definition) but the directive is used with an expression that is not-assignable.
|
||||
|
||||
In order for the two-way data-binding to work, it must be possible to write new values back into the path defined with the expression.
|
||||
|
||||
For example, given a directive:
|
||||
|
||||
```
|
||||
myModule.directive('myDirective', function factory() {
|
||||
return {
|
||||
...
|
||||
scope: {
|
||||
'bind': '=localValue'
|
||||
}
|
||||
...
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Following are invalid uses of this directive:
|
||||
```
|
||||
<!-- ERROR because `1+2=localValue` is an invalid statement -->
|
||||
<my-directive bind="1+2">
|
||||
|
||||
<!-- ERROR because `myFn()=localValue` is an invalid statement -->
|
||||
<my-directive bind="myFn()">
|
||||
```
|
||||
|
||||
|
||||
To resolve this error, always use path expressions with scope properties that are two-way data-bound:
|
||||
```
|
||||
<my-directive bind="some.property">
|
||||
<my-directive bind="some[3]['property']">
|
||||
```
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:selmulti
|
||||
@fullName Binding to Multiple Attribute
|
||||
@description
|
||||
|
||||
Binding to the `multiple` attribute of `select` element is not supported since switching between multiple and single mode changes the {@link api/ng.directive:ngModel `ngModel`} object type from instance to array of instances which breaks the model semantics.
|
||||
|
||||
If you need to use different types of `select` elements in your template based on some variable, please use {@link api/ng.directive:ngIf ngIf} or {@link api/ng.directive:ngSwitch ngSwitch} directives to select one of them to be used at runtime.
|
||||
|
||||
|
||||
Example with invalid usage:
|
||||
```
|
||||
<select ng-model="some.model" multiple="{{mode}}"></select>
|
||||
```
|
||||
|
||||
Example that uses ngIf to pick one of the `select` elements based on a variable:
|
||||
```
|
||||
<select ng-if="mode == 'multiple'" ng-model="some.model" multiple></select>
|
||||
<select ng-if="mode != 'multiple'" ng-model="some.model"></select>
|
||||
```
|
||||
@@ -1,11 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:tpload
|
||||
@fullName Error Loading Template
|
||||
@description
|
||||
|
||||
This error occurs when {@link api/ng.$compile `$compile`} attempts to fetch a template from some URL, and the request fails.
|
||||
|
||||
To resolve this error, ensure that the URL of the template is spelled correctly and resolves to correct absolute URL.
|
||||
The [Chrome Developer Tools](https://developers.google.com/chrome-developer-tools/docs/network#network_panel_overview) might also be helpful in determining why the request failed.
|
||||
|
||||
If you are using {@link api/ng.$templateCache} to pre-load templates, ensure that the cache was populated with the template.
|
||||
@@ -1,39 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:tplrt
|
||||
@fullName Invalid Template Root
|
||||
@description
|
||||
|
||||
When a directive is declared with `template` (or `templateUrl`) and `replace` mode on, the template
|
||||
must have exactly one root element. That is, the text of the template property or the content
|
||||
referenced by the templateUrl must be contained within a single html element.
|
||||
For example, `<p>blah <em>blah</em> blah</p>` instead of simply `blah <em>blah</em> blah`.
|
||||
Otherwise, the replacement operation would result in a single element (the directive) being replaced
|
||||
with multiple elements or nodes, which is unsupported and not commonly needed in practice.
|
||||
|
||||
|
||||
For example a directive with definition:
|
||||
|
||||
```
|
||||
myModule.directive('myDirective', function factory() {
|
||||
return {
|
||||
...
|
||||
replace: true,
|
||||
templateUrl: 'someUrl'
|
||||
...
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
And a template provided at URL `someUrl`. The template must be an html fragment that has only a
|
||||
single root element, like the `div` element in this template:
|
||||
|
||||
```
|
||||
<div><b>Hello</b> World!</div>
|
||||
```
|
||||
|
||||
An an invalid template to be used with this directive is one that defines multiple root nodes or
|
||||
elements. For example:
|
||||
|
||||
```
|
||||
<b>Hello</b> World!
|
||||
```
|
||||
@@ -1,34 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:uterdir
|
||||
@fullName Unterminated Directive
|
||||
@description
|
||||
|
||||
This error occurs when using multi-element directives and a `directive-start` attribute fails to form a matching pair with a corresponding `directive-end` attribute.
|
||||
A `directive-start` should have a matching `directive-end` on a sibling node in the DOM. For instance,
|
||||
|
||||
```
|
||||
<table>
|
||||
<tr ng-repeat-start="item in list">I get repeated</tr>
|
||||
<tr ng-repeat-end>I also get repeated</tr>
|
||||
</table>
|
||||
```
|
||||
|
||||
is a valid example.
|
||||
|
||||
This error can occur in several different ways. One is by leaving out the `directive-end` attribute, like so:
|
||||
|
||||
```
|
||||
<div>
|
||||
<span foo-start></span>
|
||||
</div>
|
||||
```
|
||||
|
||||
Another is by nesting a `directive-end` inside of `directive-start`, or vice versa:
|
||||
|
||||
```
|
||||
<div>
|
||||
<span foo-start><span foo-end></span></span>
|
||||
</div>
|
||||
```
|
||||
|
||||
To avoid this error, make sure each `directive-start` you use has a matching `directive-end` on a sibling node in the DOM.
|
||||
@@ -1,21 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $controller:noscp
|
||||
@fullName Missing $scope object
|
||||
@description
|
||||
|
||||
This error occurs when {@link api/ng.$controller $controller} service is called in order to instantiate a new controller but no scope is provided via `$scope` property of the locals map.
|
||||
|
||||
Example of incorrect usage that leads to this error:
|
||||
```
|
||||
$controller(MyController);
|
||||
//or
|
||||
$controller(MyController, {scope: newScope});
|
||||
```
|
||||
|
||||
To fix the example above please provide a scope to the $controller call:
|
||||
|
||||
```
|
||||
$controller(MyController, {$scope, newScope});
|
||||
```
|
||||
|
||||
Please consult the {@link api/ng.$controller $controller} service api docs to learn more.
|
||||
@@ -1,9 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $httpBackend:noxhr
|
||||
@fullName Unsupported XHR
|
||||
@description
|
||||
|
||||
This error occurs in browsers that do not support XmlHttpRequest. AngularJS
|
||||
supports Safari, Chrome, Firefox, Opera, IE8 and higher, and mobile browsers
|
||||
(Android, Chrome Mobile, iOS Safari). To avoid this error, use an officially
|
||||
supported browser.
|
||||
@@ -1,13 +0,0 @@
|
||||
@ngdoc overview
|
||||
@name Error Reference
|
||||
@description
|
||||
|
||||
Use the Error Reference manual to find information about error conditions in
|
||||
your AngularJS app. Errors thrown in production builds of AngularJS will log
|
||||
links to this site on the console.
|
||||
|
||||
Other useful references for debugging your app include:
|
||||
|
||||
- {@link api/ API Reference} for detailed information about specific features
|
||||
- {@link guide/ Developer Guide} for AngularJS concepts
|
||||
- {@link tutorial/ Tutorial} for getting started
|
||||
@@ -1,26 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $injector:cdep
|
||||
@fullName Circular Dependency
|
||||
@description
|
||||
|
||||
This error occurs when the {@link api/angular.injector $injector} tries to get
|
||||
a service that depends on itself, either directly or indirectly. To fix this,
|
||||
construct your dependency chain such that there are no circular dependencies.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
angular.module('myApp', [])
|
||||
.factory('myService', function (myService) {
|
||||
// ...
|
||||
})
|
||||
.controller('MyCtrl', function ($scope, myService) {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
When an instance of `MyCtrl` is created, the service `myService` will be created
|
||||
by the `$injector`. `myService` depends on itself, which causes the `$injector`
|
||||
to detect a circular dependency and throw the error.
|
||||
|
||||
For more information, see the {@link guide/di Dependency Injection Guide}.
|
||||
@@ -1,26 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $injector:itkn
|
||||
@fullName Bad Injection Token
|
||||
@description
|
||||
|
||||
This error occurs when using a bad token as a dependency injection annotation.
|
||||
Dependency injection annotation tokens should always be strings. Using any other
|
||||
type will cause this error to be thrown.
|
||||
|
||||
Examples of code with bad injection tokens include:
|
||||
|
||||
```
|
||||
var myCtrl = function ($scope, $http) { /* ... */ };
|
||||
myCtrl.$inject = ['$scope', 42];
|
||||
|
||||
myAppModule.controller('MyCtrl', ['$scope', {}, function ($scope, $timeout) {
|
||||
// ...
|
||||
}]);
|
||||
```
|
||||
|
||||
The bad injection tokens are `42` in the first example and `{}` in the second.
|
||||
To avoid the error, always use string literals for dependency injection annotation
|
||||
tokens.
|
||||
|
||||
For an explanation of what injection annotations are and how to use them, refer
|
||||
to the {@link guide/di Dependency Injection Guide}.
|
||||
@@ -1,11 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $injector:modulerr
|
||||
@fullName Module Error
|
||||
@description
|
||||
|
||||
This error occurs when a module fails to load due to some exception. The error
|
||||
message above should provide additional context.
|
||||
|
||||
In AngularJS `1.2.0` and later, `ngRoute` has been moved to its own module.
|
||||
If you are getting this error after upgrading to `1.2.x`, be sure that you've
|
||||
installed {@link api/ngRoute `ngRoute`}.
|
||||
@@ -1,26 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $injector:nomod
|
||||
@fullName Module Unavailable
|
||||
@description
|
||||
|
||||
This error occurs when trying to "re-open" a module that has not yet been defined.
|
||||
|
||||
To define a new module, call {@link api/angular.module angular.module} with a name
|
||||
and an array of dependent modules, like so:
|
||||
|
||||
```
|
||||
// When defining a module with no module dependencies,
|
||||
// the requires array should be defined and empty.
|
||||
var myApp = angular.module('myApp', []);
|
||||
```
|
||||
|
||||
To retrieve a reference to the same module for further configuration, call
|
||||
`angular.module` without the `requires` array.
|
||||
|
||||
```
|
||||
var myApp = angular.module('myApp');
|
||||
```
|
||||
|
||||
Calling `angular.module` without the `requires` array when the module has not yet
|
||||
been defined causes this error to be thrown. To fix it, define your module with
|
||||
a name and an empty array, as in the first example above.
|
||||
@@ -1,26 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $injector:pget
|
||||
@fullName Provider Missing $get
|
||||
@description
|
||||
|
||||
This error occurs when attempting to register a provider that does not have a
|
||||
`$get` method. For example:
|
||||
|
||||
```
|
||||
function BadProvider() {} // No $get method!
|
||||
angular.module("myApp", [])
|
||||
.provider('bad', BadProvider); // this throws the error
|
||||
```
|
||||
|
||||
To fix the error, fill in the `$get` method on the provider like so:
|
||||
|
||||
```
|
||||
function GoodProvider() {
|
||||
this.$get = angular.noop;
|
||||
}
|
||||
angular.module("myApp", [])
|
||||
.provider('good', GoodProvider);
|
||||
```
|
||||
|
||||
For more information, refer to the {@link api/AUTO.$provide#methods_provider
|
||||
$provide.provider} api doc.
|
||||
@@ -1,26 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $injector:unpr
|
||||
@fullName Unknown Provider
|
||||
@description
|
||||
|
||||
This error results from the `$injector` being unable to resolve a required
|
||||
dependency. To fix this, make sure the dependency is defined and spelled
|
||||
correctly. For example:
|
||||
|
||||
```
|
||||
angular.module('myApp', [])
|
||||
.controller('myCtrl', ['myService', function (myService) {
|
||||
// Do something with myService
|
||||
}]);
|
||||
```
|
||||
|
||||
This code will fail with `$injector:unpr` if `myService` is not defined. Making
|
||||
sure each dependency is defined will fix the problem.
|
||||
|
||||
```
|
||||
angular.module('myApp', [])
|
||||
.service('myService', function () { /* ... */ })
|
||||
.controller('myCtrl', ['myService', function (myService) {
|
||||
// Do something with myService
|
||||
}]);
|
||||
```
|
||||
@@ -1,7 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $interpolate:interr
|
||||
@fullName Interpolation Error
|
||||
@description
|
||||
|
||||
This error occurs when interpolation fails due to some exception. The error
|
||||
message above should provide additional context.
|
||||
@@ -1,12 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $interpolate:noconcat
|
||||
@fullName Multiple Expressions
|
||||
@description
|
||||
|
||||
This error occurs when performing an interpolation that concatenates multiple
|
||||
expressions when a trusted value is required. Concatenating expressions makes
|
||||
it hard to reason about whether some combination of concatenated values are
|
||||
unsafe to use and could easily lead to XSS.
|
||||
|
||||
For more information about how AngularJS helps keep your app secure, refer to
|
||||
the {@link api/ng.$sce $sce} API doc.
|
||||
@@ -1,11 +0,0 @@
|
||||
@ngdoc error
|
||||
@name jqLite:nosel
|
||||
@fullName Unsupported Selector Lookup
|
||||
@description
|
||||
|
||||
In order to keep Angular small, Angular implements only a subset of the selectors in {@link api/angular.element#description_angulars-jqlite jqLite}.
|
||||
This error occurs when a jqLite instance is invoked with a selector other than this subset.
|
||||
|
||||
In order to resolve this error, rewrite your code to only use tag name selectors and manually traverse the DOM using the APIs provided by jqLite.
|
||||
|
||||
Alternatively, you can include a full version of jQuery, which Angular will automatically use and that will make all selectors available.
|
||||
@@ -1,7 +0,0 @@
|
||||
@ngdoc error
|
||||
@name jqLite:offargs
|
||||
@fullName Invalid jqLite#off() parameter
|
||||
@description
|
||||
|
||||
This error occurs when trying to pass too many arguments to `jqLite#off`. Note
|
||||
that `jqLite#off` does not support namespaces or selectors like jQuery.
|
||||
@@ -1,8 +0,0 @@
|
||||
@ngdoc error
|
||||
@name jqLite:onargs
|
||||
@fullName Invalid jqLite#on() Parameters
|
||||
@description
|
||||
|
||||
This error occurs when trying to pass too many arguments to `jqLite#on`. Note
|
||||
that `jqLite#on` does not support the `selector` or `eventData` parameters as
|
||||
jQuery does.
|
||||
@@ -1,17 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $location:ihshprfx
|
||||
@fullName Missing Hash Prefix
|
||||
@description
|
||||
|
||||
This error occurs when {@link api/ng.$location $location} service is configured to use a hash prefix but this prefix was not present in a url that the `$location` service was asked to parse.
|
||||
|
||||
For example if you configure `$location` service with prefix `'!'`:
|
||||
```
|
||||
myApp.config(function($locationProvider) {
|
||||
$locationProvider.prefix('!');
|
||||
});
|
||||
```
|
||||
|
||||
If you enter the app at url `http:/myapp.com/#/myView` this error will be throw.
|
||||
|
||||
The correct url for this configuration is `http:/myapp.com/#!/myView` (note the `'!'` after `'#'` symbol).
|
||||
@@ -1,8 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $location:ipthprfx
|
||||
@fullName Invalid or Missing Path Prefix
|
||||
@description
|
||||
|
||||
This error occurs when you configure the {@link api/ng.$location `$location`} service in the html5 mode, specify a base url for your application via `<base>` element and try to update the location with a path that doesn't match the base prefix.
|
||||
|
||||
To resolve this issue, please check the base url specified via the `<base>` tag in the head of your main html document, as well as the url that you tried to set the location to.
|
||||
@@ -1,9 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $location:isrcharg
|
||||
@fullName Wrong $location.search() argument type
|
||||
@description
|
||||
|
||||
To resolve this error, ensure that the first argument for the `$location.search` call is a `string` or an object.
|
||||
You can use the stack trace associated with this error to identify the call site that caused this issue.
|
||||
|
||||
To learn more, please consult the {@link api/ng.$location `$location`} api docs.
|
||||
@@ -1,8 +0,0 @@
|
||||
@ngdoc error
|
||||
@name ng:areq
|
||||
@fullName Bad Argument
|
||||
@description
|
||||
|
||||
AngularJS often asserts that certain values will be present and truthy using a
|
||||
helper function. If the assertion fails, this error is thrown. To fix this problem,
|
||||
make sure that the value the assertion expects is defined and truthy.
|
||||
@@ -1,8 +0,0 @@
|
||||
@ngdoc error
|
||||
@name ng:badname
|
||||
@fullName Bad `hasOwnProperty` Name
|
||||
@description
|
||||
|
||||
Occurs when you try to use the name `hasOwnProperty` in a context where it is not allow.
|
||||
Generally, a name cannot be `hasOwnProperty` because it is used, internally, on a object
|
||||
and allowing such a name would break lookups on this object.
|
||||
@@ -1,29 +0,0 @@
|
||||
@ngdoc error
|
||||
@name ng:btstrpd
|
||||
@fullName App Already Bootstrapped with this Element
|
||||
@description
|
||||
|
||||
Occurs when calling angular.bootstrap on an element that has already been bootstrapped.
|
||||
|
||||
This usually happens when you accidentally use both `ng-app` and `angular.bootstrap` to bootstrap an application.
|
||||
|
||||
```
|
||||
<html>
|
||||
...
|
||||
<body ng-app="myApp">
|
||||
<script>
|
||||
angular.bootstrap(document.body, ['myApp']);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
Note that for bootrapping purposes, the `<html>` element is the same as `document`, so the following will also throw an error.
|
||||
```
|
||||
<html>
|
||||
...
|
||||
<script>
|
||||
angular.bootstrap(document, ['myApp']);
|
||||
</script>
|
||||
</html>
|
||||
```
|
||||
@@ -1,10 +0,0 @@
|
||||
@ngdoc error
|
||||
@name ng:cpi
|
||||
@fullName Bad Copy
|
||||
@description
|
||||
|
||||
This error occurs when attempting to copy an object to itself. Calling {@link
|
||||
api/angular.copy angular.copy} with a `destination` object deletes
|
||||
all of the elements or properties on `destination` before copying to it. Copying
|
||||
an object to itself is not supported. Make sure to check your calls to
|
||||
`angular.copy` and avoid copying objects or arrays to themselves.
|
||||
@@ -1,10 +0,0 @@
|
||||
@ngdoc error
|
||||
@name ng:cpws
|
||||
@fullName Copying Window or Scope
|
||||
@description
|
||||
|
||||
Copying Window or Scope instances is not supported because of cyclical and self
|
||||
references. Avoid copying windows and scopes, as well as any other cyclical or
|
||||
self-referential structures. Note that trying to deep copy an object containing
|
||||
cyclical references that is neither a window nor a scope will cause infinite
|
||||
recursion and a stack overflow.
|
||||
@@ -1,27 +0,0 @@
|
||||
@ngdoc error
|
||||
@name ngModel:nonassign
|
||||
@fullName Non-Assignable Expression
|
||||
@description
|
||||
|
||||
This error occurs when expression the {@link api/ng.directive:ngModel ngModel} directive is bound to is a non-assignable expression.
|
||||
|
||||
Examples using assignable expressions include:
|
||||
|
||||
```
|
||||
<input ng-model="namedVariable">
|
||||
<input ng-model="myObj.someProperty">
|
||||
<input ng-model="indexedArray[0]">
|
||||
```
|
||||
|
||||
Examples of non-assignable expressions include:
|
||||
|
||||
```
|
||||
<input ng-model="foo + bar">
|
||||
<input ng-model="42">
|
||||
<input ng-model="'oops'">
|
||||
<input ng-model="myFunc()">
|
||||
```
|
||||
|
||||
Always make sure that the expression bound via `ngModel` directive can be assigned to.
|
||||
|
||||
For more information, see the {@link api/ng.directive:ngModel ngModel API doc}.
|
||||
@@ -1,13 +0,0 @@
|
||||
@ngdoc error
|
||||
@name ngOptions:iexp
|
||||
@fullName Invalid Expression
|
||||
@description
|
||||
This error occurs when 'ngOptions' is passed an expression that isn't in an expected form.
|
||||
|
||||
Here's an example of correct syntax:
|
||||
|
||||
```
|
||||
<select ng-model="color" ng-options="c.name for c in colors">
|
||||
```
|
||||
|
||||
For more information on valid expression syntax, see 'ngOptions' in {@link api/ng.directive:select select} directive docs.
|
||||
@@ -1,7 +0,0 @@
|
||||
@ngdoc error
|
||||
@name ngPattern:noregexp
|
||||
@fullName Expected Regular Expression
|
||||
@description
|
||||
This error occurs when 'ngPattern' is passed an expression that isn't a regular expression or doesn't have the expected format.
|
||||
|
||||
For more information on valid expression syntax, see 'ngPattern' in {@link api/ng.directive:select input} directive docs.
|
||||
@@ -1,22 +0,0 @@
|
||||
@ngdoc error
|
||||
@name ngRepeat:dupes
|
||||
@fullName Duplicate Key in Repeater
|
||||
@description
|
||||
|
||||
Occurs if there are duplicate keys in an {@link api/ng.directive:ngRepeat ngRepeat} expression. Duplicate keys are banned because AngularJS uses keys to associate DOM nodes with items.
|
||||
|
||||
By default, collections are keyed by reference which is desirable for most common models but can be problematic for primitive types that are interned (share references).
|
||||
|
||||
For example the issue can be triggered by this *invalid* code:
|
||||
|
||||
```
|
||||
<div ng-repeat="value in [4, 4]"></div>
|
||||
```
|
||||
|
||||
To resolve this error either ensure that the items in the collection have unique identity of use the `track by` syntax to specify how to track the association between models and DOM.
|
||||
|
||||
To resolve the example above can be resolved by using `track by $index`, which will cause the items to be keyed by their position in the array instead of their value:
|
||||
|
||||
```
|
||||
<div ng-repeat="value in [4, 4] track by $index"></div>
|
||||
```
|
||||
@@ -1,12 +0,0 @@
|
||||
@ngdoc error
|
||||
@name ngRepeat:iexp
|
||||
@fullName Invalid Expression
|
||||
@description
|
||||
|
||||
Occurs when there is a syntax error in an {@link api/ng.directive:ngRepeat ngRepeat}'s expression. The expression should be in the form '_item_ in _collection_[ track by _id_]'.
|
||||
|
||||
Be aware, the ngRepeat directive parses the expression using a regex before sending _collection_ and optionally _id_ to the AngularJS parser. This error comes from the regex parsing.
|
||||
|
||||
To resolve, identify and fix errors in the expression, paying special attention to the 'in' and 'track by' keywords in the expression.
|
||||
|
||||
Please consult the api documentation of {@link api/ng.directive:ngRepeat ngRepeat} to learn more about valid syntax.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user