Compare commits
389 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7fa2fdba3b | |||
| b871be1392 | |||
| 65bfce7d68 | |||
| 67126bd3a0 | |||
| ce6558fd80 | |||
| 64f6a616d4 | |||
| 07b8761233 | |||
| 2e7121b8e4 | |||
| da3f2df163 | |||
| 51944b3999 | |||
| 612589d0bc | |||
| 1b32fad833 | |||
| 3bf758063e | |||
| 82ea2de3fb | |||
| 8ace661ba5 | |||
| 8a9cd3e01d | |||
| 9ea37de0f5 | |||
| b44432a719 | |||
| ac0e10d287 | |||
| 1237c77850 | |||
| 9a9b07dea8 | |||
| 8b913b99d9 | |||
| 4edd2d95c1 | |||
| 353e3a6cd8 | |||
| 6ce2913d99 | |||
| 6a24885771 | |||
| 367da583bc | |||
| 68fb70ed29 | |||
| e8e8186d40 | |||
| 0f3385d45d | |||
| 4897430559 | |||
| 098b6f519a | |||
| 549edc9d01 | |||
| 6ed4c61e72 | |||
| f83c3dea23 | |||
| f60254f79a | |||
| d2a57b9dff | |||
| 33a693ea62 | |||
| dd1a957bb3 | |||
| 775c247085 | |||
| 4d753d197a | |||
| 8b51d03c83 | |||
| b1bc25169e | |||
| 9f10428651 | |||
| 6b28705dbf | |||
| 802cdf6ccb | |||
| a19d026bff | |||
| d23512c7f3 | |||
| 8e58e22d93 | |||
| 42cff065b8 | |||
| 2c852cf62a | |||
| bf4f51573d | |||
| 5a7dc50f26 | |||
| f9e7dabb2a | |||
| 296da4b561 | |||
| 9019c2dac5 | |||
| 83a12a54a2 | |||
| 9fdb4f8c51 | |||
| fcce237902 | |||
| d7e31b5dc7 | |||
| b014607030 | |||
| fd46fc80ee | |||
| d26ba3b941 | |||
| 6fa1bb03db | |||
| 8ebd716c57 | |||
| cb94d562df | |||
| d31b3a65b6 | |||
| 5a70888153 | |||
| 3475b19482 | |||
| 00a30fad82 | |||
| 22b669407c | |||
| 99a063f9cb | |||
| 27db9f018e | |||
| 2ed2399d49 | |||
| 9d2de344f5 | |||
| 9c0659ca27 | |||
| 3b9963c54a | |||
| 26db937377 | |||
| 1d0e582b3f | |||
| a6b58019e1 | |||
| 38fd896b74 | |||
| f96d553822 | |||
| f4149b70bc | |||
| 8a8c94c3d5 | |||
| d9de526059 | |||
| 0318761f7a | |||
| 74f7b57823 | |||
| 995ccfc9f6 | |||
| 72c244564a | |||
| 4bfe7e8663 | |||
| 63fe144397 | |||
| 0f551e6109 | |||
| 541f4ba21f | |||
| 6e7d04ddb2 | |||
| 06fb391687 | |||
| 203dd4d1e3 | |||
| c991f93817 | |||
| 52ddc13bee | |||
| 1645924d49 | |||
| 6bee655679 | |||
| acd455181d | |||
| a89b6e27a9 | |||
| 46d559dc8d | |||
| 26212fb204 | |||
| 244cfc7cd5 | |||
| c6074dc34c | |||
| 4930ef2bfe | |||
| 1778d347cd | |||
| 4724d56c93 | |||
| 70fcffc375 | |||
| 181e44019e | |||
| 5ce859bcdd | |||
| fb994e4d90 | |||
| 55f26fc246 | |||
| 1161002857 | |||
| 7ccfe92bed | |||
| a126fcfee3 | |||
| f22af2b874 | |||
| 2ca4170903 | |||
| fd57df1235 | |||
| 3010ed4ee5 | |||
| de59ca7107 | |||
| fa3214cfb8 | |||
| a8cacfe938 | |||
| 1a387ba5dd | |||
| 98e4a220fe | |||
| 9001ae2822 | |||
| c405f88bbc | |||
| 159a68ec7b | |||
| b9a56d588f | |||
| f797f83cd6 | |||
| 6df970eb3c | |||
| f88b4be92f | |||
| a7bcc01581 | |||
| 40ed8094d1 | |||
| 1a722f7b19 | |||
| 4991207c7c | |||
| 33514ec384 | |||
| 28bd20ed30 | |||
| c3bfd7f59d | |||
| 553cccdb85 | |||
| c7dd2c24f4 | |||
| fbf5aebda2 | |||
| ab35c16ccf | |||
| 37b6a71678 | |||
| e79ebff223 | |||
| 36b38e1355 | |||
| 3168d95793 | |||
| 538c63f057 | |||
| a9a1461351 | |||
| 29190f9318 | |||
| ca7d2b3b3f | |||
| 81676f8323 | |||
| 6f9d07d9c7 | |||
| 5201b8146a | |||
| 6aa83d04b7 | |||
| cfbe1a701a | |||
| aa38ded59d | |||
| b03957f004 | |||
| 56f33af890 | |||
| 41bea59eb7 | |||
| 6d0dcca6f1 | |||
| f423dc6b51 | |||
| 9fca87ca5b | |||
| ebbaa4ac5e | |||
| 617137231e | |||
| 71b966ace7 | |||
| 488d5b4288 | |||
| 01b8772cca | |||
| 05ac0ba926 | |||
| 399e872228 | |||
| 3115408be7 | |||
| aea39e9fdc | |||
| 51f6752cec | |||
| db58801a55 | |||
| 2e33d170be | |||
| cc6dcb4bc2 | |||
| 294d6793fd | |||
| cefcc46e1b | |||
| c10dba144e | |||
| f05ffd9bf1 | |||
| e208d81293 | |||
| b51fca1a2b | |||
| 6685043ad4 | |||
| f176a2dbb7 | |||
| 3a366bd42b | |||
| 1c5db02638 | |||
| ffd5308d86 | |||
| aed9de9d37 | |||
| aab6825e85 | |||
| c4fad6ad61 | |||
| 2a7c37cf01 | |||
| 194c3adfed | |||
| 371957d9d5 | |||
| 1e5d36d4b0 | |||
| 3749c85829 | |||
| 886b59d317 | |||
| 2048b6df24 | |||
| 5ec0a50d39 | |||
| 60689afe1c | |||
| 881fddaaba | |||
| fda338e8e2 | |||
| 05c8d88126 | |||
| aa57f57ccb | |||
| 51b78f61f9 | |||
| 739100e8a8 | |||
| 20e0c7f966 | |||
| f34e3413c7 | |||
| 4d28598b3d | |||
| 16d6e89f3b | |||
| 6e220ab612 | |||
| ce14e4a6b7 | |||
| b5dbc9834a | |||
| 57f10251db | |||
| 48cd05a1ad | |||
| 6a71ba17f0 | |||
| cf1b175508 | |||
| 5bba68c264 | |||
| e5a4345aac | |||
| 49ef92041f | |||
| 081ae8bfca | |||
| 4f8aa6f5bb | |||
| d7e888b8c6 | |||
| 491b4af92e | |||
| 5930b8ee27 | |||
| 69d9072d5b | |||
| 9b5de0ac97 | |||
| 21b76aed06 | |||
| 363fb16c10 | |||
| e00f9f62e3 | |||
| 507c666d16 | |||
| 743b33ab9d | |||
| 9f8fa79f25 | |||
| fe3c1d44a5 | |||
| 5ae72dc7af | |||
| 47bc98a1ea | |||
| 10920a2857 | |||
| 90a9270dfa | |||
| d4b05dd13a | |||
| 59802bc790 | |||
| b0a35a794a | |||
| a9545e3963 | |||
| 269c15c74b | |||
| 9f48025733 | |||
| 1d0ccd0d73 | |||
| 03e5164528 | |||
| 3047964712 | |||
| 225afb9eb4 | |||
| b377d6b043 | |||
| ac650cb2e6 | |||
| 926088ba77 | |||
| f94cf634d8 | |||
| 85b3786f55 | |||
| 1116a96df6 | |||
| 1c1c9b27cb | |||
| c5e7a5bc9b | |||
| 7550b7bda8 | |||
| 43b97b211b | |||
| 76405897fc | |||
| bb730704f2 | |||
| 8965d57aa0 | |||
| 951a2743d5 | |||
| a2a907e439 | |||
| 308f22ba9a | |||
| 32e2643d90 | |||
| 3edaf0922f | |||
| 1095596962 | |||
| ee0dac4d1d | |||
| 6f1fae8a91 | |||
| f96485085a | |||
| 147650b3be | |||
| 10c426ffa3 | |||
| 785647eb9d | |||
| a2a6279157 | |||
| b50d2a4a1f | |||
| f539fb1f7c | |||
| 2dcb5acb7b | |||
| 905a8fd4a4 | |||
| df9b57a481 | |||
| fee2077d0b | |||
| 691aafc981 | |||
| da7af937d6 | |||
| 1c9b9e24ed | |||
| 46a5b2c298 | |||
| 28e4707dc4 | |||
| 420b5211da | |||
| 04bccee099 | |||
| a404839795 | |||
| 25d4e5cca4 | |||
| c67112563f | |||
| 2b2ec26a75 | |||
| 41f90e5fb0 | |||
| a85c591d36 | |||
| f276ad0d51 | |||
| 33f817b99c | |||
| 6a4124d0fb | |||
| 26d1b34321 | |||
| 7fba6b603f | |||
| c115b37c33 | |||
| d20ba95e28 | |||
| 7945e5010a | |||
| 21d148aedc | |||
| 4c8aeefb62 | |||
| d384834fde | |||
| f975d8d448 | |||
| 2602daf993 | |||
| 9f681c459a | |||
| d9448dcb9f | |||
| e9c718a465 | |||
| 4dc44f7205 | |||
| 499e1b2adf | |||
| 28c6c4dae2 | |||
| 791148a328 | |||
| 01b1845088 | |||
| 56c861c9e1 | |||
| 451e0f6175 | |||
| aee7f1c72f | |||
| 5fe28a0422 | |||
| f56586d9a9 | |||
| ec0baadcb6 | |||
| 9147d5c04a | |||
| cb801378c9 | |||
| 79604f4628 | |||
| bf6cb8ab0d | |||
| de74b3fd85 | |||
| c7a92d2a9a | |||
| da284fc354 | |||
| 90da3059ce | |||
| 651fd05eca | |||
| 85d7e09bef | |||
| 243a57648b | |||
| 158dec330c | |||
| a1e63c8d4a | |||
| 8cc9978d15 | |||
| 78a404da0e | |||
| f1bb8369b5 | |||
| 76b6941b4c | |||
| e72990dc37 | |||
| f338e96ccc | |||
| 0ad2b70862 | |||
| 5261a374a9 | |||
| 832eba5fc9 | |||
| 2b569fc0b2 | |||
| ee6aeb08bf | |||
| 8d43d8b8e7 | |||
| d08f5c6986 | |||
| 3e7fa19197 | |||
| 5d379db72b | |||
| 514639b585 | |||
| 9cd9956dcb | |||
| c7813e9ebf | |||
| ef91b04cdd | |||
| 1acd97e18f | |||
| 513199ee9f | |||
| 33f3c40e93 | |||
| 696cb95d5e | |||
| 457fd21a1a | |||
| 3c6dfbf67d | |||
| 3277b885c4 | |||
| 48a256d04b | |||
| 0579430799 | |||
| 39ac68dac1 | |||
| 87fb44a5d3 | |||
| 5c76b406f7 | |||
| f665968daf | |||
| 5d1291c29d | |||
| ce7f400011 | |||
| 0fc8516b0c | |||
| 28b2a9b583 | |||
| e8549372fc | |||
| 5a434eb74e | |||
| 318de4db66 | |||
| a6c79bf15d | |||
| c6a10a755e | |||
| 1d7bd5bf4f | |||
| 94572e89c2 | |||
| fee7bac392 | |||
| dbb3b0f561 | |||
| b8bfed6a52 | |||
| 7215a89e7d | |||
| b7cca56091 | |||
| 7338e433f8 | |||
| 119ed07d5a | |||
| 5f98ae8323 | |||
| 8a598b43bb | |||
| e5dff4cfbe | |||
| 6c7a9cdd5f | |||
| 3b34f762fe | |||
| fa167ba747 |
@@ -0,0 +1,11 @@
|
||||
bower_components/**
|
||||
build/**
|
||||
docs/bower_components/**
|
||||
docs/app/assets/js/angular-bootstrap/**
|
||||
docs/config/templates/**
|
||||
node_modules/**
|
||||
lib/htmlparser/**
|
||||
src/angular.bind.js
|
||||
src/ngParseExt/ucd.js
|
||||
i18n/closure/**
|
||||
tmp/**
|
||||
@@ -0,0 +1,117 @@
|
||||
{
|
||||
"rules": {
|
||||
// Rules are divided into sections from http://eslint.org/docs/rules/
|
||||
|
||||
// Possible errors
|
||||
"comma-dangle": ["error", "never"],
|
||||
"no-cond-assign": ["error", "except-parens"],
|
||||
"no-constant-condition": ["error", {"checkLoops": false}],
|
||||
"no-control-regex": "error",
|
||||
"no-debugger": "error",
|
||||
"no-dupe-args": "error",
|
||||
"no-dupe-keys": "error",
|
||||
"no-duplicate-case": "error",
|
||||
"no-empty-character-class": "error",
|
||||
"no-empty": "error",
|
||||
"no-ex-assign": "error",
|
||||
"no-extra-boolean-cast": "error",
|
||||
"no-extra-semi": "error",
|
||||
"no-func-assign": "error",
|
||||
"no-inner-declarations": "error",
|
||||
"no-invalid-regexp": "error",
|
||||
"no-irregular-whitespace": "error",
|
||||
"no-negated-in-lhs": "error",
|
||||
"no-obj-calls": "error",
|
||||
"no-regex-spaces": "error",
|
||||
"no-sparse-arrays": "error",
|
||||
"no-unreachable": "error",
|
||||
"use-isnan": "error",
|
||||
"no-unsafe-finally": "error",
|
||||
"valid-typeof": "error",
|
||||
"no-unexpected-multiline": "error",
|
||||
|
||||
// Best practices
|
||||
"accessor-pairs": "error",
|
||||
"array-callback-return": "error",
|
||||
"eqeqeq": ["error", "allow-null"],
|
||||
"no-alert": "error",
|
||||
"no-caller": "error",
|
||||
"no-case-declarations": "error",
|
||||
"no-eval": "error",
|
||||
"no-extend-native": "error",
|
||||
"no-extra-bind": "error",
|
||||
"no-extra-label": "error",
|
||||
"no-fallthrough": "error",
|
||||
"no-floating-decimal": "error",
|
||||
"no-implied-eval": "error",
|
||||
"no-invalid-this": "error",
|
||||
"no-iterator": "error",
|
||||
"no-multi-str": "error",
|
||||
"no-new-func": "error",
|
||||
"no-new-wrappers": "error",
|
||||
"no-new": "error",
|
||||
"no-octal-escape": "error",
|
||||
"no-octal": "error",
|
||||
"no-proto": "error",
|
||||
"no-redeclare": "error",
|
||||
"no-return-assign": "error",
|
||||
"no-script-url": "error",
|
||||
"no-self-assign": "error",
|
||||
"no-self-compare": "error",
|
||||
"no-sequences": "error",
|
||||
"no-throw-literal": "error",
|
||||
"no-unmodified-loop-condition": "error",
|
||||
"no-unused-expressions": "error",
|
||||
"no-unused-labels": "error",
|
||||
"no-useless-call": "error",
|
||||
"no-useless-concat": "error",
|
||||
"no-useless-escape": "error",
|
||||
"no-void": "error",
|
||||
"no-with": "error",
|
||||
"radix": "error",
|
||||
"wrap-iife": ["error", "inside"],
|
||||
|
||||
// Strict mode
|
||||
"strict": ["error", "global"],
|
||||
|
||||
// Variables
|
||||
"no-delete-var": "error",
|
||||
"no-label-var": "error",
|
||||
"no-restricted-globals": ["error", "event"],
|
||||
"no-shadow-restricted-names": "error",
|
||||
"no-undef-init": "error",
|
||||
"no-undef": "error",
|
||||
"no-unused-vars": ["error", { "vars": "local", "args": "none" }],
|
||||
|
||||
// Node.js
|
||||
"handle-callback-err": "error",
|
||||
|
||||
// Stylistic issues
|
||||
"array-bracket-spacing": ["error", "never"],
|
||||
"brace-style": ["error", "1tbs", { "allowSingleLine": true }],
|
||||
"comma-style": ["error", "last"],
|
||||
"eol-last": "error",
|
||||
"keyword-spacing": "error",
|
||||
"linebreak-style": ["error", "unix"],
|
||||
"max-len": ["error", { "code": 200, "ignoreComments": true, "ignoreUrls": true }],
|
||||
"new-cap": "error",
|
||||
"new-parens": "error",
|
||||
"no-array-constructor": "error",
|
||||
"no-bitwise": "error",
|
||||
"no-mixed-spaces-and-tabs": "error",
|
||||
"no-multiple-empty-lines": ["error", { "max": 3, "maxEOF": 1 }],
|
||||
"no-whitespace-before-property": "error",
|
||||
"no-spaced-func": "error",
|
||||
"no-trailing-spaces": "error",
|
||||
"no-unneeded-ternary": "error",
|
||||
"quotes": ["error", "single"],
|
||||
"semi-spacing": "error",
|
||||
"semi": "error",
|
||||
"space-before-blocks": ["error", "always"],
|
||||
"space-before-function-paren": ["error", "never"],
|
||||
"space-in-parens": ["error", "never"],
|
||||
"space-infix-ops": "error",
|
||||
"space-unary-ops": ["error", { "words": true, "nonwords": false }],
|
||||
"unicode-bom": ["error", "never"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "./.eslintrc-base.json",
|
||||
|
||||
"env": {
|
||||
// Note: don't set `"browser": true`; code in "src/" should be compatible with
|
||||
// non-browser environments like Node.js with a custom window implementation
|
||||
// like jsdom. All browser globals should be taken from window.
|
||||
"browser": false,
|
||||
"node": false
|
||||
},
|
||||
|
||||
"globals": {
|
||||
"window": false,
|
||||
|
||||
"angular": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "./.eslintrc-base.json",
|
||||
|
||||
"env": {
|
||||
"browser": false,
|
||||
"node": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
// This config contains proposed rules that we'd like to have enabled but haven't
|
||||
// converted the code to adhere yet. If a decision comes to not enable one of these
|
||||
// rules, it should be removed from the file. Every rule that got enabled in the
|
||||
// end should be moved from here to a respective section in .eslintrc.json
|
||||
|
||||
"rules": {
|
||||
// Rules are divided into sections from http://eslint.org/docs/rules/
|
||||
|
||||
// Best practices
|
||||
"complexity": ["error", 10],
|
||||
"dot-notation": "error",
|
||||
"dot-location": ["error", "property"],
|
||||
|
||||
// Stylistic issues
|
||||
"block-spacing": ["error", "always"],
|
||||
"comma-spacing": "error",
|
||||
"id-blacklist": ["error", "event"],
|
||||
"indent": ["error", 2],
|
||||
"key-spacing": ["error", { "beforeColon": false, "afterColon": true, "mode": "minimum" }],
|
||||
"object-curly-spacing": ["error", "never"],
|
||||
"object-property-newline": ["error", { "allowMultiplePropertiesPerLine": true }],
|
||||
"operator-linebreak": ["error", "after", { "overrides": { "?": "before", ":": "before" }}]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"root": true,
|
||||
"extends": "./.eslintrc-node.json"
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
{
|
||||
"excludeFiles": ["src/ngLocale/**"],
|
||||
"disallowKeywords": ["with"],
|
||||
"disallowKeywordsOnNewLine": ["else"],
|
||||
"disallowMixedSpacesAndTabs": true,
|
||||
"disallowMultipleLineStrings": true,
|
||||
"disallowNewlineBeforeBlockStatements": true,
|
||||
"disallowSpaceAfterObjectKeys": true,
|
||||
"disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
|
||||
"disallowSpaceBeforeBinaryOperators": [","],
|
||||
"disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
|
||||
"disallowSpacesInAnonymousFunctionExpression": {
|
||||
"beforeOpeningRoundBrace": true
|
||||
},
|
||||
"disallowSpacesInCallExpression": true,
|
||||
"disallowSpacesInFunctionDeclaration": {
|
||||
"beforeOpeningRoundBrace": true
|
||||
},
|
||||
"disallowSpacesInNamedFunctionExpression": {
|
||||
"beforeOpeningRoundBrace": true
|
||||
},
|
||||
"disallowSpacesInsideArrayBrackets": true,
|
||||
"requireSpaceBeforeKeywords": [
|
||||
"else",
|
||||
"while",
|
||||
"catch"
|
||||
],
|
||||
"disallowSpacesInsideParentheses": true,
|
||||
"disallowTrailingComma": true,
|
||||
"disallowTrailingWhitespace": true,
|
||||
"requireCommaBeforeLineBreak": true,
|
||||
"requireLineFeedAtFileEnd": true,
|
||||
"requireSpaceAfterBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"],
|
||||
"requireSpaceBeforeBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"],
|
||||
"requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"],
|
||||
"requireSpaceBeforeBlockStatements": true,
|
||||
"requireSpacesInConditionalExpression": {
|
||||
"afterTest": true,
|
||||
"beforeConsequent": true,
|
||||
"afterConsequent": true,
|
||||
"beforeAlternate": true
|
||||
},
|
||||
"requireSpacesInForStatement": true,
|
||||
"requireSpacesInFunction": {
|
||||
"beforeOpeningCurlyBrace": true
|
||||
},
|
||||
"validateLineBreaks": "LF"
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
node_modules/**
|
||||
lib/htmlparser/**
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"bitwise": true,
|
||||
"immed": true,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"noempty": true,
|
||||
"nonew": true,
|
||||
"trailing": true,
|
||||
"maxlen": 200,
|
||||
"boss": true,
|
||||
"eqnull": true,
|
||||
"expr": true,
|
||||
"globalstrict": true,
|
||||
"laxbreak": true,
|
||||
"loopfunc": true,
|
||||
"sub": true,
|
||||
"undef": true,
|
||||
"indent": 2
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
language: node_js
|
||||
sudo: false
|
||||
node_js:
|
||||
- '4.2'
|
||||
- '4.4'
|
||||
|
||||
cache:
|
||||
directories:
|
||||
|
||||
+625
-17
@@ -1,3 +1,574 @@
|
||||
<a name="1.5.8"></a>
|
||||
# 1.5.8 arbitrary-fallbacks (2016-07-22)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$animate:** do not get affected by custom, enumerable properties on `Object.prototype`
|
||||
([181e4401](https://github.com/angular/angular.js/commit/181e44019e850e5253378e29415cddf8d768bbef),
|
||||
[#14804](https://github.com/angular/angular.js/issues/14804), [#14830](https://github.com/angular/angular.js/issues/14830))
|
||||
- **$compile:** ensure `$doCheck` hooks can be defined in the controller constructor
|
||||
([3010ed4e](https://github.com/angular/angular.js/commit/3010ed4ee5c2c18b9848b5664639971b9fdc8919),
|
||||
[#14811](https://github.com/angular/angular.js/issues/14811))
|
||||
- **$injector:** fix class detection RegExp
|
||||
([4724d56c](https://github.com/angular/angular.js/commit/4724d56c939d02675433e7fe554608dff97ecf81),
|
||||
[#14533](https://github.com/angular/angular.js/issues/14533))
|
||||
- **$jsonpCallbacks:** do not overwrite callbacks added by other apps
|
||||
([1778d347](https://github.com/angular/angular.js/commit/1778d347cd3c91335e3840eaa49f1e387db8602f),
|
||||
[#14824](https://github.com/angular/angular.js/issues/14824))
|
||||
- **$timeout:** make $flush handle new $timeouts added in $timeout callbacks
|
||||
([1a387ba5](https://github.com/angular/angular.js/commit/1a387ba5dd1a8a831486fce23f6795bd1eef3d8b),
|
||||
[#5420](https://github.com/angular/angular.js/issues/5420), [#14686](https://github.com/angular/angular.js/issues/14686))
|
||||
- **copy:** fix handling of typed subarrays
|
||||
([1645924d](https://github.com/angular/angular.js/commit/1645924d49a7905ce55cced4c4276654970bb226),
|
||||
[#14842](https://github.com/angular/angular.js/issues/14842), [#14845](https://github.com/angular/angular.js/issues/14845))
|
||||
- **modules:** allow modules to be loaded in any order when using `angular-loader`
|
||||
([98e4a220](https://github.com/angular/angular.js/commit/98e4a220fe8301cec35498ae592adc0266f12437),
|
||||
[#9140](https://github.com/angular/angular.js/issues/9140), [#14794](https://github.com/angular/angular.js/issues/14794))
|
||||
- **ngAnimate:** allow removal of class that is scheduled to be added with requestAnimationFrame
|
||||
([7ccfe92b](https://github.com/angular/angular.js/commit/7ccfe92bed7361832f1b8d25b1a8411eb24d3fb5),
|
||||
[#14582](https://github.com/angular/angular.js/issues/14582))
|
||||
- **ngMocks:** allow `ErrorAddingDeclarationLocationStack` to be recognized as an `Error`
|
||||
([c6074dc3](https://github.com/angular/angular.js/commit/c6074dc34c31a07269bf7f628b971ef6dc805f17),
|
||||
[#13821](https://github.com/angular/angular.js/issues/13821), [#14344](https://github.com/angular/angular.js/issues/14344))
|
||||
- **ngOptions:** don't duplicate groups with falsy values
|
||||
([c3bfd7f5](https://github.com/angular/angular.js/commit/c3bfd7f59d0ecbf4ba3253fb407e683c7bb0766c))
|
||||
- **ngTransclude:**
|
||||
- ensure that fallback content is compiled and linked correctly
|
||||
([c405f88b](https://github.com/angular/angular.js/commit/c405f88bbc743f41591f6f3cfc022eea3c6c34ad),
|
||||
[#14787](https://github.com/angular/angular.js/issues/14787))
|
||||
- only compile fallback content if necessary
|
||||
([159a68ec](https://github.com/angular/angular.js/commit/159a68ec7ba77e9128b0d0516b813ed3d223b6e3),
|
||||
[#14768](https://github.com/angular/angular.js/issues/14768), [#14765](https://github.com/angular/angular.js/issues/14765), [#14775](https://github.com/angular/angular.js/issues/14775))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **$compile:** backport $doCheck
|
||||
([de59ca71](https://github.com/angular/angular.js/commit/de59ca71072eac95ee68de308f92bc5f921dd07b),
|
||||
[#14656](https://github.com/angular/angular.js/issues/14656))
|
||||
- **$jsonpCallbacks:** new service to abstract how JSONP callbacks are handled
|
||||
([a8cacfe9](https://github.com/angular/angular.js/commit/a8cacfe938287c54ce7099125cb735ad53f4c7c2),
|
||||
[#14795](https://github.com/angular/angular.js/issues/14795))
|
||||
- **$q:** implement $q.race
|
||||
([b9a56d58](https://github.com/angular/angular.js/commit/b9a56d588f8b597b1dff30d8e184b7c37d94cdcf),
|
||||
[#12929](https://github.com/angular/angular.js/issues/12929), [#14757](https://github.com/angular/angular.js/issues/14757))
|
||||
- **$resource:** pass the resource to a dynamic param functions
|
||||
([a126fcfe](https://github.com/angular/angular.js/commit/a126fcfee3bd8b02869bd2542c73e1eb21afe927),
|
||||
[#4899](https://github.com/angular/angular.js/issues/4899))
|
||||
- **$swipe:** add pointer support
|
||||
([f797f83c](https://github.com/angular/angular.js/commit/f797f83cd66f1fd11b3c9399e7894217ffa06c38),
|
||||
[#14061](https://github.com/angular/angular.js/issues/14061), [#14791](https://github.com/angular/angular.js/issues/14791))
|
||||
- **filterFilter:** allow overwriting the special `$` property name
|
||||
([33514ec3](https://github.com/angular/angular.js/commit/33514ec384d676d84b2a445bc15bae38c8c3ac8d),
|
||||
[#13313](https://github.com/angular/angular.js/issues/13313))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
|
||||
- **$compile:** wrap try/catch of collect comment directives into a function to avoid V8 deopt
|
||||
([acd45518](https://github.com/angular/angular.js/commit/acd455181de1cfa6b34d75f8d71a6c0b6995a777),
|
||||
[#14848](https://github.com/angular/angular.js/issues/14848))
|
||||
|
||||
|
||||
<a name="1.2.30"></a>
|
||||
# 1.2.30 patronal-resurrection (2016-07-21)
|
||||
|
||||
|
||||
_**Note:** This release contains some security fixes that required breaking changes. Since the
|
||||
legacy 1.2.x branch is the only version branch that supports IE8, it was necessary to introduce a
|
||||
couple of low-impact breaking changes in a patch release - something we generally avoid - in order
|
||||
to make the fixes available to people that still need IE8 support._
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$compile:**
|
||||
- secure `link[href]` as a `RESOURCE_URL`s in `$sce`
|
||||
([f35f334b](https://github.com/angular/angular.js/commit/f35f334bd3197585bdf034f4b6d9ffa3122dac62),
|
||||
[#14687](https://github.com/angular/angular.js/issues/14687))
|
||||
- properly sanitize `xlink:href` attribute interoplation
|
||||
([f2fa1ed8](https://github.com/angular/angular.js/commit/f2fa1ed83d18d4e79a36f8c0db1c2524d762e513),
|
||||
[2687c261](https://github.com/angular/angular.js/commit/2687c26140585d9e3716f9f559390f5d8d598fdf))
|
||||
- **ngSanitize:** blacklist the attribute `usemap` as it can be used as a security exploit
|
||||
([ac0d5286](https://github.com/angular/angular.js/commit/ac0d5286b8931633d774080d6396fb4825d8be33),
|
||||
[#14903](https://github.com/angular/angular.js/issues/14903))
|
||||
- **ngAnimate:** do not use event.timeStamp anymore for time tracking
|
||||
([8d83b563](https://github.com/angular/angular.js/commit/8d83b5633471c847d58f337426fe069797dd49d9),
|
||||
[#13494](https://github.com/angular/angular.js/issues/13494), [#13495](https://github.com/angular/angular.js/issues/13495))
|
||||
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- **$compile:** due to [f35f334b](https://github.com/angular/angular.js/commit/f35f334bd3197585bdf034f4b6d9ffa3122dac62),
|
||||
|
||||
`link[href]` attributes are now protected via `$sce`, which prevents interpolated values that fail
|
||||
the `RESOURCE_URL` context tests from being used in interpolation. For example if the application is
|
||||
running at `https://mydomain.org/` then the following will fail:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="{{ 'https://otherdomain.org/unsafe.css' }}" />
|
||||
```
|
||||
|
||||
By default, `RESOURCE_URL` safe URLs are only allowed from the same domain and protocol as the
|
||||
application document. To use URLs from other domains and/or protocols, you may either whitelist them
|
||||
using `$sceDelegateProvider.resourceUrlWhitelist(...)` or wrap them into a trusted value by calling
|
||||
`$sce.trustAsResourceUrl(url)`.
|
||||
|
||||
- **ngSanitize:** due to [234053fc](https://github.com/angular/angular.js/commit/234053fc9ad90e0d05be7e8359c6af66be94c094),
|
||||
|
||||
The `$sanitize` service will now remove instances of the `usemap` attribute from any elements passed
|
||||
to it.
|
||||
|
||||
This attribute is used to reference another element by `name` or `id`. Since the `name` and `id`
|
||||
attributes are already blacklisted, a sanitized `usemap` attribute could only reference unsanitized
|
||||
content, which is a security risk.
|
||||
|
||||
|
||||
<a name="1.5.7"></a>
|
||||
# 1.5.7 hexagonal-circumvolution (2016-06-15)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$compile:**
|
||||
- don't add merged attributes twice to $attrs
|
||||
([ebbaa4ac](https://github.com/angular/angular.js/commit/ebbaa4ac5e3559df9267203438a0bb18c2d3b7d8),
|
||||
[#8159](https://github.com/angular/angular.js/issues/8159), [#14737](https://github.com/angular/angular.js/issues/14737))
|
||||
- cope with `$onChanges` hooks throwing
|
||||
([3749c858](https://github.com/angular/angular.js/commit/3749c85829406ca57cc5729e80696c7f34134068),
|
||||
[#14444](https://github.com/angular/angular.js/issues/14444), [#14463](https://github.com/angular/angular.js/issues/14463))
|
||||
- **$parse:** allow arguments to contain filter chains
|
||||
([cc6dcb4b](https://github.com/angular/angular.js/commit/cc6dcb4bc28aadff4f62d76d6451b0f80b928e69),
|
||||
[#4175](https://github.com/angular/angular.js/issues/4175), [#4168](https://github.com/angular/angular.js/issues/4168), [#14720](https://github.com/angular/angular.js/issues/14720))
|
||||
- **$routeProvider:** do not deep-copy route definition objects
|
||||
([6d0dcca6](https://github.com/angular/angular.js/commit/6d0dcca6f18a353a12c356dc96e05475d351b795),
|
||||
[#14478](https://github.com/angular/angular.js/issues/14478), [#14699](https://github.com/angular/angular.js/issues/14699), [#14750](https://github.com/angular/angular.js/issues/14750))
|
||||
- **input[email]:** improve email address validation
|
||||
([f423dc6b](https://github.com/angular/angular.js/commit/f423dc6b51a9b4a09728a287a2cabda7d45f192e),
|
||||
[#14719](https://github.com/angular/angular.js/issues/14719))
|
||||
- **ngMessages:** create new scope for ngMessage, clean it up correctly
|
||||
([56f33af8](https://github.com/angular/angular.js/commit/56f33af89045e2ec18d144d9d1ef73affbe51959),
|
||||
[#14307](https://github.com/angular/angular.js/issues/14307))
|
||||
- **ngMessagesInclude:** don't break on empty (or whitespace-only) templates
|
||||
([01b8772c](https://github.com/angular/angular.js/commit/01b8772cca55916376355a2ae58d3ab7832a4bc2),
|
||||
[#12941](https://github.com/angular/angular.js/issues/12941), [#14726](https://github.com/angular/angular.js/issues/14726))
|
||||
- **ngMock#$controller:** properly assign bindings to all types of controllers (e.g. class-based)
|
||||
([db58801a](https://github.com/angular/angular.js/commit/db58801a55c91df755414387dc00fee5902bb5f3),
|
||||
[#14437](https://github.com/angular/angular.js/issues/14437), [#14439](https://github.com/angular/angular.js/issues/14439))
|
||||
- **ngMockE2E:** allow $httpBackend.passThrough() to work when ngMock is loaded
|
||||
([6685043a](https://github.com/angular/angular.js/commit/6685043ad40acc50d7088f87e2a71f76d2265306),
|
||||
[#1434](https://github.com/angular/angular.js/issues/1434), [#13124](https://github.com/angular/angular.js/issues/13124))
|
||||
- **ngSanitize:** call attribute setter in linky for all links
|
||||
([c4fad6ad](https://github.com/angular/angular.js/commit/c4fad6ad617af025984ca401054f7b402aa28f1d),
|
||||
[#14707](https://github.com/angular/angular.js/issues/14707))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **limitTo:** add support for array-like objects
|
||||
([b03957f0](https://github.com/angular/angular.js/commit/b03957f0047fcfe996abc8efe97f9e2be2c2e13a),
|
||||
[#14657](https://github.com/angular/angular.js/issues/14657), [#14694](https://github.com/angular/angular.js/issues/14694))
|
||||
- **orderBy:** add support for custom comparators
|
||||
([2e33d170](https://github.com/angular/angular.js/commit/2e33d170be7eb72f40fd57a8f66631583572fbf2),
|
||||
[#13238](https://github.com/angular/angular.js/issues/13238), [#14455](https://github.com/angular/angular.js/issues/14455), [#5123](https://github.com/angular/angular.js/issues/5123), [#8112](https://github.com/angular/angular.js/issues/8112), [#10368](https://github.com/angular/angular.js/issues/10368), [#14468](https://github.com/angular/angular.js/issues/14468))
|
||||
|
||||
|
||||
<a name="1.5.6"></a>
|
||||
# 1.5.6 arrow-stringification (2016-05-27)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$browser:** set the url even if the browser transforms it
|
||||
([743b33ab](https://github.com/angular/angular.js/commit/743b33ab9d8cdb8aa6ff28028a54ac0023f4dc15),
|
||||
[#14427](https://github.com/angular/angular.js/issues/14427), [#14499](https://github.com/angular/angular.js/issues/14499))
|
||||
- **$compile:**
|
||||
- properly bind context to linking functions for directives with `templateUrl`
|
||||
([5ae72dc7](https://github.com/angular/angular.js/commit/5ae72dc7affb252774b7c4cbf278269c5e178f38))
|
||||
- always use the DDO as `this` in pre-/post-linking functions
|
||||
([47bc98a1](https://github.com/angular/angular.js/commit/47bc98a1eafd7853babc1a7dc54f13363a3f4a43),
|
||||
[#9306](https://github.com/angular/angular.js/issues/9306))
|
||||
- don't run unnecessary update to one-way bindings
|
||||
([30479647](https://github.com/angular/angular.js/commit/304796471292f9805b9cf77e51aacc9cfbb09921),
|
||||
[#14546](https://github.com/angular/angular.js/issues/14546), [#14580](https://github.com/angular/angular.js/issues/14580))
|
||||
- removing unnecessary white space in element-transclusion comments
|
||||
([1116a96d](https://github.com/angular/angular.js/commit/1116a96df662c95aa83ab527c479b644a14532b6),
|
||||
[#14549](https://github.com/angular/angular.js/issues/14549), [#14550](https://github.com/angular/angular.js/issues/14550))
|
||||
- properly handle setting `srcset` to undefined
|
||||
([308f22ba](https://github.com/angular/angular.js/commit/308f22ba9a803967ce84c995d810990c80478f6f),
|
||||
[#14470](https://github.com/angular/angular.js/issues/14470), [#14493](https://github.com/angular/angular.js/issues/14493))
|
||||
- **$injector:**
|
||||
- add workaround for class stringification in Chrome v50/51
|
||||
([7550b7bd](https://github.com/angular/angular.js/commit/7550b7bda8d992cc6ed3c65b1f9f7e323a09cae4),
|
||||
[#14531](https://github.com/angular/angular.js/issues/14531))
|
||||
- add workaround for fat-arrow stringification in Chrome v50/51
|
||||
([bb730704](https://github.com/angular/angular.js/commit/bb730704f2f3dea4620e7b40083dcd65f208e2b2),
|
||||
[#14487](https://github.com/angular/angular.js/issues/14487), [#14495](https://github.com/angular/angular.js/issues/14495))
|
||||
- **$templateRequest:** trust empty templates in `$templateCache` as well
|
||||
([10955969](https://github.com/angular/angular.js/commit/10955969620248bd31a0bd37bc9fd7cc3b1f5e88),
|
||||
[#14479](https://github.com/angular/angular.js/issues/14479), [#14496](https://github.com/angular/angular.js/issues/14496))
|
||||
- **filters:** always call `splice()` with 2 arguments or more
|
||||
([6f1fae8a](https://github.com/angular/angular.js/commit/6f1fae8a916cc6f26725f64869f86fcd4991e819),
|
||||
[#14467](https://github.com/angular/angular.js/issues/14467), [#14489](https://github.com/angular/angular.js/issues/14489))
|
||||
- **ng-bind-html:** watch the unwrapped value using `$sce.valueOf()` (instead of `toString()`)
|
||||
([1c1c9b27](https://github.com/angular/angular.js/commit/1c1c9b27cbb57b3219d4c9765eeea8a11553d297),
|
||||
[#14526](https://github.com/angular/angular.js/issues/14526), [#14527](https://github.com/angular/angular.js/issues/14527))
|
||||
- **ngAnimate:**
|
||||
- don't break on anchored animations without duration
|
||||
([21b76aed](https://github.com/angular/angular.js/commit/21b76aed06d9cc04bd25a99c23ba852af782b357),
|
||||
[#14641](https://github.com/angular/angular.js/issues/14641), [#14645](https://github.com/angular/angular.js/issues/14645))
|
||||
- properly handle empty jqLite collections
|
||||
([9f480257](https://github.com/angular/angular.js/commit/9f4802573348401ee24090f815f3138fa17c161d),
|
||||
[#14558](https://github.com/angular/angular.js/issues/14558), [#14559](https://github.com/angular/angular.js/issues/14559))
|
||||
- **ngMessages:** do not compile ngMessagesInclude template if scope is destroyed
|
||||
([69d9072d](https://github.com/angular/angular.js/commit/69d9072d5b5aba988ac8a9717c92ce1fac465cbe),
|
||||
[#12695](https://github.com/angular/angular.js/issues/12695), [#14640](https://github.com/angular/angular.js/issues/14640))
|
||||
- **ngMock:**
|
||||
- match HTTP request regardless of the order of query params
|
||||
([363fb16c](https://github.com/angular/angular.js/commit/363fb16c1076a806bb31006daaf583ab5c82e467),
|
||||
[#12762](https://github.com/angular/angular.js/issues/12762))
|
||||
- pass eventHandlers to $httpBackend if passThrough is active
|
||||
([147650b3](https://github.com/angular/angular.js/commit/147650b3beae7ad8b556a930129887d187a0f5d3),
|
||||
[#14471](https://github.com/angular/angular.js/issues/14471))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **$compile:** support omitting required controller name if same as the local name
|
||||
([8965d57a](https://github.com/angular/angular.js/commit/8965d57aa0788c96859cf3cfa0f78b46d2cebedb),
|
||||
[#14513](https://github.com/angular/angular.js/issues/14513))
|
||||
- **$parse:** Add support for ES6 object initializers
|
||||
([1c9b9e24](https://github.com/angular/angular.js/commit/1c9b9e24ede7efc10ce4d53c6ab5528cc77e79d7))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
|
||||
- **$rootScope:** make queues more efficient
|
||||
([51b78f61](https://github.com/angular/angular.js/commit/51b78f61f954d94dc937f57190c9f881df9ab3ad),
|
||||
[#14545](https://github.com/angular/angular.js/issues/14545))
|
||||
- **ngAnimate:** listen for document visibility changes
|
||||
([b377d6b0](https://github.com/angular/angular.js/commit/b377d6b043db9c8da4e68493892f75a0f9759464),
|
||||
[#14568](https://github.com/angular/angular.js/issues/14568))
|
||||
- **ngClass:** improve even-odd checking
|
||||
([cf1b1755](https://github.com/angular/angular.js/commit/cf1b175508a72d4b7e3d64b8506903096c6ec25f))
|
||||
|
||||
|
||||
<a name="1.5.5"></a>
|
||||
# 1.5.5 material-conspiration (2016-04-18)
|
||||
|
||||
|
||||
## Reverts
|
||||
|
||||
- **$compile:** move setting of controller data to single location
|
||||
Reverted commit [21d148ae](https://github.com/angular/angular.js/commit/21d148aedc29c7efba4131ff2ef6383b4700868c)
|
||||
since it caused the Angular Material tabs directive to fail.
|
||||
|
||||
- **ngRoute:** allow `ngView` to be included in an asynchronously loaded template
|
||||
Eagerly loading `$route`, could break tests, because it might request the root or default route
|
||||
template (something `$httpBackend` would know nothing about).
|
||||
|
||||
It will be re-applied for `v1.6.x`, with a breaking change notice and possibly a way to disable
|
||||
the feature in tests.
|
||||
|
||||
([8237482d](https://github.com/angular/angular.js/commit/8237482d49e76e2c4994fe6207e3c9799ef04163),
|
||||
[#1213](https://github.com/angular/angular.js/issues/1213), [#6812](https://github.com/angular/angular.js/issues/6812),
|
||||
[#14088](https://github.com/angular/angular.js/issues/14088))
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$compile:**
|
||||
- do not use `noop()` as controller for multiple components
|
||||
([4c8aeefb](https://github.com/angular/angular.js/commit/4c8aeefb624de7436ad95f3cd525405e0c3f493e),
|
||||
[#14391](https://github.com/angular/angular.js/issues/14391), [#14402](https://github.com/angular/angular.js/issues/14402))
|
||||
- still trigger `$onChanges` even if the inner value already matches the new value
|
||||
([d9448dcb](https://github.com/angular/angular.js/commit/d9448dcb9f901ceb04deda1d5f3d5aac8442a718),
|
||||
[#14406](https://github.com/angular/angular.js/issues/14406))
|
||||
- handle boolean attributes in `@` bindings
|
||||
([499e1b2a](https://github.com/angular/angular.js/commit/499e1b2adf27f32d671123f8dceadb3df2ad84a9),
|
||||
[#14070](https://github.com/angular/angular.js/issues/14070))
|
||||
- don't throw if controller is named
|
||||
([e72990dc](https://github.com/angular/angular.js/commit/e72990dc3714c8b847185ddb64fd5fd00e5cceab))
|
||||
- ensure that `$onChanges` hook is called correctly
|
||||
([0ad2b708](https://github.com/angular/angular.js/commit/0ad2b70862d49ecc4355a16d767c0ca9358ecc3e),
|
||||
[#14355](https://github.com/angular/angular.js/issues/14355), [#14359](https://github.com/angular/angular.js/issues/14359))
|
||||
- **$injector:** ensure functions with overridden `toString()` are annotated properly
|
||||
([d384834f](https://github.com/angular/angular.js/commit/d384834fdee140a716298bd065f304f8fba4725e),
|
||||
[#14361](https://github.com/angular/angular.js/issues/14361))
|
||||
- **ngAnimate:**
|
||||
- remove event listeners only after all listeners have been called
|
||||
([79604f46](https://github.com/angular/angular.js/commit/79604f462899c118a99d610995083ff82d38aa35),
|
||||
[#14321](https://github.com/angular/angular.js/issues/14321))
|
||||
- fire callbacks when document is hidden
|
||||
([c7a92d2a](https://github.com/angular/angular.js/commit/c7a92d2a9a436dddd65de721c9837a93e915d939),
|
||||
[#14120](https://github.com/angular/angular.js/issues/14120))
|
||||
- fire callbacks in the correct order for certain skipped animations
|
||||
([90da3059](https://github.com/angular/angular.js/commit/90da3059cecfefaecf136b01cd87aee6775a8778))
|
||||
- **ngClass:** fix watching of an array expression containing an object
|
||||
([f975d8d4](https://github.com/angular/angular.js/commit/f975d8d4481e0b8cdba553f0e5ad9ec1688adae8),
|
||||
[#14405](https://github.com/angular/angular.js/issues/14405))
|
||||
- **ngMock:** fix collecting stack trace in `inject()` on IE10+, PhantomJS
|
||||
([e9c718a4](https://github.com/angular/angular.js/commit/e9c718a465d28b9f2691e3acab944f7c31aa9fb6),
|
||||
[#13591](https://github.com/angular/angular.js/issues/13591), [#13592](https://github.com/angular/angular.js/issues/13592), [#13593](https://github.com/angular/angular.js/issues/13593))
|
||||
- **ngOptions:** set select value when model matches disabled option
|
||||
([832eba5f](https://github.com/angular/angular.js/commit/832eba5fc952312e6b99127123e6e75bdf729006),
|
||||
[#12756](https://github.com/angular/angular.js/issues/12756))
|
||||
- **$http:** pass event object to `eventHandlers`/`uploadEventHandlers`
|
||||
([25d4e5cc](https://github.com/angular/angular.js/commit/25d4e5cca4fa615e49d65976223c6deb5b485b4c),
|
||||
[#14436](https://github.com/angular/angular.js/issues/14436))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **$compile:**
|
||||
- put custom annotations on DDO
|
||||
([f338e96c](https://github.com/angular/angular.js/commit/f338e96ccc739efc4b24022eae406c3d5451d422),
|
||||
[#14369](https://github.com/angular/angular.js/issues/14369), [#14279](https://github.com/angular/angular.js/issues/14279), [#14284](https://github.com/angular/angular.js/issues/14284))
|
||||
- add `isFirstChange()` method to onChanges object
|
||||
([8d43d8b8](https://github.com/angular/angular.js/commit/8d43d8b8e7aacf97ddb9aa48bff25db57249cdd5),
|
||||
[#14318](https://github.com/angular/angular.js/issues/14318), [#14323](https://github.com/angular/angular.js/issues/14323))
|
||||
- **$componentController:** provide isolated scope if none is passed (#14425)
|
||||
([33f817b9](https://github.com/angular/angular.js/commit/33f817b99cb20e566b381e7202235fe99b4a742a),
|
||||
[#14425](https://github.com/angular/angular.js/issues/14425))
|
||||
- **$http:**
|
||||
- support handling additional XHR events
|
||||
([01b18450](https://github.com/angular/angular.js/commit/01b18450882da9bb9c903d43c0daddbc03c2c35d) and
|
||||
[56c861c9](https://github.com/angular/angular.js/commit/56c861c9e114c45790865e5635eaae8d32eb649a),
|
||||
[#14367](https://github.com/angular/angular.js/issues/14367), [#11547](https://github.com/angular/angular.js/issues/11547), [#1934](https://github.com/angular/angular.js/issues/1934))
|
||||
- **$parse:** add the ability to define the identifier characters
|
||||
([3e7fa191](https://github.com/angular/angular.js/commit/3e7fa19197c54a764225ad27c0c0bf72263daa8d))
|
||||
- **ngAnimate:** let $animate.off() remove all listeners for an element
|
||||
([bf6cb8ab](https://github.com/angular/angular.js/commit/bf6cb8ab0d157083a1ed55743e3fffe728daa6f3))
|
||||
- **ngAria:** add support for aria-readonly based on ngReadonly
|
||||
([ec0baadc](https://github.com/angular/angular.js/commit/ec0baadcb68a4fa8da27d76b7e6a4e0840acd7fa),
|
||||
[#14140](https://github.com/angular/angular.js/issues/14140), [#14077](https://github.com/angular/angular.js/issues/14077))
|
||||
- **ngParseExt:** new ngParseExt module
|
||||
([d08f5c69](https://github.com/angular/angular.js/commit/d08f5c698624f6243685b16f2d458cb9a980ebde))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
|
||||
- **$compile:** use createMap() for directive bindings to allow fast `forEach`
|
||||
([c115b37c](https://github.com/angular/angular.js/commit/c115b37c336f3a5936187279057b29c76078caf2),
|
||||
[#12529](https://github.com/angular/angular.js/issues/12529))
|
||||
- **ngOptions:** use `documentFragment` to populate `select` options
|
||||
([6a4124d0](https://github.com/angular/angular.js/commit/6a4124d0fb17cd7fc0e8bf5a1ca4d785a1d11c1c),
|
||||
[#13607](https://github.com/angular/angular.js/issues/13607), [#13239](https://github.com/angular/angular.js/issues/13239), [#12076](https://github.com/angular/angular.js/issues/12076))
|
||||
|
||||
|
||||
<a name="1.5.4"></a>
|
||||
# 1.5.4 graduated-sophistry (2016-04-14)
|
||||
|
||||
This was a partially published release that you should ignore.
|
||||
|
||||
<a name="1.5.3"></a>
|
||||
# 1.5.3 diplohaplontic-meiosis (2016-03-25)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$compile:** workaround a GC bug in Chrome < 50
|
||||
([513199ee](https://github.com/angular/angular.js/commit/513199ee9f1c8eef1240983d6e52c824404adb98),
|
||||
[#14041](https://github.com/angular/angular.js/issues/14041), [#14286](https://github.com/angular/angular.js/issues/14286))
|
||||
- **$sniffer:** fix history sniffing in Chrome Packaged Apps
|
||||
([457fd21a](https://github.com/angular/angular.js/commit/457fd21a1a0c10c66245c32a73602f3a09038bda),
|
||||
[#11932](https://github.com/angular/angular.js/issues/11932), [#13945](https://github.com/angular/angular.js/issues/13945))
|
||||
- **formatNumber:** handle small numbers correctly when `gSize` !== `lgSize`
|
||||
([3277b885](https://github.com/angular/angular.js/commit/3277b885c4dec3edd51b8e8c3d1776057d6d4d1d),
|
||||
[#14289](https://github.com/angular/angular.js/issues/14289), [#14290](https://github.com/angular/angular.js/issues/14290))
|
||||
- **ngAnimate:** run structural animations with cancelled out class changes
|
||||
([c7813e9e](https://github.com/angular/angular.js/commit/c7813e9ebf793fe89380dcad54e8e002fafdd985),
|
||||
[#14249](https://github.com/angular/angular.js/issues/14249))
|
||||
- **ngMessages:** don't crash when nested messages are removed
|
||||
([ef91b04c](https://github.com/angular/angular.js/commit/ef91b04cdd794f308617bca7ebd0b1b747e4f7de),
|
||||
[#14183](https://github.com/angular/angular.js/issues/14183), [#14242](https://github.com/angular/angular.js/issues/14242))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **$compile:** add more lifecycle hooks to directive controllers
|
||||
([9cd9956d](https://github.com/angular/angular.js/commit/9cd9956dcbc8382e8e8757a805398bd251bbc67e),
|
||||
[#14127](https://github.com/angular/angular.js/issues/14127), [#14030](https://github.com/angular/angular.js/issues/14030), [#14020](https://github.com/angular/angular.js/issues/14020), [#13991](https://github.com/angular/angular.js/issues/13991), [#14302](https://github.com/angular/angular.js/issues/14302))
|
||||
|
||||
|
||||
|
||||
<a name="1.5.2"></a>
|
||||
# 1.5.2 differential-recovery (2016-03-18)
|
||||
|
||||
This release reverts a breaking change that accidentally made it into the 1.5.1 release. See
|
||||
[fee7bac3](https://github.com/angular/angular.js/commit/fee7bac392db24b6006d6a57ba71526f3afa102c)
|
||||
for more info.
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **ngAnimate.$animate:** remove animation callbacks when the element is removed
|
||||
([ce7f4000](https://github.com/angular/angular.js/commit/ce7f400011e1e2e1b9316f18ce87b87b79d878b4))
|
||||
|
||||
|
||||
<a name="1.5.1"></a>
|
||||
# 1.5.1 equivocal-sophistication (2016-03-16)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **core:** only call `console.log` when `window.console` exists
|
||||
([ce138f3c](https://github.com/angular/angular.js/commit/ce138f3c552f8bf741721ab8d10994ed35a4b2f5),
|
||||
[#14006](https://github.com/angular/angular.js/issues/14006), [#14007](https://github.com/angular/angular.js/issues/14007), [#14047](https://github.com/angular/angular.js/issues/14047))
|
||||
- **$compile:** allow directives to have decorators
|
||||
([0728cc2f](https://github.com/angular/angular.js/commit/0728cc2f2bb04d5dbdfca41f3afacea16c75ee07))
|
||||
- **$resource:** fix parse errors on older Android WebViews
|
||||
([df8db7b4](https://github.com/angular/angular.js/commit/df8db7b446b5bae83afef457d706d2805e597f29),
|
||||
[#13989](https://github.com/angular/angular.js/issues/13989))
|
||||
- **$routeProvider:** properly handle optional eager path named groups
|
||||
([c0797c68](https://github.com/angular/angular.js/commit/c0797c68866c9ef8ff3c2f6985e6eb9374346151),
|
||||
[#14011](https://github.com/angular/angular.js/issues/14011))
|
||||
- **copy:** add support for copying `Blob` objects
|
||||
([e9d579b6](https://github.com/angular/angular.js/commit/e9d579b608c2be8fdcf0326d0679a76bb9ae5b6e),
|
||||
[#9669](https://github.com/angular/angular.js/issues/9669), [#14064](https://github.com/angular/angular.js/issues/14064))
|
||||
- **dateFilter:** correctly format BC years
|
||||
([e36205f5](https://github.com/angular/angular.js/commit/e36205f5af82b69362def7d2b6eeeb038f592311))
|
||||
- **formatNumber:** allow negative fraction size
|
||||
([e046c170](https://github.com/angular/angular.js/commit/e046c170bcf677f26e61af6470cb5fd2f751c969),
|
||||
[#13913](https://github.com/angular/angular.js/issues/13913))
|
||||
- **input:** re-validate when partially editing date-family inputs
|
||||
([e383804c](https://github.com/angular/angular.js/commit/e383804c4ab62278fbaf4fdfaa03caeacff77fc4),
|
||||
[#12207](https://github.com/angular/angular.js/issues/12207), [#13886](https://github.com/angular/angular.js/issues/13886))
|
||||
- **input\[date\]:** support years with more than 4 digits
|
||||
([d76951f1](https://github.com/angular/angular.js/commit/d76951f1747abd2da6e320d4ff9019f170d9793f),
|
||||
[#13735](https://github.com/angular/angular.js/issues/13735), [#13905](https://github.com/angular/angular.js/issues/13905))
|
||||
- **ngOptions:** always set the 'selected' attribute for selected options
|
||||
([9f5a1722](https://github.com/angular/angular.js/commit/9f5a172291ff6926dcd246f0972288916a4c9bf6),
|
||||
[#14115](https://github.com/angular/angular.js/issues/14115))
|
||||
- **ngRoute:** allow `ngView` to be included in an asynchronously loaded template
|
||||
([8237482d](https://github.com/angular/angular.js/commit/8237482d49e76e2c4994fe6207e3c9799ef04163),
|
||||
[#1213](https://github.com/angular/angular.js/issues/1213), [#6812](https://github.com/angular/angular.js/issues/6812), [#14088](https://github.com/angular/angular.js/issues/14088))
|
||||
- **ngMock:**
|
||||
- attach `$injector` to `$rootElement` and prevent memory leak due to attached data
|
||||
([75373dd4](https://github.com/angular/angular.js/commit/75373dd4bdae6c6035272942c69444c386f824cd),
|
||||
[#14022](https://github.com/angular/angular.js/issues/14022), [#14094](https://github.com/angular/angular.js/issues/14094), [#14098](https://github.com/angular/angular.js/issues/14098))
|
||||
- don't break if `$rootScope.$destroy()` is not a function
|
||||
([50ed8712](https://github.com/angular/angular.js/commit/50ed8712566d601c9fb76b71f7b534b5bc803a36),
|
||||
[#14106](https://github.com/angular/angular.js/issues/14106), [#14107](https://github.com/angular/angular.js/issues/14107))
|
||||
- **ngMockE2E:** pass `responseType` to `$delegate` when using `passThrough`
|
||||
([d16faf9f](https://github.com/angular/angular.js/commit/d16faf9f2b9bd2b85d95e71d902cec0269282f2c),
|
||||
[#5415](https://github.com/angular/angular.js/issues/5415), [#5783](https://github.com/angular/angular.js/issues/5783))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **$compile:** add custom annotations to the controller
|
||||
([0c800930](https://github.com/angular/angular.js/commit/0c8009300b819c39c5e4892856724a731a8dcda6),
|
||||
[#14114](https://github.com/angular/angular.js/issues/14114))
|
||||
- **$controllerProvider:** add a `has()` method for checking the existence of a controller
|
||||
([bb9575db](https://github.com/angular/angular.js/commit/bb9575dbd3428176216355df7b2933d2a72783cd),
|
||||
[#13951](https://github.com/angular/angular.js/issues/13951), [#14109](https://github.com/angular/angular.js/issues/14109))
|
||||
- **dateFilter:** add support for STANDALONEMONTH in format (`LLLL`)
|
||||
([3e5b25b3](https://github.com/angular/angular.js/commit/3e5b25b33f278376def432698c704b1807fdb8c0),
|
||||
[#13999](https://github.com/angular/angular.js/issues/13999), [#14013](https://github.com/angular/angular.js/issues/14013))
|
||||
- **ngMock:** add `sharedInjector()` to `angular.mock.module`
|
||||
([a46ab60f](https://github.com/angular/angular.js/commit/a46ab60fd5bf94896f0761e858ef38b998eb0f80),
|
||||
[#14093](https://github.com/angular/angular.js/issues/14093), [#10238](https://github.com/angular/angular.js/issues/10238))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
|
||||
- **ngRepeat:** avoid duplicate jqLite wrappers
|
||||
([632e15a3](https://github.com/angular/angular.js/commit/632e15a3afdcd30168700cec1367bd81966400d4))
|
||||
- **ngAnimate:**
|
||||
- avoid jqLite/jQuery for upward DOM traversal
|
||||
([35251bd4](https://github.com/angular/angular.js/commit/35251bd4ce23251b5e9a2860cf414726c194721e))
|
||||
- avoid `$.fn.data` overhead with jQuery
|
||||
([15915e60](https://github.com/angular/angular.js/commit/15915e606fdf5114592db1a0a5e3f12e639d7cdb))
|
||||
|
||||
|
||||
<a name="1.4.10"></a>
|
||||
# 1.4.10 benignant-oscillation (2016-03-16)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **core:** only call `console.log` when `window.console` exists
|
||||
([beb00e44](https://github.com/angular/angular.js/commit/beb00e44de947981dbe35d5cf7a116e10ea8dc67),
|
||||
[#14006](https://github.com/angular/angular.js/issues/14006), [#14007](https://github.com/angular/angular.js/issues/14007), [#14047](https://github.com/angular/angular.js/issues/14047))
|
||||
- **$animateCss:** cancel fallback timeout when animation ends normally
|
||||
([a60bbc12](https://github.com/angular/angular.js/commit/a60bbc12e8c5170e70d95f1b2c3e309b3b95cb84),
|
||||
[#13787](https://github.com/angular/angular.js/issues/13787))
|
||||
- **$compile:**
|
||||
- allow directives to have decorators
|
||||
([77cdc37c](https://github.com/angular/angular.js/commit/77cdc37c65491b551fcf01a18ab848a693c293d7))
|
||||
- properly denormalize templates when only one of the start/end symbols is different
|
||||
([2d44a681](https://github.com/angular/angular.js/commit/2d44a681eb912a81a8bc8e16a278c45dae91fa24),
|
||||
[#13848](https://github.com/angular/angular.js/issues/13848))
|
||||
- handle boolean attributes in `@` bindings
|
||||
([2ffbfb0a](https://github.com/angular/angular.js/commit/2ffbfb0ad0647d103ff339ee4b772b62d4823bf3),
|
||||
[#13767](https://github.com/angular/angular.js/issues/13767), [#13769](https://github.com/angular/angular.js/issues/13769))
|
||||
- **$parse:**
|
||||
- prevent assignment on constructor properties
|
||||
([f47e2180](https://github.com/angular/angular.js/commit/f47e218006029f39b4785d820b430de3a0eebcb0),
|
||||
[#13417](https://github.com/angular/angular.js/issues/13417))
|
||||
- preserve expensive checks when runnning `$eval` inside an expression
|
||||
([96d62cc0](https://github.com/angular/angular.js/commit/96d62cc0fc77248d7e3ec4aa458bac0d3e072629))
|
||||
- copy `inputs` for expressions with expensive checks
|
||||
([0b7fff30](https://github.com/angular/angular.js/commit/0b7fff303f46202bbae1ff3ca9d0e5fa76e0fc9a))
|
||||
- **$rootScope:** set no context when calling helper functions for `$watch`
|
||||
([ab5c7698](https://github.com/angular/angular.js/commit/ab5c7698bb106669ca31b5f79a95afa54d65c5f1))
|
||||
- **$route:** allow preventing a route reload
|
||||
([4bc30314](https://github.com/angular/angular.js/commit/4bc3031497447ad527356f12bd0ceee1d7d09db5),
|
||||
[#9824](https://github.com/angular/angular.js/issues/9824), [#13894](https://github.com/angular/angular.js/issues/13894))
|
||||
- **$routeProvider:** properly handle optional eager path named groups
|
||||
([6a4403a1](https://github.com/angular/angular.js/commit/6a4403a11845173d6a96232f77d73aa544b182af),
|
||||
[#14011](https://github.com/angular/angular.js/issues/14011))
|
||||
- **copy:** add support for copying `Blob` objects
|
||||
([863a4232](https://github.com/angular/angular.js/commit/863a4232a6faa92428df45cd54d5a519be2434de),
|
||||
[#9669](https://github.com/angular/angular.js/issues/9669), [#14064](https://github.com/angular/angular.js/issues/14064))
|
||||
- **dateFilter:** follow the CLDR on pattern escape sequences
|
||||
([f476060d](https://github.com/angular/angular.js/commit/f476060de6cc016380c0343490a184543f853652),
|
||||
[#12839](https://github.com/angular/angular.js/issues/12839))
|
||||
- **dateFilter, input:** fix Date parsing in IE/Edge when timezone offset contains `:`
|
||||
([571afd65](https://github.com/angular/angular.js/commit/571afd6558786d7b99e2aebd307b4a94c9f2bb87),
|
||||
[#13880](https://github.com/angular/angular.js/issues/13880), [#13887](https://github.com/angular/angular.js/issues/13887))
|
||||
- **input:** re-validate when partially editing date-family inputs
|
||||
([02929f82](https://github.com/angular/angular.js/commit/02929f82f30449301ff18fea84a6396a017683b1),
|
||||
[#12207](https://github.com/angular/angular.js/issues/12207), [#13886](https://github.com/angular/angular.js/issues/13886))
|
||||
- **select:** handle corner case of adding options via a custom directive
|
||||
([df6e7315](https://github.com/angular/angular.js/commit/df6e731506831a3dc7f44c9a90abe17515450b3e),
|
||||
[#13874](https://github.com/angular/angular.js/issues/13874), [#13878](https://github.com/angular/angular.js/issues/13878))
|
||||
- **ngOptions:** always set the 'selected' attribute for selected options
|
||||
([f87e8288](https://github.com/angular/angular.js/commit/f87e8288fb69526fd240a66a046f5de52ed204de),
|
||||
[#14115](https://github.com/angular/angular.js/issues/14115))
|
||||
- **ngAnimate:** properly cancel previously running class-based animations
|
||||
([3b27dd37](https://github.com/angular/angular.js/commit/3b27dd37a2cc8a52992784ece6b371023dadf792),
|
||||
[#10156](https://github.com/angular/angular.js/issues/10156), [#13822](https://github.com/angular/angular.js/issues/13822))
|
||||
- **ngAnimateChildren:** make it compatible with `ngIf`
|
||||
([dc158e7e](https://github.com/angular/angular.js/commit/dc158e7e40624ef94c66560386522ef7e991a9ce),
|
||||
[#13865](https://github.com/angular/angular.js/issues/13865), [#13876](https://github.com/angular/angular.js/issues/13876))
|
||||
- **ngMockE2E:** pass `responseType` to `$delegate` when using `passThrough`
|
||||
([947cb4d1](https://github.com/angular/angular.js/commit/947cb4d1451afa4f5090a693df5b1968dd0df70c),
|
||||
[#5415](https://github.com/angular/angular.js/issues/5415), [#5783](https://github.com/angular/angular.js/issues/5783))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **$locale:** Include original locale ID in $locale
|
||||
([e69f3550](https://github.com/angular/angular.js/commit/e69f35507e10c994708ce4f1efba7573951d1acd),
|
||||
[#13390](https://github.com/angular/angular.js/issues/13390))
|
||||
- **ngAnimate:** provide ng-[event]-prepare class for structural animations
|
||||
([796f7ab4](https://github.com/angular/angular.js/commit/796f7ab41487e124b5b0c02dbf0a03bd581bf073))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
|
||||
- **$compile:** avoid needless overhead when wrapping text nodes
|
||||
([946d9ae9](https://github.com/angular/angular.js/commit/946d9ae90bb31fe911ebbe1b80cd4c8af5a665c6))
|
||||
- **ngRepeat:** avoid duplicate jqLite wrappers
|
||||
([d04c38c4](https://github.com/angular/angular.js/commit/d04c38c48968db777c3ea6a177ce2ff0116df7b4))
|
||||
- **ngAnimate:**
|
||||
- avoid jqLite/jQuery for upward DOM traversal
|
||||
([ab95ba65](https://github.com/angular/angular.js/commit/ab95ba65c08b38cace83de6717b7681079182b45))
|
||||
- avoid `$.fn.data` overhead with jQuery
|
||||
([86416bcb](https://github.com/angular/angular.js/commit/86416bcbee2192fa31c017163c5d856763182ade))
|
||||
|
||||
|
||||
<a name="1.5.0"></a>
|
||||
# 1.5.0 ennoblement-facilitation (2016-02-05)
|
||||
|
||||
@@ -33,6 +604,9 @@
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
### Upgrade to 1.5.1
|
||||
This version of AngularJS is problematic due to a issue during its release. Please upgrade to version [1.5.2](#1.5.2).
|
||||
|
||||
- **ngAria:** due to [d06431e5](https://github.com/angular/angular.js/commit/d06431e5309bb0125588877451dc79b935808134),
|
||||
Where appropriate, ngAria now applies ARIA to custom controls only, not native inputs. Because of this, support for `aria-multiline` on textareas has been removed.
|
||||
|
||||
@@ -113,7 +687,8 @@ changes section for more information
|
||||
|
||||
- **ngSanitize:** due to [234053fc](https://github.com/angular/angular.js/commit/234053fc9ad90e0d05be7e8359c6af66be94c094),
|
||||
|
||||
The `$sanitize` service will now remove instances of the `usemap` attribute from any elements passed to it.
|
||||
The `$sanitize` service will now remove instances of the `usemap` attribute from any elements passed
|
||||
to it.
|
||||
|
||||
This attribute is used to reference another element by `name` or `id`. Since the `name` and `id`
|
||||
attributes are already blacklisted, a sanitized `usemap` attribute could only reference unsanitized
|
||||
@@ -689,9 +1264,6 @@ is `$locals`.
|
||||
[#13236](https://github.com/angular/angular.js/issues/13236))
|
||||
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
|
||||
<a name="1.5.0-beta.2"></a>
|
||||
# 1.5.0-beta.2 effective-delegation (2015-11-17)
|
||||
|
||||
@@ -1011,9 +1583,6 @@ requirement more strict and alerts the developer explicitly.
|
||||
[#2318](https://github.com/angular/angular.js/issues/2318), [#9319](https://github.com/angular/angular.js/issues/9319), [#12159](https://github.com/angular/angular.js/issues/12159))
|
||||
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
|
||||
<a name="1.3.20"></a>
|
||||
# 1.3.20 shallow-translucence (2015-09-29)
|
||||
|
||||
@@ -1024,9 +1593,6 @@ requirement more strict and alerts the developer explicitly.
|
||||
([d434f3db](https://github.com/angular/angular.js/commit/d434f3db53d6209eb140b904e83bbde401686c16))
|
||||
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
|
||||
<a name="1.2.29"></a>
|
||||
# 1.2.29 ultimate-deprecation (2015-09-29)
|
||||
|
||||
@@ -1053,7 +1619,15 @@ requirement more strict and alerts the developer explicitly.
|
||||
[#9936](https://github.com/angular/angular.js/issues/9936))
|
||||
|
||||
|
||||
## Breaking Changes
|
||||
<a name="1.5.0-beta.0"></a>
|
||||
|
||||
# 1.5.0-beta.0 intialization-processation (2015-09-17)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **jqLite:**: properly handle dash-delimited node names in `jqLiteBuildFragment`
|
||||
([cdd1227a3](https://github.com/angular/angular.js/commit/cdd1227a308edd34d31b67f338083b6e0c4c0db9),
|
||||
[#10617](https://github.com/angular/angular.js/issues/10617))
|
||||
|
||||
|
||||
<a name="1.4.6"></a>
|
||||
@@ -1606,6 +2180,44 @@ describe('$q.when', function() {
|
||||
[#11580](https://github.com/angular/angular.js/issues/11580), [#12234](https://github.com/angular/angular.js/issues/12234))
|
||||
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- **ngInclude:** due to [3c6e8ce044446735eb2e70d0061db8c6db050289](https://github.com/angular/angular.js/commit/3c6e8ce044446735eb2e70d0061db8c6db050289), the `src` attribute of ngInclude no longer accepts an
|
||||
expression that returns the result of `$sce.trustAsResourceUrl`. This will now cause an infinite digest:
|
||||
|
||||
Before:
|
||||
```html
|
||||
<div ng-include="findTemplate('https://example.com/myTemplate.html')"></div>
|
||||
```
|
||||
|
||||
```js
|
||||
$scope.findTemplate = function(templateName) {
|
||||
return $sce.trustAsResourceUrl(templateName);
|
||||
};
|
||||
```
|
||||
|
||||
To migrate, either cache the result of `trustAsResourceUrl()`, or put the template url in the resource
|
||||
whitelist in the `config()` function:
|
||||
|
||||
After:
|
||||
|
||||
```js
|
||||
var templateCache = {};
|
||||
$scope.findTemplate = function(templateName) {
|
||||
if (!templateCache[templateName]) {
|
||||
templateCache[templateName] = $sce.trustAsResourceUrl(templateName);
|
||||
}
|
||||
|
||||
return templateCache[templateName];
|
||||
};
|
||||
|
||||
// Alternatively, use `$sceDelegateProvider.resourceUrlWhitelist()`:
|
||||
|
||||
angular.module('myApp', []).config(function($sceDelegateProvider) {
|
||||
$sceDelegateProvider.resourceUrlWhitelist(['self', 'https://example.com/**'])
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
<a name="1.3.17"></a>
|
||||
# 1.3.17 tsktskskly-euouae (2015-07-06)
|
||||
@@ -1884,9 +2496,7 @@ describe('$q.when', function() {
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
### ngAnimate
|
||||
|
||||
- **$animateCss:** due to [d5683d21](https://github.com/angular/angular.js/commit/d5683d21165e725bc5a850e795f681b0a8a008f5),
|
||||
- **ngAnimate** - $animateCss: due to [d5683d21](https://github.com/angular/angular.js/commit/d5683d21165e725bc5a850e795f681b0a8a008f5),
|
||||
The $animateCss service will now always return an
|
||||
object even if the animation is not set to run. If your code is using
|
||||
$animateCss then please consider the following code change:
|
||||
@@ -1970,9 +2580,7 @@ $animateProvider.classNameFilter(/ng-animate-special/);
|
||||
```
|
||||
|
||||
|
||||
### ngOptions
|
||||
|
||||
- ** due to [dfa722a8](https://github.com/angular/angular.js/commit/dfa722a8a6864793fd9580d8ae704a06d10b5509),
|
||||
- **ngOptions**: due to [dfa722a8](https://github.com/angular/angular.js/commit/dfa722a8a6864793fd9580d8ae704a06d10b5509),
|
||||
|
||||
|
||||
Although it is unlikely that anyone is using it in this way, this change does change the
|
||||
|
||||
+54
-41
@@ -14,14 +14,17 @@ today! Here are the guidelines we'd like you to follow:
|
||||
- [Further Info](#info)
|
||||
|
||||
## <a name="coc"></a> Code of Conduct
|
||||
|
||||
Help us keep Angular open and inclusive. Please read and follow our [Code of Conduct][coc].
|
||||
|
||||
## <a name="question"></a> 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] and [Gitter][gitter].
|
||||
discussion list or [StackOverflow][stackoverflow]. We are also available on [IRC][irc] and
|
||||
[Gitter][gitter].
|
||||
|
||||
## <a name="issue"></a> Found an Issue?
|
||||
|
||||
If you find a bug in the source code or a mistake in the documentation, you can help us by
|
||||
submitting an issue to our [GitHub Repository][github]. Even better you can submit a Pull Request
|
||||
with a fix.
|
||||
@@ -30,46 +33,53 @@ with a fix.
|
||||
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**.
|
||||
**Please see the [Submission Guidelines](#submit) below.**
|
||||
|
||||
## <a name="feature"></a> 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 the [GitHub Repository][github] as a Pull Request.
|
||||
[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 the [GitHub Repository][github] as a Pull
|
||||
Request.
|
||||
|
||||
|
||||
## <a name="docs"></a> Want a Doc Fix?
|
||||
|
||||
If you want to help improve the docs, it's a good idea to let others know what you're working on to
|
||||
minimize duplication of effort. Before starting, check out the issue queue for
|
||||
[Milestone:Docs Only](https://github.com/angular/angular.js/issues?milestone=24&state=open).
|
||||
Comment on an issue to let others know what you're working on, or create a new issue if your work
|
||||
doesn't fit within the scope of any of the existing doc fix projects.
|
||||
minimize duplication of effort. Create a new issue (or comment on a related existing one) to let
|
||||
others know what you're working on.
|
||||
|
||||
For large fixes, please build and test the documentation before submitting the PR to be sure you haven't
|
||||
accidentally introduced any layout or formatting issues. You should also make sure that your commit message
|
||||
is labeled "docs:" and follows the **Git Commit Guidelines** outlined below.
|
||||
For large fixes, please build and test the documentation before submitting the PR to be sure you
|
||||
haven't accidentally introduced any layout or formatting issues. You should also make sure that your
|
||||
commit message starts with "docs" and follows the **[Commit Message Guidelines](#commit)** outlined
|
||||
below.
|
||||
|
||||
If you're just making a small change, don't worry about filing an issue first. Use the friendly blue "Improve this doc" button at the top right of the doc page to fork the repository in-place and make a quick change on the fly. When naming the commit, it is advised to still label it according to the commit guidelines below, by starting the commit message with **docs** and referencing the filename. Since this is not obvious and some changes are made on the fly, this is not strictly necessary and we will understand if this isn't done the first few times.
|
||||
If you're just making a small change, don't worry about filing an issue first. Use the friendly blue
|
||||
"Improve this doc" button at the top right of the doc page to fork the repository in-place and make
|
||||
a quick change on the fly. When naming the commit, it is advised to follow the commit message
|
||||
guidelines below, by starting the commit message with **docs** and referencing the filename. Since
|
||||
this is not obvious and some changes are made on the fly, this is not strictly necessary and we will
|
||||
understand if this isn't done the first few times.
|
||||
|
||||
## <a name="submit"></a> Submission Guidelines
|
||||
|
||||
### Submitting an Issue
|
||||
Before you submit your issue search the archive, maybe your question was already answered.
|
||||
|
||||
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. Providing the following information will increase the
|
||||
chances of your issue being dealt with quickly:
|
||||
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.
|
||||
Providing the following information will increase the chances of your issue being dealt with
|
||||
quickly:
|
||||
|
||||
* **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps
|
||||
* **Motivation for or Use Case** - explain why this is a bug for you
|
||||
* **Angular Version(s)** - is it a regression?
|
||||
* **Browsers and Operating System** - is this a problem with all browsers or only IE8?
|
||||
* **Browsers and Operating System** - is this a problem with all browsers or only specific ones?
|
||||
* **Reproduce the Error** - provide a live example (using [Plunker][plunker] or
|
||||
[JSFiddle][jsfiddle]) or an unambiguous set of steps.
|
||||
* **Related Issues** - has a similar issue been reported before?
|
||||
@@ -89,22 +99,22 @@ Before you submit your pull request consider the following guidelines:
|
||||
requests. We cannot accept code without this.
|
||||
* Make your changes in a new git branch:
|
||||
|
||||
```shell
|
||||
git checkout -b my-fix-branch master
|
||||
```
|
||||
```shell
|
||||
git checkout -b my-fix-branch master
|
||||
```
|
||||
|
||||
* Create your patch, **including appropriate test cases**.
|
||||
* Follow our [Coding Rules](#rules).
|
||||
* Run the full Angular test suite, as described in the [developer documentation][dev-doc],
|
||||
and ensure that all tests pass.
|
||||
* Commit your changes using a descriptive commit message that follows our
|
||||
[commit message conventions](#commit-message-format) and passes our commit message presubmit hook
|
||||
`validate-commit-msg.js`. Adherence to the [commit message conventions](#commit-message-format)
|
||||
is required because release notes are automatically generated from these messages.
|
||||
[commit message conventions](#commit) and passes our commit message presubmit hook
|
||||
(`validate-commit-msg.js`). Adherence to the [commit message conventions](#commit) is required,
|
||||
because release notes are automatically generated from these messages.
|
||||
|
||||
```shell
|
||||
git commit -a
|
||||
```
|
||||
```shell
|
||||
git commit -a
|
||||
```
|
||||
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
|
||||
|
||||
* Build your changes locally to ensure all the tests pass:
|
||||
@@ -119,22 +129,24 @@ Before you submit your pull request consider the following guidelines:
|
||||
git push origin my-fix-branch
|
||||
```
|
||||
|
||||
* In GitHub, send a pull request to `angular:master`.
|
||||
* If we suggest changes then:
|
||||
* Make the required updates.
|
||||
* Re-run the Angular test suite to ensure tests are still passing.
|
||||
* Commit your changes to your branch (e.g. `my-fix-branch`).
|
||||
* Push the changes to your GitHub repository (this will update your Pull Request).
|
||||
In GitHub, send a pull request to `angular:master`.
|
||||
If we suggest changes, then:
|
||||
|
||||
* Make the required updates.
|
||||
* Re-run the Angular test suite to ensure tests are still passing.
|
||||
* Commit your changes to your branch (e.g. `my-fix-branch`).
|
||||
* Push the changes to your GitHub repository (this will update your Pull Request).
|
||||
|
||||
If the PR gets too outdated we may ask you to rebase and force push to update the PR:
|
||||
|
||||
```shell
|
||||
git rebase master -i
|
||||
git push origin my-fix-branch -f
|
||||
```
|
||||
```shell
|
||||
git rebase master -i
|
||||
git push origin my-fix-branch -f
|
||||
```
|
||||
|
||||
*WARNING. Squashing or reverting commits and forced push thereafter may remove GitHub comments
|
||||
on code that were previously made by you and others in your commits.*
|
||||
_WARNING: Squashing or reverting commits and force-pushing thereafter may remove GitHub comments
|
||||
on code that were previously made by you or others in your commits. Avoid any form of rebasing
|
||||
unless necessary._
|
||||
|
||||
That's it! Thank you for your contribution!
|
||||
|
||||
@@ -168,6 +180,7 @@ from the main (upstream) repository:
|
||||
```
|
||||
|
||||
## <a name="rules"></a> 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].
|
||||
@@ -280,7 +293,7 @@ You can find out more detailed information about contributing in the
|
||||
[groups]: https://groups.google.com/forum/?fromgroups#!forum/angular
|
||||
[individual-cla]: http://code.google.com/legal/individual-cla-v1.0.html
|
||||
[irc]: http://webchat.freenode.net/?channels=angularjs&uio=d4
|
||||
[js-style-guide]: http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
|
||||
[js-style-guide]: https://google.github.io/styleguide/javascriptguide.xml
|
||||
[jsfiddle]: http://jsfiddle.net/
|
||||
[list]: https://groups.google.com/forum/?fromgroups#!forum/angular
|
||||
[ngDocs]: https://github.com/angular/angular.js/wiki/Writing-AngularJS-Documentation
|
||||
|
||||
+56
-74
@@ -1,5 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
var serveFavicon = require('serve-favicon');
|
||||
var serveStatic = require('serve-static');
|
||||
var serveIndex = require('serve-index');
|
||||
var files = require('./angularFiles').files;
|
||||
var util = require('./lib/grunt/utils.js');
|
||||
var versionInfo = require('./lib/versions/version-info');
|
||||
@@ -15,7 +18,11 @@ module.exports = function(grunt) {
|
||||
|
||||
var NG_VERSION = versionInfo.currentVersion;
|
||||
NG_VERSION.cdn = versionInfo.cdnVersion;
|
||||
var dist = 'angular-'+ NG_VERSION.full;
|
||||
var dist = 'angular-' + NG_VERSION.full;
|
||||
|
||||
if (versionInfo.cdnVersion == null) {
|
||||
throw new Error('Unable to read CDN version, are you offline or has the CDN not been properly pushed?');
|
||||
}
|
||||
|
||||
//config
|
||||
grunt.initConfig({
|
||||
@@ -34,15 +41,15 @@ module.exports = function(grunt) {
|
||||
hostname: '0.0.0.0',
|
||||
base: '.',
|
||||
keepalive: true,
|
||||
middleware: function(connect, options){
|
||||
middleware: function(connect, options) {
|
||||
var base = Array.isArray(options.base) ? options.base[options.base.length - 1] : options.base;
|
||||
return [
|
||||
util.conditionalCsp(),
|
||||
util.rewrite(),
|
||||
e2e.middleware(),
|
||||
connect.favicon('images/favicon.ico'),
|
||||
connect.static(base),
|
||||
connect.directory(base)
|
||||
serveFavicon('images/favicon.ico'),
|
||||
serveStatic(base),
|
||||
serveIndex(base)
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -54,7 +61,7 @@ module.exports = function(grunt) {
|
||||
// to avoid https://github.com/joyent/libuv/issues/826
|
||||
port: 8000,
|
||||
hostname: '0.0.0.0',
|
||||
middleware: function(connect, options){
|
||||
middleware: function(connect, options) {
|
||||
var base = Array.isArray(options.base) ? options.base[options.base.length - 1] : options.base;
|
||||
return [
|
||||
function(req, resp, next) {
|
||||
@@ -67,8 +74,8 @@ module.exports = function(grunt) {
|
||||
},
|
||||
util.conditionalCsp(),
|
||||
e2e.middleware(),
|
||||
connect.favicon('images/favicon.ico'),
|
||||
connect.static(base)
|
||||
serveFavicon('images/favicon.ico'),
|
||||
serveStatic(base)
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -79,6 +86,8 @@ module.exports = function(grunt) {
|
||||
tests: {
|
||||
jqlite: 'karma-jqlite.conf.js',
|
||||
jquery: 'karma-jquery.conf.js',
|
||||
'jquery-2.2': 'karma-jquery-2.2.conf.js',
|
||||
'jquery-2.1': 'karma-jquery-2.1.conf.js',
|
||||
docs: 'karma-docs.conf.js',
|
||||
modules: 'karma-modules.conf.js'
|
||||
},
|
||||
@@ -87,6 +96,8 @@ module.exports = function(grunt) {
|
||||
autotest: {
|
||||
jqlite: 'karma-jqlite.conf.js',
|
||||
jquery: 'karma-jquery.conf.js',
|
||||
'jquery-2.2': 'karma-jquery-2.2.conf.js',
|
||||
'jquery-2.1': 'karma-jquery-2.1.conf.js',
|
||||
modules: 'karma-modules.conf.js',
|
||||
docs: 'karma-docs.conf.js'
|
||||
},
|
||||
@@ -104,65 +115,24 @@ module.exports = function(grunt) {
|
||||
tmp: ['tmp']
|
||||
},
|
||||
|
||||
jshint: {
|
||||
options: {
|
||||
jshintrc: true,
|
||||
},
|
||||
node: {
|
||||
files: { src: ['*.js', 'lib/**/*.js'] },
|
||||
},
|
||||
tests: {
|
||||
files: { src: 'test/**/*.js' },
|
||||
},
|
||||
ng: {
|
||||
files: { src: files['angularSrc'].concat('!src/angular.bind.js') },
|
||||
},
|
||||
ngAnimate: {
|
||||
files: { src: 'src/ngAnimate/**/*.js' },
|
||||
},
|
||||
ngCookies: {
|
||||
files: { src: 'src/ngCookies/**/*.js' },
|
||||
},
|
||||
ngLocale: {
|
||||
files: { src: 'src/ngLocale/**/*.js' },
|
||||
},
|
||||
ngMessageFormat: {
|
||||
files: { src: 'src/ngMessageFormat/**/*.js' },
|
||||
},
|
||||
ngMessages: {
|
||||
files: { src: 'src/ngMessages/**/*.js' },
|
||||
},
|
||||
ngMock: {
|
||||
files: { src: 'src/ngMock/**/*.js' },
|
||||
},
|
||||
ngResource: {
|
||||
files: { src: 'src/ngResource/**/*.js' },
|
||||
},
|
||||
ngRoute: {
|
||||
files: { src: 'src/ngRoute/**/*.js' },
|
||||
},
|
||||
ngSanitize: {
|
||||
files: { src: 'src/ngSanitize/**/*.js' },
|
||||
},
|
||||
ngScenario: {
|
||||
files: { src: 'src/ngScenario/**/*.js' },
|
||||
},
|
||||
ngTouch: {
|
||||
files: { src: 'src/ngTouch/**/*.js' },
|
||||
},
|
||||
ngAria: {
|
||||
files: {src: 'src/ngAria/**/*.js'},
|
||||
}
|
||||
},
|
||||
|
||||
jscs: {
|
||||
src: [
|
||||
'src/**/*.js',
|
||||
'test/**/*.js',
|
||||
'!src/angular.bind.js' // we ignore this file since contains an early return statement
|
||||
],
|
||||
options: {
|
||||
config: '.jscsrc'
|
||||
eslint: {
|
||||
all: {
|
||||
src: [
|
||||
'*.js',
|
||||
'benchmarks/**/*.js',
|
||||
'docs/**/*.js',
|
||||
'lib/**/*.js',
|
||||
'scripts/**/*.js',
|
||||
'src/**/*.js',
|
||||
'test/**/*.js',
|
||||
'i18n/**/*.js',
|
||||
'!docs/app/assets/js/angular-bootstrap/**',
|
||||
'!docs/bower_components/**',
|
||||
'!docs/config/templates/**',
|
||||
'!src/angular.bind.js',
|
||||
'!i18n/closure/**',
|
||||
'!src/ngParseExt/ucd.js'
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -231,6 +201,10 @@ module.exports = function(grunt) {
|
||||
dest: 'build/angular-aria.js',
|
||||
src: util.wrap(files['angularModules']['ngAria'], 'module')
|
||||
},
|
||||
parseext: {
|
||||
dest: 'build/angular-parse-ext.js',
|
||||
src: util.wrap(files['angularModules']['ngParseExt'], 'module')
|
||||
},
|
||||
'promises-aplus-adapter': {
|
||||
dest:'tmp/promises-aplus-adapter++.js',
|
||||
src:['src/ng/q.js', 'lib/promises-aplus/promises-aplus-test-adapter.js']
|
||||
@@ -249,7 +223,8 @@ module.exports = function(grunt) {
|
||||
resource: 'build/angular-resource.js',
|
||||
route: 'build/angular-route.js',
|
||||
sanitize: 'build/angular-sanitize.js',
|
||||
aria: 'build/angular-aria.js'
|
||||
aria: 'build/angular-aria.js',
|
||||
parseext: 'build/angular-parse-ext.js'
|
||||
},
|
||||
|
||||
|
||||
@@ -264,12 +239,17 @@ module.exports = function(grunt) {
|
||||
],
|
||||
options: {
|
||||
disallowed: [
|
||||
'fit',
|
||||
'iit',
|
||||
'xit',
|
||||
'fthey',
|
||||
'tthey',
|
||||
'xthey',
|
||||
'fdescribe',
|
||||
'ddescribe',
|
||||
'xdescribe'
|
||||
'xdescribe',
|
||||
'it.only',
|
||||
'describe.only'
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -294,7 +274,7 @@ module.exports = function(grunt) {
|
||||
|
||||
compress: {
|
||||
build: {
|
||||
options: {archive: 'build/' + dist +'.zip', mode: 'zip'},
|
||||
options: {archive: 'build/' + dist + '.zip', mode: 'zip'},
|
||||
src: ['**'],
|
||||
cwd: 'build',
|
||||
expand: true,
|
||||
@@ -342,12 +322,14 @@ module.exports = function(grunt) {
|
||||
|
||||
|
||||
//alias tasks
|
||||
grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', ['jshint', 'jscs', 'package', 'test:unit', 'test:promises-aplus', 'tests:docs', 'test:protractor']);
|
||||
grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', ['eslint', 'package', 'test:unit', 'test:promises-aplus', 'tests:docs', 'test:protractor']);
|
||||
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:jquery', 'Run the jQuery (latest) unit tests with Karma', ['tests:jquery']);
|
||||
grunt.registerTask('test:jquery-2.2', 'Run the jQuery 2.2 unit tests with Karma', ['tests:jquery-2.2']);
|
||||
grunt.registerTask('test:jquery-2.1', 'Run the jQuery 2.1 unit tests with Karma', ['tests:jquery-2.1']);
|
||||
grunt.registerTask('test:modules', 'Run the Karma module tests with Karma', ['build', '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', ['test:jqlite', 'test:jquery', 'test:modules']);
|
||||
grunt.registerTask('test:unit', 'Run unit, jQuery and Karma module tests with Karma', ['test:jqlite', 'test:jquery', 'test:jquery-2.2', 'test:jquery-2.1', 'test:modules']);
|
||||
grunt.registerTask('test:protractor', 'Run the end to end tests with Protractor and keep a test server running in the background', ['webdriver', 'connect:testserver', 'protractor:normal']);
|
||||
grunt.registerTask('test:travis-protractor', 'Run the end to end tests with Protractor for Travis CI builds', ['connect:testserver', 'protractor:travis']);
|
||||
grunt.registerTask('test:ci-protractor', 'Run the end to end tests with Protractor for Jenkins CI builds', ['webdriver', 'connect:testserver', 'protractor:jenkins']);
|
||||
@@ -357,6 +339,6 @@ module.exports = function(grunt) {
|
||||
grunt.registerTask('minify', ['bower', 'clean', 'build', 'minall']);
|
||||
grunt.registerTask('webserver', ['connect:devserver']);
|
||||
grunt.registerTask('package', ['bower', 'validate-angular-files', 'clean', 'buildall', 'minall', 'collect-errors', 'docs', 'copy', 'write', 'compress']);
|
||||
grunt.registerTask('ci-checks', ['ddescribe-iit', 'merge-conflict', 'jshint', 'jscs']);
|
||||
grunt.registerTask('ci-checks', ['ddescribe-iit', 'merge-conflict', 'eslint']);
|
||||
grunt.registerTask('default', ['package']);
|
||||
};
|
||||
|
||||
@@ -8,20 +8,22 @@ synchronizes data from your UI (view) with your JavaScript objects (model) throu
|
||||
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 helps with server-side communication, taming async callbacks with promises and
|
||||
deferreds. It also makes client-side navigation and deeplinking with hashbang urls or HTML5 pushState a
|
||||
piece of cake. Best of all?? It makes development fun!
|
||||
It also helps with server-side communication, taming async callbacks with promises and deferreds,
|
||||
and it makes client-side navigation and deeplinking with hashbang urls or HTML5 pushState a
|
||||
piece of cake. 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
|
||||
* Web site: https://angularjs.org
|
||||
* Tutorial: https://docs.angularjs.org/tutorial
|
||||
* API Docs: https://docs.angularjs.org/api
|
||||
* Developer Guide: https://docs.angularjs.org/guide
|
||||
* Contribution guidelines: [CONTRIBUTING.md](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md)
|
||||
* Dashboard: http://dashboard.angularjs.org
|
||||
|
||||
* Dashboard: https://dashboard.angularjs.org
|
||||
|
||||
##### Looking for Angular 2? Go here: https://github.com/angular/angular
|
||||
|
||||
Building AngularJS
|
||||
---------
|
||||
[Once you have your environment set up](http://docs.angularjs.org/misc/contribute) just run:
|
||||
[Once you have set up your environment](https://docs.angularjs.org/misc/contribute), just run:
|
||||
|
||||
grunt package
|
||||
|
||||
@@ -37,8 +39,12 @@ 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](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md).
|
||||
To learn more about the grunt tasks, run `grunt --help`
|
||||
|
||||
Contribute & Develop
|
||||
--------------------
|
||||
|
||||
We've set up a separate document for our [contribution guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md).
|
||||
|
||||
|
||||
[](https://github.com/igrigorik/ga-beacon)
|
||||
@@ -48,7 +54,7 @@ What to use AngularJS for and when to use it
|
||||
AngularJS is the next generation framework where each component is designed to work with every other component in an interconnected way like a well-oiled machine. AngularJS is JavaScript MVC made easy and done right. (Well it is not really MVC, read on, to understand what this means.)
|
||||
|
||||
#### MVC, no, MV* done the right way!
|
||||
MVC, short for Model-View-Controller, is a design pattern, i.e. how the code should be organized and how the different parts of an application separated for proper readability and debugging. Model is the data and the database. View is the user interface and what the user sees. Controller is the main link between Model and View. These are the three pillars of major programming frameworks present on the market today. On the other hand AngularJS works on MV*, short for Model-View-_Whatever_. The _Whatever_ is AngularJS's way of telling that you may create any kind of linking between the Model and the View here.
|
||||
MVC, short for Model-View-Controller, is a design pattern, i.e. how the code should be organized and how the different parts of an application separated for proper readability and debugging. Model is the data and the database. View is the user interface and what the user sees. Controller is the main link between Model and View. These are the three pillars of major programming frameworks present on the market today. On the other hand AngularJS works on MV*, short for Model-View-_Whatever_. The _Whatever_ is AngularJS's way of telling that you may create any kind of linking between the Model and the View here.
|
||||
|
||||
Unlike other frameworks in any programming language, where MVC, the three separate components, each one has to be written and then connected by the programmer, AngularJS helps the programmer by asking him/her to just create these and everything else will be taken care of by AngularJS.
|
||||
|
||||
|
||||
Vendored
+24
-3
@@ -5,6 +5,7 @@ var angularFiles = {
|
||||
'src/minErr.js',
|
||||
'src/Angular.js',
|
||||
'src/loader.js',
|
||||
'src/shallowCopy.js',
|
||||
'src/stringify.js',
|
||||
'src/AngularPublic.js',
|
||||
'src/jqLite.js',
|
||||
@@ -27,6 +28,7 @@ var angularFiles = {
|
||||
'src/ng/httpBackend.js',
|
||||
'src/ng/interpolate.js',
|
||||
'src/ng/interval.js',
|
||||
'src/ng/jsonpCallbacks.js',
|
||||
'src/ng/locale.js',
|
||||
'src/ng/location.js',
|
||||
'src/ng/log.js',
|
||||
@@ -78,7 +80,6 @@ var angularFiles = {
|
||||
'src/ng/directive/ngTransclude.js',
|
||||
'src/ng/directive/script.js',
|
||||
'src/ng/directive/select.js',
|
||||
'src/ng/directive/style.js',
|
||||
'src/ng/directive/validators.js',
|
||||
'src/angular.bind.js',
|
||||
'src/publishExternalApis.js',
|
||||
@@ -120,10 +121,15 @@ var angularFiles = {
|
||||
'ngMessages': [
|
||||
'src/ngMessages/messages.js'
|
||||
],
|
||||
'ngParseExt': [
|
||||
'src/ngParseExt/ucd.js',
|
||||
'src/ngParseExt/module.js'
|
||||
],
|
||||
'ngResource': [
|
||||
'src/ngResource/resource.js'
|
||||
],
|
||||
'ngRoute': [
|
||||
'src/shallowCopy.js',
|
||||
'src/ngRoute/route.js',
|
||||
'src/ngRoute/routeParams.js',
|
||||
'src/ngRoute/directive/ngView.js'
|
||||
@@ -171,6 +177,7 @@ var angularFiles = {
|
||||
'test/auto/*.js',
|
||||
'test/ng/**/*.js',
|
||||
'test/ngAnimate/*.js',
|
||||
'test/ngMessageFormat/*.js',
|
||||
'test/ngMessages/*.js',
|
||||
'test/ngCookies/*.js',
|
||||
'test/ngResource/*.js',
|
||||
@@ -202,12 +209,15 @@ var angularFiles = {
|
||||
'build/docs/docs-scenario.js'
|
||||
],
|
||||
|
||||
"karmaModules": [
|
||||
'karmaModules': [
|
||||
'build/angular.js',
|
||||
'@angularSrcModules',
|
||||
'test/modules/no_bootstrap.js',
|
||||
'src/ngScenario/browserTrigger.js',
|
||||
'test/helpers/*.js',
|
||||
'test/ngAnimate/*.js',
|
||||
'test/ngMessageFormat/*.js',
|
||||
'test/ngMessages/*.js',
|
||||
'test/ngMock/*.js',
|
||||
'test/ngCookies/*.js',
|
||||
'test/ngRoute/**/*.js',
|
||||
@@ -234,6 +244,17 @@ var angularFiles = {
|
||||
]
|
||||
};
|
||||
|
||||
['2.1', '2.2'].forEach(function(jQueryVersion) {
|
||||
angularFiles['karmaJquery' + jQueryVersion] = []
|
||||
.concat(angularFiles.karmaJquery)
|
||||
.map(function(path) {
|
||||
if (path.startsWith('bower_components/jquery')) {
|
||||
return path.replace(/^bower_components\/jquery/, 'bower_components/jquery-' + jQueryVersion);
|
||||
}
|
||||
return path;
|
||||
});
|
||||
});
|
||||
|
||||
angularFiles['angularSrcModules'] = [].concat(
|
||||
angularFiles['angularModules']['ngAnimate'],
|
||||
angularFiles['angularModules']['ngMessageFormat'],
|
||||
@@ -255,7 +276,7 @@ if (exports) {
|
||||
Array.prototype.slice.call(arguments, 0).forEach(function(filegroup) {
|
||||
angularFiles[filegroup].forEach(function(file) {
|
||||
// replace @ref
|
||||
var match = file.match(/^\@(.*)/);
|
||||
var match = file.match(/^@(.*)/);
|
||||
if (match) {
|
||||
files = files.concat(angularFiles[match[1]]);
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"root": true,
|
||||
"extends": "../.eslintrc-browser.json",
|
||||
|
||||
"globals": {
|
||||
"benchmarkSteps": false,
|
||||
|
||||
// Benchmarks are not run in IE 9 so we're fine.
|
||||
"console": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
'use strict';
|
||||
|
||||
var app = angular.module('boostrapCompileBenchmark', []);
|
||||
|
||||
var commentDirectivesEnabled;
|
||||
var cssClassDirectivesEnabled;
|
||||
|
||||
app.config(function($compileProvider) {
|
||||
$compileProvider.debugInfoEnabled(false);
|
||||
|
||||
commentDirectivesEnabled = window.location.toString().indexOf('comment=disabled') === -1;
|
||||
cssClassDirectivesEnabled = window.location.toString().indexOf('css=disabled') === -1;
|
||||
|
||||
$compileProvider
|
||||
.commentDirectivesEnabled(commentDirectivesEnabled)
|
||||
.cssClassDirectivesEnabled(cssClassDirectivesEnabled);
|
||||
})
|
||||
.controller('DataController', function DataController($compile, $http, $rootScope) {
|
||||
|
||||
this.isEA = !commentDirectivesEnabled && !cssClassDirectivesEnabled;
|
||||
this.isEAC = !commentDirectivesEnabled && cssClassDirectivesEnabled;
|
||||
this.isEAM = commentDirectivesEnabled && !cssClassDirectivesEnabled;
|
||||
this.isEACM = commentDirectivesEnabled && cssClassDirectivesEnabled;
|
||||
|
||||
this.repeats = 50;
|
||||
|
||||
this.templates = [
|
||||
'bootstrap-carousel.tpl.html',
|
||||
'bootstrap-theme.tpl.html'
|
||||
];
|
||||
|
||||
this.html = null;
|
||||
this.loadTemplate = function() {
|
||||
this.html = null;
|
||||
$http.get(window.location.pathname + this.selectedTemplate)
|
||||
.then(function(response) { this.html = response.data; }.bind(this));
|
||||
};
|
||||
|
||||
this.selectedTemplate = this.templates[0];
|
||||
this.loadTemplate();
|
||||
|
||||
|
||||
var linkers = [];
|
||||
benchmarkSteps.push({
|
||||
name: 'create',
|
||||
fn: function() {
|
||||
for (var i = 0; i < this.repeats; i++) {
|
||||
var linker = $compile(this.html);
|
||||
linkers.push(linker);
|
||||
}
|
||||
}.bind(this)
|
||||
});
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: 'destroy',
|
||||
fn: function() {
|
||||
linkers.length = 0;
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,172 @@
|
||||
<!-- code from http://getbootstrap.com/examples/carousel -->
|
||||
<div class="navbar-wrapper">
|
||||
<div class="container">
|
||||
|
||||
<nav class="navbar navbar-inverse navbar-static-top">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="#">Project name</a>
|
||||
</div>
|
||||
<div id="navbar" class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="active"><a href="#">Home</a></li>
|
||||
<li><a href="#about">About</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
<li><a href="#">Something else here</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li class="dropdown-header">Nav header</li>
|
||||
<li><a href="#">Separated link</a></li>
|
||||
<li><a href="#">One more separated link</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Carousel
|
||||
================================================== -->
|
||||
<div id="myCarousel" class="carousel slide" data-ride="carousel">
|
||||
<!-- Indicators -->
|
||||
<ol class="carousel-indicators">
|
||||
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
|
||||
<li data-target="#myCarousel" data-slide-to="1"></li>
|
||||
<li data-target="#myCarousel" data-slide-to="2"></li>
|
||||
</ol>
|
||||
<div class="carousel-inner" role="listbox">
|
||||
<div class="item active">
|
||||
<img class="first-slide" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="First slide">
|
||||
<div class="container">
|
||||
<div class="carousel-caption">
|
||||
<h1>Example headline.</h1>
|
||||
<p>Note: If you're viewing this page via a <code>file://</code> URL, the "next" and "previous" Glyphicon buttons on the left and right might not load/display properly due to web browser security rules.</p>
|
||||
<p><a class="btn btn-lg btn-primary" href="#" role="button">Sign up today</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<img class="second-slide" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Second slide">
|
||||
<div class="container">
|
||||
<div class="carousel-caption">
|
||||
<h1>Another example headline.</h1>
|
||||
<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
|
||||
<p><a class="btn btn-lg btn-primary" href="#" role="button">Learn more</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<img class="third-slide" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Third slide">
|
||||
<div class="container">
|
||||
<div class="carousel-caption">
|
||||
<h1>One more for good measure.</h1>
|
||||
<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
|
||||
<p><a class="btn btn-lg btn-primary" href="#" role="button">Browse gallery</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
|
||||
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
|
||||
<span class="sr-only">Previous</span>
|
||||
</a>
|
||||
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
|
||||
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
|
||||
<span class="sr-only">Next</span>
|
||||
</a>
|
||||
</div><!-- /.carousel -->
|
||||
|
||||
|
||||
<!-- Marketing messaging and featurettes
|
||||
================================================== -->
|
||||
<!-- Wrap the rest of the page in another container to center all the content. -->
|
||||
|
||||
<div class="container marketing">
|
||||
|
||||
<!-- Three columns of text below the carousel -->
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<img class="img-circle" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Generic placeholder image" width="140" height="140">
|
||||
<h2>Heading</h2>
|
||||
<p>Donec sed odio dui. Etiam porta sem malesuada magna mollis euismod. Nullam id dolor id nibh ultricies vehicula ut id elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna.</p>
|
||||
<p><a class="btn btn-default" href="#" role="button">View details »</a></p>
|
||||
</div><!-- /.col-lg-4 -->
|
||||
<div class="col-lg-4">
|
||||
<img class="img-circle" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Generic placeholder image" width="140" height="140">
|
||||
<h2>Heading</h2>
|
||||
<p>Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Cras mattis consectetur purus sit amet fermentum. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh.</p>
|
||||
<p><a class="btn btn-default" href="#" role="button">View details »</a></p>
|
||||
</div><!-- /.col-lg-4 -->
|
||||
<div class="col-lg-4">
|
||||
<img class="img-circle" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Generic placeholder image" width="140" height="140">
|
||||
<h2>Heading</h2>
|
||||
<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
|
||||
<p><a class="btn btn-default" href="#" role="button">View details »</a></p>
|
||||
</div><!-- /.col-lg-4 -->
|
||||
</div><!-- /.row -->
|
||||
|
||||
|
||||
<!-- START THE FEATURETTES -->
|
||||
|
||||
<hr class="featurette-divider">
|
||||
|
||||
<div class="row featurette">
|
||||
<div class="col-md-7">
|
||||
<h2 class="featurette-heading">First featurette heading. <span class="text-muted">It'll blow your mind.</span></h2>
|
||||
<p class="lead">Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.</p>
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<img class="featurette-image img-responsive center-block" data-src="holder.js/500x500/auto" alt="Generic placeholder image">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="featurette-divider">
|
||||
|
||||
<div class="row featurette">
|
||||
<div class="col-md-7 col-md-push-5">
|
||||
<h2 class="featurette-heading">Oh yeah, it's that good. <span class="text-muted">See for yourself.</span></h2>
|
||||
<p class="lead">Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.</p>
|
||||
</div>
|
||||
<div class="col-md-5 col-md-pull-7">
|
||||
<img class="featurette-image img-responsive center-block" data-src="holder.js/500x500/auto" alt="Generic placeholder image">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="featurette-divider">
|
||||
|
||||
<div class="row featurette">
|
||||
<div class="col-md-7">
|
||||
<h2 class="featurette-heading">And lastly, this one. <span class="text-muted">Checkmate.</span></h2>
|
||||
<p class="lead">Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.</p>
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<img class="featurette-image img-responsive center-block" data-src="holder.js/500x500/auto" alt="Generic placeholder image">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="featurette-divider">
|
||||
|
||||
<!-- /END THE FEATURETTES -->
|
||||
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer>
|
||||
<p class="pull-right"><a href="#">Back to top</a></p>
|
||||
<p>© 2016 Company, Inc. · <a href="#">Privacy</a> · <a href="#">Terms</a></p>
|
||||
</footer>
|
||||
|
||||
</div><!-- /.container -->
|
||||
@@ -0,0 +1,595 @@
|
||||
<!-- Fixed navbar -->
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="#">Bootstrap theme</a>
|
||||
</div>
|
||||
<div id="navbar" class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="active"><a href="#">Home</a></li>
|
||||
<li><a href="#about">About</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
<li><a href="#">Something else here</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li class="dropdown-header">Nav header</li>
|
||||
<li><a href="#">Separated link</a></li>
|
||||
<li><a href="#">One more separated link</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container theme-showcase" role="main">
|
||||
|
||||
<!-- Main jumbotron for a primary marketing message or call to action -->
|
||||
<div class="jumbotron">
|
||||
<h1>Theme example</h1>
|
||||
<p>This is a template showcasing the optional theme stylesheet included in Bootstrap. Use it as a starting point to create something more unique by building on or modifying it.</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Buttons</h1>
|
||||
</div>
|
||||
<p>
|
||||
<button type="button" class="btn btn-lg btn-default">Default</button>
|
||||
<button type="button" class="btn btn-lg btn-primary">Primary</button>
|
||||
<button type="button" class="btn btn-lg btn-success">Success</button>
|
||||
<button type="button" class="btn btn-lg btn-info">Info</button>
|
||||
<button type="button" class="btn btn-lg btn-warning">Warning</button>
|
||||
<button type="button" class="btn btn-lg btn-danger">Danger</button>
|
||||
<button type="button" class="btn btn-lg btn-link">Link</button>
|
||||
</p>
|
||||
<p>
|
||||
<button type="button" class="btn btn-default">Default</button>
|
||||
<button type="button" class="btn btn-primary">Primary</button>
|
||||
<button type="button" class="btn btn-success">Success</button>
|
||||
<button type="button" class="btn btn-info">Info</button>
|
||||
<button type="button" class="btn btn-warning">Warning</button>
|
||||
<button type="button" class="btn btn-danger">Danger</button>
|
||||
<button type="button" class="btn btn-link">Link</button>
|
||||
</p>
|
||||
<p>
|
||||
<button type="button" class="btn btn-sm btn-default">Default</button>
|
||||
<button type="button" class="btn btn-sm btn-primary">Primary</button>
|
||||
<button type="button" class="btn btn-sm btn-success">Success</button>
|
||||
<button type="button" class="btn btn-sm btn-info">Info</button>
|
||||
<button type="button" class="btn btn-sm btn-warning">Warning</button>
|
||||
<button type="button" class="btn btn-sm btn-danger">Danger</button>
|
||||
<button type="button" class="btn btn-sm btn-link">Link</button>
|
||||
</p>
|
||||
<p>
|
||||
<button type="button" class="btn btn-xs btn-default">Default</button>
|
||||
<button type="button" class="btn btn-xs btn-primary">Primary</button>
|
||||
<button type="button" class="btn btn-xs btn-success">Success</button>
|
||||
<button type="button" class="btn btn-xs btn-info">Info</button>
|
||||
<button type="button" class="btn btn-xs btn-warning">Warning</button>
|
||||
<button type="button" class="btn btn-xs btn-danger">Danger</button>
|
||||
<button type="button" class="btn btn-xs btn-link">Link</button>
|
||||
</p>
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Tables</h1>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>First Name</th>
|
||||
<th>Last Name</th>
|
||||
<th>Username</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>1</td>
|
||||
<td>Mark</td>
|
||||
<td>Otto</td>
|
||||
<td>@mdo</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2</td>
|
||||
<td>Jacob</td>
|
||||
<td>Thornton</td>
|
||||
<td>@fat</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>3</td>
|
||||
<td>Larry</td>
|
||||
<td>the Bird</td>
|
||||
<td>@twitter</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>First Name</th>
|
||||
<th>Last Name</th>
|
||||
<th>Username</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>1</td>
|
||||
<td>Mark</td>
|
||||
<td>Otto</td>
|
||||
<td>@mdo</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2</td>
|
||||
<td>Jacob</td>
|
||||
<td>Thornton</td>
|
||||
<td>@fat</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>3</td>
|
||||
<td>Larry</td>
|
||||
<td>the Bird</td>
|
||||
<td>@twitter</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>First Name</th>
|
||||
<th>Last Name</th>
|
||||
<th>Username</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowspan="2">1</td>
|
||||
<td>Mark</td>
|
||||
<td>Otto</td>
|
||||
<td>@mdo</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Mark</td>
|
||||
<td>Otto</td>
|
||||
<td>@TwBootstrap</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2</td>
|
||||
<td>Jacob</td>
|
||||
<td>Thornton</td>
|
||||
<td>@fat</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>3</td>
|
||||
<td colspan="2">Larry the Bird</td>
|
||||
<td>@twitter</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<table class="table table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>First Name</th>
|
||||
<th>Last Name</th>
|
||||
<th>Username</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>1</td>
|
||||
<td>Mark</td>
|
||||
<td>Otto</td>
|
||||
<td>@mdo</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2</td>
|
||||
<td>Jacob</td>
|
||||
<td>Thornton</td>
|
||||
<td>@fat</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>3</td>
|
||||
<td colspan="2">Larry the Bird</td>
|
||||
<td>@twitter</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Thumbnails</h1>
|
||||
</div>
|
||||
<img data-src="holder.js/200x200" class="img-thumbnail" alt="200x200" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjwhLS0KU291cmNlIFVSTDogaG9sZGVyLmpzLzIwMHgyMDAKQ3JlYXRlZCB3aXRoIEhvbGRlci5qcyAyLjYuMC4KTGVhcm4gbW9yZSBhdCBodHRwOi8vaG9sZGVyanMuY29tCihjKSAyMDEyLTIwMTUgSXZhbiBNYWxvcGluc2t5IC0gaHR0cDovL2ltc2t5LmNvCi0tPjxkZWZzPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+PCFbQ0RBVEFbI2hvbGRlcl8xNTYyY2ExYjA3YiB0ZXh0IHsgZmlsbDojQUFBQUFBO2ZvbnQtd2VpZ2h0OmJvbGQ7Zm9udC1mYW1pbHk6QXJpYWwsIEhlbHZldGljYSwgT3BlbiBTYW5zLCBzYW5zLXNlcmlmLCBtb25vc3BhY2U7Zm9udC1zaXplOjEwcHQgfSBdXT48L3N0eWxlPjwvZGVmcz48ZyBpZD0iaG9sZGVyXzE1NjJjYTFiMDdiIj48cmVjdCB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgZmlsbD0iI0VFRUVFRSIvPjxnPjx0ZXh0IHg9Ijc0LjY5NTMxMjUiIHk9IjEwNC41Ij4yMDB4MjAwPC90ZXh0PjwvZz48L2c+PC9zdmc+" data-holder-rendered="true" style="width: 200px; height: 200px;">
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Labels</h1>
|
||||
</div>
|
||||
<h1>
|
||||
<span class="label label-default">Default</span>
|
||||
<span class="label label-primary">Primary</span>
|
||||
<span class="label label-success">Success</span>
|
||||
<span class="label label-info">Info</span>
|
||||
<span class="label label-warning">Warning</span>
|
||||
<span class="label label-danger">Danger</span>
|
||||
</h1>
|
||||
<h2>
|
||||
<span class="label label-default">Default</span>
|
||||
<span class="label label-primary">Primary</span>
|
||||
<span class="label label-success">Success</span>
|
||||
<span class="label label-info">Info</span>
|
||||
<span class="label label-warning">Warning</span>
|
||||
<span class="label label-danger">Danger</span>
|
||||
</h2>
|
||||
<h3>
|
||||
<span class="label label-default">Default</span>
|
||||
<span class="label label-primary">Primary</span>
|
||||
<span class="label label-success">Success</span>
|
||||
<span class="label label-info">Info</span>
|
||||
<span class="label label-warning">Warning</span>
|
||||
<span class="label label-danger">Danger</span>
|
||||
</h3>
|
||||
<h4>
|
||||
<span class="label label-default">Default</span>
|
||||
<span class="label label-primary">Primary</span>
|
||||
<span class="label label-success">Success</span>
|
||||
<span class="label label-info">Info</span>
|
||||
<span class="label label-warning">Warning</span>
|
||||
<span class="label label-danger">Danger</span>
|
||||
</h4>
|
||||
<h5>
|
||||
<span class="label label-default">Default</span>
|
||||
<span class="label label-primary">Primary</span>
|
||||
<span class="label label-success">Success</span>
|
||||
<span class="label label-info">Info</span>
|
||||
<span class="label label-warning">Warning</span>
|
||||
<span class="label label-danger">Danger</span>
|
||||
</h5>
|
||||
<h6>
|
||||
<span class="label label-default">Default</span>
|
||||
<span class="label label-primary">Primary</span>
|
||||
<span class="label label-success">Success</span>
|
||||
<span class="label label-info">Info</span>
|
||||
<span class="label label-warning">Warning</span>
|
||||
<span class="label label-danger">Danger</span>
|
||||
</h6>
|
||||
<p>
|
||||
<span class="label label-default">Default</span>
|
||||
<span class="label label-primary">Primary</span>
|
||||
<span class="label label-success">Success</span>
|
||||
<span class="label label-info">Info</span>
|
||||
<span class="label label-warning">Warning</span>
|
||||
<span class="label label-danger">Danger</span>
|
||||
</p>
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Badges</h1>
|
||||
</div>
|
||||
<p>
|
||||
<a href="#">Inbox <span class="badge">42</span></a>
|
||||
</p>
|
||||
<ul class="nav nav-pills" role="tablist">
|
||||
<li role="presentation" class="active"><a href="#">Home <span class="badge">42</span></a></li>
|
||||
<li role="presentation"><a href="#">Profile</a></li>
|
||||
<li role="presentation"><a href="#">Messages <span class="badge">3</span></a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Dropdown menus</h1>
|
||||
</div>
|
||||
<div class="dropdown theme-dropdown clearfix">
|
||||
<a id="dropdownMenu1" href="#" class="sr-only dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||
<li class="active"><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
<li><a href="#">Something else here</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="#">Separated link</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Navs</h1>
|
||||
</div>
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" class="active"><a href="#">Home</a></li>
|
||||
<li role="presentation"><a href="#">Profile</a></li>
|
||||
<li role="presentation"><a href="#">Messages</a></li>
|
||||
</ul>
|
||||
<ul class="nav nav-pills" role="tablist">
|
||||
<li role="presentation" class="active"><a href="#">Home</a></li>
|
||||
<li role="presentation"><a href="#">Profile</a></li>
|
||||
<li role="presentation"><a href="#">Messages</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Navbars</h1>
|
||||
</div>
|
||||
|
||||
<nav class="navbar navbar-default">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="#">Project name</a>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="active"><a href="#">Home</a></li>
|
||||
<li><a href="#about">About</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
<li><a href="#">Something else here</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li class="dropdown-header">Nav header</li>
|
||||
<li><a href="#">Separated link</a></li>
|
||||
<li><a href="#">One more separated link</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<nav class="navbar navbar-inverse">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="#">Project name</a>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="active"><a href="#">Home</a></li>
|
||||
<li><a href="#about">About</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
<li><a href="#">Something else here</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li class="dropdown-header">Nav header</li>
|
||||
<li><a href="#">Separated link</a></li>
|
||||
<li><a href="#">One more separated link</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Alerts</h1>
|
||||
</div>
|
||||
<div class="alert alert-success" role="alert">
|
||||
<strong>Well done!</strong> You successfully read this important alert message.
|
||||
</div>
|
||||
<div class="alert alert-info" role="alert">
|
||||
<strong>Heads up!</strong> This alert needs your attention, but it's not super important.
|
||||
</div>
|
||||
<div class="alert alert-warning" role="alert">
|
||||
<strong>Warning!</strong> Best check yo self, you're not looking too good.
|
||||
</div>
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<strong>Oh snap!</strong> Change a few things up and try submitting again.
|
||||
</div>
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Progress bars</h1>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%;"><span class="sr-only">60% Complete</span></div>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width: 40%"><span class="sr-only">40% Complete (success)</span></div>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100" style="width: 20%"><span class="sr-only">20% Complete</span></div>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%"><span class="sr-only">60% Complete (warning)</span></div>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="80" aria-valuemin="0" aria-valuemax="100" style="width: 80%"><span class="sr-only">80% Complete (danger)</span></div>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%"><span class="sr-only">60% Complete</span></div>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-success" style="width: 35%"><span class="sr-only">35% Complete (success)</span></div>
|
||||
<div class="progress-bar progress-bar-warning" style="width: 20%"><span class="sr-only">20% Complete (warning)</span></div>
|
||||
<div class="progress-bar progress-bar-danger" style="width: 10%"><span class="sr-only">10% Complete (danger)</span></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>List groups</h1>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">Cras justo odio</li>
|
||||
<li class="list-group-item">Dapibus ac facilisis in</li>
|
||||
<li class="list-group-item">Morbi leo risus</li>
|
||||
<li class="list-group-item">Porta ac consectetur ac</li>
|
||||
<li class="list-group-item">Vestibulum at eros</li>
|
||||
</ul>
|
||||
</div><!-- /.col-sm-4 -->
|
||||
<div class="col-sm-4">
|
||||
<div class="list-group">
|
||||
<a href="#" class="list-group-item active">
|
||||
Cras justo odio
|
||||
</a>
|
||||
<a href="#" class="list-group-item">Dapibus ac facilisis in</a>
|
||||
<a href="#" class="list-group-item">Morbi leo risus</a>
|
||||
<a href="#" class="list-group-item">Porta ac consectetur ac</a>
|
||||
<a href="#" class="list-group-item">Vestibulum at eros</a>
|
||||
</div>
|
||||
</div><!-- /.col-sm-4 -->
|
||||
<div class="col-sm-4">
|
||||
<div class="list-group">
|
||||
<a href="#" class="list-group-item active">
|
||||
<h4 class="list-group-item-heading">List group item heading</h4>
|
||||
<p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p>
|
||||
</a>
|
||||
<a href="#" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">List group item heading</h4>
|
||||
<p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p>
|
||||
</a>
|
||||
<a href="#" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">List group item heading</h4>
|
||||
<p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p>
|
||||
</a>
|
||||
</div>
|
||||
</div><!-- /.col-sm-4 -->
|
||||
</div>
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Panels</h1>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Panel title</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
Panel content
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Panel title</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
Panel content
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /.col-sm-4 -->
|
||||
<div class="col-sm-4">
|
||||
<div class="panel panel-success">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Panel title</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
Panel content
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Panel title</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
Panel content
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /.col-sm-4 -->
|
||||
<div class="col-sm-4">
|
||||
<div class="panel panel-warning">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Panel title</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
Panel content
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-danger">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Panel title</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
Panel content
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /.col-sm-4 -->
|
||||
</div>
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Wells</h1>
|
||||
</div>
|
||||
<div class="well">
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed diam eget risus varius blandit sit amet non magna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Aenean lacinia bibendum nulla sed consectetur.</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Carousel</h1>
|
||||
</div>
|
||||
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
|
||||
<ol class="carousel-indicators">
|
||||
<li data-target="#carousel-example-generic" data-slide-to="0" class=""></li>
|
||||
<li data-target="#carousel-example-generic" data-slide-to="1" class=""></li>
|
||||
<li data-target="#carousel-example-generic" data-slide-to="2" class="active"></li>
|
||||
</ol>
|
||||
<div class="carousel-inner" role="listbox">
|
||||
<div class="item">
|
||||
<img data-src="holder.js/1140x500/auto/#777:#555/text:First slide" alt="First slide [1140x500]" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTE0MCIgaGVpZ2h0PSI1MDAiIHZpZXdCb3g9IjAgMCAxMTQwIDUwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+PCEtLQpTb3VyY2UgVVJMOiBob2xkZXIuanMvMTE0MHg1MDAvYXV0by8jNzc3OiM1NTUvdGV4dDpGaXJzdCBzbGlkZQpDcmVhdGVkIHdpdGggSG9sZGVyLmpzIDIuNi4wLgpMZWFybiBtb3JlIGF0IGh0dHA6Ly9ob2xkZXJqcy5jb20KKGMpIDIwMTItMjAxNSBJdmFuIE1hbG9waW5za3kgLSBodHRwOi8vaW1za3kuY28KLS0+PGRlZnM+PHN0eWxlIHR5cGU9InRleHQvY3NzIj48IVtDREFUQVsjaG9sZGVyXzE1NjJjYTIxYzRkIHRleHQgeyBmaWxsOiM1NTU7Zm9udC13ZWlnaHQ6Ym9sZDtmb250LWZhbWlseTpBcmlhbCwgSGVsdmV0aWNhLCBPcGVuIFNhbnMsIHNhbnMtc2VyaWYsIG1vbm9zcGFjZTtmb250LXNpemU6NTdwdCB9IF1dPjwvc3R5bGU+PC9kZWZzPjxnIGlkPSJob2xkZXJfMTU2MmNhMjFjNGQiPjxyZWN0IHdpZHRoPSIxMTQwIiBoZWlnaHQ9IjUwMCIgZmlsbD0iIzc3NyIvPjxnPjx0ZXh0IHg9IjM5MC41MDc4MTI1IiB5PSIyNzUuNSI+Rmlyc3Qgc2xpZGU8L3RleHQ+PC9nPjwvZz48L3N2Zz4=" data-holder-rendered="true">
|
||||
</div>
|
||||
<div class="item active left">
|
||||
<img data-src="holder.js/1140x500/auto/#666:#444/text:Second slide" alt="Second slide [1140x500]" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTE0MCIgaGVpZ2h0PSI1MDAiIHZpZXdCb3g9IjAgMCAxMTQwIDUwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+PCEtLQpTb3VyY2UgVVJMOiBob2xkZXIuanMvMTE0MHg1MDAvYXV0by8jNjY2OiM0NDQvdGV4dDpTZWNvbmQgc2xpZGUKQ3JlYXRlZCB3aXRoIEhvbGRlci5qcyAyLjYuMC4KTGVhcm4gbW9yZSBhdCBodHRwOi8vaG9sZGVyanMuY29tCihjKSAyMDEyLTIwMTUgSXZhbiBNYWxvcGluc2t5IC0gaHR0cDovL2ltc2t5LmNvCi0tPjxkZWZzPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+PCFbQ0RBVEFbI2hvbGRlcl8xNTYyY2ExZTY3NCB0ZXh0IHsgZmlsbDojNDQ0O2ZvbnQtd2VpZ2h0OmJvbGQ7Zm9udC1mYW1pbHk6QXJpYWwsIEhlbHZldGljYSwgT3BlbiBTYW5zLCBzYW5zLXNlcmlmLCBtb25vc3BhY2U7Zm9udC1zaXplOjU3cHQgfSBdXT48L3N0eWxlPjwvZGVmcz48ZyBpZD0iaG9sZGVyXzE1NjJjYTFlNjc0Ij48cmVjdCB3aWR0aD0iMTE0MCIgaGVpZ2h0PSI1MDAiIGZpbGw9IiM2NjYiLz48Zz48dGV4dCB4PSIzMzUuNjAxNTYyNSIgeT0iMjc1LjUiPlNlY29uZCBzbGlkZTwvdGV4dD48L2c+PC9nPjwvc3ZnPg==" data-holder-rendered="true">
|
||||
</div>
|
||||
<div class="item next left">
|
||||
<img data-src="holder.js/1140x500/auto/#555:#333/text:Third slide" alt="Third slide [1140x500]" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTE0MCIgaGVpZ2h0PSI1MDAiIHZpZXdCb3g9IjAgMCAxMTQwIDUwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+PCEtLQpTb3VyY2UgVVJMOiBob2xkZXIuanMvMTE0MHg1MDAvYXV0by8jNTU1OiMzMzMvdGV4dDpUaGlyZCBzbGlkZQpDcmVhdGVkIHdpdGggSG9sZGVyLmpzIDIuNi4wLgpMZWFybiBtb3JlIGF0IGh0dHA6Ly9ob2xkZXJqcy5jb20KKGMpIDIwMTItMjAxNSBJdmFuIE1hbG9waW5za3kgLSBodHRwOi8vaW1za3kuY28KLS0+PGRlZnM+PHN0eWxlIHR5cGU9InRleHQvY3NzIj48IVtDREFUQVsjaG9sZGVyXzE1NjJjYTFiNTg5IHRleHQgeyBmaWxsOiMzMzM7Zm9udC13ZWlnaHQ6Ym9sZDtmb250LWZhbWlseTpBcmlhbCwgSGVsdmV0aWNhLCBPcGVuIFNhbnMsIHNhbnMtc2VyaWYsIG1vbm9zcGFjZTtmb250LXNpemU6NTdwdCB9IF1dPjwvc3R5bGU+PC9kZWZzPjxnIGlkPSJob2xkZXJfMTU2MmNhMWI1ODkiPjxyZWN0IHdpZHRoPSIxMTQwIiBoZWlnaHQ9IjUwMCIgZmlsbD0iIzU1NSIvPjxnPjx0ZXh0IHg9IjM3Ny44NjcxODc1IiB5PSIyNzUuNSI+VGhpcmQgc2xpZGU8L3RleHQ+PC9nPjwvZz48L3N2Zz4=" data-holder-rendered="true">
|
||||
</div>
|
||||
</div>
|
||||
<a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
|
||||
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
|
||||
<span class="sr-only">Previous</span>
|
||||
</a>
|
||||
<a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
|
||||
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
|
||||
<span class="sr-only">Next</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
</div> <!-- /container -->
|
||||
@@ -0,0 +1,15 @@
|
||||
/* eslint-env node */
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
scripts: [{
|
||||
id: 'angular',
|
||||
src: '/build/angular.js'
|
||||
},
|
||||
{
|
||||
src: 'app.js'
|
||||
}]
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
<div ng-app="boostrapCompileBenchmark" ng-cloak>
|
||||
<div ng-controller="DataController as config">
|
||||
<p>Please, select which configuration you want to use:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="?comment=disabled&css=disabled">Only EA</a>
|
||||
<span ng-show="config.isEA">(active)</span>
|
||||
</li>
|
||||
<li>
|
||||
<a href="?comment=disabled">Active EA and classes directives</a>
|
||||
<span ng-show="config.isEAC">(active)</span>
|
||||
</li>
|
||||
<li>
|
||||
<a href="?css=disabled">Active EA and comment directives</a>
|
||||
<span ng-show="config.isEAM">(active)</span>
|
||||
</li>
|
||||
<li>
|
||||
<a href="?">Active all directives</a>
|
||||
<span ng-show="config.isEACM">(active)</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
<p>How many repetitions do you want to do?</p>
|
||||
<input type="number" ng-model="config.repeats">
|
||||
|
||||
<hr>
|
||||
<p>Template to $compile:</p>
|
||||
<select
|
||||
ng-options="template for template in config.templates"
|
||||
ng-model="config.selectedTemplate"
|
||||
ng-change="config.loadTemplate()"></select>
|
||||
|
||||
<p>The benchmark is
|
||||
<span ng-show="config.html">Ready!</span>
|
||||
<span ng-hide="config.html">LOADING!</span>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
var app = angular.module('eventDelegationBenchmark', []);
|
||||
|
||||
app.directive('noopDir', function() {
|
||||
@@ -5,7 +7,7 @@ app.directive('noopDir', function() {
|
||||
compile: function($element, $attrs) {
|
||||
return function($scope, $element) {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -13,12 +15,12 @@ app.directive('noopDir', function() {
|
||||
app.directive('nativeClick', ['$parse', function($parse) {
|
||||
return {
|
||||
compile: function($element, $attrs) {
|
||||
var expr = $parse($attrs.tstEvent);
|
||||
$parse($attrs.tstEvent);
|
||||
return function($scope, $element) {
|
||||
$element[0].addEventListener('click', function() {
|
||||
console.log('clicked');
|
||||
}, false);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}]);
|
||||
@@ -26,13 +28,12 @@ app.directive('nativeClick', ['$parse', function($parse) {
|
||||
app.directive('dlgtClick', function() {
|
||||
return {
|
||||
compile: function($element, $attrs) {
|
||||
var evt = $attrs.dlgtClick;
|
||||
// We don't setup the global event listeners as the costs are small and one time only...
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
app.controller('DataController', function($rootScope) {
|
||||
app.controller('DataController', function DataController($rootScope) {
|
||||
this.ngRepeatCount = 1000;
|
||||
this.rows = [];
|
||||
var self = this;
|
||||
@@ -47,8 +48,8 @@ app.controller('DataController', function($rootScope) {
|
||||
self.rows = oldRows;
|
||||
if (self.rows.length !== self.ngRepeatCount) {
|
||||
self.rows = [];
|
||||
for (var i=0; i<self.ngRepeatCount; i++) {
|
||||
self.rows.push('row'+i);
|
||||
for (var i = 0; i < self.ngRepeatCount; i++) {
|
||||
self.rows.push('row' + i);
|
||||
}
|
||||
}
|
||||
$rootScope.$apply();
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
/* eslint-env node */
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
scripts: [{
|
||||
id: 'angular',
|
||||
src: '/build/angular.js'
|
||||
},{
|
||||
src: 'app.js',
|
||||
}, {
|
||||
src: 'app.js'
|
||||
}]
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
var app = angular.module('largetableBenchmark', []);
|
||||
|
||||
app.config(function($compileProvider) {
|
||||
@@ -12,21 +14,23 @@ app.filter('noop', function() {
|
||||
};
|
||||
});
|
||||
|
||||
app.controller('DataController', function($scope, $rootScope) {
|
||||
app.controller('DataController', function DataController($scope, $rootScope) {
|
||||
var totalRows = 1000;
|
||||
var totalColumns = 20;
|
||||
|
||||
var data = $scope.data = [];
|
||||
$scope.digestDuration = '?';
|
||||
$scope.numberOfBindings = totalRows*totalColumns*2 + totalRows + 1;
|
||||
$scope.numberOfBindings = totalRows * totalColumns * 2 + totalRows + 1;
|
||||
$scope.numberOfWatches = '?';
|
||||
|
||||
/** @this */
|
||||
function iGetter() { return this.i; }
|
||||
/** @this */
|
||||
function jGetter() { return this.j; }
|
||||
|
||||
for (var i=0; i<totalRows; i++) {
|
||||
for (var i = 0; i < totalRows; i++) {
|
||||
data[i] = [];
|
||||
for (var j=0; j<totalColumns; j++) {
|
||||
for (var j = 0; j < totalColumns; j++) {
|
||||
data[i][j] = {
|
||||
i: i, j: j,
|
||||
iFn: iGetter,
|
||||
@@ -64,14 +68,13 @@ app.controller('DataController', function($scope, $rootScope) {
|
||||
});
|
||||
});
|
||||
|
||||
var fn = function() { return 'x'};
|
||||
|
||||
|
||||
app.directive('baselineBindingTable', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function ($scope, $element) {
|
||||
link: function($scope, $element) {
|
||||
var i, j, row, cell, comment;
|
||||
var document = window.document;
|
||||
var template = document.createElement('span');
|
||||
template.setAttribute('ng-repeat', 'foo in foos');
|
||||
template.classList.add('ng-scope');
|
||||
@@ -104,8 +107,9 @@ app.directive('baselineBindingTable', function() {
|
||||
app.directive('baselineInterpolationTable', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function ($scope, $element) {
|
||||
link: function($scope, $element) {
|
||||
var i, j, row, cell, comment;
|
||||
var document = window.document;
|
||||
var template = document.createElement('span');
|
||||
template.setAttribute('ng-repeat', 'foo in foos');
|
||||
template.classList.add('ng-scope');
|
||||
@@ -180,4 +184,4 @@ app.directive('baselineTable', function() {
|
||||
};
|
||||
});
|
||||
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/* eslint-env node */
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
scripts: [{
|
||||
@@ -9,7 +13,7 @@ module.exports = function(config) {
|
||||
src: '/build/angular.js'
|
||||
},
|
||||
{
|
||||
src: 'app.js',
|
||||
src: 'app.js'
|
||||
}]
|
||||
});
|
||||
};
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
//Override me with ?jquery=/bower_components/jquery/dist/jquery.js
|
||||
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
/* globals angular, benchmarkSteps */
|
||||
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
/* eslint-env node */
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
scripts: [ {
|
||||
scripts: [{
|
||||
id: 'angular',
|
||||
src: '/build/angular.js'
|
||||
},
|
||||
{
|
||||
src: 'app.js',
|
||||
src: 'app.js'
|
||||
}]
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
var app = angular.module('orderByBenchmark', []);
|
||||
|
||||
app.controller('DataController', function($rootScope, $scope) {
|
||||
app.controller('DataController', function DataController($rootScope, $scope) {
|
||||
this.ngRepeatCount = 5000;
|
||||
this.rows = [];
|
||||
var self = this;
|
||||
@@ -37,7 +39,7 @@ app.controller('DataController', function($rootScope, $scope) {
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: '$apply',
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
/* eslint-env node */
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
scripts: [
|
||||
{
|
||||
"id": "jquery",
|
||||
"src": "jquery-noop.js"
|
||||
},{
|
||||
'id': 'jquery',
|
||||
'src': 'jquery-noop.js'
|
||||
}, {
|
||||
id: 'angular',
|
||||
src: '/build/angular.js'
|
||||
},{
|
||||
src: 'app.js',
|
||||
}, {
|
||||
src: 'app.js'
|
||||
}]
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
var app = angular.module('parsedExpressionBenchmark', []);
|
||||
|
||||
app.config(function($compileProvider) {
|
||||
@@ -17,11 +19,10 @@ app.directive('bmPeWatch', function() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
compile: function($element, $attrs) {
|
||||
$element.text( $attrs.bmPeWatch );
|
||||
$element.text($attrs.bmPeWatch);
|
||||
return function($scope, $element, $attrs) {
|
||||
$scope.$watch($attrs.bmPeWatch, function(val) {
|
||||
$element.text(val);
|
||||
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -38,9 +39,9 @@ app.directive('bmPeWatchLiteral', function($parse) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
compile: function($element, $attrs) {
|
||||
$element.text( $attrs.bmPeWatchLiteral );
|
||||
$element.text($attrs.bmPeWatchLiteral);
|
||||
return function($scope, $element, $attrs) {
|
||||
$scope.$watch( $parse($attrs.bmPeWatchLiteral, retZero) );
|
||||
$scope.$watch($parse($attrs.bmPeWatchLiteral, retZero));
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -53,33 +54,33 @@ app.controller('DataController', function($scope, $rootScope) {
|
||||
|
||||
var star = '*';
|
||||
|
||||
$scope.func = function() { return star;};
|
||||
$scope.func = function() { return star; };
|
||||
|
||||
for (var i=0; i<totalRows; i++) {
|
||||
for (var i = 0; i < totalRows; i++) {
|
||||
data.push({
|
||||
index: i,
|
||||
odd: i%2 === 0,
|
||||
even: i%2 === 1,
|
||||
str0: "foo-" + Math.random()*Date.now(),
|
||||
str1: "bar-" + Math.random()*Date.now(),
|
||||
str2: "baz-" + Math.random()*Date.now(),
|
||||
num0: Math.random()*Date.now(),
|
||||
num1: Math.random()*Date.now(),
|
||||
num2: Math.random()*Date.now(),
|
||||
date0: new Date(Math.random()*Date.now()),
|
||||
date1: new Date(Math.random()*Date.now()),
|
||||
date2: new Date(Math.random()*Date.now()),
|
||||
func: function(){ return star; },
|
||||
obj: data[i-1],
|
||||
keys: data[i-1] && (data[i-1].keys || Object.keys(data[i-1])),
|
||||
constructor: data[i-1]
|
||||
odd: i % 2 === 0,
|
||||
even: i % 2 === 1,
|
||||
str0: 'foo-' + Math.random() * Date.now(),
|
||||
str1: 'bar-' + Math.random() * Date.now(),
|
||||
str2: 'baz-' + Math.random() * Date.now(),
|
||||
num0: Math.random() * Date.now(),
|
||||
num1: Math.random() * Date.now(),
|
||||
num2: Math.random() * Date.now(),
|
||||
date0: new Date(Math.random() * Date.now()),
|
||||
date1: new Date(Math.random() * Date.now()),
|
||||
date2: new Date(Math.random() * Date.now()),
|
||||
func: function() { return star; },
|
||||
obj: data[i - 1],
|
||||
keys: data[i - 1] && (data[i - 1].keys || Object.keys(data[i - 1])),
|
||||
constructor: data[i - 1]
|
||||
});
|
||||
}
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: '$apply',
|
||||
fn: function() {
|
||||
for (var i=0; i<50; i++) {
|
||||
for (var i = 0; i < 50; i++) {
|
||||
$rootScope.$digest();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
/* eslint-env node */
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
scripts: [ {
|
||||
scripts: [{
|
||||
id: 'angular',
|
||||
src: '/build/angular.js'
|
||||
},
|
||||
{
|
||||
src: 'app.js',
|
||||
src: 'app.js'
|
||||
}]
|
||||
});
|
||||
};
|
||||
|
||||
@@ -52,6 +52,11 @@
|
||||
<label for="functionCalls">Function calls</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="assignment" id="assignment">
|
||||
<label for="assignment">Assignment</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="objectLiterals" id="objectLiterals">
|
||||
<label for="objectLiterals">Object Literals</label>
|
||||
@@ -197,6 +202,18 @@
|
||||
<span bm-pe-watch="row.func(row.func(), row.func())"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="assignment" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="row.foo = row.str0"></span>
|
||||
<span bm-pe-watch="row.obj.foo = row.str1"></span>
|
||||
<span bm-pe-watch="row.obj.obj.foo = row.str2"></span>
|
||||
<span bm-pe-watch="row['bar'] = row.num0"></span>
|
||||
<span bm-pe-watch="row.obj['bar'] = row.num1"></span>
|
||||
<span bm-pe-watch="row.obj.obj['bar'] = row.num2"></span>
|
||||
<span bm-pe-watch="row[0] = row.date0"></span>
|
||||
<span bm-pe-watch="row.obj[0] = row.date1"></span>
|
||||
<span bm-pe-watch="row.obj.obj[0] = row.date2"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="objectLiterals" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch-literal="{foo: rowIdx}"></span>
|
||||
<span bm-pe-watch-literal="{foo: row, bar: rowIdx}"></span>
|
||||
|
||||
+4
-2
@@ -1,8 +1,10 @@
|
||||
{
|
||||
"name": "AngularJS",
|
||||
"name": "angularjs",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"jquery": "2.1.1",
|
||||
"jquery": "3.1.0",
|
||||
"jquery-2.2": "jquery#2.2.4",
|
||||
"jquery-2.1": "jquery#2.1.4",
|
||||
"closure-compiler": "https://dl.google.com/closure-compiler/compiler-20140814.zip",
|
||||
"ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.2.3/assets/ng-closure-runner.zip"
|
||||
}
|
||||
|
||||
+3
-5
@@ -38,7 +38,7 @@ var parseRawCommit = function(raw) {
|
||||
|
||||
lines.forEach(function(line) {
|
||||
match = line.match(/(?:Closes|Fixes)\s#(\d+)/);
|
||||
if (match) msg.closes.push(parseInt(match[1]));
|
||||
if (match) msg.closes.push(parseInt(match[1], 10));
|
||||
});
|
||||
|
||||
match = raw.match(/BREAKING CHANGE:([\s\S]*)/);
|
||||
@@ -48,7 +48,7 @@ var parseRawCommit = function(raw) {
|
||||
|
||||
|
||||
msg.body = lines.join('\n');
|
||||
match = msg.subject.match(/^(.*)\((.*)\)\:\s(.*)$/);
|
||||
match = msg.subject.match(/^(.*)\((.*)\):\s(.*)$/);
|
||||
|
||||
if (!match || !match[1] || !match[3]) {
|
||||
warn('Incorrect message: %s %s', msg.hash, msg.subject);
|
||||
@@ -148,8 +148,6 @@ var writeChangelog = function(stream, commits, version) {
|
||||
breaks: {}
|
||||
};
|
||||
|
||||
sections.breaks[EMPTY_COMPONENT] = [];
|
||||
|
||||
commits.forEach(function(commit) {
|
||||
var section = sections[commit.type];
|
||||
var component = commit.component || EMPTY_COMPONENT;
|
||||
@@ -162,7 +160,7 @@ var writeChangelog = function(stream, commits, version) {
|
||||
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),
|
||||
subject: util.format('due to %s,\n %s', linkToCommit(commit.hash), commit.breaking),
|
||||
hash: commit.hash,
|
||||
closes: []
|
||||
});
|
||||
|
||||
+2
-2
@@ -67,7 +67,7 @@ describe('changelog.js', function() {
|
||||
module2: [{subject: 'breaking change 2'}]
|
||||
};
|
||||
var expectedOutput =
|
||||
'\n' + '## test\n\n' +
|
||||
'\n## test\n\n' +
|
||||
'- **module1:** breaking change 1\n' +
|
||||
'- **module2:** breaking change 2\n' +
|
||||
'\n';
|
||||
@@ -92,7 +92,7 @@ describe('changelog.js', function() {
|
||||
]
|
||||
};
|
||||
var expectedOutput =
|
||||
'\n' + '## test\n\n' +
|
||||
'\n## test\n\n' +
|
||||
'- **module1:**\n' +
|
||||
' - breaking change 1.1\n' +
|
||||
' - breaking change 1.2\n' +
|
||||
|
||||
+40
-41
@@ -9,72 +9,72 @@ var Q = require('q');
|
||||
var _ = require('lodash');
|
||||
var semver = require('semver');
|
||||
|
||||
var exec = function (cmd) {
|
||||
return function () {
|
||||
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 Q.nfcall(cp.exec, fullCmd).then(function(out) {
|
||||
return out[0].split('\n');
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var andThen = function (fn, after) {
|
||||
return function () {
|
||||
var andThen = function(fn, after) {
|
||||
return /** @this */ function() {
|
||||
return fn.apply(this, arguments).then(after);
|
||||
};
|
||||
};
|
||||
|
||||
var oneArg = function (fn) {
|
||||
return function (arg) {
|
||||
var oneArg = function(fn) {
|
||||
return function(arg) {
|
||||
return fn(arg);
|
||||
};
|
||||
};
|
||||
|
||||
var oneLine = function (lines) {
|
||||
var oneLine = function(lines) {
|
||||
return lines[0].trim();
|
||||
};
|
||||
|
||||
var noArgs = function (fn) {
|
||||
return function () {
|
||||
var noArgs = function(fn) {
|
||||
return function() {
|
||||
return fn();
|
||||
};
|
||||
};
|
||||
|
||||
var identity = function (i) { return i; };
|
||||
var identity = function(i) { return i; };
|
||||
|
||||
// like Q.all, but runs the commands in series
|
||||
// useful for ensuring env state (like which branch is checked out)
|
||||
var allInSeries = function (fn) {
|
||||
return function (args) {
|
||||
var allInSeries = function(fn) {
|
||||
return function(args) {
|
||||
var results = [];
|
||||
var def;
|
||||
while (args.length > 0) {
|
||||
(function (arg) {
|
||||
(function(arg) {
|
||||
if (def) {
|
||||
def = def.then(function () {
|
||||
def = def.then(function() {
|
||||
return fn(arg);
|
||||
});
|
||||
} else {
|
||||
def = fn(arg);
|
||||
}
|
||||
def = def.then(function (res) {
|
||||
def = def.then(function(res) {
|
||||
results.push(res);
|
||||
});
|
||||
}(args.pop()));
|
||||
})(args.pop());
|
||||
}
|
||||
return def.then(function () {
|
||||
return def.then(function() {
|
||||
return results;
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var compareBranches = function (left, right) {
|
||||
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) {
|
||||
map(function(line) {
|
||||
return left.full[left.log.indexOf(line)]; // lol O(n^2)
|
||||
}).
|
||||
value().
|
||||
@@ -85,44 +85,43 @@ 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) {
|
||||
then(function(branch) {
|
||||
currentBranch = branch;
|
||||
}).
|
||||
then(getTags).
|
||||
then(function (tags) {
|
||||
then(function(tags) {
|
||||
return tags.
|
||||
filter(semver.valid).
|
||||
map(semver.clean).
|
||||
sort(semver.rcompare);
|
||||
}).
|
||||
then(function (tags) {
|
||||
var major = tags[0].split('.')[0];
|
||||
then(function(tags) {
|
||||
var major = semver(tags[0]).major;
|
||||
return tags.
|
||||
filter(function (ver) {
|
||||
return semver(ver).major == major;
|
||||
filter(function(ver) {
|
||||
return semver(ver).major === major;
|
||||
});
|
||||
}).
|
||||
then(function (tags) {
|
||||
then(function(tags) {
|
||||
return _(tags).
|
||||
groupBy(function (tag) {
|
||||
groupBy(function(tag) {
|
||||
return tag.split('.')[1];
|
||||
}).
|
||||
map(function (group) {
|
||||
map(function(group) {
|
||||
return _.first(group);
|
||||
}).
|
||||
map(function (tag) {
|
||||
map(function(tag) {
|
||||
return 'v' + tag;
|
||||
}).
|
||||
value();
|
||||
}).
|
||||
then(function (tags) {
|
||||
then(function(tags) {
|
||||
var master = tags.pop();
|
||||
var stable = tags.pop();
|
||||
|
||||
@@ -131,38 +130,38 @@ then(function (tags) {
|
||||
{ name: 'master', tag: master}
|
||||
];
|
||||
}).
|
||||
then(allInSeries(function (branch) {
|
||||
then(allInSeries(function(branch) {
|
||||
return checkout(branch.name).
|
||||
then(function () {
|
||||
then(function() {
|
||||
return getTheLog(branch.tag);
|
||||
}).
|
||||
then(function (log) {
|
||||
then(function(log) {
|
||||
return log.
|
||||
filter(identity);
|
||||
}).
|
||||
then(function (log) {
|
||||
branch.full = log.map(function (line) {
|
||||
then(function(log) {
|
||||
branch.full = log.map(function(line) {
|
||||
line = line.split(' ');
|
||||
var sha = line.shift();
|
||||
var msg = line.join(' ');
|
||||
return sha + ((/fix\([^\)]+\):/i.test(msg)) ? ' * ' : ' ') + msg;
|
||||
});
|
||||
branch.log = log.map(function (line) {
|
||||
branch.log = log.map(function(line) {
|
||||
return line.substr(41);
|
||||
});
|
||||
return branch;
|
||||
});
|
||||
})).
|
||||
then(function (pairs) {
|
||||
then(function(pairs) {
|
||||
compareBranches(pairs[0], pairs[1]);
|
||||
console.log('\n');
|
||||
compareBranches(pairs[1], pairs[0]);
|
||||
return pairs;
|
||||
}).
|
||||
then(function () {
|
||||
then(function() {
|
||||
return checkout(currentBranch);
|
||||
}).
|
||||
catch(function (e) {
|
||||
catch(function(e) {
|
||||
console.log(e.stack);
|
||||
});
|
||||
|
||||
|
||||
@@ -647,6 +647,11 @@ ul.events > li {
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
.diagram {
|
||||
margin-bottom: 10px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 769px) and (max-width: 991px) {
|
||||
.main-body-grid {
|
||||
margin-top: 160px;
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
"use strict";
|
||||
/* jshint browser: true */
|
||||
/* global importScripts, onmessage: true, postMessage, lunr */
|
||||
'use strict';
|
||||
|
||||
/* eslint-env worker */
|
||||
/* global importScripts, lunr */
|
||||
|
||||
// Load up the lunr library
|
||||
importScripts('../components/lunr.js-0.5.12/lunr.min.js');
|
||||
|
||||
// Create the lunr index - the docs should be an array of object, each object containing
|
||||
// the path and search terms for a page
|
||||
var index = lunr(function() {
|
||||
var index = lunr(/** @this */function() {
|
||||
this.ref('path');
|
||||
this.field('titleWords', {boost: 50});
|
||||
this.field('members', { boost: 40});
|
||||
this.field('keywords', { boost : 20 });
|
||||
this.field('members', {boost: 40});
|
||||
this.field('keywords', {boost: 20});
|
||||
});
|
||||
|
||||
// Retrieve the searchData which contains the information about each page to be indexed
|
||||
@@ -25,13 +26,13 @@ searchDataRequest.onload = function() {
|
||||
searchData.forEach(function(page) {
|
||||
index.add(page);
|
||||
});
|
||||
postMessage({ e: 'index-ready' });
|
||||
self.postMessage({e: 'index-ready'});
|
||||
};
|
||||
searchDataRequest.open('GET', 'search-data.json');
|
||||
searchDataRequest.send();
|
||||
|
||||
// The worker receives a message everytime the web app wants to query the index
|
||||
onmessage = function(oEvent) {
|
||||
self.onmessage = function(oEvent) {
|
||||
var q = oEvent.data.q;
|
||||
var hits = index.search(q);
|
||||
var results = [];
|
||||
@@ -40,5 +41,5 @@ onmessage = function(oEvent) {
|
||||
results.push(hit.ref);
|
||||
});
|
||||
// The results of the query are sent back to the web app via a new message
|
||||
postMessage({ e: 'query-ready', q: q, d: results });
|
||||
};
|
||||
self.postMessage({e: 'query-ready', q: q, d: results});
|
||||
};
|
||||
|
||||
@@ -1,28 +1,14 @@
|
||||
{
|
||||
"extends": "../../../.jshintrc-base",
|
||||
"root": true,
|
||||
"extends": "../../../.eslintrc-node.json",
|
||||
|
||||
|
||||
"env": {
|
||||
"jasmine": true,
|
||||
"protractor": true
|
||||
},
|
||||
|
||||
"globals": {
|
||||
|
||||
/* jasmine / karma */
|
||||
"it": false,
|
||||
"iit": false,
|
||||
"describe": false,
|
||||
"ddescribe": false,
|
||||
"beforeEach": false,
|
||||
"afterEach": false,
|
||||
"expect": false,
|
||||
"jasmine": false,
|
||||
"spyOn": false,
|
||||
"waits": false,
|
||||
"waitsFor": false,
|
||||
"runs": false,
|
||||
"dump": false,
|
||||
|
||||
/* e2e */
|
||||
"browser": false,
|
||||
"element": false,
|
||||
"by": false,
|
||||
|
||||
/* testabilityPatch / matchers */
|
||||
"inject": false,
|
||||
"module": false,
|
||||
@@ -39,4 +25,4 @@
|
||||
"browserTrigger": false,
|
||||
"jqLiteCacheSize": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
describe("doc.angularjs.org", function() {
|
||||
describe('doc.angularjs.org', function() {
|
||||
|
||||
describe("API pages", function() {
|
||||
describe('API pages', function() {
|
||||
|
||||
it("should display links to code on GitHub", function() {
|
||||
it('should display links to code on GitHub', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/service/$http');
|
||||
expect(element(by.css('.improve-docs')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/edit\/.+\/src\/ng\/http\.js/);
|
||||
|
||||
@@ -12,7 +12,7 @@ describe("doc.angularjs.org", function() {
|
||||
expect(element(by.css('.view-source')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/tree\/.+\/src\/ng\/http\.js#L\d+/);
|
||||
});
|
||||
|
||||
it('should change the page content when clicking a link to a service', function () {
|
||||
it('should change the page content when clicking a link to a service', function() {
|
||||
browser.get('build/docs/index.html');
|
||||
|
||||
var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]'));
|
||||
@@ -23,7 +23,7 @@ describe("doc.angularjs.org", function() {
|
||||
});
|
||||
|
||||
|
||||
it('should show the functioning input directive example', function () {
|
||||
it('should show the functioning input directive example', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/directive/input');
|
||||
|
||||
// Ensure that the page is loaded before trying to switch frames.
|
||||
@@ -38,7 +38,7 @@ describe("doc.angularjs.org", function() {
|
||||
expect(code.getText()).toContain('guest!!!');
|
||||
});
|
||||
|
||||
it("should trim indentation from code blocks", function() {
|
||||
it('should trim indentation from code blocks', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/type/$rootScope.Scope');
|
||||
|
||||
var codeBlocks = element.all(by.css('pre > code.lang-js'));
|
||||
@@ -48,4 +48,4 @@ describe("doc.angularjs.org", function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
describe("provider pages", function() {
|
||||
describe('provider pages', function() {
|
||||
|
||||
it("should show the related service", function() {
|
||||
it('should show the related service', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/provider/$compileProvider');
|
||||
var serviceLink = element.all(by.css('ol.api-profile-header-structure li a')).first();
|
||||
expect(serviceLink.getText()).toEqual('- $compile');
|
||||
expect(serviceLink.getAttribute('href')).toMatch(/api\/ng\/service\/\$compile/);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
describe("service pages", function() {
|
||||
describe('service pages', function() {
|
||||
|
||||
it("should show the related provider if there is one", function() {
|
||||
it('should show the related provider if there is one', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/service/$compile');
|
||||
var providerLink = element.all(by.css('ol.api-profile-header-structure li a')).first();
|
||||
expect(providerLink.getText()).toEqual('- $compileProvider');
|
||||
@@ -14,9 +14,9 @@ describe("service pages", function() {
|
||||
expect(providerLink.getAttribute('href')).not.toMatch(/api\/ng\/provider\/\$compileProvider/);
|
||||
});
|
||||
|
||||
it("should show parameter defaults", function() {
|
||||
it('should show parameter defaults', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/service/$timeout');
|
||||
expect(element.all(by.css('.input-arguments p em')).first().getText()).toContain('(default: 0)');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
var webdriver = require('protractor/node_modules/selenium-webdriver');
|
||||
var webdriver = require('selenium-webdriver');
|
||||
|
||||
describe('docs.angularjs.org', function () {
|
||||
describe('docs.angularjs.org', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
// read and clear logs from previous tests
|
||||
@@ -24,7 +24,7 @@ describe('docs.angularjs.org', function () {
|
||||
});
|
||||
|
||||
|
||||
describe('App', function () {
|
||||
describe('App', function() {
|
||||
// it('should filter the module list when searching', function () {
|
||||
// browser.get();
|
||||
// browser.waitForAngular();
|
||||
@@ -38,8 +38,8 @@ describe('docs.angularjs.org', function () {
|
||||
// });
|
||||
|
||||
|
||||
it('should change the page content when clicking a link to a service', function () {
|
||||
browser.get('build/docs/index.html');
|
||||
it('should change the page content when clicking a link to a service', function() {
|
||||
browser.get('build/docs/index-production.html');
|
||||
|
||||
var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]'));
|
||||
ngBindLink.click();
|
||||
@@ -51,36 +51,36 @@ describe('docs.angularjs.org', function () {
|
||||
|
||||
|
||||
it('should be resilient to trailing slashes', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/function/angular.noop/');
|
||||
browser.get('build/docs/index-production.html#!/api/ng/function/angular.noop/');
|
||||
var pageBody = element(by.css('h1'));
|
||||
expect(pageBody.getText()).toEqual('angular.noop');
|
||||
});
|
||||
|
||||
|
||||
it('should be resilient to trailing "index"', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/function/angular.noop/index');
|
||||
browser.get('build/docs/index-production.html#!/api/ng/function/angular.noop/index');
|
||||
var pageBody = element(by.css('h1'));
|
||||
expect(pageBody.getText()).toEqual('angular.noop');
|
||||
});
|
||||
|
||||
|
||||
it('should be resilient to trailing "index/"', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/function/angular.noop/index/');
|
||||
browser.get('build/docs/index-production.html#!/api/ng/function/angular.noop/index/');
|
||||
var pageBody = element(by.css('h1'));
|
||||
expect(pageBody.getText()).toEqual('angular.noop');
|
||||
});
|
||||
|
||||
|
||||
it('should display formatted error messages on error doc pages', function() {
|
||||
browser.get('build/docs/index.html#!error/ng/areq?p0=Missing&p1=not%20a%20function,%20got%20undefined');
|
||||
expect(element(by.css('.minerr-errmsg')).getText()).toEqual("Argument 'Missing' is not a function, got undefined");
|
||||
browser.get('build/docs/index-production.html#!error/ng/areq?p0=Missing&p1=not%20a%20function,%20got%20undefined');
|
||||
expect(element(by.css('.minerr-errmsg')).getText()).toEqual('Argument \'Missing\' is not a function, got undefined');
|
||||
});
|
||||
|
||||
it("should display an error if the page does not exist", function() {
|
||||
browser.get('build/docs/index.html#!/api/does/not/exist');
|
||||
it('should display an error if the page does not exist', function() {
|
||||
browser.get('build/docs/index-production.html#!/api/does/not/exist');
|
||||
expect(element(by.css('h1')).getText()).toBe('Oops!');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"root": true,
|
||||
"extends": "../../../.eslintrc-browser.json",
|
||||
|
||||
"globals": {
|
||||
"lunr": false
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('docsApp', [
|
||||
'ngRoute',
|
||||
'ngCookies',
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('directives', [])
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('DocsController', [])
|
||||
|
||||
.controller('DocsController', [
|
||||
@@ -27,9 +29,9 @@ angular.module('DocsController', [])
|
||||
|
||||
path = path.replace(/^\/?(.+?)(\/index)?\/?$/, '$1');
|
||||
|
||||
currentPage = $scope.currentPage = NG_PAGES[path];
|
||||
var currentPage = $scope.currentPage = NG_PAGES[path];
|
||||
|
||||
if ( currentPage ) {
|
||||
if (currentPage) {
|
||||
$scope.partialPath = 'partials/' + path + '.html';
|
||||
$scope.currentArea = NG_NAVIGATION[currentPage.area];
|
||||
var pathParts = currentPage.path.split('/');
|
||||
@@ -37,7 +39,7 @@ angular.module('DocsController', [])
|
||||
var breadcrumbPath = '';
|
||||
angular.forEach(pathParts, function(part) {
|
||||
breadcrumbPath += part;
|
||||
breadcrumb.push({ name: (NG_PAGES[breadcrumbPath]&&NG_PAGES[breadcrumbPath].name) || part, url: breadcrumbPath });
|
||||
breadcrumb.push({ name: (NG_PAGES[breadcrumbPath] && NG_PAGES[breadcrumbPath].name) || part, url: breadcrumbPath });
|
||||
breadcrumbPath += '/';
|
||||
});
|
||||
} else {
|
||||
@@ -52,7 +54,7 @@ angular.module('DocsController', [])
|
||||
***********************************/
|
||||
|
||||
$scope.versionNumber = angular.version.full;
|
||||
$scope.version = angular.version.full + " " + angular.version.codeName;
|
||||
$scope.version = angular.version.full + ' ' + angular.version.codeName;
|
||||
$scope.loading = 0;
|
||||
|
||||
|
||||
|
||||
+16
-14
@@ -1,23 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('errors', ['ngSanitize'])
|
||||
|
||||
.filter('errorLink', ['$sanitize', function ($sanitize) {
|
||||
var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.\;\,\(\)\{\}<>]/g,
|
||||
.filter('errorLink', ['$sanitize', function($sanitize) {
|
||||
var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.;,\(\)\{\}<>]/g,
|
||||
MAILTO_REGEXP = /^mailto:/,
|
||||
STACK_TRACE_REGEXP = /:\d+:\d+$/;
|
||||
|
||||
var truncate = function (text, nchars) {
|
||||
var truncate = function(text, nchars) {
|
||||
if (text.length > nchars) {
|
||||
return text.substr(0, nchars - 3) + '...';
|
||||
}
|
||||
return text;
|
||||
};
|
||||
|
||||
return function (text, target) {
|
||||
return function(text, target) {
|
||||
if (!text) return text;
|
||||
|
||||
var targetHtml = target ? ' target="' + target + '"' : '';
|
||||
|
||||
return $sanitize(text.replace(LINKY_URL_REGEXP, function (url) {
|
||||
return $sanitize(text.replace(LINKY_URL_REGEXP, function(url) {
|
||||
if (STACK_TRACE_REGEXP.test(url)) {
|
||||
return url;
|
||||
}
|
||||
@@ -25,7 +27,7 @@ angular.module('errors', ['ngSanitize'])
|
||||
// if we did not match ftp/http/mailto then assume mailto
|
||||
if (!/^((ftp|https?):\/\/|mailto:)/.test(url)) url = 'mailto:' + url;
|
||||
|
||||
return '<a' + targetHtml + ' href="' + url +'">' +
|
||||
return '<a' + targetHtml + ' href="' + url + '">' +
|
||||
truncate(url.replace(MAILTO_REGEXP, ''), 60) +
|
||||
'</a>';
|
||||
}));
|
||||
@@ -33,33 +35,33 @@ angular.module('errors', ['ngSanitize'])
|
||||
}])
|
||||
|
||||
|
||||
.directive('errorDisplay', ['$location', 'errorLinkFilter', function ($location, errorLinkFilter) {
|
||||
var encodeAngleBrackets = function (text) {
|
||||
.directive('errorDisplay', ['$location', 'errorLinkFilter', function($location, errorLinkFilter) {
|
||||
var encodeAngleBrackets = function(text) {
|
||||
return text.replace(/</g, '<').replace(/>/g, '>');
|
||||
};
|
||||
|
||||
var interpolate = function (formatString) {
|
||||
var interpolate = function(formatString) {
|
||||
var formatArgs = arguments;
|
||||
return formatString.replace(/\{\d+\}/g, function (match) {
|
||||
return formatString.replace(/\{\d+\}/g, function(match) {
|
||||
// Drop the braces and use the unary plus to convert to an integer.
|
||||
// The index will be off by one because of the formatString.
|
||||
var index = +match.slice(1, -1);
|
||||
if (index + 1 >= formatArgs.length) {
|
||||
return match;
|
||||
}
|
||||
return formatArgs[index+1];
|
||||
return formatArgs[index + 1];
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
link: function (scope, element, attrs) {
|
||||
link: function(scope, element, attrs) {
|
||||
var search = $location.search(),
|
||||
formatArgs = [attrs.errorDisplay],
|
||||
formattedText,
|
||||
i;
|
||||
|
||||
for (i = 0; angular.isDefined(search['p'+i]); i++) {
|
||||
formatArgs.push(search['p'+i]);
|
||||
for (i = 0; angular.isDefined(search['p' + i]); i++) {
|
||||
formatArgs.push(search['p' + i]);
|
||||
}
|
||||
|
||||
formattedText = encodeAngleBrackets(interpolate.apply(null, formatArgs));
|
||||
|
||||
+13
-12
@@ -1,8 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('examples', [])
|
||||
|
||||
.directive('runnableExample', ['$templateCache', '$document', function($templateCache, $document) {
|
||||
.directive('runnableExample', [function() {
|
||||
var exampleClassNameSelector = '.runnable-example-file';
|
||||
var doc = $document[0];
|
||||
var tpl =
|
||||
'<nav class="runnable-example-tabs" ng-if="tabs">' +
|
||||
' <a ng-class="{active:$index==activeTabIndex}"' +
|
||||
@@ -29,12 +30,12 @@ angular.module('examples', [])
|
||||
return function(scope, element) {
|
||||
var node = element[0];
|
||||
var examples = node.querySelectorAll(exampleClassNameSelector);
|
||||
var tabs = [], now = Date.now();
|
||||
var tabs = [];
|
||||
angular.forEach(examples, function(child, index) {
|
||||
tabs.push(child.getAttribute('name'));
|
||||
});
|
||||
|
||||
if(tabs.length > 0) {
|
||||
if (tabs.length > 0) {
|
||||
scope.tabs = tabs;
|
||||
scope.$on('tabChange', function(e, index, title) {
|
||||
angular.forEach(examples, function(child) {
|
||||
@@ -101,7 +102,7 @@ angular.module('examples', [])
|
||||
},
|
||||
controllerAs: 'plnkr',
|
||||
template: '<button ng-click="plnkr.open($event)" class="btn pull-right"> <i class="glyphicon glyphicon-edit"> </i> Edit in Plunker</button> ',
|
||||
controller: [function() {
|
||||
controller: [function PlnkrOpenerCtrl() {
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.example = {
|
||||
@@ -137,8 +138,8 @@ angular.module('examples', [])
|
||||
var newWindow = clickEvent.ctrlKey || clickEvent.metaKey;
|
||||
|
||||
var postData = {
|
||||
'tags[0]': "angularjs",
|
||||
'tags[1]': "example",
|
||||
'tags[0]': 'angularjs',
|
||||
'tags[1]': 'example',
|
||||
'private': true
|
||||
};
|
||||
|
||||
@@ -153,7 +154,7 @@ angular.module('examples', [])
|
||||
|
||||
postData.description = ctrl.example.name;
|
||||
|
||||
formPostData('http://plnkr.co/edit/?p=preview', newWindow, postData);
|
||||
formPostData('https://plnkr.co/edit/?p=preview', newWindow, postData);
|
||||
});
|
||||
|
||||
};
|
||||
@@ -167,7 +168,7 @@ angular.module('examples', [])
|
||||
}])
|
||||
|
||||
.factory('getExampleData', ['$http', '$q', function($http, $q) {
|
||||
return function(exampleFolder){
|
||||
return function(exampleFolder) {
|
||||
// Load the manifest for the example
|
||||
return $http.get(exampleFolder + '/manifest.json')
|
||||
.then(function(response) {
|
||||
@@ -182,8 +183,8 @@ angular.module('examples', [])
|
||||
|
||||
// The manifests provide the production index file but Plunkr wants
|
||||
// a straight index.html
|
||||
if (filename === "index-production.html") {
|
||||
filename = "index.html";
|
||||
if (filename === 'index-production.html') {
|
||||
filename = 'index.html';
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -199,4 +200,4 @@ angular.module('examples', [])
|
||||
});
|
||||
});
|
||||
};
|
||||
}]);
|
||||
}]);
|
||||
|
||||
+23
-21
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('search', [])
|
||||
|
||||
.controller('DocsSearchCtrl', ['$scope', '$location', 'docsSearch', function($scope, $location, docsSearch) {
|
||||
@@ -9,7 +11,7 @@ angular.module('search', [])
|
||||
|
||||
$scope.search = function(q) {
|
||||
var MIN_SEARCH_LENGTH = 2;
|
||||
if(q.length >= MIN_SEARCH_LENGTH) {
|
||||
if (q.length >= MIN_SEARCH_LENGTH) {
|
||||
docsSearch(q).then(function(hits) {
|
||||
// Make sure the areas are always in the same order
|
||||
var results = {
|
||||
@@ -23,28 +25,24 @@ angular.module('search', [])
|
||||
angular.forEach(hits, function(hit) {
|
||||
var area = hit.area;
|
||||
|
||||
var limit = (area == 'api') ? 40 : 14;
|
||||
var limit = (area === 'api') ? 40 : 14;
|
||||
results[area] = results[area] || [];
|
||||
if(results[area].length < limit) {
|
||||
if (results[area].length < limit) {
|
||||
results[area].push(hit);
|
||||
}
|
||||
});
|
||||
|
||||
var totalAreas = 0;
|
||||
for(var i in results) {
|
||||
++totalAreas;
|
||||
}
|
||||
if(totalAreas > 0) {
|
||||
var totalAreas = Object.keys(results).length;
|
||||
if (totalAreas > 0) {
|
||||
$scope.colClassName = 'cols-' + totalAreas;
|
||||
}
|
||||
$scope.hasResults = totalAreas > 0;
|
||||
$scope.results = results;
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
clearResults();
|
||||
}
|
||||
if(!$scope.$$phase) $scope.$apply();
|
||||
if (!$scope.$$phase) $scope.$apply();
|
||||
};
|
||||
|
||||
$scope.submit = function() {
|
||||
@@ -52,14 +50,14 @@ angular.module('search', [])
|
||||
if ($scope.results.api) {
|
||||
result = $scope.results.api[0];
|
||||
} else {
|
||||
for(var i in $scope.results) {
|
||||
for (var i in $scope.results) {
|
||||
result = $scope.results[i][0];
|
||||
if(result) {
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(result) {
|
||||
if (result) {
|
||||
$location.path(result.path);
|
||||
$scope.hideResults();
|
||||
}
|
||||
@@ -92,10 +90,12 @@ angular.module('search', [])
|
||||
// It should only be used where the browser does not support WebWorkers
|
||||
function localSearchFactory($http, $timeout, NG_PAGES) {
|
||||
|
||||
console.log('Using Local Search Index');
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log('Using Local Search Index');
|
||||
}
|
||||
|
||||
// Create the lunr index
|
||||
var index = lunr(function() {
|
||||
var index = lunr(/** @this */ function() {
|
||||
this.ref('path');
|
||||
this.field('titleWords', {boost: 50});
|
||||
this.field('members', { boost: 40});
|
||||
@@ -136,12 +136,14 @@ angular.module('search', [])
|
||||
// It should only be used where the browser does support WebWorkers
|
||||
function webWorkerSearchFactory($q, $rootScope, NG_PAGES) {
|
||||
|
||||
console.log('Using WebWorker Search Index')
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log('Using WebWorker Search Index');
|
||||
}
|
||||
|
||||
var searchIndex = $q.defer();
|
||||
var results;
|
||||
|
||||
var worker = new Worker('js/search-worker.js');
|
||||
var worker = new window.Worker('js/search-worker.js');
|
||||
|
||||
// The worker will send us a message in two situations:
|
||||
// - when the index has been built, ready to run a query
|
||||
@@ -149,7 +151,7 @@ angular.module('search', [])
|
||||
worker.onmessage = function(oEvent) {
|
||||
$rootScope.$apply(function() {
|
||||
|
||||
switch(oEvent.data.e) {
|
||||
switch (oEvent.data.e) {
|
||||
case 'index-ready':
|
||||
searchIndex.resolve();
|
||||
break;
|
||||
@@ -206,7 +208,7 @@ angular.module('search', [])
|
||||
FORWARD_SLASH_KEYCODE = 191;
|
||||
angular.element($document[0].body).on('keydown', function(event) {
|
||||
var input = element[0];
|
||||
if(event.keyCode == FORWARD_SLASH_KEYCODE && document.activeElement != input) {
|
||||
if (event.keyCode === FORWARD_SLASH_KEYCODE && window.document.activeElement !== input) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
input.focus();
|
||||
@@ -214,7 +216,7 @@ angular.module('search', [])
|
||||
});
|
||||
|
||||
element.on('keydown', function(event) {
|
||||
if(event.keyCode == ESCAPE_KEY_KEYCODE) {
|
||||
if (event.keyCode === ESCAPE_KEY_KEYCODE) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
scope.$apply(function() {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('tutorials', [])
|
||||
|
||||
.directive('docTutorialNav', function() {
|
||||
@@ -5,7 +7,8 @@ angular.module('tutorials', [])
|
||||
'',
|
||||
'step_00', 'step_01', 'step_02', 'step_03', 'step_04',
|
||||
'step_05', 'step_06', 'step_07', 'step_08', 'step_09',
|
||||
'step_10', 'step_11', 'step_12', 'the_end'
|
||||
'step_10', 'step_11', 'step_12', 'step_13', 'step_14',
|
||||
'the_end'
|
||||
];
|
||||
return {
|
||||
scope: {},
|
||||
@@ -19,7 +22,7 @@ angular.module('tutorials', [])
|
||||
scope.seq = seq;
|
||||
scope.prev = pages[seq];
|
||||
scope.next = pages[2 + seq];
|
||||
scope.diffLo = seq ? (seq - 1): '0~1';
|
||||
scope.diffLo = seq ? (seq - 1) : '0~1';
|
||||
scope.diffHi = seq;
|
||||
|
||||
element.addClass('btn-group');
|
||||
@@ -39,11 +42,11 @@ angular.module('tutorials', [])
|
||||
'<div class="alert alert-info" ng-show="show">\n' +
|
||||
' <p>Reset the workspace to step {{step}}.</p>' +
|
||||
' <p><pre>git checkout -f step-{{step}}</pre></p>\n' +
|
||||
' <p>Refresh your browser or check out this step online: '+
|
||||
' <p>Refresh your browser or check out this step online: ' +
|
||||
'<a href="http://angular.github.io/angular-phonecat/step-{{step}}/app">Step {{step}} Live Demo</a>.</p>\n' +
|
||||
'</div>\n' +
|
||||
'<p>The most important changes are listed below. You can see the full diff on ' +
|
||||
'<a ng-href="https://github.com/angular/angular-phonecat/compare/step-{{step ? (step - 1): \'0~1\'}}...step-{{step}}" title="See diff on Github">GitHub</a>\n' +
|
||||
'<a ng-href="https://github.com/angular/angular-phonecat/compare/step-{{step ? (step - 1): \'0~1\'}}...step-{{step}}" title="See diff on Github">GitHub</a>.\n' +
|
||||
'</p>'
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
angular.module('versions', [])
|
||||
|
||||
@@ -6,7 +6,7 @@ angular.module('versions', [])
|
||||
$scope.docs_version = NG_VERSIONS[0];
|
||||
$scope.docs_versions = NG_VERSIONS;
|
||||
|
||||
for(var i=0, minor = NaN; i < NG_VERSIONS.length; i++) {
|
||||
for (var i = 0, minor = NaN; i < NG_VERSIONS.length; i++) {
|
||||
var version = NG_VERSIONS[i];
|
||||
// NaN will give false here
|
||||
if (minor <= version.minor) {
|
||||
@@ -25,7 +25,7 @@ angular.module('versions', [])
|
||||
url = '';
|
||||
if (version.isOldDocsUrl) {
|
||||
url = version.docsUrl;
|
||||
}else{
|
||||
} else {
|
||||
url = version.docsUrl + currentPagePath;
|
||||
}
|
||||
$window.location = url;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"root": true,
|
||||
"extends": "../../../.eslintrc-browser.json",
|
||||
|
||||
"env": {
|
||||
"jasmine": true
|
||||
},
|
||||
|
||||
"rules": {
|
||||
// Some rules are not that important in tests and conflict with
|
||||
// Jasmine or would make it easier to write some tests; we disable
|
||||
// those ones here.
|
||||
"no-invalid-this": "off",
|
||||
"no-throw-literal": "off",
|
||||
"no-unused-vars": "off"
|
||||
},
|
||||
|
||||
"globals": {
|
||||
// ngMocks
|
||||
"module": false,
|
||||
"inject": true
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"extends": "../../../.jshintrc-base",
|
||||
"browser": true,
|
||||
"globals": {
|
||||
// AngularJS
|
||||
"angular": false,
|
||||
|
||||
// ngMocks
|
||||
"module": false,
|
||||
"inject": true,
|
||||
|
||||
// Jasmine
|
||||
"jasmine": false,
|
||||
"describe": false,
|
||||
"ddescribe": false,
|
||||
"xdescribe": false,
|
||||
"it": false,
|
||||
"iit": false,
|
||||
"xit": false,
|
||||
"beforeEach": false,
|
||||
"afterEach": false,
|
||||
"spyOn": false,
|
||||
"expect": false
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
describe("code", function() {
|
||||
'use strict';
|
||||
|
||||
describe('code', function() {
|
||||
var prettyPrintOne, oldPP;
|
||||
var compile, scope;
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
describe("DocsController", function() {
|
||||
'use strict';
|
||||
|
||||
describe('DocsController', function() {
|
||||
var $scope;
|
||||
|
||||
angular.module('fake', [])
|
||||
@@ -15,7 +17,7 @@ describe("DocsController", function() {
|
||||
|
||||
|
||||
describe('afterPartialLoaded', function() {
|
||||
it("should update the Google Analytics with currentPage path if currentPage exists", inject(function($window) {
|
||||
it('should update the Google Analytics with currentPage path if currentPage exists', inject(function($window) {
|
||||
$window._gaq = [];
|
||||
$scope.currentPage = { path: 'a/b/c' };
|
||||
$scope.$broadcast('$includeContentLoaded');
|
||||
@@ -23,9 +25,9 @@ describe("DocsController", function() {
|
||||
}));
|
||||
|
||||
|
||||
it("should update the Google Analytics with $location.path if currentPage is missing", inject(function($window, $location) {
|
||||
it('should update the Google Analytics with $location.path if currentPage is missing', inject(function($window, $location) {
|
||||
$window._gaq = [];
|
||||
spyOn($location, 'path').andReturn('x/y/z');
|
||||
spyOn($location, 'path').and.returnValue('x/y/z');
|
||||
$scope.$broadcast('$includeContentLoaded');
|
||||
expect($window._gaq.pop()).toEqual(['_trackPageview', 'x/y/z']);
|
||||
}));
|
||||
|
||||
@@ -4,7 +4,7 @@ describe('errors', function() {
|
||||
// Mock `ngSanitize` module
|
||||
angular.
|
||||
module('ngSanitize', []).
|
||||
value('$sanitize', jasmine.createSpy('$sanitize').andCallFake(angular.identity));
|
||||
value('$sanitize', jasmine.createSpy('$sanitize').and.callFake(angular.identity));
|
||||
|
||||
beforeEach(module('errors'));
|
||||
|
||||
@@ -103,12 +103,12 @@ describe('errors', function() {
|
||||
|
||||
|
||||
it('should pass the final string through `$sanitize`', function() {
|
||||
$sanitize.reset();
|
||||
$sanitize.calls.reset();
|
||||
|
||||
var input = 'start https://foo/bar?baz#qux end';
|
||||
var output = errorLinkFilter(input);
|
||||
|
||||
expect($sanitize.callCount).toBe(1);
|
||||
expect($sanitize).toHaveBeenCalledTimes(1);
|
||||
expect($sanitize).toHaveBeenCalledWith(output);
|
||||
});
|
||||
});
|
||||
@@ -123,7 +123,7 @@ describe('errors', function() {
|
||||
beforeEach(module(function($provide) {
|
||||
$provide.decorator('errorLinkFilter', function() {
|
||||
errorLinkFilter = jasmine.createSpy('errorLinkFilter');
|
||||
errorLinkFilter.andCallFake(angular.identity);
|
||||
errorLinkFilter.and.callFake(angular.identity);
|
||||
|
||||
return errorLinkFilter;
|
||||
});
|
||||
@@ -135,14 +135,14 @@ describe('errors', function() {
|
||||
}));
|
||||
|
||||
|
||||
it('should set the element\s HTML', function() {
|
||||
it('should set the element\'s HTML', function() {
|
||||
var elem = $compile('<span error-display="bar">foo</span>')($rootScope);
|
||||
expect(elem.html()).toBe('bar');
|
||||
});
|
||||
|
||||
|
||||
it('should interpolate the contents against `$location.search()`', function() {
|
||||
spyOn($location, 'search').andReturn({p0: 'foo', p1: 'bar'});
|
||||
spyOn($location, 'search').and.returnValue({p0: 'foo', p1: 'bar'});
|
||||
|
||||
var elem = $compile('<span error-display="foo = {0}, bar = {1}"></span>')($rootScope);
|
||||
expect(elem.html()).toBe('foo = foo, bar = bar');
|
||||
@@ -150,10 +150,10 @@ describe('errors', function() {
|
||||
|
||||
|
||||
it('should pass the interpolated text through `errorLinkFilter`', function() {
|
||||
$location.search = jasmine.createSpy('search').andReturn({p0: 'foo'});
|
||||
$location.search = jasmine.createSpy('search').and.returnValue({p0: 'foo'});
|
||||
|
||||
var elem = $compile('<span error-display="foo = {0}"></span>')($rootScope);
|
||||
expect(errorLinkFilter.callCount).toBe(1);
|
||||
$compile('<span error-display="foo = {0}"></span>')($rootScope);
|
||||
expect(errorLinkFilter).toHaveBeenCalledTimes(1);
|
||||
expect(errorLinkFilter).toHaveBeenCalledWith('foo = foo', '_blank');
|
||||
});
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "AngularJS-docs-app",
|
||||
"dependencies": {
|
||||
"jquery": "2.1.1",
|
||||
"jquery": "2.2.3",
|
||||
"lunr.js": "0.5.12",
|
||||
"open-sans-fontface": "1.0.4",
|
||||
"google-code-prettify": "1.0.1",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
var path = require('canonical-path');
|
||||
var packagePath = __dirname;
|
||||
@@ -54,6 +54,8 @@ module.exports = new Package('angularjs', [
|
||||
.config(function(parseTagsProcessor) {
|
||||
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/tutorial-step'));
|
||||
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/sortOrder'));
|
||||
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/installation'));
|
||||
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/this'));
|
||||
})
|
||||
|
||||
|
||||
@@ -86,7 +88,7 @@ module.exports = new Package('angularjs', [
|
||||
docTypes: ['overview', 'tutorial'],
|
||||
getPath: function(doc) {
|
||||
var docPath = path.dirname(doc.fileInfo.relativePath);
|
||||
if ( doc.fileInfo.baseName !== 'index' ) {
|
||||
if (doc.fileInfo.baseName !== 'index') {
|
||||
docPath = path.join(docPath, doc.fileInfo.baseName);
|
||||
}
|
||||
return docPath;
|
||||
@@ -107,12 +109,12 @@ module.exports = new Package('angularjs', [
|
||||
});
|
||||
|
||||
computePathsProcessor.pathTemplates.push({
|
||||
docTypes: ['module' ],
|
||||
docTypes: ['module'],
|
||||
pathTemplate: '${area}/${name}',
|
||||
outputPathTemplate: 'partials/${area}/${name}.html'
|
||||
});
|
||||
computePathsProcessor.pathTemplates.push({
|
||||
docTypes: ['componentGroup' ],
|
||||
docTypes: ['componentGroup'],
|
||||
pathTemplate: '${area}/${moduleName}/${groupType}',
|
||||
outputPathTemplate: 'partials/${area}/${moduleName}/${groupType}.html'
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
// eslint-disable-next-line new-cap
|
||||
var encoder = new require('node-html-encoder').Encoder();
|
||||
|
||||
/**
|
||||
@@ -11,7 +12,7 @@ module.exports = function typeInlineTagDef(getTypeClass) {
|
||||
return {
|
||||
name: 'type',
|
||||
handler: function(doc, tagName, tagDescription) {
|
||||
return '<a href="" class="' + getTypeClass(tagDescription) + '">'+encoder.htmlEncode(tagDescription) + '</a>';
|
||||
return '<a href="" class="' + getTypeClass(tagDescription) + '">' + encoder.htmlEncode(tagDescription) + '</a>';
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
"use strict";
|
||||
|
||||
var _ = require('lodash');
|
||||
var path = require('canonical-path');
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @dgProcessor errorDocsProcessor
|
||||
@@ -18,7 +15,7 @@ module.exports = function errorDocsProcessor(errorNamespaceMap, getMinerrInfo) {
|
||||
docs.forEach(function(doc) {
|
||||
var parts, namespaceDoc;
|
||||
|
||||
if ( doc.docType === 'error' ) {
|
||||
if (doc.docType === 'error') {
|
||||
|
||||
// Parse out the error info from the id
|
||||
parts = doc.name.split(':');
|
||||
@@ -27,7 +24,7 @@ module.exports = function errorDocsProcessor(errorNamespaceMap, getMinerrInfo) {
|
||||
|
||||
// Get or create the relevant errorNamespace doc
|
||||
namespaceDoc = errorNamespaceMap.get(doc.namespace);
|
||||
if ( !namespaceDoc ) {
|
||||
if (!namespaceDoc) {
|
||||
namespaceDoc = {
|
||||
area: 'error',
|
||||
name: doc.namespace,
|
||||
@@ -49,4 +46,4 @@ module.exports = function errorDocsProcessor(errorNamespaceMap, getMinerrInfo) {
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
var _ = require('lodash');
|
||||
var path = require('canonical-path');
|
||||
|
||||
/**
|
||||
* @dgProcessor generateIndexPagesProcessor
|
||||
@@ -21,7 +20,7 @@ module.exports = function generateIndexPagesProcessor() {
|
||||
// Collect up all the areas in the docs
|
||||
var areas = {};
|
||||
docs.forEach(function(doc) {
|
||||
if ( doc.area ) {
|
||||
if (doc.area) {
|
||||
areas[doc.area] = doc.area;
|
||||
}
|
||||
});
|
||||
@@ -40,4 +39,4 @@ module.exports = function generateIndexPagesProcessor() {
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
var _ = require('lodash');
|
||||
var fs = require('fs');
|
||||
@@ -37,7 +37,7 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
|
||||
var KEYWORD_REGEX = /^((ng:|[\$_a-z])[\w\-_]+)/;
|
||||
|
||||
// Load up the keywords to ignore, if specified in the config
|
||||
if ( this.ignoreWordsFile ) {
|
||||
if (this.ignoreWordsFile) {
|
||||
|
||||
var ignoreWordsPath = path.resolve(readFilesProcessor.basePath, this.ignoreWordsFile);
|
||||
wordsToIgnore = fs.readFileSync(ignoreWordsPath, 'utf8').toString().split(/[,\s\n\r]+/gm);
|
||||
@@ -59,7 +59,7 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
|
||||
// without the ng to the title text, e.g. "controller".
|
||||
function extractTitleWords(title) {
|
||||
var match = /ng([A-Z]\w*)/.exec(title);
|
||||
if ( match ) {
|
||||
if (match) {
|
||||
title = title + ' ' + match[1].toLowerCase();
|
||||
}
|
||||
return title;
|
||||
@@ -68,11 +68,11 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
|
||||
function extractWords(text, words, keywordMap) {
|
||||
|
||||
var tokens = text.toLowerCase().split(/[\.\s,`'"#]+/mg);
|
||||
_.forEach(tokens, function(token){
|
||||
_.forEach(tokens, function(token) {
|
||||
var match = token.match(KEYWORD_REGEX);
|
||||
if (match){
|
||||
if (match) {
|
||||
var key = match[1];
|
||||
if ( !keywordMap[key]) {
|
||||
if (!keywordMap[key]) {
|
||||
keywordMap[key] = true;
|
||||
words.push(key);
|
||||
}
|
||||
@@ -96,11 +96,11 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
|
||||
// Search each top level property of the document for search terms
|
||||
_.forEach(doc, function(value, key) {
|
||||
|
||||
if ( _.isString(value) && !propertiesToIgnore[key] ) {
|
||||
if (_.isString(value) && !propertiesToIgnore[key]) {
|
||||
extractWords(value, words, keywordMap);
|
||||
}
|
||||
|
||||
if ( key === 'methods' || key === 'properties' || key === 'events' ) {
|
||||
if (key === 'methods' || key === 'properties' || key === 'events') {
|
||||
_.forEach(value, function(member) {
|
||||
extractWords(member.name, members, membersMap);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
var _ = require('lodash');
|
||||
var path = require('canonical-path');
|
||||
@@ -67,7 +67,7 @@ module.exports = function generatePagesDataProcessor(log) {
|
||||
})
|
||||
|
||||
.tap(function(docTypes) {
|
||||
if ( docTypes.input ) {
|
||||
if (docTypes.input) {
|
||||
docTypes.directive = docTypes.directive || [];
|
||||
// Combine input docTypes into directive docTypes
|
||||
docTypes.directive = docTypes.directive.concat(docTypes.input);
|
||||
@@ -79,7 +79,7 @@ module.exports = function generatePagesDataProcessor(log) {
|
||||
|
||||
sectionPages = _.sortBy(sectionPages, 'name');
|
||||
|
||||
if ( sectionPages.length > 0 ) {
|
||||
if (sectionPages.length > 0) {
|
||||
// Push a navItem for this section
|
||||
navItems.push({
|
||||
name: sectionName,
|
||||
@@ -158,7 +158,7 @@ module.exports = function generatePagesDataProcessor(log) {
|
||||
|
||||
// We are only interested in pages that are not landing pages
|
||||
var navPages = _.filter(pages, function(page) {
|
||||
return page.docType != 'componentGroup';
|
||||
return page.docType !== 'componentGroup';
|
||||
});
|
||||
|
||||
// Generate an object collection of pages that is grouped by area e.g.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
var _ = require('lodash');
|
||||
|
||||
@@ -31,4 +31,4 @@ module.exports = function generateVersionDocProcessor(gitData) {
|
||||
docs.push(versionDoc);
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
module.exports = function debugDeployment(getVersion) {
|
||||
return {
|
||||
name: 'debug',
|
||||
examples: {
|
||||
commonFiles: {
|
||||
scripts: [ '../../../angular.js' ]
|
||||
scripts: ['../../../angular.js']
|
||||
},
|
||||
dependencyPath: '../../../'
|
||||
},
|
||||
@@ -35,4 +35,4 @@ module.exports = function debugDeployment(getVersion) {
|
||||
'css/animations.css'
|
||||
]
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
module.exports = function defaultDeployment(getVersion) {
|
||||
return {
|
||||
name: 'default',
|
||||
examples: {
|
||||
commonFiles: {
|
||||
scripts: [ '../../../angular.min.js' ]
|
||||
scripts: ['../../../angular.min.js']
|
||||
},
|
||||
dependencyPath: '../../../'
|
||||
},
|
||||
@@ -35,4 +35,4 @@ module.exports = function defaultDeployment(getVersion) {
|
||||
'css/animations.css'
|
||||
]
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
module.exports = function jqueryDeployment(getVersion) {
|
||||
return {
|
||||
@@ -39,4 +39,4 @@ module.exports = function jqueryDeployment(getVersion) {
|
||||
'css/animations.css'
|
||||
]
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
var versionInfo = require('../../../../lib/versions/version-info');
|
||||
var cdnUrl = "//ajax.googleapis.com/ajax/libs/angularjs/" + versionInfo.cdnVersion;
|
||||
var cdnUrl = '//ajax.googleapis.com/ajax/libs/angularjs/' + versionInfo.cdnVersion;
|
||||
|
||||
module.exports = function productionDeployment(getVersion) {
|
||||
return {
|
||||
name: 'production',
|
||||
examples: {
|
||||
commonFiles: {
|
||||
scripts: [ cdnUrl + '/angular.min.js' ]
|
||||
scripts: [cdnUrl + '/angular.min.js']
|
||||
},
|
||||
dependencyPath: cdnUrl + '/'
|
||||
},
|
||||
@@ -38,4 +38,4 @@ module.exports = function productionDeployment(getVersion) {
|
||||
'css/animations.css'
|
||||
]
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"use strict";
|
||||
'use strict';
|
||||
var StringMap = require('stringmap');
|
||||
|
||||
/**
|
||||
@@ -7,4 +7,4 @@ var StringMap = require('stringmap');
|
||||
*/
|
||||
module.exports = function errorNamespaceMap() {
|
||||
return new StringMap();
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
var path = require('canonical-path');
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"use strict";
|
||||
'use strict';
|
||||
var path = require('canonical-path');
|
||||
|
||||
/**
|
||||
@@ -14,4 +14,4 @@ module.exports = function getVersion(readFilesProcessor) {
|
||||
packageFile = packageFile || 'bower.json';
|
||||
return require(path.join(sourceFolder,component,packageFile)).version;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
name: 'installation'
|
||||
};
|
||||
@@ -1,6 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
name: 'sortOrder',
|
||||
transforms: function(doc, tag, value) {
|
||||
return parseInt(value, 10);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
name: 'this'
|
||||
};
|
||||
@@ -1,7 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
name: 'step',
|
||||
transforms: function(doc, tag, value) {
|
||||
if ( doc.docType !== 'tutorial' ) {
|
||||
if (doc.docType !== 'tutorial') {
|
||||
throw new Error('Invalid tag, step. You should only use this tag on tutorial docs');
|
||||
}
|
||||
return parseInt(value,10);
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
{% extends "base.template.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<a href='https://github.com/{$ git.info.owner $}/{$ git.info.repo $}/tree/{$ git.version.isSnapshot and 'master' or git.version.raw $}/{$ doc.fileInfo.projectRelativePath $}#L{$ doc.startingLine $}' class='view-source pull-right btn btn-primary'>
|
||||
<i class="glyphicon glyphicon-zoom-in"> </i>View Source
|
||||
</a>
|
||||
|
||||
{% block header %}
|
||||
<header class="api-profile-header">
|
||||
<h1 class="api-profile-header-heading">{$ doc.name $}</h1>
|
||||
<ol class="api-profile-header-structure naked-list step-list">
|
||||
{% block related_components %}{% endblock %}
|
||||
<li>
|
||||
- {$ doc.docType $} in module <a href="{$ doc.moduleDoc.path $}">{$ doc.moduleDoc.name $}</a>
|
||||
</li>
|
||||
</ol>
|
||||
</header>
|
||||
{% endblock %}
|
||||
|
||||
{% block description %}
|
||||
<div class="api-profile-description">
|
||||
{$ doc.description | marked $}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% if doc.knownIssues %}
|
||||
<h2 id="known-issues">Known Issues</h2>
|
||||
{% for issue in doc.knownIssues -%}
|
||||
<div class="known-issue">
|
||||
{$ issue | marked $} {% if not loop.last %}<hr>{% endif %}
|
||||
</div>
|
||||
{% endfor -%}
|
||||
{% endif %}
|
||||
|
||||
{% if doc.deprecated %}
|
||||
<fieldset class="deprecated">
|
||||
<legend>Deprecated API</legend>
|
||||
{$ doc.deprecated| marked $}
|
||||
</fieldset>
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
{% block dependencies %}
|
||||
{%- if doc.requires %}
|
||||
<h2 id="dependencies">Dependencies</h2>
|
||||
<ul>
|
||||
{% for require in doc.requires %}<li>{$ require | link $}</li>{% endfor %}
|
||||
</ul>
|
||||
{% endif -%}
|
||||
{% endblock %}
|
||||
|
||||
{% block additional %}
|
||||
{% endblock %}
|
||||
|
||||
{% block examples %}
|
||||
{%- if doc.examples %}
|
||||
<h2 id="example">Example</h2>
|
||||
{%- for example in doc.examples -%}
|
||||
{$ example | marked $}
|
||||
{%- endfor -%}
|
||||
{% endif -%}
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,100 @@
|
||||
{% extends "base.template.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h1>
|
||||
{% if doc.title %}{$ doc.title | marked $}{% else %}{$ doc.name | code $}{% endif %}
|
||||
</h1>
|
||||
|
||||
<h2>Installation</h2>
|
||||
{% if doc.installation or doc.installation == '' %}
|
||||
{$ doc.installation | marked $}
|
||||
{% else %}
|
||||
|
||||
<p>First, get the file:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://developers.google.com/speed/libraries/devguide#angularjs">Google CDN</a> e.g.
|
||||
{% code %}"//ajax.googleapis.com/ajax/libs/angularjs/X.Y.Z/{$ doc.packageFile $}"{% endcode %}
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.npmjs.com/">NPM</a> e.g.
|
||||
{% code %}npm install {$ doc.packageName $}@X.Y.Z{% endcode %}
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://bower.io">Bower</a> e.g.
|
||||
{% code %}bower install {$ doc.packageName $}#X.Y.Z{% endcode %}
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://code.angularjs.org/">code.angularjs.org</a>
|
||||
(discouraged for production use) e.g.
|
||||
{% code %}"//code.angularjs.org/X.Y.Z/{$ doc.packageFile $}"{% endcode %}
|
||||
</li>
|
||||
</ul>
|
||||
<p>where X.Y.Z is the AngularJS version you are running.</p>
|
||||
|
||||
<p>Then, include {$ doc.packageFile | code $} in your HTML:</p>
|
||||
|
||||
{% code %}
|
||||
<script src="path/to/angular.js"></script>
|
||||
<script src="path/to/{$ doc.packageFile $}"></script>
|
||||
{% endcode %}
|
||||
|
||||
<p>Finally, load the module in your application by adding it as a dependent module:</p>
|
||||
{% code %}
|
||||
angular.module('app', ['{$ doc.name $}']);
|
||||
{% endcode %}
|
||||
|
||||
<p>With that you're ready to get started!</p>
|
||||
{% endif %}
|
||||
|
||||
{$ doc.description | marked $}
|
||||
|
||||
{% if doc.knownIssueDocs %}
|
||||
<div class="known-issues">
|
||||
<h2 id="known-issues">Known Issues</h2>
|
||||
<table class="definition-table">
|
||||
<tr><th>Name</th><th>Description</th></tr>
|
||||
{% for issueDoc in doc.knownIssueDocs -%}
|
||||
<tr>
|
||||
<td>{$ issueDoc.id | link(issueDoc.name, issueDoc) $}</td>
|
||||
<td>
|
||||
{% for issue in issueDoc.knownIssues -%}
|
||||
{$ issue | marked $} {% if not loop.last %}<hr>{% endif %}
|
||||
{% endfor -%}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor -%}
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if doc.componentGroups.length %}
|
||||
<div class="component-breakdown">
|
||||
<h2>Module Components</h2>
|
||||
{% for componentGroup in doc.componentGroups %}
|
||||
<div>
|
||||
<h3 class="component-heading" id="{$ componentGroup.groupType | dashCase $}">{$ componentGroup.groupType | title $}</h3>
|
||||
<table class="definition-table">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
{% for component in componentGroup.components %}
|
||||
<tr>
|
||||
<td>{$ component.id | link(component.name, component) $}</td>
|
||||
<td>{$ component.description | firstParagraph | marked $}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if doc.usage %}
|
||||
<h2>Usage</h2>
|
||||
{$ doc.usage | marked $}
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
@@ -228,10 +228,10 @@
|
||||
)
|
||||
</p>
|
||||
<p>
|
||||
Code licensed under the
|
||||
<a href="https://github.com/angular/angular.js/blob/master/LICENSE" target="_blank">The
|
||||
MIT License</a>. Documentation licensed under <a
|
||||
href="http://creativecommons.org/licenses/by/3.0/">CC BY 3.0</a>.
|
||||
Code licensed under
|
||||
<a href="https://github.com/angular/angular.js/blob/master/LICENSE" target="_blank">The MIT License</a>.
|
||||
Documentation licensed under
|
||||
<a href="http://creativecommons.org/licenses/by/3.0/" target="_blank">CC BY 3.0</a>.
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
// Meta data used by the AngularJS docs app
|
||||
angular.module('navData', [])
|
||||
.value('NG_NAVIGATION', {$ doc.areas | json $});
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
// Meta data used by the AngularJS docs app
|
||||
angular.module('pagesData', [])
|
||||
.value('NG_PAGES', {$ doc.pages | json $});
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
// Meta data used by the AngularJS docs app
|
||||
angular.module('versionsData', [])
|
||||
.value('NG_VERSION', {$ doc.currentVersion | json $})
|
||||
|
||||
@@ -8,6 +8,8 @@ Welcome to the AngularJS API docs page. These pages contain the AngularJS refere
|
||||
The documentation is organized into **{@link guide/module modules}** which contain various components of an AngularJS application.
|
||||
These components are {@link guide/directive directives}, {@link guide/services services}, {@link guide/filter filters}, {@link guide/providers providers}, {@link guide/templates templates}, global APIs, and testing mocks.
|
||||
|
||||
There is also a {@link guide/index guide} with articles on various topics, and a list of external resources.
|
||||
|
||||
<div class="alert alert-info">
|
||||
**Angular Prefixes `$` and `$$`**:
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
@ngdoc error
|
||||
@name $compile:baddir
|
||||
@fullName Invalid Directive Name
|
||||
@fullName Invalid Directive/Component Name
|
||||
@description
|
||||
|
||||
This error occurs when the name of a directive is not valid.
|
||||
This error occurs when the name of a directive or component is not valid.
|
||||
|
||||
Directives must start with a lowercase character and must not contain leading or trailing whitespaces.
|
||||
Directives and Components must start with a lowercase character and must not contain leading or trailing whitespaces.
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
@ngdoc error
|
||||
@name $compile:infchng
|
||||
@fullName Unstable `$onChanges` hooks
|
||||
@description
|
||||
|
||||
This error occurs when the application's model becomes unstable because some `$onChanges` hooks are causing updates which then trigger
|
||||
further calls to `$onChanges` that can never complete.
|
||||
Angular detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
|
||||
|
||||
For example, the situation can occur by setting up a `$onChanges()` hook which triggers an event on the component, which subsequently
|
||||
triggers the component's bound inputs to be updated:
|
||||
|
||||
```html
|
||||
<c1 prop="a" on-change="a = -a"></c1>
|
||||
```
|
||||
|
||||
```js
|
||||
function Controller1() {}
|
||||
Controller1.$onChanges = function() {
|
||||
this.onChange();
|
||||
};
|
||||
|
||||
mod.component('c1', {
|
||||
controller: Controller1,
|
||||
bindings: {'prop': '<', onChange: '&'}
|
||||
}
|
||||
```
|
||||
|
||||
The maximum number of allowed iterations of the `$onChanges` hooks is controlled via TTL setting which can be configured via
|
||||
{@link ng.$compileProvider#onChangesTtl `$compileProvider.onChangesTtl`}.
|
||||
@@ -0,0 +1,47 @@
|
||||
@ngdoc error
|
||||
@name $compile:reqslot
|
||||
@fullName Required transclusion slot
|
||||
@description
|
||||
|
||||
This error occurs when a directive or component try to transclude a slot that is not provided.
|
||||
|
||||
Transcluded elements must contain something. This error could happen when you try to transclude a self closing tag element.
|
||||
Also you can make a transclusion slot optional with a `?` prefix.
|
||||
|
||||
```js
|
||||
// In this example the <my-component> must have an <important-component> inside to transclude it.
|
||||
// If not, a reqslot error will be generated.
|
||||
|
||||
var componentConfig = {
|
||||
template: 'path/to/template.html',
|
||||
transclude: {
|
||||
importantSlot: 'importantComponent', // mandatory transclusion
|
||||
optionalSlot: '?optionalComponent', // optional transclusion
|
||||
}
|
||||
};
|
||||
|
||||
angular
|
||||
.module('doc')
|
||||
.component('myComponent', componentConfig)
|
||||
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- Will not work because <important-component> is missing -->
|
||||
<my-component>
|
||||
</my-component>
|
||||
|
||||
<my-component>
|
||||
<optional-component></optional-component>
|
||||
</my-component>
|
||||
|
||||
<!-- Will work -->
|
||||
<my-component>
|
||||
<important-component></important-component>
|
||||
</my-component>
|
||||
|
||||
<my-component>
|
||||
<optional-component></optional-component>
|
||||
<important-component></important-component>
|
||||
</my-component>
|
||||
```
|
||||
@@ -43,7 +43,7 @@ well. Consider the following template:
|
||||
|
||||
```
|
||||
<div class='container'>
|
||||
<div class='wrapper>
|
||||
<div class='wrapper'>
|
||||
...
|
||||
</div> <!-- wrapper -->
|
||||
</div> <!-- container -->
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
@ngdoc error
|
||||
@name $location:badpath
|
||||
@fullName Invalid Path
|
||||
@description
|
||||
|
||||
This error occurs when the path of a location contains invalid characters.
|
||||
The most common fault is when the path starts with double slashes (`//`) or backslashes ('\\').
|
||||
For example if the base path of an application is `https://a.b.c/` then the following path is
|
||||
invalid `https://a.b.c///d/e/f`.
|
||||
@@ -0,0 +1,12 @@
|
||||
@ngdoc error
|
||||
@name $parse:isecaf
|
||||
@fullName Assigning to Fields of Disallowed Context
|
||||
@description
|
||||
|
||||
Occurs when an expression attempts to assign a value on a field of any of the `Boolean`, `Number`,
|
||||
`String`, `Array`, `Object`, or `Function` constructors or the corresponding prototypes.
|
||||
|
||||
Angular bans the modification of these constructors or their prototypes from within expressions,
|
||||
since it is a known way to modify the behaviour of existing functions/operations.
|
||||
|
||||
To resolve this error, avoid assigning to fields of constructors or their prototypes in expressions.
|
||||
@@ -222,7 +222,7 @@ value of its attribute becomes true.
|
||||
angular.module('app', []).directive('setFocusIf', function() {
|
||||
return function link($scope, $element, $attr) {
|
||||
$scope.$watch($attr.setFocusIf, function(value) {
|
||||
if ( value ) { $element[0].focus(); }
|
||||
if (value) { $element[0].focus(); }
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
@fullName Model is not of type `number`
|
||||
@description
|
||||
|
||||
The number input directive `<input type="number">` requires the model to be a `number`.
|
||||
The `input[type="number"]` and `input[type="range"][ng-input-range]` directives require the model to
|
||||
be a `number`.
|
||||
|
||||
If the model is something else, this error will be thrown.
|
||||
|
||||
@@ -17,10 +18,10 @@ pipeline.
|
||||
## Example
|
||||
|
||||
In this example, our model stores the number as a string, so we provide the `stringToNumber`
|
||||
directive to convert it into the format the `input[number]` directive expects.
|
||||
directive to convert it into the format the `input[type="number"]` directive expects.
|
||||
|
||||
|
||||
<example module="numfmt-error-module">
|
||||
<example module="numfmt-error-module" name="number-format-error">
|
||||
<file name="index.html">
|
||||
<table>
|
||||
<tr ng-repeat="x in ['0', '1']">
|
||||
@@ -47,10 +48,10 @@ directive to convert it into the format the `input[number]` directive expects.
|
||||
return '' + value;
|
||||
});
|
||||
ngModel.$formatters.push(function(value) {
|
||||
return parseFloat(value, 10);
|
||||
return parseFloat(value);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
</file>
|
||||
</example>
|
||||
</example>
|
||||
|
||||
@@ -227,18 +227,18 @@ it('should show example', inject(
|
||||
},
|
||||
function($location) {
|
||||
// open http://example.com/base/index.html#!/a
|
||||
$location.absUrl() == 'http://example.com/base/index.html#!/a'
|
||||
$location.path() == '/a'
|
||||
$location.absUrl() === 'http://example.com/base/index.html#!/a'
|
||||
$location.path() === '/a'
|
||||
|
||||
$location.path('/foo')
|
||||
$location.absUrl() == 'http://example.com/base/index.html#!/foo'
|
||||
$location.absUrl() === 'http://example.com/base/index.html#!/foo'
|
||||
|
||||
$location.search() == {}
|
||||
$location.search() === {}
|
||||
$location.search({a: 'b', c: true});
|
||||
$location.absUrl() == 'http://example.com/base/index.html#!/foo?a=b&c'
|
||||
$location.absUrl() === 'http://example.com/base/index.html#!/foo?a=b&c'
|
||||
|
||||
$location.path('/new').search('x=y');
|
||||
$location.absUrl() == 'http://example.com/base/index.html#!/new?x=y'
|
||||
$location.absUrl() === 'http://example.com/base/index.html#!/new?x=y'
|
||||
}
|
||||
));
|
||||
```
|
||||
@@ -271,29 +271,29 @@ it('should show example', inject(
|
||||
// in browser with HTML5 history support:
|
||||
// open http://example.com/#!/a -> rewrite to http://example.com/a
|
||||
// (replacing the http://example.com/#!/a history record)
|
||||
$location.path() == '/a'
|
||||
$location.path() === '/a'
|
||||
|
||||
$location.path('/foo');
|
||||
$location.absUrl() == 'http://example.com/foo'
|
||||
$location.absUrl() === 'http://example.com/foo'
|
||||
|
||||
$location.search() == {}
|
||||
$location.search() === {}
|
||||
$location.search({a: 'b', c: true});
|
||||
$location.absUrl() == 'http://example.com/foo?a=b&c'
|
||||
$location.absUrl() === 'http://example.com/foo?a=b&c'
|
||||
|
||||
$location.path('/new').search('x=y');
|
||||
$location.url() == 'new?x=y'
|
||||
$location.absUrl() == 'http://example.com/new?x=y'
|
||||
$location.url() === 'new?x=y'
|
||||
$location.absUrl() === 'http://example.com/new?x=y'
|
||||
|
||||
// in browser without html5 history support:
|
||||
// open http://example.com/new?x=y -> redirect to http://example.com/#!/new?x=y
|
||||
// (again replacing the http://example.com/new?x=y history item)
|
||||
$location.path() == '/new'
|
||||
$location.search() == {x: 'y'}
|
||||
$location.path() === '/new'
|
||||
$location.search() === {x: 'y'}
|
||||
|
||||
$location.path('/foo/bar');
|
||||
$location.path() == '/foo/bar'
|
||||
$location.url() == '/foo/bar?x=y'
|
||||
$location.absUrl() == 'http://example.com/#!/foo/bar?x=y'
|
||||
$location.path() === '/foo/bar'
|
||||
$location.url() === '/foo/bar?x=y'
|
||||
$location.absUrl() === 'http://example.com/#!/foo/bar?x=y'
|
||||
}
|
||||
));
|
||||
```
|
||||
@@ -350,7 +350,7 @@ base and the path that should be handled by the application.
|
||||
### Base href constraints
|
||||
|
||||
The `$location` service is not able to function properly if the current URL is outside the URL given
|
||||
as the base href. This can have subtle confusing consequencies...
|
||||
as the base href. This can have subtle confusing consequences...
|
||||
|
||||
Consider a base href set as follows: `<base href="/base/">` (i.e. the application exists in the "folder"
|
||||
called `/base`). The URL `/base` is actually outside the application (it refers to the `base` file found
|
||||
@@ -409,11 +409,11 @@ In these examples we use `<base href="/base/index.html" />`. The inputs represen
|
||||
.constant('baseHref', '/base/index.html')
|
||||
.value('$sniffer', { history: true })
|
||||
|
||||
.controller("LocationController", function($scope, $location) {
|
||||
.controller('LocationController', function($scope, $location) {
|
||||
$scope.$location = {};
|
||||
angular.forEach("protocol host port path search hash".split(" "), function(method){
|
||||
$scope.$location[method] = function(){
|
||||
var result = $location[method].call($location);
|
||||
angular.forEach('protocol host port path search hash'.split(' '), function(method) {
|
||||
$scope.$location[method] = function() {
|
||||
var result = $location[method]();
|
||||
return angular.isObject(result) ? angular.toJson(result) : result;
|
||||
};
|
||||
});
|
||||
@@ -460,8 +460,8 @@ In these examples we use `<base href="/base/index.html" />`. The inputs represen
|
||||
.directive('ngAddressBar', function($browser, $timeout) {
|
||||
return {
|
||||
template: 'Address: <input id="addressBar" type="text" style="width: 400px" >',
|
||||
link: function(scope, element, attrs){
|
||||
var input = element.children("input"), delay;
|
||||
link: function(scope, element, attrs) {
|
||||
var input = element.children('input'), delay;
|
||||
|
||||
input.on('keypress keyup keydown', function(event) {
|
||||
delay = (!delay ? $timeout(fireUrlChange, 250) : null);
|
||||
@@ -488,7 +488,7 @@ In these examples we use `<base href="/base/index.html" />`. The inputs represen
|
||||
url = 'http://www.example.com/base/path?a=b#h';
|
||||
|
||||
|
||||
it("should show fake browser info on load", function(){
|
||||
it("should show fake browser info on load", function() {
|
||||
expect(addressBar.getAttribute('value')).toBe(url);
|
||||
|
||||
expect(element(by.binding('$location.protocol()')).getText()).toBe('http');
|
||||
@@ -500,7 +500,7 @@ In these examples we use `<base href="/base/index.html" />`. The inputs represen
|
||||
|
||||
});
|
||||
|
||||
it("should change $location accordingly", function(){
|
||||
it("should change $location accordingly", function() {
|
||||
var navigation = element.all(by.css("#navigation a"));
|
||||
|
||||
navigation.get(0).click();
|
||||
@@ -563,11 +563,11 @@ In these examples we use `<base href="/base/index.html" />`. The inputs represen
|
||||
$locationProvider.html5Mode(true).hashPrefix('!');
|
||||
})
|
||||
|
||||
.controller("LocationController", function($scope, $location) {
|
||||
.controller('LocationController', function($scope, $location) {
|
||||
$scope.$location = {};
|
||||
angular.forEach("protocol host port path search hash".split(" "), function(method){
|
||||
$scope.$location[method] = function(){
|
||||
var result = $location[method].call($location);
|
||||
angular.forEach('protocol host port path search hash'.split(' '), function(method) {
|
||||
$scope.$location[method] = function() {
|
||||
var result = $location[method]();
|
||||
return angular.isObject(result) ? angular.toJson(result) : result;
|
||||
};
|
||||
});
|
||||
@@ -614,8 +614,8 @@ In these examples we use `<base href="/base/index.html" />`. The inputs represen
|
||||
.directive('ngAddressBar', function($browser, $timeout) {
|
||||
return {
|
||||
template: 'Address: <input id="addressBar" type="text" style="width: 400px" >',
|
||||
link: function(scope, element, attrs){
|
||||
var input = element.children("input"), delay;
|
||||
link: function(scope, element, attrs) {
|
||||
var input = element.children('input'), delay;
|
||||
|
||||
input.on('keypress keyup keydown', function(event) {
|
||||
delay = (!delay ? $timeout(fireUrlChange, 250) : null);
|
||||
@@ -641,7 +641,7 @@ In these examples we use `<base href="/base/index.html" />`. The inputs represen
|
||||
var addressBar = element(by.css("#addressBar")),
|
||||
url = 'http://www.example.com/base/index.html#!/path?a=b#h';
|
||||
|
||||
it("should show fake browser info on load", function(){
|
||||
it("should show fake browser info on load", function() {
|
||||
expect(addressBar.getAttribute('value')).toBe(url);
|
||||
|
||||
expect(element(by.binding('$location.protocol()')).getText()).toBe('http');
|
||||
@@ -653,7 +653,7 @@ In these examples we use `<base href="/base/index.html" />`. The inputs represen
|
||||
|
||||
});
|
||||
|
||||
it("should change $location accordingly", function(){
|
||||
it("should change $location accordingly", function() {
|
||||
var navigation = element.all(by.css("#navigation a"));
|
||||
|
||||
navigation.get(0).click();
|
||||
@@ -735,7 +735,7 @@ ng.$rootScope.Scope scope} life-cycle. This means it's your responsibility to ca
|
||||
```js
|
||||
describe('serviceUnderTest', function() {
|
||||
beforeEach(module(function($provide) {
|
||||
$provide.factory('serviceUnderTest', function($location){
|
||||
$provide.factory('serviceUnderTest', function($location) {
|
||||
// whatever it does...
|
||||
});
|
||||
});
|
||||
@@ -834,7 +834,7 @@ then uses the information it obtains to compose hashbang URLs (such as
|
||||
Because `$location` uses getters/setters, you can use `ng-model-options="{ getterSetter: true }"`
|
||||
to bind it to `ngModel`:
|
||||
|
||||
<example module="locationExample">
|
||||
<example module="locationExample" name="location-two-way-binding">
|
||||
<file name="index.html">
|
||||
<div ng-controller="LocationController">
|
||||
<input type="text" ng-model="locationPath" ng-model-options="{ getterSetter: true }" />
|
||||
@@ -843,7 +843,7 @@ to bind it to `ngModel`:
|
||||
<file name="script.js">
|
||||
angular.module('locationExample', [])
|
||||
.controller('LocationController', ['$scope', '$location', function($scope, $location) {
|
||||
$scope.locationPath = function (newLocation) {
|
||||
$scope.locationPath = function(newLocation) {
|
||||
return $location.path(newLocation);
|
||||
};
|
||||
}]);
|
||||
|
||||
@@ -10,7 +10,7 @@ The goal of ngAria is to improve Angular's default accessibility by enabling com
|
||||
[ARIA](http://www.w3.org/TR/wai-aria/) attributes that convey state or semantic information for
|
||||
assistive technologies used by persons with disabilities.
|
||||
|
||||
##Including ngAria
|
||||
## Including ngAria
|
||||
|
||||
Using {@link ngAria ngAria} is as simple as requiring the ngAria module in your application. ngAria hooks into
|
||||
standard AngularJS directives and quietly injects accessibility support into your application
|
||||
@@ -20,7 +20,7 @@ at runtime.
|
||||
angular.module('myApp', ['ngAria'])...
|
||||
```
|
||||
|
||||
###Using ngAria
|
||||
### Using ngAria
|
||||
Most of what ngAria does is only visible "under the hood". To see the module in action, once you've
|
||||
added it as a dependency, you can test a few things:
|
||||
* Using your favorite element inspector, look for attributes added by ngAria in your own code.
|
||||
@@ -28,12 +28,13 @@ added it as a dependency, you can test a few things:
|
||||
* Fire up a screen reader such as VoiceOver or NVDA to check for ARIA support.
|
||||
[Helpful screen reader tips.](http://webaim.org/articles/screenreader_testing/)
|
||||
|
||||
##Supported directives
|
||||
## Supported directives
|
||||
Currently, ngAria interfaces with the following directives:
|
||||
|
||||
* {@link guide/accessibility#ngmodel ngModel}
|
||||
* {@link guide/accessibility#ngdisabled ngDisabled}
|
||||
* {@link guide/accessibility#ngrequired ngRequired}
|
||||
* {@link guide/accessibility#ngreadonly ngReadonly}
|
||||
* {@link guide/accessibility#ngvaluechecked ngChecked}
|
||||
* {@link guide/accessibility#ngvaluechecked ngValue}
|
||||
* {@link guide/accessibility#ngshow ngShow}
|
||||
@@ -57,12 +58,62 @@ attributes (if they have not been explicitly specified by the developer):
|
||||
* aria-valuenow
|
||||
* aria-invalid
|
||||
* aria-required
|
||||
* aria-readonly
|
||||
|
||||
###Example
|
||||
### Example
|
||||
|
||||
<example module="ngAria_ngModelExample" deps="angular-aria.js">
|
||||
<file name="index.html">
|
||||
<style>
|
||||
<example module="ngAria_ngModelExample" deps="angular-aria.js" name="accessibility-ng-model">
|
||||
<file name="index.html">
|
||||
<form ng-controller="formsController">
|
||||
<some-checkbox role="checkbox" ng-model="checked" ng-class="{active: checked}"
|
||||
ng-disabled="isDisabled" ng-click="toggleCheckbox()"
|
||||
aria-label="Custom Checkbox" show-attrs>
|
||||
<span class="icon" aria-hidden="true"></span>
|
||||
Custom Checkbox
|
||||
</some-checkbox>
|
||||
</form>
|
||||
</file>
|
||||
<file name="script.js">
|
||||
angular.module('ngAria_ngModelExample', ['ngAria'])
|
||||
.controller('formsController', function($scope) {
|
||||
$scope.checked = false;
|
||||
$scope.toggleCheckbox = function() {
|
||||
$scope.checked = !$scope.checked;
|
||||
};
|
||||
})
|
||||
.directive('someCheckbox', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function($scope, $el, $attrs) {
|
||||
$el.on('keypress', function(event) {
|
||||
event.preventDefault();
|
||||
if (event.keyCode === 32 || event.keyCode === 13) {
|
||||
$scope.toggleCheckbox();
|
||||
$scope.$apply();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
})
|
||||
.directive('showAttrs', function() {
|
||||
return function($scope, $el, $attrs) {
|
||||
var pre = document.createElement('pre');
|
||||
$el.after(pre);
|
||||
$scope.$watch(function() {
|
||||
var $attrs = {};
|
||||
Array.prototype.slice.call($el[0].attributes, 0).forEach(function(item) {
|
||||
if (item.name !== 'show-$attrs') {
|
||||
$attrs[item.name] = item.value;
|
||||
}
|
||||
});
|
||||
return $attrs;
|
||||
}, function(newAttrs, oldAttrs) {
|
||||
pre.textContent = JSON.stringify(newAttrs, null, 2);
|
||||
}, true);
|
||||
};
|
||||
});
|
||||
</file>
|
||||
<file name="style.css">
|
||||
[role=checkbox] {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
@@ -81,58 +132,7 @@ attributes (if they have not been explicitly specified by the developer):
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
</style>
|
||||
<div>
|
||||
<form ng-controller="formsController">
|
||||
<some-checkbox role="checkbox" ng-model="checked" ng-class="{active: checked}"
|
||||
ng-disabled="isDisabled" ng-click="toggleCheckbox()"
|
||||
aria-label="Custom Checkbox" show-attrs>
|
||||
<span class="icon" aria-hidden="true"></span>
|
||||
Custom Checkbox
|
||||
</some-checkbox>
|
||||
</form>
|
||||
</div>
|
||||
<script>
|
||||
var app = angular.module('ngAria_ngModelExample', ['ngAria'])
|
||||
.controller('formsController', function($scope){
|
||||
$scope.checked = false;
|
||||
$scope.toggleCheckbox = function(){
|
||||
$scope.checked = !$scope.checked;
|
||||
}
|
||||
})
|
||||
.directive('someCheckbox', function(){
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function($scope, $el, $attrs) {
|
||||
$el.on('keypress', function(event){
|
||||
event.preventDefault();
|
||||
if(event.keyCode === 32 || event.keyCode === 13){
|
||||
$scope.toggleCheckbox();
|
||||
$scope.$apply();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.directive('showAttrs', function() {
|
||||
return function($scope, $el, $attrs) {
|
||||
var pre = document.createElement('pre');
|
||||
$el.after(pre);
|
||||
$scope.$watch(function() {
|
||||
var $attrs = {};
|
||||
Array.prototype.slice.call($el[0].attributes, 0).forEach(function(item) {
|
||||
if (item.name !== 'show-$attrs') {
|
||||
$attrs[item.name] = item.value;
|
||||
}
|
||||
});
|
||||
return $attrs;
|
||||
}, function(newAttrs, oldAttrs) {
|
||||
pre.textContent = JSON.stringify(newAttrs, null, 2);
|
||||
}, true);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</file>
|
||||
</file>
|
||||
</example>
|
||||
|
||||
ngAria will also add `tabIndex`, ensuring custom elements with these roles will be reachable from
|
||||
@@ -147,7 +147,7 @@ To ease the transition between native inputs and custom controls, ngAria now sup
|
||||
The original directives were created for native inputs only, so ngAria extends
|
||||
support to custom elements by managing `aria-checked` for accessibility.
|
||||
|
||||
###Example
|
||||
### Example
|
||||
|
||||
```html
|
||||
<custom-checkbox ng-checked="val"></custom-checkbox>
|
||||
@@ -169,7 +169,7 @@ using ngAria with {@link ng.ngDisabled ngDisabled} will also
|
||||
add `aria-disabled`. This tells assistive technologies when a non-native input is disabled, helping
|
||||
custom controls to be more accessible.
|
||||
|
||||
###Example
|
||||
### Example
|
||||
|
||||
```html
|
||||
<md-checkbox ng-disabled="disabled"></md-checkbox>
|
||||
@@ -181,8 +181,10 @@ Becomes:
|
||||
<md-checkbox disabled aria-disabled="true"></md-checkbox>
|
||||
```
|
||||
|
||||
>You can check whether a control is legitimately disabled for a screen reader by visiting
|
||||
<div class="alert alert-info">
|
||||
You can check whether a control is legitimately disabled for a screen reader by visiting
|
||||
[chrome://accessibility](chrome://accessibility) and inspecting [the accessibility tree](http://www.paciellogroup.com/blog/2015/01/the-browser-accessibility-tree/).
|
||||
</div>
|
||||
|
||||
<h2 id="ngrequired">ngRequired</h2>
|
||||
|
||||
@@ -191,7 +193,7 @@ The boolean `required` attribute is only valid for native form controls such as
|
||||
as required, using ngAria with {@link ng.ngRequired ngRequired} will also add
|
||||
`aria-required`. This tells accessibility APIs when a custom control is required.
|
||||
|
||||
###Example
|
||||
### Example
|
||||
|
||||
```html
|
||||
<md-checkbox ng-required="val"></md-checkbox>
|
||||
@@ -203,9 +205,28 @@ Becomes:
|
||||
<md-checkbox ng-required="val" aria-required="true"></md-checkbox>
|
||||
```
|
||||
|
||||
<h2 id="ngreadonly">ngReadonly</h2>
|
||||
|
||||
The boolean `readonly` attribute is only valid for native form controls such as `input` and
|
||||
`textarea`. To properly indicate custom element directives such as `<md-checkbox>` or `<custom-input>`
|
||||
as required, using ngAria with {@link ng.ngReadonly ngReadonly} will also add
|
||||
`aria-readonly`. This tells accessibility APIs when a custom control is read-only.
|
||||
|
||||
### Example
|
||||
|
||||
```html
|
||||
<md-checkbox ng-readonly="val"></md-checkbox>
|
||||
```
|
||||
|
||||
Becomes:
|
||||
|
||||
```html
|
||||
<md-checkbox ng-readonly="val" aria-readonly="true"></md-checkbox>
|
||||
```
|
||||
|
||||
<h2 id="ngshow">ngShow</h2>
|
||||
|
||||
>The {@link ng.ngShow ngShow} directive shows or hides the
|
||||
The {@link ng.ngShow ngShow} directive shows or hides the
|
||||
given HTML element based on the expression provided to the `ngShow` attribute. The element is
|
||||
shown or hidden by removing or adding the `.ng-hide` CSS class onto the element.
|
||||
|
||||
@@ -222,7 +243,7 @@ screen reader users won't accidentally focus on "mystery elements". Managing tab
|
||||
child control can be complex and affect performance, so it’s best to just stick with the default
|
||||
`display: none` CSS. See the [fourth rule of ARIA use](http://www.w3.org/TR/aria-in-html/#fourth-rule-of-aria-use).
|
||||
|
||||
###Example
|
||||
### Example
|
||||
```css
|
||||
.ng-hide {
|
||||
display: block;
|
||||
@@ -242,7 +263,7 @@ Becomes:
|
||||
|
||||
<h2 id="nghide">ngHide</h2>
|
||||
|
||||
>The {@link ng.ngHide ngHide} directive shows or hides the
|
||||
The {@link ng.ngHide ngHide} directive shows or hides the
|
||||
given HTML element based on the expression provided to the `ngHide` attribute. The element is
|
||||
shown or hidden by removing or adding the `.ng-hide` CSS class onto the element.
|
||||
|
||||
@@ -283,11 +304,11 @@ Becomes:
|
||||
|
||||
<h2 id="ngmessages">ngMessages</h2>
|
||||
|
||||
The new ngMessages module makes it easy to display form validation or other messages with priority
|
||||
The ngMessages module makes it easy to display form validation or other messages with priority
|
||||
sequencing and animation. To expose these visual messages to screen readers,
|
||||
ngAria injects `aria-live="assertive"`, causing them to be read aloud any time a message is shown,
|
||||
regardless of the user's focus location.
|
||||
###Example
|
||||
### Example
|
||||
|
||||
```html
|
||||
<div ng-messages="myForm.myName.$error">
|
||||
@@ -305,12 +326,12 @@ Becomes:
|
||||
</div>
|
||||
```
|
||||
|
||||
##Disabling attributes
|
||||
## Disabling attributes
|
||||
The attribute magic of ngAria may not work for every scenario. To disable individual attributes,
|
||||
you can use the {@link ngAria.$ariaProvider#config config} method. Just keep in mind this will
|
||||
tell ngAria to ignore the attribute globally.
|
||||
|
||||
<example module="ngAria_ngClickExample" deps="angular-aria.js">
|
||||
<example module="ngAria_ngClickExample" deps="angular-aria.js" name="accessibility-ng-click">
|
||||
<file name="index.html">
|
||||
<div ng-click="someFunction" show-attrs>
|
||||
<div> with ng-click and bindRoleForClick, tabindex set to false
|
||||
@@ -343,7 +364,7 @@ tell ngAria to ignore the attribute globally.
|
||||
</file>
|
||||
</example>
|
||||
|
||||
##Common Accessibility Patterns
|
||||
## Common Accessibility Patterns
|
||||
|
||||
Accessibility best practices that apply to web apps in general also apply to Angular.
|
||||
|
||||
|
||||
@@ -12,35 +12,41 @@ triggered, will attempt to perform a CSS Transition, CSS Keyframe Animation or a
|
||||
placed on the given directive). Animations can be placed using vanilla CSS by following the naming conventions set in place by AngularJS
|
||||
or with JavaScript code when it's defined as a factory.
|
||||
|
||||
<div class="alert alert-info">
|
||||
Note that we have used non-prefixed CSS transition properties in our examples as the major browsers now support non-prefixed
|
||||
properties. If you intend to support older browsers or certain mobile browsers then you will need to include prefixed
|
||||
versions of the transition properties. Take a look at http://caniuse.com/#feat=css-transitions for what browsers require prefixes,
|
||||
and https://github.com/postcss/autoprefixer for a tool that can automatically generate the prefixes for you.
|
||||
</div>
|
||||
|
||||
Animations are not available unless you include the {@link ngAnimate `ngAnimate` module} as a dependency within your application.
|
||||
|
||||
Below is a quick example of animations being enabled for `ngShow` and `ngHide`:
|
||||
|
||||
<example module="ngAnimate" deps="angular-animate.js" animations="true">
|
||||
<example module="ngAnimate" deps="angular-animate.js" animations="true" name="animate-ng-show">
|
||||
<file name="index.html">
|
||||
<div ng-init="checked=true">
|
||||
<div ng-init="checked = true">
|
||||
<label>
|
||||
<input type="checkbox" ng-model="checked" style="float:left; margin-right:10px;"> Is Visible...
|
||||
<input type="checkbox" ng-model="checked" />
|
||||
Is visible
|
||||
</label>
|
||||
<div class="check-element sample-show-hide" ng-show="checked" style="clear:both;">
|
||||
Visible...
|
||||
<div class="content-area sample-show-hide" ng-show="checked">
|
||||
Content...
|
||||
</div>
|
||||
</div>
|
||||
</file>
|
||||
<file name="animations.css">
|
||||
.sample-show-hide {
|
||||
padding:10px;
|
||||
border:1px solid black;
|
||||
background:white;
|
||||
.content-area {
|
||||
border: 1px solid black;
|
||||
margin-top: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.sample-show-hide {
|
||||
-webkit-transition:all linear 0.5s;
|
||||
transition:all linear 0.5s;
|
||||
transition: all linear 0.5s;
|
||||
}
|
||||
|
||||
.sample-show-hide.ng-hide {
|
||||
opacity:0;
|
||||
opacity: 0;
|
||||
}
|
||||
</file>
|
||||
</example>
|
||||
@@ -80,11 +86,8 @@ occur when ngRepeat triggers them:
|
||||
class
|
||||
*/
|
||||
.repeated-item.ng-enter, .repeated-item.ng-move {
|
||||
-webkit-transition:0.5s linear all;
|
||||
-moz-transition:0.5s linear all;
|
||||
-o-transition:0.5s linear all;
|
||||
transition:0.5s linear all;
|
||||
opacity:0;
|
||||
transition: all 0.5s linear;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -95,7 +98,7 @@ occur when ngRepeat triggers them:
|
||||
*/
|
||||
.repeated-item.ng-enter.ng-enter-active,
|
||||
.repeated-item.ng-move.ng-move-active {
|
||||
opacity:1;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -104,10 +107,7 @@ occur when ngRepeat triggers them:
|
||||
that has the .repeated-item class
|
||||
*/
|
||||
.repeated-item.ng-leave {
|
||||
-webkit-animation:0.5s my_animation;
|
||||
-moz-animation:0.5s my_animation;
|
||||
-o-animation:0.5s my_animation;
|
||||
animation:0.5s my_animation;
|
||||
animation: 0.5s my_animation;
|
||||
}
|
||||
|
||||
@keyframes my_animation {
|
||||
@@ -115,24 +115,6 @@ occur when ngRepeat triggers them:
|
||||
to { opacity:0; }
|
||||
}
|
||||
|
||||
/*
|
||||
Unfortunately each browser vendor requires
|
||||
its own definition of keyframe animation code...
|
||||
*/
|
||||
@-webkit-keyframes my_animation {
|
||||
from { opacity:1; }
|
||||
to { opacity:0; }
|
||||
}
|
||||
|
||||
@-moz-keyframes my_animation {
|
||||
from { opacity:1; }
|
||||
to { opacity:0; }
|
||||
}
|
||||
|
||||
@-o-keyframes my_animation {
|
||||
from { opacity:1; }
|
||||
to { opacity:0; }
|
||||
}
|
||||
```
|
||||
|
||||
The same approach to animation can be used using JavaScript code (**jQuery is used within to perform animations**):
|
||||
@@ -206,7 +188,7 @@ able to capture class changes if an **expression** or the **ng-class** directive
|
||||
|
||||
The example below shows how to perform animations during class changes:
|
||||
|
||||
<example module="ngAnimate" deps="angular-animate.js" animations="true">
|
||||
<example module="ngAnimate" deps="angular-animate.js" animations="true" name="animate-css-class">
|
||||
<file name="index.html">
|
||||
<p>
|
||||
<input type="button" value="set" ng-click="myCssVar='css-class'">
|
||||
@@ -217,10 +199,7 @@ The example below shows how to perform animations during class changes:
|
||||
</file>
|
||||
<file name="style.css">
|
||||
.css-class-add, .css-class-remove {
|
||||
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
||||
-moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
||||
-o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
||||
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
||||
transition: all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
||||
}
|
||||
|
||||
.css-class,
|
||||
@@ -231,7 +210,7 @@ The example below shows how to perform animations during class changes:
|
||||
|
||||
.css-class-remove.css-class-remove-active {
|
||||
font-size:1.0em;
|
||||
color:black;
|
||||
color: black;
|
||||
}
|
||||
</file>
|
||||
</example>
|
||||
@@ -317,8 +296,8 @@ app.config(function($animateProvider) {
|
||||
```css
|
||||
/* prefixed with animate- */
|
||||
.animate-fade-add.animate-fade-add-active {
|
||||
transition:1s linear all;
|
||||
opacity:0;
|
||||
transition: all 1s linear;
|
||||
opacity: 0;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -334,8 +313,8 @@ This function can be used to enable / disable animations in two different ways:
|
||||
With a single `boolean` argument, it enables / disables animations globally: `$animate.enabled(false)`
|
||||
disables all animations in your app.
|
||||
|
||||
When the second argument is a native DOM or jQuery element, the function enables / disables
|
||||
animations on this element *and all its children*: `$animate.enabled(false, myElement)`. This is the
|
||||
When the first argument is a native DOM or jqLite/jQuery element, the function enables / disables
|
||||
animations on this element *and all its children*: `$animate.enabled(myElement, false)`. This is the
|
||||
most flexible way to change the animation state. For example, even if you have used it to disable
|
||||
animations on a parent element, you can still re-enable it for a child element. And compared to the
|
||||
`classNameFilter`, you can change the animation status at runtime instead of during the config phase.
|
||||
@@ -368,6 +347,7 @@ By setting `transition: 0s`, ngAnimate will ignore the existing transition style
|
||||
animations will still execute, though). This can be used to prevent {@link guide/animations#preventing-collisions-with-existing-animations-and-third-party-libraries
|
||||
issues with existing animations interfering with ngAnimate}.
|
||||
|
||||
|
||||
## Preventing flicker before an animation starts
|
||||
|
||||
When nesting elements with structural animations such as `ngIf` into elements that have class-based
|
||||
@@ -430,18 +410,37 @@ You can prevent this unwanted behavior by adding CSS to the `.ng-animate` class
|
||||
for the whole duration of an animation. Simply overwrite the transition / animation duration. In the
|
||||
case of the spinner, this would be:
|
||||
|
||||
```css
|
||||
.spinner.ng-animate {
|
||||
transition: 0s none;
|
||||
animation: 0s none;
|
||||
}
|
||||
```
|
||||
|
||||
If you do have CSS transitions / animations defined for the animation events, make sure they have higher priority
|
||||
than any styles that are independent from ngAnimate.
|
||||
|
||||
You can also use one of the two other {@link guide/animations#how-to-selectively-enable-disable-and-skip-animations strategies to disable animations}.
|
||||
|
||||
|
||||
### Enable animations for elements outside of the Angular application DOM tree: {@link ng.$animate#pin $animate.pin()}
|
||||
|
||||
Before animating, `ngAnimate` checks to see if the element being animated is inside the application DOM tree,
|
||||
and if it is not, no animation is run. Usually, this is not a problem as most apps use the `ngApp`
|
||||
attribute / bootstrap the app on the `html` or `body` element.
|
||||
|
||||
Problems arise when the application is bootstrapped on a different element, and animations are
|
||||
attempted on elements that are outside the application tree, e.g. when libraries append popup and modal
|
||||
elements as the last child in the body tag.
|
||||
|
||||
You can use {@link ng.$animate#pin `$animate.pin(elementToAnimate, parentHost)`} to specify that an
|
||||
element belongs to your application. Simply call it before the element is added to the DOM / before
|
||||
the animation starts, with the element you want to animate, and the element which should be its
|
||||
assumed parent.
|
||||
|
||||
|
||||
## More about animations
|
||||
|
||||
For a full breakdown of each method available on `$animate`, see the {@link ng.$animate API documentation}.
|
||||
|
||||
To see a complete demo, see the {@link tutorial/step_12 animation step within the AngularJS phonecat tutorial}.
|
||||
To see a complete demo, see the {@link tutorial/step_14 animation step within the AngularJS phonecat tutorial}.
|
||||
|
||||
@@ -77,7 +77,7 @@ to write directives.
|
||||
Here is a directive which makes any element draggable. Notice the `draggable` attribute on the
|
||||
`<span>` element.
|
||||
|
||||
<example module="drag">
|
||||
<example module="drag" name="draggable">
|
||||
<file name="script.js">
|
||||
angular.module('drag', []).
|
||||
directive('draggable', function($document) {
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
|
||||
# Component Router
|
||||
|
||||
<div class="alert alert-info">
|
||||
**Deprecation Notice:** In an effort to keep synchronized with router changes in Angular 2, this implementation of the Component Router (ngComponentRouter module) has been deprecated and will not receive further updates.
|
||||
We are investigating backporting the Angular 2 Router to Angular 1, but alternatively, use the {@link ngRoute} module or community developed projects (e.g. [ui-router](https://github.com/angular-ui/ui-router)).
|
||||
</div>
|
||||
|
||||
This guide describes the new Component Router for AngularJS 1.5.
|
||||
|
||||
<div class="alert alert-info">
|
||||
@@ -33,7 +38,7 @@ Here is a table of the main concepts used in the Component Router.
|
||||
|
||||
## Component-based Applications
|
||||
|
||||
It recommended to develop AngularJS applications as a hierarchy of Components. Each Component
|
||||
It is recommended to develop AngularJS applications as a hierarchy of Components. Each Component
|
||||
is an isolated part of the application, which is responsible for its own user interface and has
|
||||
a well defined programmatic interface to the Component that contains it. Take a look at the
|
||||
{@link guide/component component guide} for more information.
|
||||
@@ -105,7 +110,7 @@ Here we have specified that the **Root Component** is the component directive wi
|
||||
Remember to instantiate this **Root Component** in our `index.html` file.
|
||||
|
||||
```html
|
||||
<my-app><my-app>
|
||||
<my-app></my-app>
|
||||
```
|
||||
|
||||
## Route Matching
|
||||
@@ -124,9 +129,9 @@ This process continues until we run out of **Routing Components** or consume the
|
||||
|
||||

|
||||
|
||||
In the previous diagram can see that the URL `/heros/2` has been matched against the `App`, `Heroes` and
|
||||
In the previous diagram, we can see that the URL `/heros/4` has been matched against the `App`, `Heroes` and
|
||||
`HeroDetail` **Routing Components**. The **Routers** for each of the **Routing Components** consumed a part
|
||||
of the URL: "/", "/heroes" and "/2" respectively.
|
||||
of the URL: "/", "/heroes" and "/4" respectively.
|
||||
|
||||
The result is that we end up with a hierarchy of **Routing Components** rendered in **Outlets**, via the
|
||||
{@link ngOutlet} directive, in each **Routing Component's** template, as you can see in the following diagram.
|
||||
@@ -225,8 +230,8 @@ You can see the complete application running below.
|
||||
|
||||
this.getHero = function(id) {
|
||||
return heroesPromise.then(function(heroes) {
|
||||
for(var i=0; i<heroes.length; i++) {
|
||||
if ( heroes[i].id == id) return heroes[i];
|
||||
for (var i = 0; i < heroes.length; i++) {
|
||||
if (heroes[i].id === id) return heroes[i];
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -245,7 +250,7 @@ You can see the complete application running below.
|
||||
};
|
||||
|
||||
this.isSelected = function(hero) {
|
||||
return (hero.id == selectedId);
|
||||
return (hero.id === selectedId);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -316,8 +321,8 @@ You can see the complete application running below.
|
||||
|
||||
this.getCrisis = function(id) {
|
||||
return crisesPromise.then(function(crises) {
|
||||
for(var i=0; i<crises.length; i++) {
|
||||
if ( crises[i].id == id) return crises[i];
|
||||
for (var i = 0; i < crises.length; i++) {
|
||||
if (crises[i].id === id) return crises[i];
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -337,7 +342,7 @@ You can see the complete application running below.
|
||||
};
|
||||
|
||||
this.isSelected = function(crisis) {
|
||||
return (crisis.id == selectedId);
|
||||
return (crisis.id === selectedId);
|
||||
};
|
||||
|
||||
this.onSelect = function(crisis) {
|
||||
@@ -462,13 +467,13 @@ to display list and detail views of Heroes and Crises.
|
||||
|
||||
## Install the libraries
|
||||
|
||||
It is simplest to use npm to install the **Component Router** module. For this guide we will also install
|
||||
It is easier to use npm to install the **Component Router** module. For this guide we will also install
|
||||
AngularJS itself via npm:
|
||||
|
||||
```bash
|
||||
npm init
|
||||
npm install@1.5.x angular --save
|
||||
npm install @angular/router --save
|
||||
npm install angular@1.5.x --save
|
||||
npm install @angular/router@0.2.0 --save
|
||||
```
|
||||
|
||||
|
||||
@@ -482,10 +487,18 @@ Just like any Angular application, we load the JavaScript files into our `index.
|
||||
<script src="/app/app.js"></script>
|
||||
```
|
||||
|
||||
You also need to include ES6 shims for browsers that do not support ES6 code (Internet Explorer,
|
||||
iOs < 8, Android < 5.0, Windows Mobile < 10):
|
||||
```html
|
||||
<!-- IE required polyfills, in this exact order -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.33.3/es6-shim.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.20/system-polyfills.js"></script>
|
||||
<script src="https://npmcdn.com/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
|
||||
```
|
||||
|
||||
## Create the `app` module
|
||||
|
||||
In the app.js file, create the main application module `app` which depends upon the `ngComponentRouter`
|
||||
In the app.js file, create the main application module `app` which depends on the `ngComponentRouter`
|
||||
module, which is provided by the **Component Router** script.
|
||||
|
||||
```js
|
||||
@@ -494,10 +507,10 @@ angular.module('app', ['ngComponentRouter'])
|
||||
|
||||
We must choose what **Location Mode** the **Router** should use. We are going to use HTML5 mode locations,
|
||||
so that we will not have hash-based paths. We must rely on the browser to provide `pushState` support,
|
||||
which is true of most modern browsers. See {@link $locationProvider#html5Mode} for more information.
|
||||
which is true for most modern browsers. See {@link $locationProvider#html5Mode} for more information.
|
||||
|
||||
<div class="alert alert-info">
|
||||
Using HTML5 mode means that we can have clean URLs for our application routes but it does require that our
|
||||
Using HTML5 mode means that we can have clean URLs for our application routes. However, HTML5 mode does require that our
|
||||
web server, which hosts the application, understands that it must respond with the index.html file for
|
||||
requests to URLs that represent all our application routes. We are going to use the `lite-server` web server
|
||||
to do this for us.
|
||||
@@ -550,7 +563,7 @@ Bootstrap the Angular application and add the top level App Component.
|
||||
|
||||
# Implementing the AppComponent
|
||||
|
||||
In the previous section we created a single top level **App Component**. Let's now create some more
|
||||
In the previous section we have created a single top level **App Component**. Let's now create some more
|
||||
**Routing Components** and wire up **Route Config** for those. We start with a Heroes Feature, which
|
||||
will display one of two views.
|
||||
|
||||
@@ -590,7 +603,7 @@ of this view will be rendered.
|
||||
### ngLink
|
||||
|
||||
We have used the `ng-link` directive to create a link to navigate to the Heroes Component. By using this
|
||||
directive we don't need to know what the actual URL will be. We can leave the Router to generate that for us.
|
||||
directive we don't need to know what the actual URL will be. We can let the Router generate that for us.
|
||||
|
||||
We have included a link to the Crisis Center but have not included the `ng-link` directive as we have not yet
|
||||
implemented the CrisisCenter component.
|
||||
@@ -658,7 +671,7 @@ because the `HeroList` and `HeroDetail` will not contain any child routes.
|
||||
|
||||
The `component` property in a **Route Definition** defines the **Component** directive that will be rendered
|
||||
into the DOM via the **Outlet**. For example the `heroDetail` **Component** will be rendered into the page
|
||||
where the `<ng-outlet></ng-outlet>` lives as `<hero-detail></hero-detail>.
|
||||
where the `<ng-outlet></ng-outlet>` lives as `<hero-detail></hero-detail>`.
|
||||
|
||||
The `name` property is used to reference the **Route Definition** when generating URLs or navigating to
|
||||
**Routes**. For example this link will `<a ng-link="['Heroes']">Heroes</a>` navigate the **Route Definition**
|
||||
@@ -712,8 +725,8 @@ function HeroService($q) {
|
||||
|
||||
this.getHero = function(id) {
|
||||
return heroesPromise.then(function(heroes) {
|
||||
for(var i=0; i<heroes.length; i++) {
|
||||
if ( heroes[i].id == id) return heroes[i];
|
||||
for (var i = 0; i < heroes.length; i++) {
|
||||
if (heroes[i].id === id) return heroes[i];
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -765,7 +778,7 @@ function HeroListComponent(heroService) {
|
||||
Running the application should update the browser's location to `/heroes` and display the list of heroes
|
||||
returned from the `heroService`.
|
||||
|
||||
By returning a promise for the list of heroes from `$routerOnActivate()` we can delay activation of the
|
||||
By returning a promise for the list of heroes from `$routerOnActivate()` we can delay the activation of the
|
||||
Route until the heroes have arrived successfully. This is similar to how a `resolve` works in {@link ngRoute}.
|
||||
|
||||
|
||||
@@ -854,7 +867,6 @@ Router itself, which was made available by the binding in the **Component Defini
|
||||
function HeroDetailComponent(heroService) {
|
||||
...
|
||||
this.gotoHeroes = function() {
|
||||
var heroId = this.hero && this.hero.id;
|
||||
this.$router.navigate(['HeroList']);
|
||||
};
|
||||
```
|
||||
@@ -912,7 +924,7 @@ function HeroListComponent(heroService) {
|
||||
};
|
||||
|
||||
this.isSelected = function(hero) {
|
||||
return (hero.id == selectedId);
|
||||
return (hero.id === selectedId);
|
||||
};
|
||||
}
|
||||
```
|
||||
@@ -956,9 +968,9 @@ respectively.
|
||||
|
||||
**How do I prevent navigation from occurring?**
|
||||
|
||||
Each **Component** can provide the `$routerCanActivate` and `$routerCanDeactivate` **Lifecycle Hooks**. The
|
||||
`$routerCanDeactivate` hook is an instance method on the **Component**. The `$routerCanActivate` hook is a
|
||||
static method defined on either the **Component Definition Object** or the **Component's** constructor function.
|
||||
Each **Component** can provide the `$canActivate` and `$routerCanDeactivate` **Lifecycle Hooks**. The
|
||||
`$routerCanDeactivate` hook is an instance method on the **Component**. The `$canActivate` hook is used as a
|
||||
static method defined on the **Component Definition Object**.
|
||||
|
||||
The **Router** will call these hooks to control navigation from one **Route** to another. Each of these hooks can
|
||||
return a `boolean` or a Promise that will resolve to a `boolean`.
|
||||
@@ -966,7 +978,7 @@ return a `boolean` or a Promise that will resolve to a `boolean`.
|
||||
During a navigation, some **Components** will become inactive and some will become active. Before the navigation
|
||||
can complete, all the **Components** must agree that they can be deactivated or activated, respectively.
|
||||
|
||||
The **Router** will call the `$routerCanDeactivate` and `$routerCanActivate` hooks, if they are provided. If any
|
||||
The **Router** will call the `$routerCanDeactivate` and `$canActivate` hooks, if they are provided. If any
|
||||
of the hooks resolve to `false` then the navigation is cancelled.
|
||||
|
||||
### Dialog Box Service
|
||||
|
||||
@@ -29,11 +29,11 @@ and link functions are unavailable
|
||||
Components can be registered using the `.component()` method of an Angular module (returned by {@link module `angular.module()`}). The method takes two arguments:
|
||||
|
||||
* The name of the Component (as string).
|
||||
* The Component config object (note that, unlike the `.directive()` method, this method does **not** take a factory function.
|
||||
* The Component config object. (Note that, unlike the `.directive()` method, this method does **not** take a factory function.)
|
||||
|
||||
<example name="heroComponentSimple" module="heroApp">
|
||||
<file name="index.js">
|
||||
angular.module('heroApp', []).controller('mainCtrl', function() {
|
||||
angular.module('heroApp', []).controller('MainCtrl', function MainCtrl() {
|
||||
this.hero = {
|
||||
name: 'Spawn'
|
||||
};
|
||||
@@ -55,7 +55,7 @@ Components can be registered using the `.component()` method of an Angular modul
|
||||
</file>
|
||||
<file name="index.html">
|
||||
<!-- components match only elements -->
|
||||
<div ng-controller="mainCtrl as ctrl">
|
||||
<div ng-controller="MainCtrl as ctrl">
|
||||
<b>Hero</b><br>
|
||||
<hero-detail hero="ctrl.hero"></hero-detail>
|
||||
</div>
|
||||
@@ -133,6 +133,8 @@ components should follow a few simple conventions:
|
||||
For a deletion, that means the component doesn't delete the `hero` itself, but sends it back to
|
||||
the owner component via the correct event.
|
||||
```html
|
||||
<!-- note that we use kebab-case for bindings in the template as usual -->
|
||||
<editable-field on-update="$ctrl.update('location', value)"></editable-field><br>
|
||||
<button ng-click="$ctrl.onDelete({hero: $ctrl.hero})">Delete</button>
|
||||
```
|
||||
- That way, the parent component can decide what to do with the event (e.g. delete an item or update the properties)
|
||||
@@ -147,6 +149,36 @@ components should follow a few simple conventions:
|
||||
}
|
||||
```
|
||||
|
||||
- **Components have a well-defined lifecycle**
|
||||
Each component can implement "lifecycle hooks". These are methods that will be called at certain points in the life
|
||||
of the component. The following hook methods can be implemented:
|
||||
|
||||
* `$onInit()` - Called on each controller after all the controllers on an element have been constructed and
|
||||
had their bindings initialized (and before the pre & post linking functions for the directives on
|
||||
this element). This is a good place to put initialization code for your controller.
|
||||
* `$onChanges(changesObj)` - Called whenever one-way bindings are updated. The `changesObj` is a hash whose keys
|
||||
are the names of the bound properties that have changed, and the values are an object of the form
|
||||
`{ currentValue, previousValue, isFirstChange() }`. Use this hook to trigger updates within a component such as
|
||||
cloning the bound value to prevent accidental mutation of the outer value.
|
||||
* `$doCheck()` - Called on each turn of the digest cycle. Provides an opportunity to detect and act on
|
||||
changes. Any actions that you wish to take in response to the changes that you detect must be
|
||||
invoked from this hook; implementing this has no effect on when `$onChanges` is called. For example, this hook
|
||||
could be useful if you wish to perform a deep equality check, or to check a Date object, changes to which would not
|
||||
be detected by Angular's change detector and thus not trigger `$onChanges`. This hook is invoked with no arguments;
|
||||
if detecting changes, you must store the previous value(s) for comparison to the current values.
|
||||
* `$onDestroy()` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
|
||||
external resources, watches and event handlers.
|
||||
* `$postLink()` - Called after this controller's element and its children have been linked. Similar to the post-link
|
||||
function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
|
||||
Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
|
||||
they are waiting for their template to load asynchronously and their own compilation and linking has been
|
||||
suspended until that occurs.
|
||||
This hook can be considered analogous to the `ngAfterViewInit` and `ngAfterContentInit` hooks in Angular 2.
|
||||
Since the compilation process is rather different in Angular 1 there is no direct mapping and care should
|
||||
be taken when upgrading.
|
||||
|
||||
By implementing these methods, your component can hook into its lifecycle.
|
||||
|
||||
- **An application is a tree of components:**
|
||||
Ideally, the whole application should be a tree of components that implement clearly defined inputs
|
||||
and outputs, and minimize two-way data binding. That way, it's easier to predict when data changes and what the state
|
||||
@@ -168,7 +200,7 @@ it upwards to the heroList component, which updates the original data.
|
||||
|
||||
<example name="heroComponentTree" module="heroApp">
|
||||
<file name="index.js">
|
||||
var mode = angular.module('heroApp', []);
|
||||
angular.module('heroApp', []);
|
||||
</file>
|
||||
|
||||
<file name="heroList.js">
|
||||
@@ -207,9 +239,13 @@ it upwards to the heroList component, which updates the original data.
|
||||
</file>
|
||||
|
||||
<file name="heroDetail.js">
|
||||
function HeroDetailController($scope, $element, $attrs) {
|
||||
function HeroDetailController() {
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.delete = function() {
|
||||
ctrl.onDelete({hero: ctrl.hero});
|
||||
};
|
||||
|
||||
ctrl.update = function(prop, value) {
|
||||
ctrl.onUpdate({hero: ctrl.hero, prop: prop, value: value});
|
||||
};
|
||||
@@ -277,7 +313,7 @@ it upwards to the heroList component, which updates the original data.
|
||||
<div>
|
||||
Name: {{$ctrl.hero.name}}<br>
|
||||
Location: <editable-field field-value="$ctrl.hero.location" field-type="text" on-update="$ctrl.update('location', value)"></editable-field><br>
|
||||
<button ng-click="$ctrl.onDelete({hero: $ctrl.hero})">Delete</button>
|
||||
<button ng-click="$ctrl.delete()">Delete</button>
|
||||
</div>
|
||||
</file>
|
||||
<file name="editableField.html">
|
||||
@@ -347,12 +383,12 @@ but they are guaranteed to be available just before the `$onInit` method is exec
|
||||
|
||||
Here is a tab pane example built from components:
|
||||
|
||||
<example module="docsTabsExample">
|
||||
<example module="docsTabsExample" name="component-tabs-pane">
|
||||
<file name="script.js">
|
||||
angular.module('docsTabsExample', [])
|
||||
.component('myTabs', {
|
||||
transclude: true,
|
||||
controller: function() {
|
||||
controller: function MyTabsController() {
|
||||
var panes = this.panes = [];
|
||||
this.select = function(pane) {
|
||||
angular.forEach(panes, function(pane) {
|
||||
@@ -417,54 +453,52 @@ angular.module('docsTabsExample', [])
|
||||
|
||||
# Unit-testing Component Controllers
|
||||
|
||||
The easiest way to unit-test a component controller is by using the {@link ngMock.$componentController $componentController}
|
||||
that is included in {@link ngMock}. The advantage of this method is that you do not have
|
||||
to create any DOM elements. The following example shows how to do this for the `heroDetail` component
|
||||
from above.
|
||||
The easiest way to unit-test a component controller is by using the
|
||||
{@link ngMock.$componentController $componentController} that is included in {@link ngMock}. The
|
||||
advantage of this method is that you do not have to create any DOM elements. The following example
|
||||
shows how to do this for the `heroDetail` component from above.
|
||||
|
||||
The examples use the [Jasmine](http://jasmine.github.io/) testing framework.
|
||||
|
||||
**Controller Test:**
|
||||
```js
|
||||
describe('component: heroDetail', function() {
|
||||
var component, scope, hero, $componentController;
|
||||
var $componentController;
|
||||
|
||||
beforeEach(module('simpleComponent'));
|
||||
|
||||
beforeEach(inject(function($rootScope, _$componentController_) {
|
||||
scope = $rootScope.$new();
|
||||
beforeEach(module('heroApp'));
|
||||
beforeEach(inject(function(_$componentController_) {
|
||||
$componentController = _$componentController_;
|
||||
hero = {name: 'Wolverine'};
|
||||
}));
|
||||
|
||||
it('should set the default values of the hero', function() {
|
||||
// It's necessary to always pass the scope in the locals, so that the controller instance can be bound to it
|
||||
component = $componentController('heroDetail', {$scope: scope});
|
||||
|
||||
expect(component.hero).toEqual({
|
||||
name: undefined,
|
||||
location: 'unknown'
|
||||
});
|
||||
});
|
||||
|
||||
it('should assign the name bindings to the hero object', function() {
|
||||
it('should expose a `hero` object', function() {
|
||||
// Here we are passing actual bindings to the component
|
||||
var bindings = {hero: {name: 'Wolverine'}};
|
||||
var ctrl = $componentController('heroDetail', null, bindings);
|
||||
|
||||
component = $componentController('heroDetail',
|
||||
{$scope: scope},
|
||||
{hero: hero}
|
||||
);
|
||||
expect(component.hero.name).toBe('Wolverine');
|
||||
expect(ctrl.hero).toBeDefined();
|
||||
expect(ctrl.hero.name).toBe('Wolverine');
|
||||
});
|
||||
|
||||
it('should call the onDelete binding when a hero is deleted', function() {
|
||||
component = $componentController('heroDetail',
|
||||
{$scope: scope},
|
||||
{hero: hero, onDelete: jasmine.createSpy('deleteSpy')}
|
||||
);
|
||||
it('should call the `onDelete` binding, when deleting the hero', function() {
|
||||
var onDeleteSpy = jasmine.createSpy('onDelete');
|
||||
var bindings = {hero: {}, onDelete: onDeleteSpy};
|
||||
var ctrl = $componentController('heroDetail', null, bindings);
|
||||
|
||||
component.onDelete({hero: component.hero});
|
||||
expect(spy('deleteSpy')).toHaveBeenCalledWith(component.hero);
|
||||
ctrl.delete();
|
||||
expect(onDeleteSpy).toHaveBeenCalledWith({hero: ctrl.hero});
|
||||
});
|
||||
|
||||
it('should call the `onUpdate` binding, when updating a property', function() {
|
||||
var onUpdateSpy = jasmine.createSpy('onUpdate');
|
||||
var bindings = {hero: {}, onUpdate: onUpdateSpy};
|
||||
var ctrl = $componentController('heroDetail', null, bindings);
|
||||
|
||||
ctrl.update('foo', 'bar');
|
||||
expect(onUpdateSpy).toHaveBeenCalledWith({
|
||||
hero: ctrl.hero,
|
||||
prop: 'foo',
|
||||
value: 'bar'
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user