Compare commits

...

106 Commits

Author SHA1 Message Date
Igor Minar 4b8629b6b8 chore(release): cut 1.0.6 universal-irreversibility release 2013-04-04 10:48:05 -07:00
Misko Hevery ed81d19ce9 chore(docs): correct few unclosed elements
Conflicts:

	src/ng/filter/filter.js
2013-04-04 09:46:46 -07:00
Felipe Lahti 3497bf2d82 docs(guide): add missing closing div tag 2013-04-04 09:43:47 -07:00
Felipe Lahti afcf03fd2c docs(guide): fix typo in DI. angualar -> angular 2013-04-04 09:43:35 -07:00
Gert Goet 582612b000 docs(mocks): fix typos
Conflicts:

	src/ngMock/angular-mocks.js
2013-04-04 09:43:16 -07:00
Srinivas Kusunam 7bf32ccadb docs(directive): fix typo 2013-04-04 09:42:12 -07:00
Matthew McComb f5c18861b6 docs(controller): improve $controller function doc readability
Improved $controller function doc readability.
2013-04-04 09:42:01 -07:00
Misko Hevery 4acd75b904 fix(mock): prevent NPE when module definition outside of it. 2013-04-04 09:30:07 -07:00
James deBoer cd6dd22b19 Update forms.ngdoc
docs(forms): Fixed a typo. render -> $render
2013-04-04 09:29:51 -07:00
Chirayu Krishnappa 139c532019 chore($ngLocale): refactor slurper & parse extended datetime symbols 2013-04-04 09:28:23 -07:00
Chirayu Krishnappa e5b57bf01c chore($ngLocale): generate ngLocale files from the Closure code (includes datetimesymbolsext.js) 2013-04-04 09:00:36 -07:00
Mark Chapman 5ecd6d4e0a refactor(ngRepeat): make use of declared variable
Rename unused arrayLength variable to arrayBound and use it inside loop
2013-04-04 08:59:19 -07:00
Igor Minar 03bbe9aab1 docs($resource): improve installation section 2013-04-04 08:57:14 -07:00
Ciro Nunes 0ef9d54ccd docs($resource): Added an installation section. 2013-04-04 08:54:45 -07:00
Igor Minar 6ade77efa2 chore(karma): upgrade karma to 0.8.4
we needed this upgrade to disable animations in scenario runner
(karma ships with its own copy of angular-scenario.js which
got update in 0.8.4)
2013-04-03 18:22:31 -07:00
Vojta Jina 91fa865bf2 chore: use Karma 2013-04-03 18:22:03 -07:00
Igor Minar 10ae76673c docs(ngSwitch): improve the @usage example 2013-04-01 21:35:02 -07:00
Arlen Christian Mart Cuss 9497757842 chore(select): Fix ngOptions regexp capture comment.
Off-by-one error.
2013-03-20 11:45:42 -07:00
Javier Mendiara Cañardo bb5abe0e9c chore(Angular): remove superfluous fromCharCode function
Remove fromCharCode function as it was used only in two inner
functions in the code, and its functionality is achieved in several
other places by using String.fromCharCode

Breaks fromCharCode closure function, String.fromCharCode should be
used instead
2013-03-20 11:41:14 -07:00
Bruno Coelho 76c0ddfc0b docs(filter): Using indefinite article
This doc was using both definite article and indefinite article at the same time.
2013-03-20 11:41:14 -07:00
Arlen Christian Mart Cuss 36b888e781 docs(directive): Fix entity confusion in example. 2013-03-20 11:41:14 -07:00
Manuel Braun a476972e2e fix($location): parse FirefoxOS packaged app urls
FirefoxOS uses special URLs like
app://{d0419af1-8b42-41c5-96f4-ef4179e52315}/index.html for packaged Apps.

Closes #2112
2013-03-15 21:19:58 -07:00
Jamie Mason 866d3fb573 $routeChangeSuccess documentation
I hope this helps someone, I ran into some issues when following the API as described - handlers of this event receive 3 arguments, not 2.

Although this is mentioned [elsewhere](http://docs.angularjs.org/api/ng.$rootScope.Scope#$on) it's not clear when viewing the docs for this behaviour in isolation. 

The first argument is an Event Object, not the current route. The previous route argument can also be omitted on occasions.
2013-03-15 21:02:14 -07:00
Shyam Seshadri 70cf0a389f feat(docs): Add Improve this doc link in each doc page, which links to the edit mode of that file in github 2013-03-15 20:56:22 -07:00
Sujeet Pillai 7d4ccea579 fix(timezone): correct timezone date filter for 1/2 hour offsets 2013-03-14 22:18:20 -07:00
Shyam Seshadri 654dd1d5e8 Fix failing test in IE 10 2013-03-14 22:04:06 -07:00
Arlen Christian Mart Cuss bf114f6ee3 docs($injector): correct misuse of $inject
$inject was used where $injector was appropriate; confusing and
misleading.
2013-03-12 13:00:46 -07:00
Igor Minar 5727eaf767 chore(Gruntfile): run webserver on 0.0.0.0
... so that we can access it from local VMs.

The security risk of doing this is very low since only the current
working directory is being made accessible to everyone. There is also
an option to run a local firewall, which is a better way to secure the
developer's machine anyway.
2013-03-11 15:27:35 -07:00
Thibault Leruitte 346e98330c fix($location): correctly rewrite html5 url to hashbang url
In situations where path() matched basepath and we needed to
convert from html5 url to hashbang url, the $location service
considered the url to be already rewritten, which resulted in
an error.
2013-03-11 15:27:31 -07:00
Christian Vuerings 2b1f10266a docs(ngCloak): update the CSS rule with data-ng-cloak 2013-03-08 17:26:07 -08:00
Chirayu Krishnappa fc7970fdf0 chore($ngLocale): Generate ngLocale files from the Closure code. 2013-03-08 17:00:03 -08:00
Jason Morrison 65957e99ba docs($injector): remove extranneous 'the' from injector docs 2013-03-08 23:49:03 +01:00
Niel de la Rouviere 7f9a94f8bc docs(directive): minor typo fix
Changed "obeject" to "object"
2013-03-08 23:30:00 +01:00
Igor Minar cb560e2441 test($route): add tests for matching 'otherwise' routes 2013-03-08 12:01:09 -08:00
Igor Minar 55856565c2 fix($route): make nextRoute.$route private
the `nextRoute` object available in `$routeChangeStart` handler
accidentaly leaked  property which pointed to the route definition
currently being matched.

this was done just for the internal needs of the `$route` implementation
and was never documented as public api.

Some confusion arouse around why the $route property was not always
available on the `nextRoute` object (see #1907). The right thing for us
to do is to prefix the property with $$ for now and refactor the code
to remove the property completely in the future. Application developers
should use the `nextRoute` object itself rather than its `$route` property.
The main diff is that nextRoute inherits from the object referenced by $route.

BREAKING CHANGE: in $routeChangeStart event, nextRoute.$route property is gone.

Use the nextRoute object instead of nextRoute.$route.

Closes #1907
2013-03-08 12:01:05 -08:00
Julie 13968343d4 feat(angular.bootstrap): support deferred bootstrap
This features enables tools like Batarang and test runners to
hook into angular's bootstrap process and sneak in more modules
into the DI registry which can replace or augment DI services for
the purpose of instrumentation or mocking out heavy dependencies.

If window.name contains prefix NG_DEFER_BOOTSTRAP! when
angular.bootstrap is called, the bootstrap process will be paused
until angular.resumeBootstrap is called.

angular.resumeBootstrap takes an optional array of modules that
should be added to the original list of modules that the app was
about to be bootstrapped with.

Conflicts:

	src/Angular.js
2013-03-06 16:25:21 -08:00
Dave Geddes 4c428121b9 docs(contribute): add note about running command line as admin on win 2013-03-06 14:55:42 -08:00
Igor Minar 4816f7ee5c chore(Grunt): include dot files in the final zip 2013-03-06 14:23:05 -08:00
Dave Geddes ce53fbde50 chore(Grunt): don't remove root dir from zip 2013-03-06 13:20:54 -08:00
Igor Minar 1516a69cd2 docs($http): add more info about transform function 2013-03-06 11:20:49 -08:00
Dave Geddes 7a77fdae4f chore(Grunt): switch from Rake to Grunt
Migrates the Angular project from Rake to Grunt.

Benefits:
- Drops Ruby dependency
- Lowers barrier to entry for contributions from JavaScript ninjas
- Simplifies the Angular project setup and build process
- Adopts industry-standard tools specific to JavaScript projects
- Support building angular.js on Windows platform (really?!? why?!?)

BREAKING CHANGE: Rake is completely replaced by Grunt. Below are the deprecated Rake tasks and their Grunt equivalents:

rake --> grunt
rake package --> grunt package
rake init --> N/A
rake clean --> grunt clean
rake concat_scenario --> grunt build:scenario
rake concat --> grunt build
rake concat_scenario --> grunt build:scenario
rake minify --> grunt minify
rake version --> grunt write:version
rake docs --> grunt docs
rake webserver --> grunt webserver
rake test --> grunt test
rake test:unit --> grunt test:unit
rake test:<jqlite|jquery|modules|e2e> --> grunt test:<jqlite|jquery|modules|end2end|e2e>
rake test[Firefox+Safari] --> grunt test --browsers Firefox,Safari
rake test[Safari] --> grunt test --browsers Safari
rake autotest --> grunt autotest

NOTES:
* For convenience grunt test:e2e starts a webserver for you, while grunt test:end2end doesn't.
  Use grunt test:end2end if you already have the webserver running.
* Removes duplicate entry for Describe.js in the angularScenario section of angularFiles.js
* Updates docs/src/gen-docs.js to use #done intead of the deprecated #end
* Uses grunt-contrib-connect instead of lib/nodeserver (removed)
* Removes nodeserver.sh, travis now uses grunt webserver
* Built and minified files are identical to Rake's output, with the exception of one less
  character for git revisions (using --short) and a couple minor whitespace differences

Closes #199

Conflicts:

	Rakefile
2013-03-05 23:35:13 -08:00
Andrew McLeod b13da18e11 fix($http): don't encode URL query substring "null" to "+"
Fixes issue in encodeUriQuery used by $http and $resource that
treats null as a string and replaces the characters "null" with "+".
2013-02-26 17:29:08 -08:00
Matt Ginzton f98f8a3892 docs(ngMock): fix minor typo in comment
Change "constroctor" to "constructor".
2013-02-25 23:55:54 -08:00
danilsomsikov 77c4a7fd66 fix($compile): compile replace directives in external template
Passing DOMNode#childNodes to compileNodes when compiling remote
template, so that directives with replace:true can be compiled.
The previous version used jqLite#contents which returned collection
that was not updated during the compilation.

Closes #1859
2013-02-25 21:45:44 -08:00
Igor Minar e281413919 chore(sortedHtml): print attributes with empty value
I had to also fix some tests as they started failing on IE8.

We should figure out why these extra attributes are set in IE8,
but I'm too tired of IE to worry about it now. Since I'm
not introducing this issue just making it visible, I'm going
to commit this as is.
2013-02-25 21:45:39 -08:00
Vineet Kumar 2007ddd3f8 docs(guide/directives): update obsolete doc reference
Replace an obsolete reference to a nonexistent "Creating Widgets"
section with a real link to "Creating Components".
2013-02-25 14:51:59 -08:00
Pawel Kozlowski d8922fe3e9 docs(dateFilter): properly specify range for the Z format modifier
Closes #1533
2013-02-25 13:51:38 -08:00
Igor Minar 6c611df8f0 fix($compile): whitelist file:// in url sanitization 2013-02-25 10:02:50 -08:00
Steven Davidson 6be24df5bc chore(nodeserver): fix log message for 301 response 2013-02-23 23:44:46 -08:00
Igor Minar 4759aacba9 fix($compile): handle elements with no childNodes property
see the test for more details
2013-02-23 23:40:03 -08:00
Igor Minar 802bfc259c chore(release): start 1.0.6 universal-irreversibility iteration 2013-02-23 21:11:14 -08:00
Igor Minar 64db8d166e docs(changelog): fix release notes 2013-02-20 15:44:09 -08:00
Igor Minar d2a769e196 chore(release): cut the 1.0.5 flatulent-propulsion release 2013-02-20 12:58:02 -08:00
Igor Minar 68a8c8907d docs(changelog): add release notes for 1.0.5 and 1.1.3 2013-02-20 12:57:08 -08:00
Igor Minar 701d61080a chore(matchers): fix hasBeenCalledOnceWith matcher
the error message was wrong and misleading
2013-02-20 08:44:53 -08:00
Igor Minar a8cc449706 fix($compile): sanitize values bound to a[href] 2013-02-20 00:40:51 -08:00
Per Rovegård 2aa212b19c fix(ngClass): keep track of old ngClass value manually
ngClassWatchAction, when called as a $watch function, gets the wrong old
value after it has been invoked previously due to observation of the
interpolated class attribute. As a result it doesn't remove classes
properly. Keeping track of the old value manually seems to fix this.

Closes #1637
2013-02-18 20:35:40 -08:00
Pete Bacon Darwin 1f23cfe9c7 fix(compile): should not leak memory when there are top level empty text nodes
The change to prevent <span> elements being wrapped around empty text nodes caused these empty text nodes to have scopes and controllers attached, through jqLite.data() calls, which led to memory leaks and errors in IE8.
Now we exclude all but document nodes and elements from having jqLite.data() set both in the compiler and in ng-view.

Fixes: #1968 and #1876
2013-02-18 13:04:24 +00:00
Will Moore 0fa8e47fb5 fix($httpBackend): patch for Firefox bug w/ CORS and response headers
A workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=608735
In FF getAllResponseHeaders() returns null if the request is the result of CORS.

Tried to format the code so that when a FF patch is released and gains enough
traction it can easily be selected and deleted. Heavily inspired by jQuery's
patch for the same bug. This patch falls short of passing through custom headers
but covers all of the "simple response headers" in the spec at
http://www.w3.org/TR/cors/

This commit should get reverted once Firefox 21 gets out.

Closes #1468

Conflicts:
	src/ng/httpBackend.js
2013-02-14 16:52:02 -08:00
Igor Minar 8043784fd7 fix(a): workaround IE bug affecting mailto urls
Apparently there is a really weird bug in IE6-8 that causes anchor textContent
to be reset with href content when both contain @ symbol.

Inserting a bogus comment node into all anchor elements in IE works around this
browser bug.

I'm fixing the issue via directive because that way we'll fix it for jQuery as
well.

I fixed an e2e test too because it was incorrect.

Closes #1949
2013-02-14 16:43:28 -08:00
Igor Minar 526a6b31e5 fix(*): don't use instanceof to detect arrays
this breaks when multiple javascript contexts are involved - like in node-webkit

see original PR: #1966

Closes #1966
2013-02-14 16:40:58 -08:00
Cedric Soulas 14fd064a62 docs($resource): fix bad indentation producing a code block 2013-02-14 15:45:37 -08:00
Ewen Cumming 3178afbf0c docs($rootScope): rearrange event listener docs 2013-02-14 15:42:51 -08:00
deboer ce3b616432 fix(ngSwitch): make ngSwitch compatible with controller BC module
add a $scope to the ngSwitch's controller to fool the controller
BC (backwards compatibility) module used by DFA.
2013-02-14 15:38:20 -08:00
Vineet Kumar 54a761905d docs($q): fix a few typos 2013-02-14 15:19:49 -08:00
Dylan Pyle aa531d7bd1 docs(guide): fix some invalid javascript in directive documentation
Use double quotes to maintain consistency with other HTML
2013-02-14 15:15:06 -08:00
Daniel Luz d7e9ae1215 fix($rootScope): minor typo fixes 2013-02-14 14:43:32 -08:00
Daniel Luz 6cf9ede88e docs($parse): document function argument types, fix minor typo 2013-02-14 14:43:32 -08:00
Trotter Cashion 6092291bd7 chore(reakefile): auto install npm packages 2013-02-14 14:43:31 -08:00
Shyam Seshadri 3d0f11212f fix(compiler): Allow startingTag method to handle text / comment nodes 2013-02-14 14:43:31 -08:00
Fredrik Bonander 6194e002e2 fix(resource): Update RegExp to allow urlParams with out leading slash
Will allow reoucese to be loaded from a relative path
Example:
var R = $resource(':path');
R.get({ path : 'data.json' });

Example usage:
Load resources in applications not using webserver, ie local webapp in
on a tablet.
2013-02-14 14:43:31 -08:00
Kury Kruitbosch 75545d4d1c fix(numberFilter): fix formatting when "0" passed as fractionSize
When checking to add decimal and trialing 0s number filter used to check
trueness of fractionSize. "0" evaluating to true causes "123" to return "123."
2013-02-14 13:46:07 -08:00
Jesse Cooke d67eb2f2db docs(guide): Fix typos in concepts/model,view. 2013-02-14 13:09:40 -08:00
Igor Minar 6b8153ff0f chore(Rakefile): parallelize the build on Travis
now that the forking issue is solved we can run regular build there

https://github.com/travis-ci/travis-ci/issues/845
2013-02-14 12:52:20 -08:00
Cedric Soulas fb132732f1 docs($resource): fix missing punctuation 2013-02-14 12:14:13 -08:00
Igor Minar 336b157497 test(angular.copy): add tests for scenarios when target is missing 2013-02-11 22:10:58 -08:00
Igor Minar d16975a9de revert: refactor(angular.copy): use slice(0) to clone arrays
This reverts commit a5b3bcf41c.

slice(0) doesn't perform deep copy of the array so its unsuitable
for our purposes.
2013-02-11 22:01:15 -08:00
Igor Minar 87f6b36bab chore(docs): improve docs parser type
previously we barfed on function type definition with optional arguments
like {function(number=)}

this fixes it

I also added a bunch of code that helps to debug incorrectly parsed docs.
2013-02-11 14:08:27 -08:00
Igor Minar 43fccf5617 refactor(angular.copy): use array.length=0 to empty arrays 2013-02-11 14:07:57 -08:00
Igor Minar a5b3bcf41c refactor(angular.copy): use slice(0) to clone arrays
slice(0) is way faster on most browsers
2013-02-11 14:07:10 -08:00
Igor Minar 8801d9c286 fix(angular.forEach): correctly iterate over objects with length prop
Should handle JQLite, jQuery, NodeList and other objects like arrays
but not other generic objects or instances of user defined types
with length property.

Closes #1840
2013-02-11 12:46:13 -08:00
radu a8e114f351 docs($q): fix typos 2013-02-07 04:16:49 -08:00
Julie 9a3a9b46e5 fix(scenario): include error messages in XML output
Fix the XML output of scenario tests so that it properly includes error
messages from failing specs.
2013-02-07 04:10:17 -08:00
Enrique Paredes 934204ec18 fix($compile): rename $compileNote to compileNode
Directives was observing different instances of Attributes than the one
that interpolation was registered with because we failed to realize
that the compile node and link node were the same (one of them
was a wrapper rather than raw node)

Closes #1941
2013-02-07 02:49:18 -08:00
Fredrik Bonander 7cb8f8fb44 fix($cookies): set cookies on Safari&IE when base[href] is undefined
Safari and IE don't like being told to store cookies with path set to
undefined. This change ensures that if base[href] (from which cookie path
is derived) is undefined then the cookie path defaults to ''.

The test verifies that the cookie is set instead of checking that cookie has correct path,
this is due to that cookie meta information is not avabile once the cookie is set.

Closes #1190, #1191
2013-02-07 02:36:52 -08:00
Philip Roberts 8d34bf2fea fix(date): invert timezone sign and always display sign
This commit fixes #1261 and #1532. This covers
two separate issues:

- Positive timezones were being formatted without
a leading `+` resulting in a formatting string
like: "HH:MM:ssZ" giving "12:13:141000" instead
of "12:13:14+1000". Fixed by checking if timezone
is > 0 and adding a leading "+".

- Timezone output signs were inverted.
mock.TzDate expects the timezone _offset_ as it's
first argument, _not_ the timezone. This means
that a mock.TzDate with a positive offset should
result in a date string with a negative timezone,
and vice-versa.

Closes #1261, #1532
2013-02-07 01:47:19 -08:00
Igor Minar 8801e69dba docs(guide): remove stale info about filters changing DOM
as of v0.10.6 this is not the case any more
2013-02-06 14:15:43 -08:00
Thomas Schultz f4afa398a1 docs(tutorial): remove extra back-tick character 2013-02-06 22:22:55 +01:00
theotheo 32063278bd docs(module): fix code example 2013-02-06 21:36:21 +01:00
radu 92208d2f85 docs(ngApp): fix typo 2013-02-05 22:14:43 +01:00
Igor Minar ab7c74b4b9 docs(contributing): add CLA anchor for deeplinking 2013-02-04 09:38:55 -08:00
PowerKiKi e283abe171 docs(ngClass): fix typo in description 2013-02-04 10:37:19 +00:00
Brian Ford d7620f68bb feat(Scope): expose transcluded and isolate scope info for batarang
test($compile): add test for exposing transclude and isolate scope info to batarang
2013-01-30 10:44:35 -05:00
Dean Sofer 971d97e2ec docs($cookies): added example to $cookies api docs
Better than nothing.
2013-01-29 16:17:12 -08:00
radu 559d5efc04 docs(nextUid): fix typo
Update src/Angular.js

removed redundant 'the' from nextUid()'s ngdoc
2013-01-29 15:50:03 -08:00
radu 85042820fb docs(tutorial): fix typo
Update docs/content/tutorial/step_00.ngdoc

removed redundant verb
2013-01-29 15:47:43 -08:00
Fred Sauer 24a2eec815 docs(Scope): fix argument docs for $on 2013-01-29 15:39:10 -08:00
metaweta d987a79ab1 test(ngBindHtml): prevent variable name leak
Add "var" so element is local instead of global

Strict mode doesn't allow undeclared global vars, and these really should be local anyway.
2013-01-29 15:35:03 -08:00
metaweta eba09353e6 refactor(Angular.js): prevent Error variable name leak in tests
Remove var Error = window.Error

window.Error is a read-only property in Apps Script.

Igor says, "we should just delete that line instead. I think it was
misko's attempt to get better closure minification, but it turns out
that it's actually hurting us after gzip (I verified it)."
2013-01-29 15:35:03 -08:00
Igor Minar 297660c9a3 chore(release): start 1.0.5 flatulent-propulsion iteration 2013-01-29 15:34:04 -08:00
Fred Sauer 8343c05fd8 docs(a): escape sample code in ng a directive 2013-01-26 23:03:40 +01:00
Igor Minar 7c3d064786 fix(docs): properly generate angular.js urls in doc examples 2013-01-24 11:36:42 -08:00
Igor Minar c2ccc1cbdf docs(date): add missing doc about TZ behavior 2013-01-24 10:51:47 -08:00
Igor Minar 04e080660a docs(changelog): correct 1.0.4 release notes 2013-01-24 09:50:51 -08:00
Vineet Kumar f3cca88384 docs($injector): clarify $inject property description
Section heading about `$inject` property refers to it as `$injector` property.
2013-01-24 00:18:48 -05:00
Igor Minar 978bbd2d49 chore(release): update the CDN version 2013-01-23 12:07:01 -08:00
375 changed files with 46627 additions and 1994 deletions
+4 -4
View File
@@ -5,9 +5,9 @@ node_js:
before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
- npm install -g testacular@canary
- rake package
- ./nodeserver.sh > /dev/null &
- npm install -g grunt-cli
- grunt package
- grunt webserver > /dev/null &
script:
- rake test[Firefox,"--reporters=dots"]
- grunt test --browsers Firefox --reporters=dots
+122 -2
View File
@@ -1,3 +1,123 @@
<a name="1.1.3"></a>
# 1.1.3 radioactive-gargle (2013-02-20)
_Note: 1.1.x releases are [considered unstable](http://blog.angularjs.org/2012/07/angularjs-10-12-roadmap.html).
They pass all tests but we reserve the right to change new features/apis in between minor releases. Check them
out and please give us feedback._
_Note: This release also contains all bug fixes available in [1.0.5](#1.0.5)._
## Bug Fixes
- **$compile:**
- initialize interpolated attributes before directive linking
([bb8448c0](https://github.com/angular/angular.js/commit/bb8448c011127306df08c7479b66e5afe7a0fa94))
- interpolate @ locals before the link function runs
([2ed53087](https://github.com/angular/angular.js/commit/2ed53087d7dd06d728e333a449265f7685275548))
- **$http:**
- do not encode special characters `@$:,` in params
([288b69a3](https://github.com/angular/angular.js/commit/288b69a314e9bd14458b6647532eb62aad5c5cdf))
- **$resource:**
- params should expand array values properly
([2a212344](https://github.com/angular/angular.js/commit/2a2123441c2b749b8f316a24c3ca3f77a9132a01))
## Features
- **$http:** allow overriding the XSRF header and cookie name
([8155c3a2](https://github.com/angular/angular.js/commit/8155c3a29ea0eb14806913b8ac08ba7727e1969c))
- **$parse:** added `constant` and `literal` properties
([1ed63858](https://github.com/angular/angular.js/commit/1ed638582d2f2c7f89384d9712f4cfac52cc5b70))
- **$resource:** expose promise based api via $then and $resolved
([dba6bc73](https://github.com/angular/angular.js/commit/dba6bc73e802fdae685a9f351d3e23c7efa8568a))
- **$routeProvider:** add support to catch-all parameters in routes
([7eafbb98](https://github.com/angular/angular.js/commit/7eafbb98c64c0dc079d7d3ec589f1270b7f6fea5))
- **Scope:**
- expose transcluded and isolate scope info for batarang
([649b8922](https://github.com/angular/angular.js/commit/649b892205615a144dafff9984c0e6ab10ed341d))
- only evaluate constant $watch expressions once
([1d7a95df](https://github.com/angular/angular.js/commit/1d7a95df565192fc02a18b0b297b39dd615eaeb5))
- **angular.noConflict:** added api to restore previous angular namespace reference
([12ba6cec](https://github.com/angular/angular.js/commit/12ba6cec4fb79521101744e02a7e09f9fbb591c4))
- **Directives:**
- **ngSwitch:** support multiple matches on ngSwitchWhen and ngSwitchDefault
([0af17204](https://github.com/angular/angular.js/commit/0af172040e03811c59d01682968241e3df226774),
[#1074](https://github.com/angular/angular.js/issues/1074))
- **Filters:**
- **date:** add `[.,]sss` formatter for milliseconds
([df744f3a](https://github.com/angular/angular.js/commit/df744f3af46fc227a934f16cb63c7a6038e7133b))
- **filter:** add comparison function to filter
([ace54ff0](https://github.com/angular/angular.js/commit/ace54ff08c4593195b49eadb04d258e6409d969e))
## Breaking Changes
- **$http:** due to [288b69a3](https://github.com/angular/angular.js/commit/288b69a314e9bd14458b6647532eb62aad5c5cdf),
$http now follows RFC3986 and does not encode special characters like `$@,:` in params.
If your application needs to encode these characters, encode them manually, before sending the request.
- **$resource:** due to [2a212344](https://github.com/angular/angular.js/commit/2a2123441c2b749b8f316a24c3ca3f77a9132a01),
if the server relied on the buggy behavior of serializing arrays as http query arguments then
either the backend should be fixed or a simple serialization of the array should be done
on the client before calling the resource service.
<a name="1.0.5"></a>
# 1.0.5 flatulent-propulsion (2013-02-20)
## Bug Fixes
- **$compile:**
- sanitize values bound to `a[href]`
([9532234b](https://github.com/angular/angular.js/commit/9532234bf1c408af9a6fd2c4743fdb585b920531))
- rename $compileNote to compileNode
([92ca7efa](https://github.com/angular/angular.js/commit/92ca7efaa4bc4f37da3008b234e19343a1fa4207),
[#1941](https://github.com/angular/angular.js/issues/1941))
- should not leak memory when there are top level empty text nodes
([791804bd](https://github.com/angular/angular.js/commit/791804bdbfa6da7a39283623bd05628a01cd8720))
- allow startingTag method to handle text / comment nodes
([755beb2b](https://github.com/angular/angular.js/commit/755beb2b66ce9f9f9a218f2355bbaf96d94fbc15))
- **$cookies:** set cookies on Safari&IE when `base[href]` is undefined
([70909245](https://github.com/angular/angular.js/commit/7090924515214752b919b0c5630b3ea5e7c77223),
[#1190](https://github.com/angular/angular.js/issues/1190))
- **$http:**
- patch for Firefox bug w/ CORS and response headers
([e19b04c9](https://github.com/angular/angular.js/commit/e19b04c9ec985821edf1269c628cfa261f81d631),
[#1468](https://github.com/angular/angular.js/issues/1468))
- **$resource:**
- update RegExp to allow urlParams with out leading slash
([b7e1fb05](https://github.com/angular/angular.js/commit/b7e1fb0515798e1b4f3f2426f6b050951bee2617))
- **Directives:**
- **a:** workaround IE bug affecting mailto urls
([37e8b122](https://github.com/angular/angular.js/commit/37e8b12265291918396bfee65d444a8f63697b73),
[#1949](https://github.com/angular/angular.js/issues/1949))
- **ngClass:** keep track of old ngClass value manually
([5f5d4fea](https://github.com/angular/angular.js/commit/5f5d4feadbfa9d8ecc8150041dfd2bca2b2e9fea),
[#1637](https://github.com/angular/angular.js/issues/1637))
- **ngSwitch:** make ngSwitch compatible with controller backwards-compatiblity module
([9b7c1d0f](https://github.com/angular/angular.js/commit/9b7c1d0f7ce442d4ad2ec587e66d2d335e64fa4e))
- **Filters:**
- **date:** invert timezone sign and always display sign
([b001c8ec](https://github.com/angular/angular.js/commit/b001c8ece5472626bf49cf82753e8ac1aafd2513),
[#1261](https://github.com/angular/angular.js/issues/1261))
- **number:** fix formatting when "0" passed as fractionSize
([f5835963](https://github.com/angular/angular.js/commit/f5835963d5982003a713dd354eefd376ed39ac02))
- **scenario runner:** include error messages in XML output
([d46fe3c2](https://github.com/angular/angular.js/commit/d46fe3c23fa269dcc10249148f2af14f3db6b066))
- **Misc:**
- don't use instanceof to detect arrays
([3c2aee01](https://github.com/angular/angular.js/commit/3c2aee01b0b299995eb92f4255159585b0f53c10),
[#1966](https://github.com/angular/angular.js/issues/1966))
- angular.forEach should correctly iterate over objects with length prop
([ec54712f](https://github.com/angular/angular.js/commit/ec54712ff3dab1ade44f94fa82d67edeffa79a1d),
[#1840](https://github.com/angular/angular.js/issues/1840))
<a name="1.1.2"></a>
# 1.1.2 tofu-animation (2013-01-22)
@@ -73,6 +193,8 @@ _Note: This release also contains all bug fixes available in [1.0.4](#1.0.4)._
- HTTP method should be case-insensitive
([8991680d](https://github.com/angular/angular.js/commit/8991680d8ab632dda60cd70c780868c803c74509),
[#1403](https://github.com/angular/angular.js/issues/1403))
- correct leading slash removal in resource URLs
([b2f46251](https://github.com/angular/angular.js/commit/b2f46251aca76c8568ee7d4bab54edbc9d7a186a))
- **$route:**
- support route params not separated with slashes.
([c6392616](https://github.com/angular/angular.js/commit/c6392616ea5245bd0d2f77dded0b948d9e2637c8))
@@ -100,8 +222,6 @@ _Note: This release also contains all bug fixes available in [1.0.4](#1.0.4)._
- **ngRepeat:** correctly apply $last if repeating over object
([7e746015](https://github.com/angular/angular.js/commit/7e746015ea7dec3e9eb81bc4678fa9b6a83bc47c),
[#1789](https://github.com/angular/angular.js/issues/1789))
- **ngResource:** correct leading slash removal.
([b2f46251](https://github.com/angular/angular.js/commit/b2f46251aca76c8568ee7d4bab54edbc9d7a186a))
- **ngSwitch:** don't leak when destroyed while not attached
([a26234f7](https://github.com/angular/angular.js/commit/a26234f7183013e2fcc9b35377e181ad96dc9917),
[#1621](https://github.com/angular/angular.js/issues/1621))
+171
View File
@@ -0,0 +1,171 @@
var files = require('./angularFiles').files;
var util = require('./lib/grunt/utils.js');
module.exports = function(grunt) {
//grunt plugins
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-compress');
grunt.loadTasks('lib/grunt');
var NG_VERSION = util.getVersion();
var dist = 'angular-'+ NG_VERSION.full;
//global beforeEach
util.init();
//config
grunt.initConfig({
NG_VERSION: NG_VERSION,
connect: {
devserver: {
options: {
port: 8000,
hostname: '0.0.0.0',
base: '.',
keepalive: true,
middleware: function(connect, options){
return [
//uncomment to enable CSP
// util.csp(),
util.rewrite(),
connect.favicon('images/favicon.ico'),
connect.static(options.base),
connect.directory(options.base)
];
}
}
},
testserver: {}
},
test: {
jqlite: 'karma-jqlite.conf.js',
jquery: 'karma-jquery.conf.js',
modules: 'karma-modules.conf.js',
//NOTE run grunt test:e2e instead and it will start a webserver for you
end2end: 'karma-e2e.conf.js'
},
autotest: {
jqlite: 'karma-jqlite.conf.js',
jquery: 'karma-jquery.conf.js'
},
clean: {build: ['build']},
build: {
scenario: {
dest: 'build/angular-scenario.js',
src: [
'lib/jquery/jquery.js',
util.wrap([files['angularSrc'], files['angularScenario']], 'ngScenario/angular')
],
styles: {
css: ['css/angular.css', 'css/angular-scenario.css']
}
},
angular: {
dest: 'build/angular.js',
src: util.wrap([files['angularSrc']], 'angular'),
styles: {
css: ['css/angular.css'],
minify: true
}
},
loader: {
dest: 'build/angular-loader.js',
src: util.wrap(['src/loader.js'], 'loader')
},
mocks: {
dest: 'build/angular-mocks.js',
src: ['src/ngMock/angular-mocks.js'],
strict: false
},
sanitize: {
dest: 'build/angular-sanitize.js',
src: util.wrap([
'src/ngSanitize/sanitize.js',
'src/ngSanitize/directive/ngBindHtml.js',
'src/ngSanitize/filter/linky.js',
], 'module')
},
resource: {
dest: 'build/angular-resource.js',
src: util.wrap(['src/ngResource/resource.js'], 'module')
},
cookies: {
dest: 'build/angular-cookies.js',
src: util.wrap(['src/ngCookies/cookies.js'], 'module')
},
bootstrap: {
dest: 'build/angular-bootstrap.js',
src: util.wrap(['src/bootstrap/bootstrap.js'], 'module')
},
bootstrapPrettify: {
dest: 'build/angular-bootstrap-prettify.js',
src: util.wrap(['src/bootstrap/bootstrap-prettify.js', 'src/bootstrap/google-prettify/prettify.js'], 'module'),
styles: {
css: ['src/bootstrap/google-prettify/prettify.css'],
minify: true
}
}
},
min: {
angular: 'build/angular.js',
cookies: 'build/angular-cookies.js',
loader: 'build/angular-loader.js',
resource: 'build/angular-resource.js',
sanitize: 'build/angular-sanitize.js',
bootstrap: 'build/angular-bootstrap.js',
bootstrapPrettify: 'build/angular-bootstrap-prettify.js',
},
docs: {
process: ['build/docs/*.html', 'build/docs/.htaccess']
},
copy: {
i18n: {
files: [
{ src: 'src/ngLocale/**', dest: 'build/i18n/', expand: true, flatten: true }
]
}
},
compress: {
build: {
options: {archive: 'build/' + dist +'.zip'},
src: ['**'], cwd: 'build', expand: true, dot: true, dest: dist + '/'
}
},
write: {
versionTXT: {file: 'build/version.txt', val: NG_VERSION.full},
versionJSON: {file: 'build/version.json', val: JSON.stringify(NG_VERSION)}
}
});
//alias tasks
grunt.registerTask('test:unit', ['test:jqlite', 'test:jquery', 'test:modules']);
grunt.registerTask('minify', ['clean', 'build', 'minall']);
grunt.registerTask('test:e2e', ['connect:testserver', 'test:end2end']);
grunt.registerTask('webserver', ['connect:devserver']);
grunt.registerTask('package', ['clean', 'buildall', 'minall', 'docs', 'copy', 'write', 'compress']);
grunt.registerTask('default', ['package']);
};
+6 -12
View File
@@ -21,25 +21,19 @@ Building AngularJS
---------
[Once you have your environment setup](http://docs.angularjs.org/misc/contribute) just run:
rake package
grunt package
Running Tests
-------------
Running tests requires installation of [Testacular](http://vojtajina.github.com/testacular):
sudo npm install -g testacular
To execute all unit tests, use:
rake test:unit
grunt test:unit
To execute end-to-end (e2e) tests, use:
rake package
rake webserver &
rake test:e2e
grunt package
grunt test:e2e
To learn more about the rake tasks, run `rake -T` and also read our
[contribution guidelines](http://docs.angularjs.org/misc/contribute) and instructions in this
[commit message](https://github.com/angular/angular.js/commit/9d168f058f9c6d7eeae0daa7cb72ea4e02a0003a).
To learn more about the grunt tasks, run `grunt --help` and also read our
[contribution guidelines](http://docs.angularjs.org/misc/contribute).
-374
View File
@@ -1,374 +0,0 @@
require 'yaml'
include FileUtils
## High level flow of the build:
##
## clean -> init -> concat -> minify -> package
##
content = File.open('angularFiles.js', 'r') {|f| f.read }
files = eval(content.gsub(/\};(\s|\S)*/, '}').
gsub(/angularFiles = /, '').
gsub(/:/, '=>').
gsub(/\/\//, '#'));
BUILD_DIR = 'build'
task :default => [:package]
desc 'Init the build workspace'
task :init do
FileUtils.mkdir(BUILD_DIR) unless File.directory?(BUILD_DIR)
v = YAML::load( File.open( 'version.yaml' ) )
match = v['version'].match(/^([^-]*)(-snapshot)?$/)
NG_VERSION = Struct.new(:full, :major, :minor, :dot, :codename, :stable).
new(match[1] + (match[2] ? ('-' + %x(git rev-parse HEAD)[0..7]) : ''),
match[1].split('.')[0],
match[1].split('.')[1],
match[1].split('.')[2].sub(/\D+.*$/, ''),
v['codename'],
v['stable'])
end
desc 'Clean Generated Files'
task :clean do
FileUtils.rm_r(BUILD_DIR, :force => true)
FileUtils.mkdir(BUILD_DIR)
FileUtils.rm_r('test_out', :force => true)
end
desc 'Concat Scenario'
task :concat_scenario => :init do
concat_file('angular-scenario.js', [
'lib/jquery/jquery.js',
'src/ngScenario/angular.prefix',
files['angularSrc'],
files['angularScenario'],
'src/ngScenario/angular.suffix',
], gen_css('css/angular.css') + "\n" + gen_css('css/angular-scenario.css'))
end
desc 'Concat JSTD Scenario Adapter'
task :concat_jstd_scenario_adapter => :init do
concat_file('jstd-scenario-adapter.js', [
'src/ngScenario/jstd-scenario-adapter/angular.prefix',
'src/ngScenario/jstd-scenario-adapter/Adapter.js',
'src/ngScenario/jstd-scenario-adapter/angular.suffix',
])
# TODO(vojta) use jstd configuration when implemented
# (instead of including jstd-adapter-config.js)
File.open(path_to('jstd-scenario-adapter-config.js'), 'w') do |f|
f.write("/**\r\n" +
" * Configuration for jstd scenario adapter \n */\n" +
"var jstdScenarioAdapter = {\n relativeUrlPrefix: '/build/docs/'\n};\n")
end
end
desc 'Concat AngularJS files'
task :concat => :init do
concat_file('angular.js', [
'src/angular.prefix',
files['angularSrc'],
'src/angular.suffix',
], gen_css('css/angular.css', true))
FileUtils.cp_r 'src/ngLocale', path_to('i18n')
concat_file('angular-loader.js', [
'src/loader.prefix',
'src/loader.js',
'src/loader.suffix'])
concat_module('sanitize', [
'src/ngSanitize/sanitize.js',
'src/ngSanitize/directive/ngBindHtml.js',
'src/ngSanitize/filter/linky.js'])
concat_module('resource', ['src/ngResource/resource.js'])
concat_module('cookies', ['src/ngCookies/cookies.js'])
concat_module('bootstrap', ['src/bootstrap/bootstrap.js'])
concat_module('bootstrap-prettify', ['src/bootstrap/bootstrap-prettify.js',
'src/bootstrap/google-prettify/prettify.js'],
gen_css('src/bootstrap/google-prettify/prettify.css', true))
FileUtils.cp 'src/ngMock/angular-mocks.js', path_to('angular-mocks.js')
rewrite_file(path_to('angular-mocks.js')) do |content|
content.sub!('"NG_VERSION_FULL"', NG_VERSION.full)
end
end
desc 'Minify JavaScript'
task :minify => [:init, :concat, :concat_scenario, :concat_jstd_scenario_adapter] do
[ 'angular.js',
'angular-cookies.js',
'angular-loader.js',
'angular-resource.js',
'angular-sanitize.js',
'angular-bootstrap.js',
'angular-bootstrap-prettify.js'
].each do |file|
unless ENV['TRAVIS']
fork { closure_compile(file) }
else
closure_compile(file)
end
end
Process.waitall
end
desc 'Generate version.txt and version.json files'
task :version => [:init] do
`echo #{NG_VERSION.full} > #{path_to('version.txt')}`
`echo '{
"full": "#{NG_VERSION.full}",
"major": "#{NG_VERSION.major}",
"minor": "#{NG_VERSION.minor}",
"dot": "#{NG_VERSION.dot}",
"codename": "#{NG_VERSION.codename}"\n}' > #{path_to('version.json')}`
end
desc 'Generate docs'
task :docs => [:init] do
`node docs/src/gen-docs.js`
[ path_to('docs/.htaccess'),
path_to('docs/index.html'),
path_to('docs/index-debug.html'),
path_to('docs/index-nocache.html'),
path_to('docs/index-jq.html'),
path_to('docs/index-jq-debug.html'),
path_to('docs/index-jq-nocache.html'),
path_to('docs/docs-scenario.html')
].each do |src|
rewrite_file(src) do |content|
content.sub!('"NG_VERSION_FULL"', NG_VERSION.full).
sub('"NG_VERSION_STABLE"', NG_VERSION.stable)
end
end
end
desc 'Create angular distribution'
task :package => [:clean, :minify, :version, :docs] do
zip_dir = "angular-#{NG_VERSION.full}"
zip_file = "#{zip_dir}.zip"
FileUtils.ln_s BUILD_DIR, zip_dir
%x(zip -r #{zip_file} #{zip_dir})
FileUtils.rm zip_dir
FileUtils.mv zip_file, path_to(zip_file)
puts "Package created: #{path_to(zip_file)}"
end
desc 'Start development webserver'
task :webserver, :port do |t, args|
exec "node lib/nodeserver/server.js #{args[:port]}"
end
desc 'Run all AngularJS tests'
task :test, :browsers, :misc_options do |t, args|
[ 'test:jqlite',
'test:jquery',
'test:modules',
'test:e2e'
].each do |task|
Rake::Task[task].invoke(args[:browsers], args[:misc_options])
end
end
namespace :test do
desc 'Run all unit tests (single run)'
task :unit, :browsers, :misc_options do |t, args|
[ 'test:jqlite',
'test:jquery',
'test:modules'
].each do |task|
Rake::Task[task].invoke(args[:browsers], args[:misc_options])
end
end
desc 'Run jqLite-based unit test suite (single run)'
task :jqlite, :browsers, :misc_options do |t, args|
start_testacular('testacular-jqlite.conf.js', true, args[:browsers], args[:misc_options])
end
desc 'Run jQuery-based unit test suite (single run)'
task :jquery, :browsers, :misc_options do |t, args|
start_testacular('testacular-jquery.conf.js', true, args[:browsers], args[:misc_options])
end
desc 'Run bundled modules unit test suite (single run)'
task :modules, :browsers, :misc_options do |t, args|
start_testacular('testacular-modules.conf.js', true, args[:browsers], args[:misc_options])
end
desc 'Run e2e test suite (single run)'
task :e2e, :browsers, :misc_options do |t, args|
start_testacular('testacular-e2e.conf.js', true, args[:browsers], args[:misc_options])
end
end
namespace :autotest do
desc 'Run jqLite-based unit test suite (autowatch)'
task :jqlite, :browsers, :misc_options do |t, args|
start_testacular('testacular-jqlite.conf.js', false, args[:browsers], args[:misc_options])
end
desc 'Run jQuery-based unit test suite (autowatch)'
task :jquery, :browsers, :misc_options do |t, args|
start_testacular('testacular-jquery.conf.js', false, args[:browsers], args[:misc_options])
end
end
###################
# utility methods #
###################
##
# generates css snippet from a given files and optionally applies simple minification rules
#
def gen_css(cssFile, minify = false)
css = ''
File.open(cssFile, 'r') do |f|
css = f.read
end
if minify
css.gsub! /\n/, ''
css.gsub! /\/\*.*?\*\//, ''
css.gsub! /:\s+/, ':'
css.gsub! /\s*\{\s*/, '{'
css.gsub! /\s*\}\s*/, '}'
css.gsub! /\s*\,\s*/, ','
css.gsub! /\s*\;\s*/, ';'
end
#escape for js
css.gsub! /\\/, "\\\\\\"
css.gsub! /'/, "\\\\'"
css.gsub! /\n/, "\\n"
return %Q{angular.element(document).find('head').append('<style type="text/css">#{css}</style>');}
end
##
# returns path to the file in the build directory
#
def path_to(filename)
return File.join(BUILD_DIR, *filename)
end
##
# returns the 32-bit mode force flags for java compiler if supported, this makes the build much
# faster
#
def java32flags
return '-d32 -client' unless Rake::Win32.windows? || `java -version -d32 2>&1`.match(/Error/i)
end
def closure_compile(filename)
puts "Minifying #{filename} ..."
min_path = path_to(filename.gsub(/\.js$/, '.min.js'))
%x(java \
#{java32flags()} \
-jar lib/closure-compiler/compiler.jar \
--compilation_level SIMPLE_OPTIMIZATIONS \
--language_in ECMASCRIPT5_STRICT \
--js #{path_to(filename)} \
--js_output_file #{min_path})
rewrite_file(min_path) do |content|
content.sub!("'use strict';", "").
sub!(/\(function\([^)]*\)\{/, "\\0'use strict';")
end
end
def concat_file(filename, deps, footer='')
puts "Creating #{filename} ..."
File.open(path_to(filename), 'w') do |f|
concat = 'cat ' + deps.flatten.join(' ')
content = %x{#{concat}}.
gsub('"NG_VERSION_FULL"', NG_VERSION.full).
gsub('"NG_VERSION_MAJOR"', NG_VERSION.major).
gsub('"NG_VERSION_MINOR"', NG_VERSION.minor).
gsub('"NG_VERSION_DOT"', NG_VERSION.dot).
gsub('"NG_VERSION_CODENAME"', NG_VERSION.codename).
gsub(/^\s*['"]use strict['"];?\s*$/, ''). # remove all file-specific strict mode flags
sub(/\(function\([^)]*\)\s*\{/, "\\0\n'use strict';") # add single strict mode flag
f.write(content)
f.write(footer)
end
end
def concat_module(name, files, footer='')
concat_file('angular-' + name + '.js', ['src/module.prefix'] + files + ['src/module.suffix'], footer)
end
def rewrite_file(filename)
File.open(filename, File::RDWR) do |f|
content = f.read
content = yield content
raise "File rewrite failed - No content!" unless content
f.truncate 0
f.rewind
f.write content
end
end
def start_testacular(config, singleRun, browsers, misc_options)
sh "./node_modules/testacular/bin/testacular start " +
"#{config} " +
"#{'--single-run=true' if singleRun} " +
"#{'--browsers=' + browsers.gsub('+', ',') if browsers} " +
"#{(misc_options || '').gsub('+', ',')}"
end
+1 -1
View File
@@ -201,7 +201,7 @@ if (exports) {
var files = [];
[].splice.call(arguments, 0).forEach(function(file) {
if (file.match(/testacular/)) {
if (file.match(/karma/)) {
files.push(file);
} else {
angularFiles[file].forEach(function(f) {
+1 -1
View File
@@ -1,5 +1,5 @@
#!/bin/bash
rake minify
grunt minify
gzip -c < build/angular.min.js > build/angular.min.js.gzip
ls -l build/angular.min.*
+3 -3
View File
@@ -234,7 +234,7 @@ The separation of the controller and the view is important because:
The model is the data which is used merged with the template to produce the view. To be able to
render the model into the view, the model has to be able to be referenced from the scope. Unlike many
other frameworks Angular makes no restrictions or requirements an the model. There are no classes
other frameworks Angular makes no restrictions or requirements on the model. There are no classes
to inherit from or special accessor methods for accessing or changing the model. The model can be
primitive, object hash, or a full object Type. In short the model is a plain JavaScript object.
@@ -248,9 +248,9 @@ primitive, object hash, or a full object Type. In short the model is a plain Jav
<img class="pull-right" style="padding-left: 3em; padding-bottom: 1em;" src="img/guide/concepts-view.png">
The view is what the users sees. The view begins its life as a template, it is merged with the
The view is what the user sees. The view begins its life as a template, is merged with the
model and finally rendered into the browser DOM. Angular takes a very different approach to
rendering the view, compared to most other templating systems.
rendering the view compared to most other templating systems.
* **Others** - Most templating systems begin as an HTML string with special templating markup.
Often the template markup breaks the HTML syntax which means that the template can not be
@@ -178,8 +178,9 @@ have a look at an example:
<body ng-controller="MainCtrl">
<p>Good {{timeOfDay}}, {{name}}!</p>
<div ng-controller="ChildCtrl">
<p>Good {{timeOfDay}}, {{name}}!</p>
<p ng-controller="BabyCtrl">Good {{timeOfDay}}, {{name}}!</p>
<p>Good {{timeOfDay}}, {{name}}!</p>
<p ng-controller="BabyCtrl">Good {{timeOfDay}}, {{name}}!</p>
</div>
</body>
function MainCtrl($scope) {
@@ -2,9 +2,7 @@
@name Developer Guide: Templates: Understanding Angular Filters
@description
Angular filters format data for display to the user. In addition to formatting data, filters can
also modify the DOM. This allows filters to handle tasks such as conditionally applying CSS styles
to filtered output.
Angular filters format data for display to the user.
For example, you might have a data object that needs to be formatted according to the locale before
displaying it to the user. You can pass expressions through a chain of filters like this:
+1 -1
View File
@@ -213,7 +213,7 @@ services, and filters. The factory methods are registered with the module, and t
of declaring factories is:
<pre>
angualar.module('myModule', []).
angular.module('myModule', []).
config(['depProvider', function(depProvider){
...
}]).
+11 -10
View File
@@ -39,11 +39,11 @@ the following example.
</script>
<div ng-controller="Ctrl1">
Hello <input ng-model='name'> <hr/>
&ltspan ng:bind="name"&gt <span ng:bind="name"></span> <br/>
&ltspan ng_bind="name"&gt <span ng_bind="name"></span> <br/>
&ltspan ng-bind="name"&gt <span ng-bind="name"></span> <br/>
&ltspan data-ng-bind="name"&gt <span data-ng-bind="name"></span> <br/>
&ltspan x-ng-bind="name"&gt <span x-ng-bind="name"></span> <br/>
&lt;span ng:bind="name"&gt; <span ng:bind="name"></span> <br/>
&lt;span ng_bind="name"&gt; <span ng_bind="name"></span> <br/>
&lt;span ng-bind="name"&gt; <span ng-bind="name"></span> <br/>
&lt;span data-ng-bind="name"&gt; <span data-ng-bind="name"></span> <br/>
&lt;span x-ng-bind="name"&gt; <span x-ng-bind="name"></span> <br/>
</div>
</doc:source>
<doc:scenario>
@@ -95,7 +95,7 @@ Compilation of HTML happens in three phases:
var $compile = ...; // injected into your code
var scope = ...;
var html = '<div ng-bind='exp'></div>';
var html = '<div ng-bind="exp"></div>';
// Step 1: parse HTML into DOM element
var template = angular.element(html);
@@ -206,7 +206,7 @@ In this example we will build a directive that displays the current time.
}
// listen on DOM destroy (removal) event, and cancel the next UI update
// to prevent updating time ofter the DOM element was removed.
// to prevent updating time after the DOM element was removed.
element.bind('$destroy', function() {
$timeout.cancel(timeoutId);
});
@@ -355,7 +355,7 @@ compiler}. The attributes are:
* `$scope` - Current scope associated with the element
* `$element` - Current element
* `$attrs` - Current attributes obeject for the element
* `$attrs` - Current attributes object for the element
* `$transclude` - A transclude linking function pre-bound to the correct transclusion scope:
`function(cloneLinkingFn)`.
@@ -376,8 +376,8 @@ compiler}. The attributes are:
* `M` - Comment: `<!-- directive: my-directive exp -->`
* `template` - replace the current element with the contents of the HTML. The replacement process
migrates all of the attributes / classes from the old element to the new one. See Creating
Widgets section below for more information.
migrates all of the attributes / classes from the old element to the new one. See the
{@link guide/directive#Components Creating Components} section below for more information.
* `templateUrl` - Same as `template` but the template is loaded from the specified URL. Because
the template loading is asynchronous the compilation/linking is suspended until the template
@@ -601,6 +601,7 @@ restrict: 'E',
replace: true
</pre>
<a name="Components"></a>
# Creating Components
It is often desirable to replace a single directive with a more complex DOM structure. This
+1 -1
View File
@@ -278,7 +278,7 @@ However, if you need more flexibility, you can write your own form control as a
In order for custom control to work with `ngModel` and to achieve two-way data-binding it needs to:
- implement `render` method, which is responsible for rendering the data after it passed the {@link api/ng.directive:ngModel.NgModelController#$formatters NgModelController#$formatters},
- implement `$render` method, which is responsible for rendering the data after it passed the {@link api/ng.directive:ngModel.NgModelController#$formatters NgModelController#$formatters},
- call `$setViewValue` method, whenever the user interacts with the control and model needs to be updated. This is usually done inside a DOM Event listener.
See {@link guide/directive $compileProvider.directive} for more info.
+3 -3
View File
@@ -158,9 +158,9 @@ angular.module('myModule', []).
angular.module('myModule', []).
config(function($provide, $compileProvider, $filterProvider) {
$provide.value('a', 123)
$provide.factory('a', function() { return 123; })
$compileProvider.directive('directiveName', ...).
$provide.value('a', 123);
$provide.factory('a', function() { return 123; });
$compileProvider.directive('directiveName', ...);
$filterProvider.register('filterName', ...);
});
</pre>
+30 -17
View File
@@ -81,15 +81,11 @@ Several steps are needed to check out and build AngularJS:
Before you can build AngularJS, you must install or configure the following dependencies on your
machine:
* {@link http://rake.rubyforge.org Rake}: We use Rake as our build system, which is pre-installed
on most Macintosh and Linux machines. If that is not true in your case, you can grab it from the
Rake website.
* Git: The {@link http://help.github.com/mac-git-installation Github Guide to Installing Git} is
quite a good source for information on Git.
* {@link http://nodejs.org Node.js}: We use Node to generate the documentation and to run a
development web server. Depending on your system, you can install Node either from source or as a
* {@link http://nodejs.org Node.js}: We use Node to generate the documentation, run a
development web server, run tests, and generate a build. Depending on your system, you can install Node either from source or as a
pre-packaged bundle.
Once installed, you'll also need several npms (node packages), which you can install once you checked out a local copy
@@ -98,6 +94,10 @@ pre-packaged bundle.
* `cd angular.js`
* `npm install`
* {@link http://gruntjs.com Grunt}: We use Grunt as our build system. Install the grunt command-line tool globally with:
* `sudo npm install -g grunt-cli`
## Creating a Github Account and Forking Angular
@@ -108,7 +108,7 @@ https://github.com/angular/angular.js main angular repository}.
## Building AngularJS
To build AngularJS, you check out the source code and use Rake to generate the non-minified and
To build AngularJS, you check out the source code and use Grunt to generate the non-minified and
minified AngularJS files:
1. To clone your Github repository, run:
@@ -129,7 +129,11 @@ minified AngularJS files:
5. To build AngularJS, run:
rake package
grunt package
NOTE: If you're using Windows you must run your command line with administrative privileges (right click, run as
Administrator).
The build output can be located under the `build` directory. It consists of the following files and
directories:
@@ -158,7 +162,7 @@ made available a local web server based on Node.js.
1. To start the web server, run:
rake webserver
grunt webserver
2. To access the local server, go to this website:
@@ -173,18 +177,20 @@ made available a local web server based on Node.js.
Our unit and integration tests are written with Jasmine and executed with Testacular. To run all of the
tests once on Chrome run:
rake test:unit
grunt test:unit
To run the tests on other browsers (Chrome, ChromeCanary, Firefox, Opera and Safari are pre-configured) use:
rake test:unit[Opera+Firefox]
grunt test:unit --browsers Opera,Firefox
Note there should be _no spaces between browsers_. `Opera, Firefox` is INVALID.
During development it's however more productive to continuously run unit tests every time the source or test files
change. To execute tests in this mode run:
1. To start the Testacular server, capture Chrome browser and run unit tests, run:
rake autotest:jqlite
grunt autotest:jqlite
2. To capture more browsers, open this url in the desired browser (url might be different if you have multiple instance
of Testacular running, read Testacular's console output for the correct url):
@@ -194,9 +200,9 @@ change. To execute tests in this mode run:
3. To re-run tests just change any source or test file.
To learn more about all of the preconfigured Rake tasks run:
To learn more about all of the preconfigured Grunt tasks run:
rake -T
grunt --help
## Running the end-to-end Test Suite
@@ -205,7 +211,7 @@ To run the E2E test suite:
1. Start the local web server if it's not running already.
rake webserver
grunt webserver
2. In a browser, go to:
@@ -213,7 +219,13 @@ To run the E2E test suite:
or in terminal run:
rake test:e2e
grunt test:end2end
For convenience you can also simply run:
grunt test:e2e
This will start the webserver for you and run the tests.
@@ -222,7 +234,8 @@ To run the E2E test suite:
To create and submit a change:
1. Please sign our Contributor License Agreement (CLA) before sending pull requests. For any code changes to be
1. <a name="CLA"></a>
Please sign our Contributor License Agreement (CLA) before sending pull requests. For any code changes to be
accepted, the CLA must be signed. It's a quick process, we promise!
For individuals we have a [simple click-through form](http://code.google.com/legal/individual-cla-v1.0.html). For
+2 -2
View File
@@ -109,7 +109,7 @@ __`app/index.html`:__
<html ng-app>
The `ng-app` attribute is represents an Angular directive (named `ngApp`; Angular uses
The `ng-app` attribute represents an Angular directive (named `ngApp`; Angular uses
`name-with-dashes` for attribute names and `camelCase` for the corresponding directive name)
used to flag an element which Angular should consider to be the root element of our application.
This gives application developers the freedom to tell Angular if the entire html page or only a
@@ -127,7 +127,7 @@ being the element on which the `ngApp` directive was defined.
* Double-curly binding with an expression:
Nothing here {{'yet' + '!'}}`
Nothing here {{'yet' + '!'}}
This line demonstrates the core feature of Angular's templating capabilities a binding, denoted
by double-curlies `{{ }}` as well as a simple expression `'yet' + '!'` used in this binding.
+23 -5
View File
@@ -55,12 +55,15 @@ describe('ngdoc', function() {
'@name a\n' +
'@param {*} a short\n' +
'@param {Type} b med\n' +
'@param {Class=} [c=2] long\nline');
'@param {Class=} [c=2] long\nline\n' +
'@param {function(number, string=)} d fn with optional arguments');
doc.parse();
expect(doc.param).toEqual([
{name:'a', description:'<p>short</p>', type:'*', optional:false, 'default':undefined},
{name:'b', description:'<p>med</p>', type:'Type', optional:false, 'default':undefined},
{name:'c', description:'<p>long\nline</p>', type:'Class', optional:true, 'default':'2'}
{name:'c', description:'<p>long\nline</p>', type:'Class', optional:true, 'default':'2'},
{name:'d', description:'<p>fn with optional arguments</p>',
type: 'function(number, string=)', optional: false, 'default':undefined}
]);
});
@@ -318,9 +321,9 @@ describe('ngdoc', function() {
});
it('should not parse @property without a type', function() {
var doc = new Doc("@property fake");
var doc = new Doc("@property fake", 'test.js', '44');
expect(function() { doc.parse(); }).
toThrow(new Error("Not a valid 'property' format: fake"));
toThrow(new Error("Not a valid 'property' format: fake (found in: test.js:44)"));
});
it('should parse @property with type', function() {
@@ -350,15 +353,30 @@ describe('ngdoc', function() {
describe('@returns', function() {
it('should not parse @returns without type', function() {
var doc = new Doc("@returns lala");
expect(doc.parse).toThrow();
expect(function() { doc.parse(); }).
toThrow();
});
it('should not parse @returns with invalid type', function() {
var doc = new Doc("@returns {xx}x} lala", 'test.js', 34);
expect(function() { doc.parse(); }).
toThrow(new Error("Not a valid 'returns' format: {xx}x} lala (found in: test.js:34)"));
});
it('should parse @returns with type and description', function() {
var doc = new Doc("@name a\n@returns {string} descrip tion");
doc.parse();
expect(doc.returns).toEqual({type: 'string', description: '<p>descrip tion</p>'});
});
it('should parse @returns with complex type and description', function() {
var doc = new Doc("@name a\n@returns {function(string, number=)} description");
doc.parse();
expect(doc.returns).toEqual({type: 'function(string, number=)', description: '<p>description</p>'});
});
it('should transform description of @returns with markdown', function() {
var doc = new Doc("@name a\n@returns {string} descrip *tion*");
doc.parse();
+5 -9
View File
@@ -5,10 +5,6 @@ var reader = require('./reader.js'),
appCache = require('./appCache.js').appCache,
Q = require('qq');
process.on('uncaughtException', function(err) {
console.error(err.stack || err);
});
var start = now();
var docs;
@@ -36,16 +32,16 @@ writer.makeDir('build/docs/', true).then(function() {
});
}).then(function printStats() {
console.log('DONE. Generated ' + docs.length + ' pages in ' + (now()-start) + 'ms.' );
}).done();
});
function writeTheRest(writesFuture) {
var metadata = ngdoc.metadata(docs);
writesFuture.push(writer.symlinkTemplate('css'));
writesFuture.push(writer.symlinkTemplate('font'));
writesFuture.push(writer.symlink('../../docs/img', 'build/docs/img'));
writesFuture.push(writer.symlinkTemplate('js'));
writesFuture.push(writer.symlinkTemplate('css', 'dir'));
writesFuture.push(writer.symlinkTemplate('font', 'dir'));
writesFuture.push(writer.symlink('../../docs/img', 'build/docs/img', 'dir'));
writesFuture.push(writer.symlinkTemplate('js', 'dir'));
var manifest = 'manifest="/build/docs/appcache.manifest"';
+59 -43
View File
@@ -203,7 +203,7 @@ Doc.prototype = {
flush();
this.shortName = this.name.split(/[\.:#]/).pop().trim();
this.id = this.id || // if we have an id just use it
(((this.file||'').match(/.*\/([^\/]*)\.ngdoc/)||{})[1]) || // try to extract it from file name
(((this.file||'').match(/.*(\/|\\)([^(\/|\\)]*)\.ngdoc/)||{})[2]) || // try to extract it from file name
this.name; // default to name
this.description = this.markdown(this.description);
this.example = this.markdown(this.example);
@@ -214,23 +214,25 @@ Doc.prototype = {
if (atName) {
var text = trim(atText.join('\n')), match;
if (atName == 'param') {
match = text.match(/^\{([^}=]+)(=)?\}\s+(([^\s=]+)|\[(\S+)=([^\]]+)\])\s+(.*)/);
// 1 12 2 34 4 5 5 6 6 3 7 7
match = text.match(/^\{([^}]+)\}\s+(([^\s=]+)|\[(\S+)=([^\]]+)\])\s+(.*)/);
// 1 1 23 3 4 4 5 5 2 6 6
if (!match) {
throw new Error("Not a valid 'param' format: " + text);
throw new Error("Not a valid 'param' format: " + text + ' (found in: ' + self.file + ':' + self.line + ')');
}
var optional = (match[1].slice(-1) === '=');
var param = {
name: match[5] || match[4],
description:self.markdown(text.replace(match[0], match[7])),
type: match[1],
optional: !!match[2],
'default':match[6]
name: match[4] || match[3],
description:self.markdown(text.replace(match[0], match[6])),
type: optional ? match[1].substring(0, match[1].length-1) : match[1],
optional: optional,
'default':match[5]
};
self.param.push(param);
} else if (atName == 'returns' || atName == 'return') {
match = text.match(/^\{([^}=]+)\}\s+(.*)/);
match = text.match(/^\{([^}]+)\}\s+(.*)/);
if (!match) {
throw new Error("Not a valid 'returns' format: " + text + ' in ' + self.file + ':' + self.line);
throw new Error("Not a valid 'returns' format: " + text + ' (found in: ' + self.file + ':' + self.line + ')');
}
self.returns = {
type: match[1],
@@ -245,7 +247,7 @@ Doc.prototype = {
} else if(atName == 'property') {
match = text.match(/^\{(\S+)\}\s+(\S+)(\s+(.*))?/);
if (!match) {
throw new Error("Not a valid 'property' format: " + text);
throw new Error("Not a valid 'property' format: " + text + ' (found in: ' + self.file + ':' + self.line + ')');
}
var property = new Doc({
type: match[1],
@@ -270,8 +272,9 @@ Doc.prototype = {
self = this;
dom.h(title(this.name), function() {
notice('deprecated', 'Deprecated API', self.deprecated);
notice('deprecated', 'Deprecated API', self.deprecated);
dom.tag('a', {href: 'http://github.com/angular/angular.js/edit/master/' + self.file, class: 'improve-docs btn btn-primary'}, 'Improve this doc');
if (self.ngdoc != 'overview') {
dom.h('Description', self.description, dom.html);
}
@@ -383,40 +386,53 @@ Doc.prototype = {
var self = this;
dom.h('Usage', function() {
var restrict = self.restrict || 'AC';
if (restrict.match(/E/)) {
dom.text('as element (see ');
dom.text('This directive can be used as custom element, but we aware of ');
dom.tag('a', {href:'guide/ie'}, 'IE restrictions');
dom.text(')');
dom.code(function() {
dom.text('<');
dom.text(dashCase(self.shortName));
renderParams('\n ', '="', '"');
dom.text('>\n</');
dom.text(dashCase(self.shortName));
dom.text('>');
});
dom.text('.');
}
if (restrict.match(/A/)) {
var element = self.element || 'ANY';
dom.text('as attribute');
dom.code(function() {
dom.text('<' + element + ' ');
dom.text(dashCase(self.shortName));
renderParams('\n ', '="', '"', true);
dom.text('>\n ...\n');
dom.text('</' + element + '>');
});
}
if (restrict.match(/C/)) {
dom.text('as class');
var element = self.element || 'ANY';
dom.code(function() {
dom.text('<' + element + ' class="');
dom.text(dashCase(self.shortName));
renderParams(' ', ': ', ';', true);
dom.text('">\n ...\n');
dom.text('</' + element + '>');
if (self.usage) {
dom.tag('pre', function() {
dom.tag('code', function() {
dom.text(self.usage);
});
});
} else {
if (restrict.match(/E/)) {
dom.text('as element:');
dom.code(function() {
dom.text('<');
dom.text(dashCase(self.shortName));
renderParams('\n ', '="', '"');
dom.text('>\n</');
dom.text(dashCase(self.shortName));
dom.text('>');
});
}
if (restrict.match(/A/)) {
var element = self.element || 'ANY';
dom.text('as attribute');
dom.code(function() {
dom.text('<' + element + ' ');
dom.text(dashCase(self.shortName));
renderParams('\n ', '="', '"', true);
dom.text('>\n ...\n');
dom.text('</' + element + '>');
});
}
if (restrict.match(/C/)) {
dom.text('as class');
var element = self.element || 'ANY';
dom.code(function() {
dom.text('<' + element + ' class="');
dom.text(dashCase(self.shortName));
renderParams(' ', ': ', ';', true);
dom.text('">\n ...\n');
dom.text('</' + element + '>');
});
}
}
self.html_usage_directiveInfo(dom);
self.html_usage_parameters(dom);
+3 -2
View File
@@ -7,7 +7,8 @@ exports.collect = collect;
var ngdoc = require('./ngdoc.js'),
Q = require('qq'),
qfs = require('q-fs');
qfs = require('q-fs'),
PATH = require('path');
var NEW_LINE = /\n\r?/;
@@ -43,7 +44,7 @@ function collect() {
var work2;
if (file.match(/\.ngdoc$/)) {
work2 = Q.when(qfs.read(file, 'b'), function(content){
var section = '@section ' + file.split('/')[2] + '\n';
var section = '@section ' + file.split(PATH.sep)[2] + '\n';
allDocs.push(new ngdoc.Doc(section + content.toString(),file, 1).parse());
});
}
+1 -1
View File
@@ -4,7 +4,7 @@
# current angular version. If this rule matches the appcache-offline.manifest will be served for
# requests to appcache.manifest
#
# This file must be processed by Rake in order to replace %ANGULAR_VERSION% with the actual version.
# This file must be processed by Grunt in order to replace %ANGULAR_VERSION% with the actual version.
Options -Indexes
RewriteEngine on
+4
View File
@@ -86,6 +86,10 @@ img.AngularJS-small {
/* Content */
/* =============================== */
.improve-docs {
float: right;
}
.hint {
font-size: .7em;
color: #c0c0c0;
+4 -5
View File
@@ -61,22 +61,21 @@ exports.copy = function(from, to, transform) {
exports.symlink = symlink;
function symlink(from, to) {
function symlink(from, to, type) {
return qfs.exists(to).then(function(exists) {
if (!exists) {
return qfs.symbolicLink(to, from);
return qfs.symbolicLink(to, from, type);
}
});
}
exports.symlinkTemplate = symlinkTemplate;
function symlinkTemplate(filename) {
function symlinkTemplate(filename, type) {
var dest = OUTPUT_DIR + filename,
dirDepth = dest.split('/').length,
src = Array(dirDepth).join('../') + 'docs/src/templates/' + filename;
return symlink(src, dest);
return symlink(src, dest, type);
}
+158 -121
View File
@@ -16,14 +16,14 @@
/**
* @fileoverview A utility to get better currency format pattern.
*
* This module implement a new currency format representation model. It
* This module implements a new currency format representation model. It
* provides 3 currency representation forms: global, portable and local. Local
* format is the most popular format people use to represent currency in its
* circulating country without worrying about how it should be distinguished
* from other currencies. Global format is a formal representation in context
* of multiple currencies in same page, it is ISO 4217 currency code. Portable
* format is a compromise between global and local. It looks similar to how
* people would like to see how their currencies is being represented in other
* people would like to see how their currency is being represented in other
* media. While at the same time, it should be distinguishable to world's
* popular currencies (like USD, EUR) and currencies somewhat relevant in the
* area (like CNY in HK, though native currency is HKD). There is no guarantee
@@ -43,15 +43,14 @@ goog.i18n.currency.PRECISION_MASK_ = 0x07;
/**
* If this flag is set, it means the currency sign should position before
* number.
* Whether the currency sign should be positioned after the number.
* @private
*/
goog.i18n.currency.POSITION_FLAG_ = 0x08;
/**
* Should a space to inserted between number and currency sign.
* Whether a space should be inserted between the number and currency sign.
* @private
*/
goog.i18n.currency.SPACE_FLAG_ = 0x20;
@@ -59,8 +58,8 @@ goog.i18n.currency.SPACE_FLAG_ = 0x20;
/**
* This function will add tier2 currency support. Be default, only tier1
* (most popular currencies) are supportted. If an application really need
* to support some of the rarely used currency, it should call this function
* (most popular currencies) are supported. If an application really needs
* to support some of the rarely used currencies, it should call this function
* before any other functions in this namespace.
*/
goog.i18n.currency.addTier2Support = function() {
@@ -75,8 +74,8 @@ goog.i18n.currency.addTier2Support = function() {
* Global currency pattern always uses ISO-4217 currency code as prefix. Local
* currency sign is added if it is different from currency code. Each currency
* is unique in this form. The negative side is that ISO code looks weird in
* some countries as poeple normally do not use it. Local currency sign
* alleviate the problem, but also make it a little verbose.
* some countries as people normally do not use it. Local currency sign
* alleviates the problem, but also makes it a little verbose.
*
* @param {string} currencyCode ISO-4217 3-letter currency code.
* @return {string} Global currency pattern string for given currency.
@@ -85,9 +84,6 @@ goog.i18n.currency.getGlobalCurrencyPattern = function(currencyCode) {
var info = goog.i18n.currency.CurrencyInfo[currencyCode];
var patternNum = info[0];
if (currencyCode == info[1]) {
if ((patternNum & goog.i18n.currency.POSITION_FLAG_) == 0) {
patternNum |= goog.i18n.currency.SPACE_FLAG_;
}
return goog.i18n.currency.getCurrencyPattern_(patternNum, info[1]);
}
return currencyCode + ' ' +
@@ -104,10 +100,8 @@ goog.i18n.currency.getGlobalCurrencyPattern = function(currencyCode) {
*/
goog.i18n.currency.getGlobalCurrencySign = function(currencyCode) {
var info = goog.i18n.currency.CurrencyInfo[currencyCode];
if (currencyCode == info[1]) {
return currencyCode;
}
return currencyCode + ' ' + info[1];
return (currencyCode == info[1]) ? currencyCode :
currencyCode + ' ' + info[1];
};
@@ -128,6 +122,7 @@ goog.i18n.currency.getLocalCurrencyPattern = function(currencyCode) {
/**
* Returns local currency sign string for those applications that need to
* handle currency sign separately.
*
* @param {string} currencyCode ISO-4217 3-letter currency code.
* @return {string} Local currency sign for given currency.
*/
@@ -156,6 +151,7 @@ goog.i18n.currency.getPortableCurrencyPattern = function(currencyCode) {
/**
* Return portable currency sign string for those applications that need to
* handle currency sign themselves.
*
* @param {string} currencyCode ISO-4217 3-letter currency code.
* @return {string} Portable currency sign for given currency.
*/
@@ -165,10 +161,13 @@ goog.i18n.currency.getPortableCurrencySign = function(currencyCode) {
/**
* This function returns the default currency sign position. Some application
* This function returns the default currency sign position. Some applications
* may want to handle currency sign and currency amount separately. This
* function can be used in such situation to position the currency sign
* relative to amount field correctly.
* function can be used in such situations to correctly position the currency
* sign relative to the amount.
*
* To match the behavior of ICU, position is not determined by display locale.
*
* @param {string} currencyCode ISO-4217 3-letter currency code.
* @return {boolean} true if currency should be positioned before amount field.
*/
@@ -179,13 +178,12 @@ goog.i18n.currency.isPrefixSignPosition = function(currencyCode) {
/**
* This function construct the currency pattern. Currency sign is provided. The
* This function constructs the currency pattern. Currency sign is provided. The
* pattern information is encoded in patternNum.
*
* @param {number} patternNum Encoded pattern number that has
* currency pattern information.
* @param {string} sign the currency sign that will be used in pattern.
*
* @param {string} sign The currency sign that will be used in pattern.
* @return {string} currency pattern string.
* @private
*/
@@ -211,56 +209,97 @@ goog.i18n.currency.getCurrencyPattern_ = function(patternNum, sign) {
};
/**
* Modify currency pattern string by adjusting precision for given currency.
* Standard currency pattern will have 2 digit after decimal point.
* Examples:
* $#,##0.00 -> $#,##0 (precision == 0)
* $#,##0.00 -> $#,##0.0 (precision == 1)
* $#,##0.00 -> $#,##0.000 (precision == 3)
*
* @param {string} pattern currency pattern string.
* @param {string} currencyCode 3-letter currency code.
* @return {string} modified currency pattern string.
*/
goog.i18n.currency.adjustPrecision = function(pattern, currencyCode) {
var strParts = ['0'];
var info = goog.i18n.currency.CurrencyInfo[currencyCode];
var precision = info[0] & goog.i18n.currency.PRECISION_MASK_;
if (precision > 0) {
strParts.push('.');
for (var i = 0; i < precision; i++) {
strParts.push('0');
}
}
return pattern.replace(/0.00/g, strParts.join(''));
};
/**
* Tier 1 currency information.
*
* The first number in the array is a combination of the precision mask and
* other flags. The precision mask indicates how many decimal places to show for
* the currency. Valid values are [0..7]. The position flag indicates whether
* the currency sign should be positioned after the number. Valid values are 0
* (before the number) or 16 (after the number). The space flag indicates
* whether a space should be inserted between the currency sign and number.
* Valid values are 0 (no space) and 24 (space).
*
* The number in the array is calculated by adding together the mask and flag
* values. For example:
*
* 0: no precision (0), currency sign first (0), no space (0)
* 2: two decimals precision (2), currency sign first (0), no space (0)
* 18: two decimals precision (2), currency sign last (16), no space (0)
* 42: two decimals precision (2), currency sign last (16), space (24)
*
* @type {!Object.<!Array>}
*/
goog.i18n.currency.CurrencyInfo = {
'AED': [2, '\u062F\u002e\u0625', 'DH'],
'ARS': [2, '$', 'AR$'],
'AED': [2, 'dh', '\u062f.\u0625.', 'DH'],
'AUD': [2, '$', 'AU$'],
'BDT': [2, '\u09F3', 'Tk'],
'BRL': [2, 'R$', 'R$'],
'CAD': [2, '$', 'C$'],
'CHF': [2, 'Fr.', 'CHF'],
'CHF': [2, 'CHF', 'CHF'],
'CLP': [0, '$', 'CL$'],
'CNY': [2, '¥', 'RMB¥'],
'COP': [2, '$', 'COL$'],
'CRC': [2, '\u20a1', 'CR'],
'CUP': [2, '$', '$MN'],
'CZK': [10, '', ''],
'DKK': [26, 'kr', 'kr'],
'COP': [0, '$', 'COL$'],
'CRC': [0, '\u20a1', 'CR\u20a1'],
'CZK': [2, 'K\u010d', 'K\u010d'],
'DKK': [18, 'kr', 'kr'],
'DOP': [2, '$', 'RD$'],
'EGP': [2, '£', 'LE'],
'EUR': [26, '€', '€'],
'EUR': [18, '€', '€'],
'GBP': [2, '£', 'GB£'],
'HKD': [2, '$', 'HK$'],
'ILS': [10, '\u20AA', 'IL'],
'INR': [2, 'Rs', 'Rs'],
'ISK': [10, 'kr', 'kr'],
'ILS': [2, '\u20AA', 'IL\u20AA'],
'INR': [2, '\u20B9', 'Rs'],
'ISK': [0, 'kr', 'kr'],
'JMD': [2, '$', 'JA$'],
'JPY': [0, '¥', 'JP¥'],
'KRW': [0, '\u20A9', 'KR₩'],
'LKR': [2, 'Rs', 'SLRs'],
'MNT': [2, '\u20AE', 'MN₮'],
'MNT': [0, '\u20AE', 'MN₮'],
'MXN': [2, '$', 'Mex$'],
'MYR': [2, 'RM', 'RM'],
'NOK': [26, 'kr', 'NOkr'],
'NOK': [18, 'kr', 'NOkr'],
'PAB': [2, 'B/.', 'B/.'],
'PEN': [2, 'S/.', 'S/.'],
'PHP': [2, 'P', 'PHP'],
'PKR': [2, 'Rs.', 'PKRs.'],
'RUB': [10, 'руб', 'руб'],
'SAR': [2, '\u0633\u002E\u0631', 'SR'],
'SEK': [10, 'kr', 'kr'],
'PHP': [2, '\u20B1', 'Php'],
'PKR': [0, 'Rs', 'PKRs.'],
'RUB': [42, 'руб.', 'руб.'],
'SAR': [2, 'Rial', 'Rial'],
'SEK': [2, 'kr', 'kr'],
'SGD': [2, '$', 'S$'],
'THB': [2, '\u0e3f', 'THB'],
'TRY': [2, 'YTL', 'YTL'],
'TRY': [2, 'TL', 'YTL'],
'TWD': [2, 'NT$', 'NT$'],
'USD': [2, '$', 'US$'],
'UYU': [2, '$', 'UY$'],
'VND': [10, '\u20AB', 'VN'],
'YER': [2, 'YER', 'YER'],
'VND': [0, '\u20AB', 'VN\u20AB'],
'YER': [0, 'Rial', 'Rial'],
'ZAR': [2, 'R', 'ZAR']
};
@@ -270,116 +309,114 @@ goog.i18n.currency.CurrencyInfo = {
* @type {!Object.<!Array>}
*/
goog.i18n.currency.CurrencyInfoTier2 = {
'AFN': [18, '\u060b', 'AFN'],
'ALL': [2, 'Lek', 'Lek'],
'AMD': [10, '\u0564\u0580\u002e', 'dram'],
'ANG': [2, '\u0083', 'NAƒ'],
'AFN': [16, 'Af.', 'AFN'],
'ALL': [0, 'Lek', 'Lek'],
'AMD': [0, 'Dram', 'dram'],
'AOA': [2, 'Kz', 'Kz'],
'AWG': [2, 'ƒ', 'Afl.'],
'AZN': [2, 'm', 'man'],
'BAM': [18, 'КМ', 'KM'],
'ARS': [2, '$', 'AR$'],
'AWG': [2, 'Afl.', 'Afl.'],
'AZN': [2, 'man.', 'man.'],
'BAM': [18, 'KM', 'KM'],
'BBD': [2, '$', 'Bds$'],
'BGN': [10, '\u043b\u0432', 'лв'],
'BHD': [3, '\u0628\u002e\u062f\u002e', 'BD'],
'BGN': [2, 'lev', 'lev'],
'BHD': [3, 'din', 'din'],
'BIF': [0, 'FBu', 'FBu'],
'BMD': [2, '$', 'BD$'],
'BND': [2, '$', 'B$'],
'BOB': [2, 'B$', 'B$'],
'BSD': [2, '$', 'B$'],
'BOB': [2, 'Bs', 'Bs'],
'BSD': [2, '$', 'BS$'],
'BTN': [2, 'Nu.', 'Nu.'],
'BWP': [2, 'P', 'pula'],
'BYR': [0, 'Br', 'Br'],
'BYR': [0, 'BYR', 'BYR'],
'BZD': [2, '$', 'BZ$'],
'CDF': [2, 'F', 'CDF'],
'CVE': [2, '$', 'Esc'],
'CDF': [2, 'FrCD', 'CDF'],
'CUC': [1, '$', 'CUC$'],
'CUP': [2, '$', 'CU$'],
'CVE': [2, 'CVE', 'Esc'],
'DJF': [0, 'Fdj', 'Fdj'],
'DZD': [2, '\u062f\u062C', 'DA'],
'EEK': [10, 'EEK', 'EEK'],
'DZD': [2, 'din', 'din'],
'ERN': [2, 'Nfk', 'Nfk'],
'ETB': [2, 'Br', 'Br'],
'ETB': [2, 'Birr', 'Birr'],
'FJD': [2, '$', 'FJ$'],
'FKP': [2, '£', 'FK£'],
'GEL': [2, 'GEL', 'GEL'],
'GHS': [2, '\u20B5', 'GHS¢'],
'GHS': [2, 'GHS', 'GHS'],
'GIP': [2, '£', 'GI£'],
'GMD': [2, 'D', 'GMD'],
'GMD': [2, 'GMD', 'GMD'],
'GNF': [0, 'FG', 'FG'],
'GTQ': [2, 'Q', 'GTQ'],
'GYD': [2, '$', 'GY$'],
'GYD': [0, '$', 'GY$'],
'HNL': [2, 'L', 'HNL'],
'HRK': [2, 'kn', 'kn'],
'HTG': [2, 'G', 'HTG'],
'HUF': [10, 'Ft', 'Ft'],
'IDR': [2, 'Rp', 'Rp'],
'IQD': [3, '\u0639\u062F', 'IQD'],
'IRR': [2, '\ufdfc', 'IRR'],
'JOD': [3, 'JOD', 'JOD'],
'KES': [2, 'KSh', 'KSh'],
'KGS': [2, 'som', 'som'],
'KHR': [10, '\u17DB', 'KHR'],
'KMF': [0, 'KMF', 'KMF'],
'KPW': [2, '\u20A9', 'KPW'],
'KWD': [3, '\u062F\u002e\u0643', 'KWD'],
'KYD': [2, '$', 'CI$'],
'KZT': [10, 'KZT', 'KZT'],
'LAK': [2, '\u20AD', 'LA₭'],
'LBP': [2, '\u0644\u002e\u0644', 'LBP'],
'HTG': [2, 'HTG', 'HTG'],
'HUF': [0, 'Ft', 'Ft'],
'IDR': [0, 'Rp', 'Rp'],
'IQD': [0, 'din', 'IQD'],
'IRR': [0, 'Rial', 'IRR'],
'JOD': [3, 'din', 'JOD'],
'KES': [2, 'Ksh', 'Ksh'],
'KGS': [2, 'KGS', 'KGS'],
'KHR': [2, 'Riel', 'KHR'],
'KMF': [0, 'CF', 'KMF'],
'KPW': [0, '\u20A9KP', 'KPW'],
'KWD': [3, 'din', 'KWD'],
'KYD': [2, '$', 'KY$'],
'KZT': [2, '\u20B8', 'KZT'],
'LAK': [0, '\u20AD', '\u20AD'],
'LBP': [0, '', 'LBP'],
'LRD': [2, '$', 'L$'],
'LSL': [2, 'L', 'LSL'],
'LTL': [10, 'Lt', 'Lt'],
'LVL': [10, 'Ls', 'Ls'],
'LYD': [3, '\u0644\u002e\u062F', 'LD'],
'MAD': [2, '\u0645\u002E\u062F\u002E', 'MAD'],
'LSL': [2, 'LSL', 'LSL'],
'LTL': [2, 'Lt', 'Lt'],
'LVL': [2, 'Ls', 'Ls'],
'LYD': [3, 'din', 'LD'],
'MAD': [2, 'dh', 'MAD'],
'MDL': [2, 'MDL', 'MDL'],
'MGA': [1, 'MGA', 'MGA'],
'MKD': [2, 'MKD', 'MKD'],
'MMK': [2, 'K', 'MMK'],
'MOP': [2, 'MOP$', 'MOP$'],
'MRO': [1, 'UM', 'UM'],
'MUR': [2, 'Rs', 'MURs'],
'MVR': [2, 'Rf', 'MRF'],
'MWK': [2, 'MK', 'MK'],
'MGA': [0, 'Ar', 'MGA'],
'MKD': [2, 'din', 'MKD'],
'MMK': [0, 'K', 'MMK'],
'MOP': [2, 'MOP', 'MOP$'],
'MRO': [0, 'MRO', 'MRO'],
'MUR': [0, 'MURs', 'MURs'],
'MWK': [2, 'MWK', 'MWK'],
'MZN': [2, 'MTn', 'MTn'],
'NAD': [2, '$', 'N$'],
'NGN': [2, '\u20A6', 'NG'],
'NGN': [2, '\u20A6', 'NG\u20A6'],
'NIO': [2, 'C$', 'C$'],
'NPR': [2, 'Rs', 'NPRs'],
'NZD': [2, '$', 'NZ$'],
'OMR': [3, '\u0639\u002E\u062F\u002E', 'OMR'],
'PGK': [2, 'K', 'PGK'],
'PLN': [10, 'zł', 'zł'],
'PYG': [0, '\u20b2', 'PYG'],
'QAR': [2, '\u0642\u002E\u0631', 'QR'],
'RON': [2, 'L', 'RON'],
'RSD': [2, 'РС\u0414', 'RSD'],
'OMR': [3, 'Rial', 'OMR'],
'PGK': [2, 'PGK', 'PGK'],
'PLN': [2, 'z\u0142', 'z\u0142'],
'PYG': [0, 'Gs', 'PYG'],
'QAR': [2, 'Rial', 'QR'],
'RON': [2, 'RON', 'RON'],
'RSD': [0, 'din', 'RSD'],
'RWF': [0, 'RF', 'RF'],
'SBD': [2, '$', 'SI$'],
'SCR': [2, 'SR', 'SCR'],
'SCR': [2, 'SCR', 'SCR'],
'SDG': [2, 'SDG', 'SDG'],
'SHP': [2, '£', 'SH£'],
'SKK': [10, 'Sk', 'Sk'],
'SLL': [2, 'Le', 'Le'],
'SOS': [2, 'So. Sh.', 'So. Sh.'],
'SLL': [0, 'SLL', 'SLL'],
'SOS': [0, 'SOS', 'SOS'],
'SRD': [2, '$', 'SR$'],
'STD': [2, 'Db', 'Db'],
'SYP': [18, 'SYP', 'SYP'],
'SZL': [2, 'L', 'SZL'],
'TJS': [2, 'TJS', 'TJS'],
'TMM': [2, 'm', 'TMM'],
'TND': [3, '\u062F\u002e\u062A ', 'DT'],
'STD': [0, 'Db', 'Db'],
'SYP': [16, '£', 'SY£'],
'SZL': [2, 'SZL', 'SZL'],
'TJS': [2, 'Som', 'TJS'],
'TND': [3, 'din', 'DT'],
'TOP': [2, 'T$', 'T$'],
'TTD': [2, '$', 'TT$'],
'TZS': [10, 'TZS', 'TZS'],
'UAH': [10, '\u20B4', 'грн'],
'UGX': [2, 'USh', 'USh'],
'UZS': [2, 'UZS', 'UZS'],
'VEF': [2, 'Bs.F', 'Bs.F'],
'VUV': [0, 'Vt', 'Vt'],
'WST': [2, 'WS$', 'WS$'],
'TZS': [0, 'TSh', 'TSh'],
'UAH': [2, '\u20B4', 'UAH'],
'UGX': [0, 'UGX', 'UGX'],
'UYU': [1, '$', '$U'],
'UZS': [0, 'so\u02bcm', 'UZS'],
'VEF': [2, 'Bs', 'Bs'],
'VUV': [0, 'VUV', 'VUV'],
'WST': [2, 'WST', 'WST'],
'XAF': [0, 'FCFA', 'FCFA'],
'XCD': [2, '$', 'EC$'],
'XOF': [0, 'CFA', 'CFA'],
'XPF': [0, 'F', 'XPF'],
'ZMK': [2, 'ZK', 'ZK'],
'ZWL': [2, '$', 'ZW$']
'XPF': [0, 'FCFP', 'FCFP'],
'ZMK': [0, 'ZMK', 'ZMK']
};
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+213 -146
View File
@@ -1,4 +1,4 @@
// Copyright 2011 The Closure Library Authors. All Rights Reserved
// Copyright 2012 The Closure Library Authors. All Rights Reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -7,35 +7,24 @@
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// distributed under the License is distributed on an "AS-IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
/**
* @fileoverview Plural rules.
*
* This file is autogenerated by script:
* http://go/generate_pluralrules.py
* using the --for_closure flag.
* http://go/generate_pluralrules.py
*
* To reduce the file size (which may cause issues in some JS
* developing environments), this file will only contain locales
* that are usually supported by google products. This is defined as
* closure_tier1_locales and will change (most likely addition)
* over time. Rest of the data can be found in another file named
* "pluralrulesext.js", which will be generated at the
* same time together with this file.
*
* Before checkin, this file could have been manually edited. This is
* to incorporate changes before we could fix CLDR. All manual
* modification must be documented in this section, and should be
* removed after those changes land to CLDR.
* Before check in, this file could have been manually edited. This is to
* incorporate changes before we could fix CLDR. All manual modification must be
* documented in this section, and should be removed after those changes land to
* CLDR.
*/
goog.provide('goog.i18n.pluralRules');
/**
* Plural pattern keyword
* @enum {string}
@@ -53,7 +42,7 @@ goog.i18n.pluralRules.Keyword = {
/**
* Default plural select rule.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Default plural value.
* @return {goog.i18n.pluralRules.Keyword} Default value.
* @private
*/
goog.i18n.pluralRules.defaultSelect_ = function(n) {
@@ -64,25 +53,25 @@ goog.i18n.pluralRules.defaultSelect_ = function(n) {
/**
* Plural select rules for ar locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale specific plural value.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.arSelect_ = function(n) {
if (n == 0) {
return goog.i18n.pluralRules.Keyword.ZERO;
return goog.i18n.pluralRules.Keyword.ZERO;
}
if (n == 1) {
return goog.i18n.pluralRules.Keyword.ONE;
return goog.i18n.pluralRules.Keyword.ONE;
}
if (n == 2) {
return goog.i18n.pluralRules.Keyword.TWO;
return goog.i18n.pluralRules.Keyword.TWO;
}
if ((n % 100) >= 3 && (n % 100) <= 10 && n == Math.floor(n)) {
return goog.i18n.pluralRules.Keyword.FEW;
if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) {
return goog.i18n.pluralRules.Keyword.FEW;
}
if ((n % 100) >= 11 && (n % 100) <= 99 && n == Math.floor(n)) {
return goog.i18n.pluralRules.Keyword.MANY;
if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) {
return goog.i18n.pluralRules.Keyword.MANY;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
@@ -91,13 +80,13 @@ goog.i18n.pluralRules.arSelect_ = function(n) {
/**
* Plural select rules for en locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale specific plural value.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.enSelect_ = function(n) {
if (n == 1) {
return goog.i18n.pluralRules.Keyword.ONE;
return goog.i18n.pluralRules.Keyword.ONE;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
@@ -106,13 +95,13 @@ goog.i18n.pluralRules.enSelect_ = function(n) {
/**
* Plural select rules for fil locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale specific plural value.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.filSelect_ = function(n) {
if (n == 0 || n == 1) {
return goog.i18n.pluralRules.Keyword.ONE;
return goog.i18n.pluralRules.Keyword.ONE;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
@@ -121,13 +110,13 @@ goog.i18n.pluralRules.filSelect_ = function(n) {
/**
* Plural select rules for fr locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale specific plural value.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.frSelect_ = function(n) {
if (n >= 0 && n < 2) {
return goog.i18n.pluralRules.Keyword.ONE;
if (n >= 0 && n <= 2 && n != 2) {
return goog.i18n.pluralRules.Keyword.ONE;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
@@ -136,16 +125,34 @@ goog.i18n.pluralRules.frSelect_ = function(n) {
/**
* Plural select rules for lv locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale specific plural value.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.lvSelect_ = function(n) {
if (n == 0) {
return goog.i18n.pluralRules.Keyword.ZERO;
return goog.i18n.pluralRules.Keyword.ZERO;
}
if ((n % 10) == 1 && (n % 100) != 11) {
return goog.i18n.pluralRules.Keyword.ONE;
if (n % 10 == 1 && n % 100 != 11) {
return goog.i18n.pluralRules.Keyword.ONE;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
/**
* Plural select rules for iu locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.iuSelect_ = function(n) {
if (n == 1) {
return goog.i18n.pluralRules.Keyword.ONE;
}
if (n == 2) {
return goog.i18n.pluralRules.Keyword.TWO;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
@@ -154,16 +161,22 @@ goog.i18n.pluralRules.lvSelect_ = function(n) {
/**
* Plural select rules for ga locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale specific plural value.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.gaSelect_ = function(n) {
if (n == 1) {
return goog.i18n.pluralRules.Keyword.ONE;
return goog.i18n.pluralRules.Keyword.ONE;
}
if (n == 2) {
return goog.i18n.pluralRules.Keyword.TWO;
return goog.i18n.pluralRules.Keyword.TWO;
}
if (n == (n | 0) && n >= 3 && n <= 6) {
return goog.i18n.pluralRules.Keyword.FEW;
}
if (n == (n | 0) && n >= 7 && n <= 10) {
return goog.i18n.pluralRules.Keyword.MANY;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
@@ -172,17 +185,16 @@ goog.i18n.pluralRules.gaSelect_ = function(n) {
/**
* Plural select rules for ro locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale specific plural value.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.roSelect_ = function(n) {
if (n == 1) {
return goog.i18n.pluralRules.Keyword.ONE;
return goog.i18n.pluralRules.Keyword.ONE;
}
if (n == 0 || n != 1 && (n % 100) >= 1 &&
(n % 100) <= 19 && n == Math.floor(n)) {
return goog.i18n.pluralRules.Keyword.FEW;
if (n == 0 || n != 1 && n == (n | 0) && n % 100 >= 1 && n % 100 <= 19) {
return goog.i18n.pluralRules.Keyword.FEW;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
@@ -191,40 +203,37 @@ goog.i18n.pluralRules.roSelect_ = function(n) {
/**
* Plural select rules for lt locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale specific plural value.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.ltSelect_ = function(n) {
if ((n % 10) == 1 && ((n % 100) < 11 || (n % 100) > 19)) {
return goog.i18n.pluralRules.Keyword.ONE;
if (n % 10 == 1 && (n % 100 < 11 || n % 100 > 19)) {
return goog.i18n.pluralRules.Keyword.ONE;
}
if ((n % 10) >= 2 && (n % 10) <= 9 &&
((n % 100) < 11 || (n % 100) > 19) && n == Math.floor(n)) {
return goog.i18n.pluralRules.Keyword.FEW;
if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 9 && (n % 100 < 11 || n % 100 > 19)) {
return goog.i18n.pluralRules.Keyword.FEW;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
/**
* Plural select rules for hr locale
* Plural select rules for be locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale specific plural value.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.hrSelect_ = function(n) {
if ((n % 10) == 1 && (n % 100) != 11) {
return goog.i18n.pluralRules.Keyword.ONE;
goog.i18n.pluralRules.beSelect_ = function(n) {
if (n % 10 == 1 && n % 100 != 11) {
return goog.i18n.pluralRules.Keyword.ONE;
}
if ((n % 10) >= 2 && (n % 10) <= 4 &&
((n % 100) < 12 || (n % 100) > 14) && n == Math.floor(n)) {
return goog.i18n.pluralRules.Keyword.FEW;
if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) {
return goog.i18n.pluralRules.Keyword.FEW;
}
if ((n % 10) == 0 || ((n % 10) >= 5 && (n % 10) <= 9) ||
((n % 100) >= 11 && (n % 100) <= 14) && n == Math.floor(n)) {
return goog.i18n.pluralRules.Keyword.MANY;
if (n % 10 == 0 || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 11 && n % 100 <= 14) {
return goog.i18n.pluralRules.Keyword.MANY;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
@@ -233,16 +242,16 @@ goog.i18n.pluralRules.hrSelect_ = function(n) {
/**
* Plural select rules for cs locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale specific plural value.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.csSelect_ = function(n) {
if (n == 1) {
return goog.i18n.pluralRules.Keyword.ONE;
return goog.i18n.pluralRules.Keyword.ONE;
}
if (n == 2 || n == 3 || n == 4) {
return goog.i18n.pluralRules.Keyword.FEW;
if (n == (n | 0) && n >= 2 && n <= 4) {
return goog.i18n.pluralRules.Keyword.FEW;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
@@ -251,22 +260,19 @@ goog.i18n.pluralRules.csSelect_ = function(n) {
/**
* Plural select rules for pl locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale specific plural value.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.plSelect_ = function(n) {
if (n == 1) {
return goog.i18n.pluralRules.Keyword.ONE;
return goog.i18n.pluralRules.Keyword.ONE;
}
if ((n % 10) >= 2 && (n % 10) <= 4 &&
((n % 100) < 12 || (n % 100) > 14) && n == Math.floor(n)) {
return goog.i18n.pluralRules.Keyword.FEW;
if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) {
return goog.i18n.pluralRules.Keyword.FEW;
}
if ((n % 10) == 0 || n != 1 && (n % 10) == 1 ||
((n % 10) >= 5 && (n % 10) <= 9 || (n % 100) >= 12 && (n % 100) <= 14) &&
n == Math.floor(n)) {
return goog.i18n.pluralRules.Keyword.MANY;
if (n != 1 && (n % 10 == 0 || n % 10 == 1) || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 12 && n % 100 <= 14) {
return goog.i18n.pluralRules.Keyword.MANY;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
@@ -275,19 +281,19 @@ goog.i18n.pluralRules.plSelect_ = function(n) {
/**
* Plural select rules for sl locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale specific plural value.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.slSelect_ = function(n) {
if ((n % 100) == 1) {
return goog.i18n.pluralRules.Keyword.ONE;
if (n % 100 == 1) {
return goog.i18n.pluralRules.Keyword.ONE;
}
if ((n % 100) == 2) {
return goog.i18n.pluralRules.Keyword.TWO;
if (n % 100 == 2) {
return goog.i18n.pluralRules.Keyword.TWO;
}
if ((n % 100) == 3 || (n % 100) == 4) {
return goog.i18n.pluralRules.Keyword.FEW;
if (n % 100 == 3 || n % 100 == 4) {
return goog.i18n.pluralRules.Keyword.FEW;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
@@ -296,19 +302,19 @@ goog.i18n.pluralRules.slSelect_ = function(n) {
/**
* Plural select rules for mt locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale specific plural value.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.mtSelect_ = function(n) {
if (n == 1) {
return goog.i18n.pluralRules.Keyword.ONE;
return goog.i18n.pluralRules.Keyword.ONE;
}
if (n == 0 || ((n % 100) >= 2 && (n % 100) <= 4 && n == Math.floor(n))) {
return goog.i18n.pluralRules.Keyword.FEW;
if (n == 0 || n == (n | 0) && n % 100 >= 2 && n % 100 <= 10) {
return goog.i18n.pluralRules.Keyword.FEW;
}
if ((n % 100) >= 11 && (n % 100) <= 19 && n == Math.floor(n)) {
return goog.i18n.pluralRules.Keyword.MANY;
if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 19) {
return goog.i18n.pluralRules.Keyword.MANY;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
@@ -317,13 +323,13 @@ goog.i18n.pluralRules.mtSelect_ = function(n) {
/**
* Plural select rules for mk locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale specific plural value.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.mkSelect_ = function(n) {
if ((n % 10) == 1 && n != 11) {
return goog.i18n.pluralRules.Keyword.ONE;
if (n % 10 == 1 && n != 11) {
return goog.i18n.pluralRules.Keyword.ONE;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
@@ -332,25 +338,25 @@ goog.i18n.pluralRules.mkSelect_ = function(n) {
/**
* Plural select rules for cy locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale specific plural value.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.cySelect_ = function(n) {
if (n == 0) {
return goog.i18n.pluralRules.Keyword.ZERO;
return goog.i18n.pluralRules.Keyword.ZERO;
}
if (n == 1) {
return goog.i18n.pluralRules.Keyword.ONE;
return goog.i18n.pluralRules.Keyword.ONE;
}
if (n == 2) {
return goog.i18n.pluralRules.Keyword.TWO;
return goog.i18n.pluralRules.Keyword.TWO;
}
if (n == 3) {
return goog.i18n.pluralRules.Keyword.FEW;
return goog.i18n.pluralRules.Keyword.FEW;
}
if (n == 6) {
return goog.i18n.pluralRules.Keyword.MANY;
return goog.i18n.pluralRules.Keyword.MANY;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
@@ -359,16 +365,16 @@ goog.i18n.pluralRules.cySelect_ = function(n) {
/**
* Plural select rules for lag locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale specific plural value.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.lagSelect_ = function(n) {
if (n == 0) {
return goog.i18n.pluralRules.Keyword.ZERO;
return goog.i18n.pluralRules.Keyword.ZERO;
}
if (n > 0 && n < 2) {
return goog.i18n.pluralRules.Keyword.ONE;
if (n >= 0 && n <= 2 && n != 0 && n != 2) {
return goog.i18n.pluralRules.Keyword.ONE;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
@@ -377,16 +383,16 @@ goog.i18n.pluralRules.lagSelect_ = function(n) {
/**
* Plural select rules for shi locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale specific plural value.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.shiSelect_ = function(n) {
if (n >= 0 && n <= 1) {
return goog.i18n.pluralRules.Keyword.ONE;
return goog.i18n.pluralRules.Keyword.ONE;
}
if (n >= 2 && n <= 10 && n == Math.floor(n)) {
return goog.i18n.pluralRules.Keyword.FEW;
if (n == (n | 0) && n >= 2 && n <= 10) {
return goog.i18n.pluralRules.Keyword.FEW;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
@@ -395,25 +401,91 @@ goog.i18n.pluralRules.shiSelect_ = function(n) {
/**
* Plural select rules for br locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale specific plural value.
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.brSelect_ = function(n) {
if (n % 10 == 1 && n % 100 != 11 && n % 100 != 71 && n % 100 != 91) {
return goog.i18n.pluralRules.Keyword.ONE;
}
if (n % 10 == 2 && n % 100 != 12 && n % 100 != 72 && n % 100 != 92) {
return goog.i18n.pluralRules.Keyword.TWO;
}
if ((n % 10 == 3 || n % 10 == 4 || n % 10 == 9) && ((n % 100 < 10 || n % 100 > 19) && (n % 100 < 70 || n % 100 > 79) && (n % 100 < 90 || n % 100 > 99))) {
return goog.i18n.pluralRules.Keyword.FEW;
}
if (n % 1000000 == 0 && n != 0) {
return goog.i18n.pluralRules.Keyword.MANY;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
/**
* Plural select rules for ksh locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.kshSelect_ = function(n) {
if (n == 0) {
return goog.i18n.pluralRules.Keyword.ZERO;
return goog.i18n.pluralRules.Keyword.ZERO;
}
if (n == 1) {
return goog.i18n.pluralRules.Keyword.ONE;
return goog.i18n.pluralRules.Keyword.ONE;
}
if (n == 2) {
return goog.i18n.pluralRules.Keyword.TWO;
return goog.i18n.pluralRules.Keyword.OTHER;
};
/**
* Plural select rules for tzm locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.tzmSelect_ = function(n) {
if (n == 0 || n == 1 || n == (n | 0) && n >= 11 && n <= 99) {
return goog.i18n.pluralRules.Keyword.ONE;
}
if (n == 3) {
return goog.i18n.pluralRules.Keyword.FEW;
return goog.i18n.pluralRules.Keyword.OTHER;
};
/**
* Plural select rules for gv locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.gvSelect_ = function(n) {
if (n % 10 == 1 || n % 10 == 2 || n % 20 == 0) {
return goog.i18n.pluralRules.Keyword.ONE;
}
if (n == 6) {
return goog.i18n.pluralRules.Keyword.MANY;
return goog.i18n.pluralRules.Keyword.OTHER;
};
/**
* Plural select rules for gd locale
*
* @param {number} n The count of items.
* @return {goog.i18n.pluralRules.Keyword} Locale-specific plural value.
* @private
*/
goog.i18n.pluralRules.gdSelect_ = function(n) {
if (n == 1 || n == 11) {
return goog.i18n.pluralRules.Keyword.ONE;
}
if (n == 2 || n == 12) {
return goog.i18n.pluralRules.Keyword.TWO;
}
if (n == (n | 0) && (n >= 3 && n <= 10 || n >= 13 && n <= 19)) {
return goog.i18n.pluralRules.Keyword.FEW;
}
return goog.i18n.pluralRules.Keyword.OTHER;
};
@@ -423,7 +495,6 @@ goog.i18n.pluralRules.brSelect_ = function(n) {
* Selected plural rules by locale.
*/
goog.i18n.pluralRules.select = goog.i18n.pluralRules.enSelect_;
if (goog.LOCALE == 'am') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.filSelect_;
}
@@ -557,7 +628,7 @@ if (goog.LOCALE == 'hi') {
}
if (goog.LOCALE == 'hr') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.hrSelect_;
goog.i18n.pluralRules.select = goog.i18n.pluralRules.beSelect_;
}
if (goog.LOCALE == 'hu') {
@@ -581,7 +652,7 @@ if (goog.LOCALE == 'it') {
}
if (goog.LOCALE == 'iw') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.enSelect_;
goog.i18n.pluralRules.select = goog.i18n.pluralRules.defaultSelect_;
}
if (goog.LOCALE == 'ja') {
@@ -612,10 +683,6 @@ if (goog.LOCALE == 'ml') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.enSelect_;
}
if (goog.LOCALE == 'mo') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.roSelect_;
}
if (goog.LOCALE == 'mr') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.enSelect_;
}
@@ -661,7 +728,7 @@ if (goog.LOCALE == 'ro') {
}
if (goog.LOCALE == 'ru') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.hrSelect_;
goog.i18n.pluralRules.select = goog.i18n.pluralRules.beSelect_;
}
if (goog.LOCALE == 'sk') {
@@ -677,7 +744,7 @@ if (goog.LOCALE == 'sq') {
}
if (goog.LOCALE == 'sr') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.hrSelect_;
goog.i18n.pluralRules.select = goog.i18n.pluralRules.beSelect_;
}
if (goog.LOCALE == 'sv') {
@@ -709,7 +776,7 @@ if (goog.LOCALE == 'tr') {
}
if (goog.LOCALE == 'uk') {
goog.i18n.pluralRules.select = goog.i18n.pluralRules.hrSelect_;
goog.i18n.pluralRules.select = goog.i18n.pluralRules.beSelect_;
}
if (goog.LOCALE == 'ur') {
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
set -e
PARENT_DIR="$(dirname "$0")"
jasmine-node "$PARENT_DIR"/spec/
+250
View File
@@ -0,0 +1,250 @@
var closureI18nExtractor = require('../src/closureI18nExtractor.js');
var converter = require('../src/converter.js');
findLocaleId = closureI18nExtractor.findLocaleId;
extractNumberSymbols = closureI18nExtractor.extractNumberSymbols;
extractCurrencySymbols = closureI18nExtractor.extractCurrencySymbols;
extractDateTimeSymbols = closureI18nExtractor.extractDateTimeSymbols;
function newTestLocaleInfo() {
return { fr_CA: {
DATETIME_FORMATS: {
MONTH: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre',
'octobre', 'novembre', 'décembre'],
SHORTMONTH: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.',
'nov.', 'déc.'],
DAY: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
SHORTDAY: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],
AMPMS: ['AM', 'PM'],
medium: 'yyyy-MM-dd HH:mm:ss',
short: 'yy-MM-dd HH:mm',
fullDate: 'EEEE d MMMM y',
longDate: 'd MMMM y',
mediumDate: 'yyyy-MM-dd',
shortDate: 'yy-MM-dd',
mediumTime: 'HH:mm:ss',
shortTime: 'HH:mm'
},
NUMBER_FORMATS: {
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
"PATTERNS": [{
"minInt": 1,
"minFrac": 0,
"macFrac": 0,
"posPre": "",
"posSuf": "",
"negPre": "-",
"negSuf": "",
"gSize": 3,
"lgSize": 3,
"maxFrac": 3
}, {
"minInt": 1,
"minFrac": 2,
"macFrac": 0,
"posPre": "¤",
"posSuf": "",
"negPre": "¤-",
"negSuf": "",
"gSize": 3,
"lgSize": 3,
"maxFrac": 2
}],
"CURRENCY_SYM": "£"
}}};
}
describe("findLocaleId", function () {
it("should find the id from numbers", function() {
expect(findLocaleId("NumberFormatSymbols_en_GB", "num")).toEqual("en_GB");
});
it("should find the id from datetime", function() {
expect(findLocaleId("DateTimeSymbols_en_ISO", "datetime")).toEqual("en_ISO");
});
it("should throw an error otherwise", function() {
expect(function() {
findLocaleId("str", "otherwise")
}).toThrow("unknown type in findLocaleId: otherwise");
});
});
describe("extractNumberSymbols", function () {
it("should extract number data", function() {
var CONTENT = [
"goog.provide('goog.i18n.NumberFormatSymbols_en_GB');",
"goog.i18n.NumberFormatSymbols_en_GB = {",
"DECIMAL_SEP: '.',",
"GROUP_SEP: ',',",
"PERCENT: '%',",
"ZERO_DIGIT: '0',",
"PLUS_SIGN: '+',",
"MINUS_SIGN: '-',",
"EXP_SYMBOL: 'E',",
"PERMILL: '\u2030',",
"INFINITY: '\u221E',",
"NAN: 'NaN',",
"DECIMAL_PATTERN: '#,##0.###',",
"SCIENTIFIC_PATTERN: '#E0',",
"PERCENT_PATTERN: '#,##0%',",
"CURRENCY_PATTERN: '\u00A4#,##0.00',",
"DEF_CURRENCY_CODE: 'GBP' };"
].join('\n');
var currencySymbols = {'GBP':[2, '£', 'GB£']};
var expectedNumberFormats = converter.convertNumberData(
{
DECIMAL_SEP:'.',
GROUP_SEP:',',
DECIMAL_PATTERN:'#,##0.###',
CURRENCY_PATTERN:'\u00A4#,##0.00',
DEF_CURRENCY_CODE: 'GBP'
}, currencySymbols
);
var localeInfo = {};
extractNumberSymbols(CONTENT, localeInfo, currencySymbols);
expect(localeInfo).toEqual({
'en_GB': { NUMBER_FORMATS: expectedNumberFormats }
});
})
});
describe("extractCurrencySymbols", function () {
it("should extract currency data", function() {
var CONTENT = [
"goog.i18n.currency.CurrencyInfo = {",
" 'GBP':[2, '£', 'GB£'],",
"};",
"goog.i18n.currency.CurrencyInfoTier2 = {",
" 'AOA':[2, 'Kz', 'Kz'],",
"};"
].join('\n');
var localeInfo = {};
expect(extractCurrencySymbols(CONTENT)).toEqual({
'GBP':[2, '£', 'GB£'],
'AOA':[2, 'Kz', 'Kz']
});
});
});
describe("extractDateTimeSymbols", function () {
it("should extract date time data", function() {
var CONTENT = [
"goog.i18n.DateTimeSymbols_fr_CA = {",
" ERAS: ['av. J.-C.', 'ap. J.-C.'],",
" ERANAMES: ['avant Jésus-Christ', 'après Jésus-Christ'],",
" NARROWMONTHS: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],",
" STANDALONENARROWMONTHS: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O',",
" 'N', 'D'],",
" MONTHS: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet',",
" 'août', 'septembre', 'octobre', 'novembre', 'décembre'],",
" STANDALONEMONTHS: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin',",
" 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'],",
" SHORTMONTHS: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.',",
" 'août', 'sept.', 'oct.', 'nov.', 'déc.'],",
" STANDALONESHORTMONTHS: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin',",
" 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'],",
" WEEKDAYS: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi',",
" 'samedi'],",
" STANDALONEWEEKDAYS: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi',",
" 'vendredi', 'samedi'],",
" SHORTWEEKDAYS: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],",
" STANDALONESHORTWEEKDAYS: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.',",
" 'sam.'],",
" NARROWWEEKDAYS: ['D', 'L', 'M', 'M', 'J', 'V', 'S'],",
" STANDALONENARROWWEEKDAYS: ['D', 'L', 'M', 'M', 'J', 'V', 'S'],",
" SHORTQUARTERS: ['T1', 'T2', 'T3', 'T4'],",
" QUARTERS: ['1er trimestre', '2e trimestre', '3e trimestre', '4e trimestre'],",
" AMPMS: ['AM', 'PM'],",
" DATEFORMATS: ['EEEE d MMMM y', 'd MMMM y', 'yyyy-MM-dd', 'yy-MM-dd'],",
" TIMEFORMATS: ['HH \\'h\\' mm \\'min\\' ss \\'s\\' zzzz', 'HH:mm:ss z',",
" 'HH:mm:ss', 'HH:mm'],",
" FIRSTDAYOFWEEK: 6,",
" WEEKENDRANGE: [5, 6],",
" FIRSTWEEKCUTOFFDAY: 2",
"};"
].join('\n');
var localeInfo = {};
var expectedLocaleInfo = {
fr_CA: {
DATETIME_FORMATS: {
MONTH: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre',
'octobre', 'novembre', 'décembre'],
SHORTMONTH: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.',
'nov.', 'déc.'],
DAY: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
SHORTDAY: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],
AMPMS: ['AM', 'PM'],
medium: 'yyyy-MM-dd HH:mm:ss',
short: 'yy-MM-dd HH:mm',
fullDate: 'EEEE d MMMM y',
longDate: 'd MMMM y',
mediumDate: 'yyyy-MM-dd',
shortDate: 'yy-MM-dd',
mediumTime: 'HH:mm:ss',
shortTime: 'HH:mm'
}
}
};
extractDateTimeSymbols(CONTENT, localeInfo);
expect(localeInfo).toEqual(expectedLocaleInfo);
})
});
describe("pluralExtractor", function() {
it("should output PLURAL_CAT in the output string code", function() {
var localeIds = ["fr_CA"];
var content = (
"goog.provide('goog.i18n.pluralRules');\n" +
"\n" +
"goog.i18n.pluralRules.Keyword = {\n" +
" ZERO: 'zero',\n" +
" ONE: 'one',\n" +
" TWO: 'two',\n" +
" FEW: 'few',\n" +
" MANY: 'many',\n" +
" OTHER: 'other'\n" +
"};\n" +
"\n" +
"goog.i18n.pluralRules.frSelect_ = function(n) {\n" +
" if (n >= 0 && n < 2) {\n" +
" return goog.i18n.pluralRules.Keyword.ONE;\n" +
" }\n" +
" return goog.i18n.pluralRules.Keyword.OTHER;\n" +
"};\n" +
"\n" +
"if (goog.LOCALE == 'fr') {\n" +
" goog.i18n.pluralRules.select = goog.i18n.pluralRules.frSelect_;\n" +
"}"
);
var localeInfo = newTestLocaleInfo();
closureI18nExtractor.pluralExtractor(content, localeInfo);
var pluralCat = localeInfo["fr_CA"].pluralCat;
expect(pluralCat).toBeDefined();
// pluralCat is the source text for the pluralCat and contains @@
// placeholders that need to be stripped before evaluation.
// Ref: closureI18nExtractor.pluralExtractor.
pluralCat = pluralCat.replace(/^@@|@@$/g, '');
// pluralCat requires these constants to exist.
var PLURAL_CATEGORY = {
ZERO: "zero", ONE: "one", TWO: "two",
FEW: "few", MANY: "many", OTHER: "other"
};
// Obtain the function by evaluating the source text.
pluralCat = eval("(" + pluralCat + ")");
// Confirm some expectations for pluralCat in fr_CA.
expect(pluralCat(0)).toEqual("one");
expect(pluralCat(3)).toEqual("other");
})
});
+2
View File
@@ -24,6 +24,8 @@ describe('parsePattern', function() {
parseAndExpect('#,##,##0.###', '', '-', '', '', 1, 0, 3, 2, 3);
parseAndExpect("#,##0.###;\'\u202A\'-#,##0.###\'\u202C\'",
'', '\u202A-', '', '\u202C', 1, 0, 3, 3, 3);
parseAndExpect('#0.###;#0.###-', '', '', '', '-', 1, 0, 3, 0, 0);
});
it('should parse CURRENCY patterns', function() {
+175
View File
@@ -0,0 +1,175 @@
'use strict';
var converter = require('./converter.js');
exports.extractNumberSymbols = extractNumberSymbols;
exports.extractCurrencySymbols = extractCurrencySymbols;
exports.extractDateTimeSymbols = extractDateTimeSymbols;
exports.pluralExtractor = pluralExtractor;
exports.outputLocale = outputLocale;
exports.correctedLocaleId = correctedLocaleId;
exports.findLocaleId = findLocaleId;
var goog = { provide: function() {},
require: function() {},
i18n: {currency: {}, pluralRules: {}} };
function findLocaleId(str, type) {
if (type === 'num') {
return (str.match(/^NumberFormatSymbols_(.+)$/) || [])[1];
}
if (type != 'datetime') { throw new Error('unknown type in findLocaleId: ' + type); }
return (str.match(/^DateTimeSymbols_(.+)$/) || [])[1];
}
function getInfoForLocale(localeInfo, localeID) {
if (!localeInfo[localeID]) {
localeInfo[localeID] = {};
//localeIds.push(localeID);
}
return localeInfo[localeID];
}
function extractNumberSymbols(content, localeInfo, currencySymbols) {
//eval script in the current context so that we get access to all the symbols
eval(content.toString());
for (var propName in goog.i18n) {
var localeID = findLocaleId(propName, 'num');
if (localeID) {
var info = getInfoForLocale(localeInfo, localeID);
info.NUMBER_FORMATS =
converter.convertNumberData(goog.i18n[propName], currencySymbols);
}
}
}
function extractCurrencySymbols(content) {
//eval script in the current context so that we get access to all the symbols
eval(content.toString());
var currencySymbols = goog.i18n.currency.CurrencyInfo;
currencySymbols.__proto__ = goog.i18n.currency.CurrencyInfoTier2;
return currencySymbols;
}
function extractDateTimeSymbols(content, localeInfo) {
//eval script in the current context so that we get access to all the symbols
eval(content.toString());
for (var propName in goog.i18n) {
var localeID = findLocaleId(propName, 'datetime');
if (localeID) {
var info = getInfoForLocale(localeInfo, localeID);
localeInfo[localeID].DATETIME_FORMATS =
converter.convertDatetimeData(goog.i18n[propName]);
}
}
}
function pluralExtractor(content, localeInfo) {
var contentText = content.toString();
var localeIds = Object.keys(localeInfo);
for (var i = 0; i < localeIds.length; i++) {
//We don't need to care about country ID because the plural rules in more specific id are
//always the same as those in its language ID.
// e.g. plural rules for en_SG is the same as those for en.
goog.LOCALE = localeIds[i].match(/[^_]+/)[0];
try {
eval(contentText);
} catch(e) {
console.log("Error in eval(contentText): " + e.stack);
}
if (!goog.i18n.pluralRules.select) {
console.log('No select for lang [' + goog.LOCALE + ']');
continue;
}
var temp = goog.i18n.pluralRules.select.toString().
replace(/goog.i18n.pluralRules.Keyword/g, 'PLURAL_CATEGORY').replace(/\n/g, '');
///@@ is a crazy place holder to be replaced before writing to file
localeInfo[localeIds[i]].pluralCat = "@@" + temp + "@@";
}
}
function correctedLocaleId(localeID) {
// e.g. from zh_CN to zh-CN, from en_US to en-US
return localeID.replace(/_/g, '-').toLowerCase();
}
function canonicalizeForJsonStringify(unused_key, object) {
// This function is intended to be called as the 2nd argument to
// JSON.stringify. The goal here is to ensure that the generated JSON has
// objects with their keys in ascending order. Without this, it's much
// harder to diff the generated files in src/ngLocale as the order isn't
// exactly consistent. We've gotten lucky in the past.
//
// Iteration order, for string keys, ends up being the same as insertion
// order. Refer :-
// 1. http://ejohn.org/blog/javascript-in-chrome/
// (search for "for loop order").
// Currently all major browsers loop over the properties of an object
// in the order in which they were defined.
// - John Resig
// 2. https://code.google.com/p/v8/issues/detail?id=164
// ECMA-262 does not specify enumeration order. The de facto standard
// is to match insertion order, which V8 also does ...
if (typeof object != "object") {
return object;
}
var result = {};
Object.keys(object).sort().forEach(function(key) {
result[key] = object[key];
});
return result;
}
function outputLocale(localeInfo, localeID) {
var fallBackID = localeID.match(/[A-Za-z]+/)[0],
localeObj = localeInfo[localeID],
fallBackObj = localeInfo[fallBackID];
// fallBack to language formats when country format is missing
// e.g. if NUMBER_FORMATS of en_xyz is not present, use the NUMBER_FORMATS of en instead
if (!localeObj.NUMBER_FORMATS) {
localeObj.NUMBER_FORMATS = fallBackObj.NUMBER_FORMATS;
}
// datetimesymbolsext.js provides more top level locales than the other
// files. We process datetimesymbolsext.js because we want the country
// specific formats that are missing from datetimesymbols.js. However, we
// don't want to write locale files that only have dateformat (i.e. missing
// number formats.) So we skip them.
if (!localeObj.NUMBER_FORMATS) {
console.log("Skipping locale %j: Don't have any number formats", localeID);
return null;
}
if (!localeObj.DATETIME_FORMATS) {
localeObj.DATETIME_FORMATS = fallBackObj.DATETIME_FORMATS;
}
localeObj.id = correctedLocaleId(localeID);
var prefix =
'angular.module("ngLocale", [], ["$provide", function($provide) {\n' +
'var PLURAL_CATEGORY = {' +
'ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"' +
'};\n' +
'$provide.value("$locale", ';
var suffix = ');\n}]);';
localeObj = {
DATETIME_FORMATS: localeObj.DATETIME_FORMATS,
NUMBER_FORMATS: localeObj.NUMBER_FORMATS,
pluralCat: localeObj.pluralCat,
id: localeObj.id
};
var content = JSON.stringify(localeInfo[localeID], canonicalizeForJsonStringify, ' ')
.replace(/\¤/g, '\\u00A4')
.replace(/"@@|@@"/g, '');
return prefix + content + suffix;
}
+57 -102
View File
@@ -1,130 +1,85 @@
#!/usr/bin/env node
'use strict';
var Q = require('qq'),
var Q = require('q'),
qfs = require('q-fs'),
converter = require('./converter.js'),
util = require('./util.js'),
closureI18nExtractor = require('./closureI18nExtractor.js'),
localeInfo = {},
localeIds = [],
currencySymbols,
goog = { provide: function() {},
require: function() {},
i18n: {currency: {}, pluralRules: {}} };
createFolder('../../src/ngLocale/').then(function() {
var promiseA = Q.defer(),
promiseB = Q.defer();
qfs.read(__dirname + '/../closure/currencySymbols.js', 'b').then(function(content) {
eval(content.toString());
currencySymbols = goog.i18n.currency.CurrencyInfo;
currencySymbols.__proto__ = goog.i18n.currency.CurrencyInfoTier2;
var NG_LOCALE_DIR = '../src/ngLocale/';
qfs.read(__dirname + '/../closure/numberSymbols.js', 'b').then(function(content) {
//eval script in the current context so that we get access to all the symbols
eval(content.toString());
for (var propName in goog.i18n) {
var localeID = util.findLocaleId(propName, 'num');
if (localeID) {
if (!localeInfo[localeID]) {
localeInfo[localeID] = {};
localeIds.push(localeID);
}
var convertedData = converter.convertNumberData(goog.i18n[propName], currencySymbols);
localeInfo[localeID].NUMBER_FORMATS = convertedData;
}
}
promiseA.resolve();
function readSymbols() {
console.log("Processing currency and number symbols ...");
var numericStagePromise = qfs.read(__dirname + '/../closure/currencySymbols.js', 'b')
.then(function(content) {
var currencySymbols = closureI18nExtractor.extractCurrencySymbols(content);
return qfs.read(__dirname + '/../closure/numberSymbols.js', 'b').then(function(content) {
closureI18nExtractor.extractNumberSymbols(content, localeInfo, currencySymbols);
});
});
console.log("Processing datetime symbols ...");
var datetimeStagePromise = qfs.read(__dirname + '/../closure/datetimeSymbols.js', 'b')
.then(function(content) {
closureI18nExtractor.extractDateTimeSymbols(content, localeInfo);
return qfs.read(__dirname + '/../closure/datetimeSymbolsExt.js', 'b').then(function(content) {
closureI18nExtractor.extractDateTimeSymbols(content, localeInfo);
});
});
return Q.all([numericStagePromise, datetimeStagePromise]);
}
function extractPlurals() {
console.log('Extracting Plurals ...');
return qfs.read(__dirname + '/../closure/pluralRules.js').then(function(content) {
closureI18nExtractor.pluralExtractor(content, localeInfo);
});
}
qfs.read(__dirname + '/../closure/datetimeSymbols.js', 'b').then(function(content) {
eval(content.toString());
for (var propName in goog.i18n) {
var localeID = util.findLocaleId(propName, 'datetime');
if (localeID) {
if (!localeInfo[localeID]) {
localeInfo[localeID] = {};
localeIds.push(localeID);
}
var convertedData = converter.convertDatetimeData(goog.i18n[propName]);
localeInfo[localeID].DATETIME_FORMATS = convertedData;
}
}
promiseB.resolve();
});
return Q.join(promiseA.promise, promiseB.promise, noop);
}).then(function() {
var promise = Q.defer();
qfs.read(__dirname + '/../closure/pluralRules.js').then(function(content) {
for(var i = 0; i < localeIds.length; i++) {
//We don't need to care about country ID because the plural rules in more specific id are
//always the same as those in its language ID.
// e.g. plural rules for en_SG is the same as those for en.
goog.LOCALE = localeIds[i].match(/[^_]+/)[0];
eval(content);
var temp = goog.i18n.pluralRules.select.toString().
replace(/goog.i18n.pluralRules.Keyword/g, 'PLURAL_CATEGORY').replace(/\n/g, '');
///@@ is a crazy place holder to be replaced before writing to file
localeInfo[localeIds[i]].pluralCat = "@@" + temp + "@@";
}
promise.resolve();
});
return promise.promise;
}).then(function() {
function writeLocaleFiles() {
console.log('Final stage: Writing angular locale files to directory: %j', NG_LOCALE_DIR);
var writePromises = [];
var localeIds = Object.keys(localeInfo);
var num_files = 0;
localeIds.forEach(function(localeID) {
var fallBackID = localeID.match(/[A-Za-z]+/)[0],
localeObj = localeInfo[localeID],
fallBackObj = localeInfo[fallBackID];
// fallBack to language formats when country format is missing
// e.g. if NUMBER_FORMATS of en_xyz is not present, use the NUMBER_FORMATS of en instead
if (!localeObj.NUMBER_FORMATS) {
localeObj.NUMBER_FORMATS = fallBackObj.NUMBER_FORMATS;
}
if (!localeObj.DATETIME_FORMATS) {
localeObj.DATETIME_FORMATS = fallBackObj.DATETIME_FORMATS;
}
// e.g. from zh_CN to zh-CN, from en_US to en-US
var correctedLocaleId = localeID.replace(/_/g, '-').toLowerCase();
localeObj.id = correctedLocaleId;
var prefix =
'angular.module("ngLocale", [], ["$provide", function($provide) {\n' +
'var PLURAL_CATEGORY = {' +
'ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"' +
'};\n' +
'$provide.value("$locale", ';
var suffix = ');\n}]);';
var content = JSON.stringify(localeInfo[localeID]).replace(/\¤/g,'\\u00A4').
replace(/"@@|@@"/g, '');
var toWrite = prefix + content + suffix;
qfs.write(__dirname + '/../locale/' + 'angular-locale_' + correctedLocaleId + '.js', toWrite);
var content = closureI18nExtractor.outputLocale(localeInfo, localeID);
if (!content) return;
var correctedLocaleId = closureI18nExtractor.correctedLocaleId(localeID);
var filename = NG_LOCALE_DIR + 'angular-locale_' + correctedLocaleId + '.js'
writePromises.push(
qfs.write(filename, content)
.then(function () {
console.log('Wrote ' + filename);
++num_files;
}));
console.log('Writing ' + filename);
});
console.log('Generated ' + localeIds.length + ' locale files!');
}).end();
function noop() {};
console.log('Generated %j locale files.', localeIds.length);
return Q.all(writePromises).then(function() { return num_files });
}
/**
* Make a folder under current directory.
* @param folder {string} name of the folder to be made
*/
function createFolder(folder) {
return qfs.isDirectory(__dirname + '/' + folder).then(function(isDir) {
if (!isDir) return qfs.makeDirectory(__dirname + '/' + folder);
return qfs.isDirectory(folder).then(function(isDir) {
if (!isDir) return qfs.makeDirectory(folder).then(function() {
console.log('Created directory %j', folder); });
});
}
createFolder(NG_LOCALE_DIR)
.then(readSymbols)
.then(extractPlurals)
.then(writeLocaleFiles)
.done(function(num_files) { console.log("Wrote %j files.\nAll Done!", num_files); });
+2 -2
View File
@@ -45,8 +45,8 @@ function parsePattern(pattern) {
}
var groups = integer.split(GROUP_SEP);
p.gSize = groups[1].length;
p.lgSize = (groups[2] || groups[1]).length;
p.gSize = groups[1] ? groups[1].length : 0;
p.lgSize = (groups[2] || groups[1]) ? (groups[2] || groups[1]).length : 0;
if (negative) {
var trunkLen = positive.length - p.posPre.length - p.posSuf.length,
+5
View File
@@ -1,9 +1,14 @@
#!/bin/bash
set -e # Exit on error.
BASE_DIR=`dirname $0`
cd $BASE_DIR
set -x # Trace commands as they're executed.
curl http://closure-library.googlecode.com/svn/trunk/closure/goog/i18n/currency.js > closure/currencySymbols.js
curl http://closure-library.googlecode.com/svn/trunk/closure/goog/i18n/datetimesymbols.js > closure/datetimeSymbols.js
curl http://closure-library.googlecode.com/svn/trunk/closure/goog/i18n/datetimesymbolsext.js > closure/datetimeSymbolsExt.js
curl http://closure-library.googlecode.com/svn/trunk/closure/goog/i18n/numberformatsymbols.js > closure/numberSymbols.js
curl http://closure-library.googlecode.com/svn/trunk/closure/goog/i18n/pluralrules.js > closure/pluralRules.js

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

+61
View File
@@ -0,0 +1,61 @@
var util = require('./utils.js');
var spawn = require('child_process').spawn;
module.exports = function(grunt) {
grunt.registerMultiTask('min', 'minify JS files', function(){
util.min.call(util, this.data, this.async());
});
grunt.registerTask('minall', 'minify all the JS files in parallel', function(){
var files = grunt.config('min');
files = Object.keys(files).map(function(key){ return files[key]; });
grunt.util.async.forEach(files, util.min.bind(util), this.async());
});
grunt.registerMultiTask('build', 'build JS files', function(){
util.build.call(util, this.data, this.async());
});
grunt.registerTask('buildall', 'build all the JS files in parallel', function(){
var builds = grunt.config('build');
builds = Object.keys(builds).map(function(key){ return builds[key]; });
grunt.util.async.forEach(builds, util.build.bind(util), this.async());
});
grunt.registerMultiTask('write', 'write content to a file', function(){
grunt.file.write(this.data.file, this.data.val);
grunt.log.ok('wrote to ' + this.data.file);
});
grunt.registerMultiTask('docs', 'create angular docs', function(){
var done = this.async();
var files = this.data;
var docs = spawn('node', ['docs/src/gen-docs.js']);
docs.stdout.pipe(process.stdout);
docs.stderr.pipe(process.stderr);
docs.on('exit', function(code){
if(code !== 0) grunt.fail.warn('Error creating docs');
grunt.file.expand(files).forEach(function(file){
grunt.file.write(file, util.process(grunt.file.read(file), grunt.config('NG_VERSION'), false));
});
grunt.log.ok('docs created');
done();
});
});
grunt.registerMultiTask('test', 'Run the unit tests with Karma', function(){
util.startKarma.call(util, this.data, true, this.async());
});
grunt.registerMultiTask('autotest', 'Run and watch the unit tests with Karma', function(){
util.startKarma.call(util, this.data, false, this.async());
});
};
+175
View File
@@ -0,0 +1,175 @@
var fs = require('fs');
var shell = require('shelljs');
var yaml = require('yaml-js');
var grunt = require('grunt');
var spawn = require('child_process').spawn;
module.exports = {
init: function() {
shell.exec('npm install');
},
getVersion: function(){
var versionYaml = yaml.load(fs.readFileSync('version.yaml', 'UTF-8'));
var match = versionYaml.version.match(/^([^\-]*)(-snapshot)?$/);
var semver = match[1].split('.');
var hash = shell.exec('git rev-parse --short HEAD', {silent: true}).output.replace('\n', '');
var version = {
full: (match[1] + (match[2] ? '-' + hash : '')),
major: semver[0],
minor: semver[1],
dot: semver[2],
codename: versionYaml.codename,
stable: versionYaml.stable
};
return version;
},
startKarma: function(config, singleRun, done){
var browsers = grunt.option('browsers');
var reporters = grunt.option('reporters');
var noColor = grunt.option('no-colors');
var p = spawn('node', ['node_modules/karma/bin/karma', 'start', config,
singleRun ? '--single-run=true' : '',
reporters ? '--reporters=' + reporters : '',
browsers ? '--browsers=' + browsers : '',
noColor ? '--no-colors' : ''
]);
p.stdout.pipe(process.stdout);
p.stderr.pipe(process.stderr);
p.on('exit', function(code){
if(code !== 0) grunt.fail.warn("Test(s) failed");
done();
});
},
wrap: function(src, name){
src.unshift('src/' + name + '.prefix');
src.push('src/' + name + '.suffix');
return src;
},
addStyle: function(src, styles, minify){
styles = styles.map(processCSS.bind(this)).join('\n');
src += styles;
return src;
function processCSS(file){
var css = fs.readFileSync(file).toString();
if(minify){
css = css
.replace(/\n/g, '')
.replace(/\/\*.*?\*\//g, '')
.replace(/:\s+/g, ':')
.replace(/\s*\{\s*/g, '{')
.replace(/\s*\}\s*/g, '}')
.replace(/\s*\,\s*/g, ',')
.replace(/\s*\;\s*/g, ';');
}
//espace for js
css = css
.replace(/\\/g, '\\\\')
.replace(/'/g, "\\'")
.replace(/\n/g, '\\n');
return "angular.element(document).find('head').append('<style type=\"text/css\">" + css + "</style>');";
}
},
process: function(src, NG_VERSION, strict){
var processed = src
.replace(/"NG_VERSION_FULL"/g, NG_VERSION.full)
.replace(/"NG_VERSION_MAJOR"/, NG_VERSION.major)
.replace(/"NG_VERSION_MINOR"/, NG_VERSION.minor)
.replace(/"NG_VERSION_DOT"/, NG_VERSION.dot)
.replace(/"NG_VERSION_STABLE"/, NG_VERSION.stable)
.replace(/"NG_VERSION_CODENAME"/, NG_VERSION.codename);
if (strict !== false) processed = this.singleStrict(processed, '\n\n', true);
return processed;
},
build: function(config, fn){
var files = grunt.file.expand(config.src);
var styles = config.styles;
//concat
var src = files.map(function(filepath){
return grunt.file.read(filepath);
}).join(grunt.util.normalizelf('\n'));
//process
var processed = this.process(src, grunt.config('NG_VERSION'), config.strict);
if (styles) processed = this.addStyle(processed, styles.css, styles.minify);
//write
grunt.file.write(config.dest, processed);
grunt.log.ok('File ' + config.dest + ' created.');
fn();
},
singleStrict: function(src, insert, newline){
var useStrict = newline ? "$1\n'use strict';" : "$1'use strict';";
return src
.replace(/\s*("|')use strict("|');\s*/g, insert) // remove all file-specific strict mode flags
.replace(/(\(function\([^)]*\)\s*\{)/, useStrict); // add single strict mode flag
},
min: function(file, done) {
var minFile = file.replace(/\.js$/, '.min.js');
shell.exec(
'java ' +
this.java32flags() + ' ' +
'-jar lib/closure-compiler/compiler.jar ' +
'--compilation_level SIMPLE_OPTIMIZATIONS ' +
'--language_in ECMASCRIPT5_STRICT ' +
'--js ' + file + ' ' +
'--js_output_file ' + minFile,
function(code) {
if (code !== 0) grunt.fail.warn('Error minifying ' + file);
grunt.file.write(minFile, this.singleStrict(grunt.file.read(minFile), '\n'));
grunt.log.ok(file + ' minified into ' + minFile);
done();
}.bind(this));
},
//returns the 32-bit mode force flags for java compiler if supported, this makes the build much faster
java32flags: function(){
if (process.platform === "win32") return '';
if (shell.exec('java -version -d32 2>&1', {silent: true}).code !== 0) return '';
return ' -d32 -client';
},
//csp connect middleware
csp: function(){
return function(req, res, next){
res.setHeader("X-WebKit-CSP", "default-src 'self';");
res.setHeader("X-Content-Security-Policy", "default-src 'self'");
next();
};
},
//rewrite connect middleware
rewrite: function(){
return function(req, res, next){
var REWRITE = /\/(guide|api|cookbook|misc|tutorial).*$/,
IGNORED = /(\.(css|js|png|jpg)$|partials\/.*\.html$)/,
match;
if (!IGNORED.test(req.url) && (match = req.url.match(REWRITE))) {
console.log('rewriting', req.url);
req.url = req.url.replace(match[0], '/index.html');
}
next();
};
}
};
-273
View File
@@ -1,273 +0,0 @@
var sys = require('sys'),
http = require('http'),
fs = require('fs'),
url = require('url'),
events = require('events');
var DEFAULT_PORT = 8000;
function main(argv) {
new HttpServer({
'GET': createServlet(StaticServlet),
'HEAD': createServlet(StaticServlet)
}).start(Number(argv[2]) || DEFAULT_PORT);
}
function escapeHtml(value) {
return value.toString().
replace('<', '&lt;').
replace('>', '&gt').
replace('"', '&quot;');
}
function createServlet(Class) {
var servlet = new Class();
return servlet.handleRequest.bind(servlet);
}
/**
* An Http server implementation that uses a map of methods to decide
* action routing.
*
* @param {Object} Map of method => Handler function
*/
function HttpServer(handlers) {
this.handlers = handlers;
this.server = http.createServer(this.handleRequest_.bind(this));
}
HttpServer.prototype.start = function(port) {
this.port = port;
this.server.listen(port);
sys.puts('Http Server running at http://127.0.0.1:' + port + '/');
};
HttpServer.prototype.parseUrl_ = function(urlString) {
var parsed = url.parse(urlString);
parsed.pathname = url.resolve('/', parsed.pathname);
return url.parse(url.format(parsed), true);
};
HttpServer.prototype.handleRequest_ = function(req, res) {
var logEntry = req.method + ' ' + req.url;
if (req.headers['user-agent']) {
logEntry += ' ' + req.headers['user-agent'];
}
sys.puts(logEntry);
req.url = this.parseUrl_(req.url);
var handler = this.handlers[req.method];
if (!handler) {
res.writeHead(501);
res.end();
} else {
handler.call(this, req, res);
}
};
/**
* Handles static content.
*/
function StaticServlet() {}
StaticServlet.MimeMap = {
'txt': 'text/plain',
'html': 'text/html',
'css': 'text/css',
'xml': 'application/xml',
'json': 'application/json',
'js': 'application/javascript',
'jpg': 'image/jpeg',
'jpeg': 'image/jpeg',
'gif': 'image/gif',
'png': 'image/png',
'manifest': 'text/cache-manifest',
// it should be application/font-woff
// but only this silences chrome warnings
'woff': 'font/opentype'
};
StaticServlet.prototype.handleRequest = function(req, res) {
var self = this;
var path = ('./' + req.url.pathname).replace('//','/').replace(/%(..)/g, function(match, hex){
return String.fromCharCode(parseInt(hex, 16));
});
var parts = path.split('/');
if (parts[parts.length-1].charAt(0) === '.')
return self.sendForbidden_(req, res, path);
// favicon rewriting
if (path === './favicon.ico')
return self.sendFile_(req, res, './lib/nodeserver/favicon.ico');
// docs rewriting
var REWRITE = /\/(guide|api|cookbook|misc|tutorial).*$/,
IGNORED = /(\.(css|js|png|jpg)$|partials\/.*\.html$)/,
match;
if (!IGNORED.test(path) && (match = path.match(REWRITE))) {
path = path.replace(match[0], '/index.html');
sys.puts('Rewrite to ' + path);
}
// end of docs rewriting
fs.stat(path, function(err, stat) {
if (err)
return self.sendMissing_(req, res, path);
if (stat.isDirectory())
return fs.stat(path + 'index.html', function(err, stat) {
// send index.html if exists
if (!err)
return self.sendFile_(req, res, path + 'index.html');
// list files otherwise
return self.sendDirectory_(req, res, path);
});
return self.sendFile_(req, res, path);
});
};
StaticServlet.prototype.sendError_ = function(req, res, error) {
res.writeHead(500, {
'Content-Type': 'text/html'
});
res.write('<!doctype html>\n');
res.write('<title>Internal Server Error</title>\n');
res.write('<h1>Internal Server Error</h1>');
res.write('<pre>' + escapeHtml(sys.inspect(error)) + '</pre>');
sys.puts('500 Internal Server Error');
sys.puts(sys.inspect(error));
};
StaticServlet.prototype.sendMissing_ = function(req, res, path) {
path = path.substring(1);
res.writeHead(404, {
'Content-Type': 'text/html'
});
res.write('<!doctype html>\n');
res.write('<title>404 Not Found</title>\n');
res.write('<h1>Not Found</h1>');
res.write(
'<p>The requested URL ' +
escapeHtml(path) +
' was not found on this server.</p>'
);
res.end();
sys.puts('404 Not Found: ' + path);
};
StaticServlet.prototype.sendForbidden_ = function(req, res, path) {
path = path.substring(1);
res.writeHead(403, {
'Content-Type': 'text/html'
});
res.write('<!doctype html>\n');
res.write('<title>403 Forbidden</title>\n');
res.write('<h1>Forbidden</h1>');
res.write(
'<p>You do not have permission to access ' +
escapeHtml(path) + ' on this server.</p>'
);
res.end();
sys.puts('403 Forbidden: ' + path);
};
StaticServlet.prototype.sendRedirect_ = function(req, res, redirectUrl) {
res.writeHead(301, {
'Content-Type': 'text/html',
'Location': redirectUrl
});
res.write('<!doctype html>\n');
res.write('<title>301 Moved Permanently</title>\n');
res.write('<h1>Moved Permanently</h1>');
res.write(
'<p>The document has moved <a href="' +
redirectUrl +
'">here</a>.</p>'
);
res.end();
sys.puts('401 Moved Permanently: ' + redirectUrl);
};
StaticServlet.prototype.sendFile_ = function(req, res, path) {
var self = this;
var file = fs.createReadStream(path);
res.writeHead(200, {
// CSP headers, uncomment to enable CSP
//"X-WebKit-CSP": "default-src 'self';",
//"X-Content-Security-Policy": "default-src 'self'",
'Content-Type': StaticServlet.
MimeMap[path.split('.').pop()] || 'text/plain'
});
if (req.method === 'HEAD') {
res.end();
} else {
file.on('data', res.write.bind(res));
file.on('close', function() {
res.end();
});
file.on('error', function(error) {
self.sendError_(req, res, error);
});
}
};
StaticServlet.prototype.sendDirectory_ = function(req, res, path) {
var self = this;
if (path.match(/[^\/]$/)) {
req.url.pathname += '/';
var redirectUrl = url.format(url.parse(url.format(req.url)));
return self.sendRedirect_(req, res, redirectUrl);
}
fs.readdir(path, function(err, files) {
if (err)
return self.sendError_(req, res, error);
if (!files.length)
return self.writeDirectoryIndex_(req, res, path, []);
var remaining = files.length;
files.forEach(function(fileName, index) {
fs.stat(path + '/' + fileName, function(err, stat) {
if (err)
return self.sendError_(req, res, err);
if (stat.isDirectory()) {
files[index] = fileName + '/';
}
if (!(--remaining))
return self.writeDirectoryIndex_(req, res, path, files);
});
});
});
};
StaticServlet.prototype.writeDirectoryIndex_ = function(req, res, path, files) {
path = path.substring(1);
res.writeHead(200, {
'Content-Type': 'text/html'
});
if (req.method === 'HEAD') {
res.end();
return;
}
res.write('<!doctype html>\n');
res.write('<title>' + escapeHtml(path) + '</title>\n');
res.write('<style>\n');
res.write(' ol { list-style-type: none; font-size: 1.2em; }\n');
res.write('</style>\n');
res.write('<h1>Directory: ' + escapeHtml(path) + '</h1>');
res.write('<ol>');
files.forEach(function(fileName) {
if (fileName.charAt(0) !== '.') {
res.write('<li><a href="' +
escapeHtml(fileName) + '">' +
escapeHtml(fileName) + '</a></li>');
}
});
res.write('</ol>');
res.end();
};
// Must be last,
main(process.argv);
-1
View File
@@ -1 +0,0 @@
node lib/nodeserver/server.js $1
+13 -5
View File
@@ -1,10 +1,18 @@
{
"name": "AngularJS",
"version": "0.0.0",
"dependencies" : {
"testacular" : "canary",
"jasmine-node" : "*",
"q-fs" : "*",
"qq" : "*"
"dependencies": {
"grunt": "0.4.0",
"grunt-contrib-clean": "0.4.0",
"grunt-contrib-compress": "0.4.1",
"grunt-contrib-connect": "0.1.2",
"grunt-contrib-copy": "0.4.0",
"jasmine-node": "1.2.3",
"q": "~0.9.2",
"q-fs": "0.1.36",
"qq": "0.3.5",
"shelljs": "0.1.2",
"karma": "0.8.4",
"yaml-js": "0.0.5"
}
}
+76 -32
View File
@@ -28,12 +28,12 @@ var uppercase = function(string){return isString(string) ? string.toUpperCase()
var manualLowercase = function(s) {
return isString(s)
? s.replace(/[A-Z]/g, function(ch) {return fromCharCode(ch.charCodeAt(0) | 32);})
? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})
: s;
};
var manualUppercase = function(s) {
return isString(s)
? s.replace(/[a-z]/g, function(ch) {return fromCharCode(ch.charCodeAt(0) & ~32);})
? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})
: s;
};
@@ -46,11 +46,8 @@ if ('i' !== 'I'.toLowerCase()) {
uppercase = manualUppercase;
}
function fromCharCode(code) {return String.fromCharCode(code);}
var Error = window.Error,
/** holds major version number for IE or NaN for real browsers */
var /** holds major version number for IE or NaN for real browsers */
msie = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]),
jqLite, // delay binding since jQuery could be loaded after us.
jQuery, // delay binding
@@ -91,6 +88,30 @@ var Error = window.Error,
* @param {Object=} context Object to become context (`this`) for the iterator function.
* @returns {Object|Array} Reference to `obj`.
*/
/**
* @private
* @param {*} obj
* @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, ...)
*/
function isArrayLike(obj) {
if (!obj || (typeof obj.length !== 'number')) return false;
// We have on object which has length property. Should we treat it as array?
if (typeof obj.hasOwnProperty != 'function' &&
typeof obj.constructor != 'function') {
// This is here for IE8: it is a bogus object treat it as array;
return true;
} else {
return obj instanceof JQLite || // JQLite
(jQuery && obj instanceof jQuery) || // jQuery
toString.call(obj) !== '[object Object]' || // some browser native object
typeof obj.callee === 'function'; // arguments (on IE8 looks like regular obj)
}
}
function forEach(obj, iterator, context) {
var key;
if (obj) {
@@ -102,7 +123,7 @@ function forEach(obj, iterator, context) {
}
} else if (obj.forEach && obj.forEach !== forEach) {
obj.forEach(iterator, context);
} else if (isObject(obj) && isNumber(obj.length)) {
} else if (isArrayLike(obj)) {
for (key = 0; key < obj.length; key++)
iterator.call(context, obj[key], key);
} else {
@@ -147,7 +168,7 @@ function reverseParams(iteratorFn) {
/**
* A consistent way of creating unique IDs in angular. The ID is a sequence of alpha numeric
* characters such as '012ABC'. The reason why we are not using simply a number counter is that
* the number string gets longer over time, and it can also overflow, where as the the nextId
* the number string gets longer over time, and it can also overflow, where as the nextId
* will grow much slower, it is a string, and it will never overflow.
*
* @returns an unique alpha-numeric string
@@ -543,9 +564,7 @@ function copy(source, destination){
} else {
if (source === destination) throw Error("Can't copy equivalent objects or arrays");
if (isArray(source)) {
while(destination.length) {
destination.pop();
}
destination.length = 0;
for ( var i = 0; i < source.length; i++) {
destination.push(copy(source[i]));
}
@@ -756,9 +775,18 @@ function startingTag(element) {
// are not allowed to have children. So we just ignore it.
element.html('');
} catch(e) {}
return jqLite('<div>').append(element).html().
match(/^(<[^>]+>)/)[1].
replace(/^<([\w\-]+)/, function(match, nodeName) { return '<' + lowercase(nodeName); });
// As Per DOM Standards
var TEXT_NODE = 3;
var elemHtml = jqLite('<div>').append(element).html();
try {
return element[0].nodeType === TEXT_NODE ? lowercase(elemHtml) :
elemHtml.
match(/^(<[^>]+>)/)[1].
replace(/^<([\w\-]+)/, function(match, nodeName) { return '<' + lowercase(nodeName); });
} catch(e) {
return lowercase(elemHtml);
}
}
@@ -825,7 +853,7 @@ function encodeUriQuery(val, pctEncodeSpaces) {
replace(/%3A/gi, ':').
replace(/%24/g, '$').
replace(/%2C/gi, ',').
replace((pctEncodeSpaces ? null : /%20/g), '+');
replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
}
@@ -842,7 +870,7 @@ function encodeUriQuery(val, pctEncodeSpaces) {
* Use this directive to auto-bootstrap on application. Only
* one directive can be used per HTML document. The directive
* designates the root of the application and is typically placed
* ot the root of the page.
* at the root of the page.
*
* In the example below if the `ngApp` directive would not be placed
* on the `html` element then the document would not be compiled
@@ -914,22 +942,38 @@ function angularInit(element, bootstrap) {
* @returns {AUTO.$injector} Returns the newly created injector for this app.
*/
function bootstrap(element, modules) {
element = jqLite(element);
modules = modules || [];
modules.unshift(['$provide', function($provide) {
$provide.value('$rootElement', element);
}]);
modules.unshift('ng');
var injector = createInjector(modules);
injector.invoke(
['$rootScope', '$rootElement', '$compile', '$injector', function(scope, element, compile, injector){
scope.$apply(function() {
element.data('$injector', injector);
compile(element)(scope);
});
}]
);
return injector;
var resumeBootstrapInternal = function() {
element = jqLite(element);
modules = modules || [];
modules.unshift(['$provide', function($provide) {
$provide.value('$rootElement', element);
}]);
modules.unshift('ng');
var injector = createInjector(modules);
injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
function(scope, element, compile, injector) {
scope.$apply(function() {
element.data('$injector', injector);
compile(element)(scope);
});
}]
);
return injector;
};
var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;
if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
return resumeBootstrapInternal();
}
window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
angular.resumeBootstrap = function(extraModules) {
forEach(extraModules, function(module) {
modules.push(module);
});
resumeBootstrapInternal();
};
}
var SNAKE_CASE_REGEXP = /[A-Z]/g;
+2 -2
View File
@@ -14,8 +14,8 @@
* - `codeName` `{string}` Code name of the release, such as "jiggling-armfat".
*/
var version = {
full: '"NG_VERSION_FULL"', // all of these placeholder strings will be replaced by rake's
major: "NG_VERSION_MAJOR", // compile task
full: '"NG_VERSION_FULL"', // all of these placeholder strings will be replaced by grunt's
major: "NG_VERSION_MAJOR", // package task
minor: "NG_VERSION_MINOR",
dot: "NG_VERSION_DOT",
codeName: '"NG_VERSION_CODENAME"'
+5 -5
View File
@@ -100,15 +100,15 @@ function annotate(fn) {
*
* <pre>
* // inferred (only works if code not minified/obfuscated)
* $inject.invoke(function(serviceA){});
* $injector.invoke(function(serviceA){});
*
* // annotated
* function explicit(serviceA) {};
* explicit.$inject = ['serviceA'];
* $inject.invoke(explicit);
* $injector.invoke(explicit);
*
* // inline
* $inject.invoke(['serviceA', function(serviceA){}]);
* $injector.invoke(['serviceA', function(serviceA){}]);
* </pre>
*
* ## Inference
@@ -192,7 +192,7 @@ function annotate(fn) {
* This method does not work with code minfication / obfuscation. For this reason the following annotation strategies
* are supported.
*
* # The `$injector` property
* # The `$inject` property
*
* If a function has an `$inject` property and its value is an array of strings, then the strings represent names of
* services to be injected into the function.
@@ -254,7 +254,7 @@ function annotate(fn) {
* @description
*
* Use `$provide` to register new providers with the `$injector`. The providers are the factories for the instance.
* The providers share the same name as the instance they create with the `Provider` suffixed to them.
* The providers share the same name as the instance they create with `Provider` suffixed to them.
*
* A provider is an object with a `$get()` method. The injector calls the `$get` method to create a new instance of
* a service. The Provider can have additional methods which would allow for configuration of the provider.
+4 -4
View File
@@ -4,10 +4,10 @@ var directive = {};
var service = { value: {} };
var DEPENDENCIES = {
'angular.js': 'http://code.angularjs.org/' + angular.version.full + 'angular.min.js',
'angular-resource.js': 'http://code.angularjs.org/' + angular.version.full + 'angular-resource.min.js',
'angular-sanitize.js': 'http://code.angularjs.org/' + angular.version.full + 'angular-sanitize.min.js',
'angular-cookies.js': 'http://code.angularjs.org/' + angular.version.full + 'angular-cookies.min.js'
'angular.js': 'http://code.angularjs.org/' + angular.version.full + '/angular.min.js',
'angular-resource.js': 'http://code.angularjs.org/' + angular.version.full + '/angular-resource.min.js',
'angular-sanitize.js': 'http://code.angularjs.org/' + angular.version.full + '/angular-sanitize.min.js',
'angular-cookies.js': 'http://code.angularjs.org/' + angular.version.full + '/angular-cookies.min.js'
};
+1 -1
View File
@@ -237,7 +237,7 @@ function Browser(window, document, $log, $sniffer) {
*/
self.baseHref = function() {
var href = baseElement.attr('href');
return href ? href.replace(/^https?\:\/\/[^\/]*/, '') : href;
return href ? href.replace(/^https?\:\/\/[^\/]*/, '') : '';
};
//////////////////////////////////////////////////////////////
+68 -12
View File
@@ -155,7 +155,8 @@ function $CompileProvider($provide) {
Suffix = 'Directive',
COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,
CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/,
MULTI_ROOT_TEMPLATE_ERROR = 'Template must have exactly one root element. was: ';
MULTI_ROOT_TEMPLATE_ERROR = 'Template must have exactly one root element. was: ',
urlSanitizationWhitelist = /^\s*(https?|ftp|mailto|file):/;
/**
@@ -209,11 +210,41 @@ function $CompileProvider($provide) {
};
/**
* @ngdoc function
* @name ng.$compileProvider#urlSanitizationWhitelist
* @methodOf ng.$compileProvider
* @function
*
* @description
* Retrieves or overrides the default regular expression that is used for whitelisting of safe
* urls during a[href] sanitization.
*
* The sanitization is a security measure aimed at prevent XSS attacks via html links.
*
* Any url about to be assigned to a[href] via data-binding is first normalized and turned into an
* absolute url. Afterwards the url is matched against the `urlSanitizationWhitelist` regular
* expression. If a match is found the original url is written into the dom. Otherwise the
* absolute url is prefixed with `'unsafe:'` string and only then it is written into the DOM.
*
* @param {RegExp=} regexp New regexp to whitelist urls with.
* @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
* chaining otherwise.
*/
this.urlSanitizationWhitelist = function(regexp) {
if (isDefined(regexp)) {
urlSanitizationWhitelist = regexp;
return this;
}
return urlSanitizationWhitelist;
};
this.$get = [
'$injector', '$interpolate', '$exceptionHandler', '$http', '$templateCache', '$parse',
'$controller', '$rootScope',
'$controller', '$rootScope', '$document',
function($injector, $interpolate, $exceptionHandler, $http, $templateCache, $parse,
$controller, $rootScope) {
$controller, $rootScope, $document) {
var Attributes = function(element, attr) {
this.$$element = element;
@@ -235,7 +266,8 @@ function $CompileProvider($provide) {
*/
$set: function(key, value, writeAttr, attrName) {
var booleanKey = getBooleanAttrName(this.$$element[0], key),
$$observers = this.$$observers;
$$observers = this.$$observers,
normalizedVal;
if (booleanKey) {
this.$$element.prop(key, value);
@@ -254,6 +286,19 @@ function $CompileProvider($provide) {
}
}
// sanitize a[href] values
if (nodeName_(this.$$element[0]) === 'A' && key === 'href') {
urlSanitizationNode.setAttribute('href', value);
// href property always returns normalized absolute url, so we can match against that
normalizedVal = urlSanitizationNode.href;
if (!normalizedVal.match(urlSanitizationWhitelist)) {
this[key] = value = 'unsafe:' + normalizedVal;
}
}
if (writeAttr !== false) {
if (value === null || value === undefined) {
this.$$element.removeAttr(attrName);
@@ -297,7 +342,8 @@ function $CompileProvider($provide) {
}
};
var startSymbol = $interpolate.startSymbol(),
var urlSanitizationNode = $document[0].createElement('a'),
startSymbol = $interpolate.startSymbol(),
endSymbol = $interpolate.endSymbol(),
denormalizeTemplate = (startSymbol == '{{' || endSymbol == '}}')
? identity
@@ -312,7 +358,7 @@ function $CompileProvider($provide) {
function compile($compileNodes, transcludeFn, maxPriority) {
if (!($compileNodes instanceof jqLite)) {
// jquery always rewraps, where as we need to preserve the original selector so that we can modify it.
// jquery always rewraps, whereas we need to preserve the original selector so that we can modify it.
$compileNodes = jqLite($compileNodes);
}
// We can not compile top level text elements since text nodes can be merged and we will
@@ -330,7 +376,14 @@ function $CompileProvider($provide) {
var $linkNode = cloneConnectFn
? JQLitePrototype.clone.call($compileNodes) // IMPORTANT!!!
: $compileNodes;
$linkNode.data('$scope', scope);
// Attach scope only to non-text nodes.
for(var i = 0, ii = $linkNode.length; i<ii; i++) {
var node = $linkNode[i];
if (node.nodeType == 1 /* element */ || node.nodeType == 9 /* document */) {
$linkNode.eq(i).data('$scope', scope);
}
}
safeAddClass($linkNode, 'ng-scope');
if (cloneConnectFn) cloneConnectFn($linkNode, scope);
if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode);
@@ -357,7 +410,7 @@ function $CompileProvider($provide) {
* functions return values - the linking functions - are combined into a composite linking
* function, which is the a linking function for the node.
*
* @param {NodeList} nodeList an array of nodes to compile
* @param {NodeList} nodeList an array of nodes or NodeList to compile
* @param {function(angular.Scope[, cloneAttachFn]} transcludeFn A linking function, where the
* scope argument is auto-generated to the new child of the transcluded parent scope.
* @param {DOMElement=} $rootElement If the nodeList is the root of the compilation tree then the
@@ -380,7 +433,7 @@ function $CompileProvider($provide) {
? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement)
: null;
childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || !nodeList[i].childNodes.length)
childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || !nodeList[i].childNodes || !nodeList[i].childNodes.length)
? null
: compileNodes(nodeList[i].childNodes,
nodeLinkFn ? nodeLinkFn.transclude : transcludeFn);
@@ -420,6 +473,7 @@ function $CompileProvider($provide) {
(function(transcludeFn) {
return function(cloneFn) {
var transcludeScope = scope.$new();
transcludeScope.$$transcluded = true;
return transcludeFn(transcludeScope, cloneFn).
bind('$destroy', bind(transcludeScope, transcludeScope.$destroy));
@@ -725,6 +779,8 @@ function $CompileProvider($provide) {
lastValue,
parentGet, parentSet;
scope.$$isolateBindings[scopeName] = mode + attrName;
switch (mode) {
case '@': {
@@ -935,8 +991,8 @@ function $CompileProvider($provide) {
}
directives.unshift(derivedSyncDirective);
afterTemplateNodeLinkFn = applyDirectivesToNode(directives, $compileNode, tAttrs, childTranscludeFn);
afterTemplateChildLinkFn = compileNodes($compileNode.contents(), childTranscludeFn);
afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs, childTranscludeFn);
afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn);
while(linkQueue.length) {
@@ -1015,10 +1071,10 @@ function $CompileProvider($provide) {
function addAttrInterpolateDirective(node, directives, value, name) {
var interpolateFn = $interpolate(value, true);
// no interpolation found -> ignore
if (!interpolateFn) return;
directives.push({
priority: 100,
compile: valueFn(function attrInterpolateLinkFn(scope, element, attr) {
+1 -1
View File
@@ -52,7 +52,7 @@ function $ControllerProvider() {
* @description
* `$controller` service is responsible for instantiating controllers.
*
* It's just simple call to {@link AUTO.$injector $injector}, but extracted into
* It's just a simple call to {@link AUTO.$injector $injector}, but extracted into
* a service, so that one can override this service with {@link https://gist.github.com/1649788
* BC version}.
*/
+15 -5
View File
@@ -11,15 +11,25 @@
*
* The reasoning for this change is to allow easy creation of action links with `ngClick` directive
* without changing the location or causing page reloads, e.g.:
* <a href="" ng-click="model.$save()">Save</a>
* `<a href="" ng-click="model.$save()">Save</a>`
*/
var htmlAnchorDirective = valueFn({
restrict: 'E',
compile: function(element, attr) {
// turn <a href ng-click="..">link</a> into a link in IE
// but only if it doesn't have name attribute, in which case it's an anchor
if (!attr.href) {
attr.$set('href', '');
if (msie <= 8) {
// turn <a href ng-click="..">link</a> into a stylable link in IE
// but only if it doesn't have name attribute, in which case it's an anchor
if (!attr.href && !attr.name) {
attr.$set('href', '');
}
// add a comment node to anchors to workaround IE bug that causes element content to be reset
// to new attribute content if attribute is updated with value containing @ and element also
// contains value with @
// see issue #1949
element.append(document.createComment('IE fix'));
}
return function(scope, element) {
+4 -3
View File
@@ -66,7 +66,7 @@
it('should execute ng-click but not reload when no href but name specified', function() {
element('#link-5').click();
expect(input('value').val()).toEqual('5');
expect(element('#link-5').attr('href')).toBe('');
expect(element('#link-5').attr('href')).toBe(undefined);
});
it('should only change url when only ng-href', function() {
@@ -309,8 +309,9 @@ forEach(['src', 'href'], function(attrName) {
// on IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist
// then calling element.setAttribute('src', 'foo') doesn't do anything, so we need
// to set the property as well to achieve the desired effect
if (msie) element.prop(attrName, value);
// to set the property as well to achieve the desired effect.
// we use attr[attrName] value since $set can sanitize the url.
if (msie) element.prop(attrName, attr[attrName]);
});
}
};
+4 -2
View File
@@ -3,6 +3,7 @@
function classDirective(name, selector) {
name = 'ngClass' + name;
return ngDirective(function(scope, element, attr) {
var oldVal = undefined;
scope.$watch(attr[name], ngClassWatchAction, true);
@@ -26,13 +27,14 @@ function classDirective(name, selector) {
}
function ngClassWatchAction(newVal, oldVal) {
function ngClassWatchAction(newVal) {
if (selector === true || scope.$index % 2 === selector) {
if (oldVal && (newVal !== oldVal)) {
removeClass(oldVal);
}
addClass(newVal);
}
oldVal = newVal;
}
@@ -65,7 +67,7 @@ function classDirective(name, selector) {
*
* The directive won't add duplicate classes if a particular class was already set.
*
* When the expression changes, the previously added classes are removed and only then the classes
* When the expression changes, the previously added classes are removed and only then the
* new classes are added.
*
* @element ANY
+1 -1
View File
@@ -16,7 +16,7 @@
* `angular.min.js` files. Following is the css rule:
*
* <pre>
* [ng\:cloak], [ng-cloak], .ng-cloak {
* [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
* display: none;
* }
* </pre>
+3 -3
View File
@@ -96,7 +96,7 @@ var ngRepeatDirective = ngDirective({
// Same as lastOrder but it has the current state. It will become the
// lastOrder on the next iteration.
nextOrder = new HashQueueMap(),
arrayLength,
arrayBound,
childScope,
key, value, // key/value of iteration
array,
@@ -117,7 +117,7 @@ var ngRepeatDirective = ngDirective({
array = collection || [];
}
arrayLength = array.length;
arrayBound = array.length-1;
// we are not using forEach for perf reasons (trying to avoid #call)
for (index = 0, length = array.length; index < length; index++) {
@@ -154,7 +154,7 @@ var ngRepeatDirective = ngDirective({
childScope.$index = index;
childScope.$first = (index === 0);
childScope.$last = (index === (arrayLength - 1));
childScope.$last = (index === arrayBound);
childScope.$middle = !(childScope.$first || childScope.$last);
if (!last) {
+7 -4
View File
@@ -8,11 +8,13 @@
* @description
* Conditionally change the DOM structure.
*
* @usageContent
* <ANY ng-switch-when="matchValue1">...</ANY>
* @usage
* <ANY ng-switch="expression">
* <ANY ng-switch-when="matchValue1">...</ANY>
* <ANY ng-switch-when="matchValue2">...</ANY>
* ...
* <ANY ng-switch-default>...</ANY>
* </ANY>
*
* @scope
* @param {*} ngSwitch|on expression to match against <tt>ng-switch-when</tt>.
@@ -63,9 +65,10 @@ var NG_SWITCH = 'ng-switch';
var ngSwitchDirective = valueFn({
restrict: 'EA',
require: 'ngSwitch',
controller: function ngSwitchController() {
// asks for $scope to fool the BC controller module
controller: ['$scope', function ngSwitchController() {
this.cases = {};
},
}],
link: function(scope, element, attr, ctrl) {
var watchExpr = attr.ngSwitch || attr.on,
selectedTransclude,
+1 -1
View File
@@ -147,7 +147,7 @@ var ngViewDirective = ['$http', '$templateCache', '$route', '$anchorScroll', '$c
if (current.controller) {
locals.$scope = lastScope;
controller = $controller(current.controller, locals);
element.contents().data('$ngControllerController', controller);
element.children().data('$ngControllerController', controller);
}
link(lastScope);
+1 -1
View File
@@ -122,7 +122,7 @@
var ngOptionsDirective = valueFn({ terminal: true });
var selectDirective = ['$compile', '$parse', function($compile, $parse) {
//00001111100000000000222200000000000000000000003333000000000000044444444444444444000000000555555555555555550000000666666666666666660000000000000007777
//0000111110000000000022220000000000000000000000333300000000000000444444444444444440000000005555555555555555500000006666666666666666600000000000000077770
var NG_OPTIONS_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w\d]*)|(?:\(\s*([\$\w][\$\w\d]*)\s*,\s*([\$\w][\$\w\d]*)\s*\)))\s+in\s+(.*)$/,
nullModelCtrl = {$setViewValue: noop};
+1 -1
View File
@@ -7,7 +7,7 @@
*
* Filters are just functions which transform input to an output. However filters need to be Dependency Injected. To
* achieve this a filter definition consists of a factory function which is annotated with dependencies and is
* responsible for creating a the filter function.
* responsible for creating a filter function.
*
* <pre>
* // Filter registration
+5 -5
View File
@@ -43,22 +43,22 @@
Search: <input ng-model="searchText">
<table id="searchTextResults">
<tr><th>Name</th><th>Phone</th><tr>
<tr><th>Name</th><th>Phone</th></tr>
<tr ng-repeat="friend in friends | filter:searchText">
<td>{{friend.name}}</td>
<td>{{friend.phone}}</td>
<tr>
</tr>
</table>
<hr>
Any: <input ng-model="search.$"> <br>
Name only <input ng-model="search.name"><br>
Phone only <input ng-model="search.phone"å><br>
<table id="searchObjResults">
<tr><th>Name</th><th>Phone</th><tr>
<tr><th>Name</th><th>Phone</th></tr>
<tr ng-repeat="friend in friends | filter:search">
<td>{{friend.name}}</td>
<td>{{friend.phone}}</td>
<tr>
</tr>
</table>
</doc:source>
<doc:scenario>
@@ -82,7 +82,7 @@
*/
function filterFilter() {
return function(array, expression) {
if (!(array instanceof Array)) return array;
if (!isArray(array)) return array;
var predicates = [];
predicates.check = function(value) {
for (var j = 0; j < predicates.length; j++) {
+12 -6
View File
@@ -168,7 +168,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
fraction += '0';
}
if (fractionSize) formatedText += decimalSep + fraction.substr(0, fractionSize);
if (fractionSize && fractionSize !== "0") formatedText += decimalSep + fraction.substr(0, fractionSize);
}
parts.push(isNegative ? pattern.negPre : pattern.posPre);
@@ -211,8 +211,13 @@ function dateStrGetter(name, shortForm) {
}
function timeZoneGetter(date) {
var offset = date.getTimezoneOffset();
return padNumber(offset / 60, 2) + padNumber(Math.abs(offset % 60), 2);
var zone = -1 * date.getTimezoneOffset();
var paddedZone = (zone >= 0) ? "+" : "";
paddedZone += padNumber(Math[zone > 0 ? 'floor' : 'ceil'](zone / 60), 2) +
padNumber(Math.abs(zone % 60), 2);
return paddedZone;
}
function ampmGetter(date, formats) {
@@ -276,7 +281,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
* * `'ss'`: Second in minute, padded (00-59)
* * `'s'`: Second in minute (0-59)
* * `'a'`: am/pm marker
* * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-1200)
* * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-+1200)
*
* `format` string can also be one of the following predefined
* {@link guide/i18n localizable formats}:
@@ -298,7 +303,8 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
*
* @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or
* number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.SSSZ and it's
* shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ).
* shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is
* specified in the string input, the time is considered to be in the local timezone.
* @param {string=} format Formatting rules (see Description). If not specified,
* `mediumDate` is used.
* @returns {string} Formatted string or the input if input is not recognized as date/millis.
@@ -318,7 +324,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
expect(binding("1288323623006 | date:'medium'")).
toMatch(/Oct 2\d, 2010 \d{1,2}:\d{2}:\d{2} (AM|PM)/);
expect(binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")).
toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2} \-?\d{4}/);
toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2} (\-|\+)?\d{4}/);
expect(binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")).
toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(AM|PM)/);
});
+3 -3
View File
@@ -52,12 +52,12 @@
(<a href ng-click="predicate = '-name'; reverse=false">^</a>)</th>
<th><a href="" ng-click="predicate = 'phone'; reverse=!reverse">Phone Number</a></th>
<th><a href="" ng-click="predicate = 'age'; reverse=!reverse">Age</a></th>
<tr>
</tr>
<tr ng-repeat="friend in friends | orderBy:predicate:reverse">
<td>{{friend.name}}</td>
<td>{{friend.phone}}</td>
<td>{{friend.age}}</td>
<tr>
</tr>
</table>
</div>
</doc:source>
@@ -89,7 +89,7 @@
orderByFilter.$inject = ['$parse'];
function orderByFilter($parse){
return function(array, sortPredicate, reverseOrder) {
if (!(array instanceof Array)) return array;
if (!isArray(array)) return array;
if (!sortPredicate) return array;
sortPredicate = isArray(sortPredicate) ? sortPredicate: [sortPredicate];
sortPredicate = map(sortPredicate, function(predicate){
+8 -4
View File
@@ -245,10 +245,14 @@ function $HttpProvider() {
* - if XSRF prefix is detected, strip it (see Security Considerations section below)
* - if json response is detected, deserialize it using a JSON parser
*
* To override these transformation locally, specify transform functions as `transformRequest`
* and/or `transformResponse` properties of the config object. To globally override the default
* transforms, override the `$httpProvider.defaults.transformRequest` and
* `$httpProvider.defaults.transformResponse` properties of the `$httpProvider`.
* To globally augment or override the default transforms, modify the `$httpProvider.defaults.transformRequest` and
* `$httpProvider.defaults.transformResponse` properties of the `$httpProvider`. These properties are by default an
* array of transform functions, which allows you to `push` or `unshift` a new transformation function into the
* transformation chain. You can also decide to completely override any default transformations by assigning your
* transformation functions to these properties directly without the array wrapper.
*
* Similarly, to locally override the request/response transforms, augment the `transformRequest` and/or
* `transformResponse` properties of the config object passed into `$http`.
*
*
* # Caching
+24 -2
View File
@@ -65,8 +65,30 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
// always async
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
completeRequest(
callback, status || xhr.status, xhr.responseText, xhr.getAllResponseHeaders());
var responseHeaders = xhr.getAllResponseHeaders();
// TODO(vojta): remove once Firefox 21 gets released.
// begin: workaround to overcome Firefox CORS http response headers bug
// https://bugzilla.mozilla.org/show_bug.cgi?id=608735
// Firefox already patched in nightly. Should land in Firefox 21.
// CORS "simple response headers" http://www.w3.org/TR/cors/
var value,
simpleHeaders = ["Cache-Control", "Content-Language", "Content-Type",
"Expires", "Last-Modified", "Pragma"];
if (!responseHeaders) {
responseHeaders = "";
forEach(simpleHeaders, function (header) {
var value = xhr.getResponseHeader(header);
if (value) {
responseHeaders += header + ": " + value + "\n";
}
});
}
// end of the workaround.
completeRequest(callback, status || xhr.status, xhr.responseText,
responseHeaders);
}
};
+3 -2
View File
@@ -1,6 +1,6 @@
'use strict';
var URL_MATCH = /^([^:]+):\/\/(\w+:{0,1}\w*@)?([\w\.-]*)(:([0-9]+))?(\/[^\?#]*)?(\?([^#]*))?(#(.*))?$/,
var URL_MATCH = /^([^:]+):\/\/(\w+:{0,1}\w*@)?(\{?[\w\.-]*\}?)(:([0-9]+))?(\/[^\?#]*)?(\?([^#]*))?(#(.*))?$/,
PATH_MATCH = /^([^\?#]*)?(\?([^#]*))?(#(.*))?$/,
HASH_MATCH = PATH_MATCH,
DEFAULT_PORTS = {'http': 80, 'https': 443, 'ftp': 21};
@@ -79,7 +79,8 @@ function convertToHashbangUrl(url, basePath, hashPrefix) {
var match = matchUrl(url);
// already hashbang url
if (decodeURIComponent(match.path) == basePath) {
if (decodeURIComponent(match.path) == basePath && !isUndefined(match.hash) &&
match.hash.indexOf(hashPrefix) === 0) {
return url;
// convert html5 url -> hashbang url
} else {
+4 -3
View File
@@ -840,9 +840,10 @@ function getterFn(path, csp) {
* @param {string} expression String expression to compile.
* @returns {function(context, locals)} a function which represents the compiled expression:
*
* * `context`: an object against which any expressions embedded in the strings are evaluated
* against (Topically a scope object).
* * `locals`: local variables context object, useful for overriding values in `context`.
* * `context` `{object}` an object against which any expressions embedded in the strings
* are evaluated against (tipically a scope object).
* * `locals` `{object=}` local variables context object, useful for overriding values in
* `context`.
*
* The return function also has an `assign` property, if the expression is assignable, which
* allows one to set values to expressions.
+9 -9
View File
@@ -12,7 +12,7 @@
* interface for interacting with an object that represents the result of an action that is
* performed asynchronously, and may or may not be finished at any given point in time.
*
* From the perspective of dealing with error handling, deferred and promise apis are to
* From the perspective of dealing with error handling, deferred and promise APIs are to
* asynchronous programming what `try`, `catch` and `throw` keywords are to synchronous programming.
*
* <pre>
@@ -47,7 +47,7 @@
*
* At first it might not be obvious why this extra complexity is worth the trouble. The payoff
* comes in the way of
* [guarantees that promise and deferred apis make](https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md).
* [guarantees that promise and deferred APIs make](https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md).
*
* Additionally the promise api allows for composition that is very hard to do with the
* traditional callback ([CPS](http://en.wikipedia.org/wiki/Continuation-passing_style)) approach.
@@ -59,7 +59,7 @@
*
* A new instance of deferred is constructed by calling `$q.defer()`.
*
* The purpose of the deferred object is to expose the associated Promise instance as well as apis
* The purpose of the deferred object is to expose the associated Promise instance as well as APIs
* that can be used for signaling the successful or unsuccessful completion of the task.
*
* **Methods**
@@ -102,7 +102,7 @@
* return result + 1;
* });
*
* // promiseB will be resolved immediately after promiseA is resolved and it's value will be
* // promiseB will be resolved immediately after promiseA is resolved and its value will be
* // the result of promiseA incremented by 1
* </pre>
*
@@ -127,7 +127,7 @@
* # Testing
*
* <pre>
* it('should simulate promise', inject(function($q, $rootSCope) {
* it('should simulate promise', inject(function($q, $rootScope) {
* var deferred = $q.defer();
* var promise = deferred.promise;
* var resolvedValue;
@@ -136,7 +136,7 @@
* expect(resolvedValue).toBeUndefined();
*
* // Simulate resolving of promise
* defered.resolve(123);
* deferred.resolve(123);
* // Note that the 'then' function does not get called synchronously.
* // This is because we want the promise API to always be async, whether or not
* // it got called synchronously or asynchronously.
@@ -312,12 +312,12 @@ function qFactory(nextTick, exceptionHandler) {
* @methodOf ng.$q
* @description
* Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise.
* This is useful when you are dealing with on object that might or might not be a promise, or if
* This is useful when you are dealing with an object that might or might not be a promise, or if
* the promise comes from a source that can't be trusted.
*
* @param {*} value Value or a promise
* @returns {Promise} Returns a single promise that will be resolved with an array of values,
* each value coresponding to the promise at the same index in the `promises` array. If any of
* each value corresponding to the promise at the same index in the `promises` array. If any of
* the promises is resolved with a rejection, this resulting promise will be resolved with the
* same rejection.
*/
@@ -379,7 +379,7 @@ function qFactory(nextTick, exceptionHandler) {
*
* @param {Array.<Promise>} promises An array of promises.
* @returns {Promise} Returns a single promise that will be resolved with an array of values,
* each value coresponding to the promise at the same index in the `promises` array. If any of
* each value corresponding to the promise at the same index in the `promises` array. If any of
* the promises is resolved with a rejection, this resulting promise will be resolved with the
* same rejection.
*/
+6 -5
View File
@@ -137,6 +137,7 @@ function $RootScopeProvider(){
this.$$destroyed = false;
this.$$asyncQueue = [];
this.$$listeners = {};
this.$$isolateBindings = {};
}
/**
@@ -618,10 +619,6 @@ function $RootScopeProvider(){
* Listens on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for discussion of
* event life cycle.
*
* @param {string} name Event name to listen on.
* @param {function(event)} listener Function to call when the event is emitted.
* @returns {function()} Returns a deregistration function for this listener.
*
* The event listener function format is: `function(event, args...)`. The `event` object
* passed into the listener has the following attributes:
*
@@ -632,6 +629,10 @@ function $RootScopeProvider(){
* propagation (available only for events that were `$emit`-ed).
* - `preventDefault` - `{function}`: calling `preventDefault` sets `defaultPrevented` flag to true.
* - `defaultPrevented` - `{boolean}`: true if `preventDefault` was called.
*
* @param {string} name Event name to listen on.
* @param {function(event, args...)} listener Function to call when the event is emitted.
* @returns {function()} Returns a deregistration function for this listener.
*/
$on: function(name, listener) {
var namedListeners = this.$$listeners[name];
@@ -809,7 +810,7 @@ function $RootScopeProvider(){
/**
* function used as an initial value for watchers.
* because it's uniqueue we can easily tell it apart from other values
* because it's unique we can easily tell it apart from other values
*/
function initWatchVal() {}
}];
+4 -3
View File
@@ -263,8 +263,9 @@ function $RouteProvider(){
* {@link ng.directive:ngView ngView} listens for the directive
* to instantiate the controller and render the view.
*
* @param {Object} angularEvent Synthetic event object.
* @param {Route} current Current route information.
* @param {Route} previous Previous route information.
* @param {Route|Undefined} previous Previous route information, or undefined if current is first route entered.
*/
/**
@@ -362,7 +363,7 @@ function $RouteProvider(){
var next = parseRoute(),
last = $route.current;
if (next && last && next.$route === last.$route
if (next && last && next.$$route === last.$$route
&& equals(next.pathParams, last.pathParams) && !next.reloadOnSearch && !forceReload) {
last.params = next.params;
copy(last.params, $routeParams);
@@ -441,7 +442,7 @@ function $RouteProvider(){
match = inherit(route, {
params: extend({}, $location.search(), params),
pathParams: params});
match.$route = route;
match.$$route = route;
}
});
// No route matched; fallback to "otherwise" route
+12
View File
@@ -19,6 +19,18 @@ angular.module('ngCookies', ['ng']).
* this object, new cookies are created/deleted at the end of current $eval.
*
* @example
<doc:example>
<doc:source>
<script>
function ExampleController($cookies) {
// Retrieving a cookie
var favoriteCookie = $cookies.myFavorite;
// Setting a cookie
$cookies.myFavorite = 'oatmeal';
}
</script>
</doc:source>
</doc:example>
*/
factory('$cookies', ['$rootScope', '$browser', function ($rootScope, $browser) {
var cookies = {},
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "vm.",
"1": "nm."
},
"DAY": {
"0": "Sondag",
"1": "Maandag",
"2": "Dinsdag",
"3": "Woensdag",
"4": "Donderdag",
"5": "Vrydag",
"6": "Saterdag"
},
"MONTH": {
"0": "Januarie",
"1": "Februarie",
"2": "Maart",
"3": "April",
"4": "Mei",
"5": "Junie",
"6": "Julie",
"7": "Augustus",
"8": "September",
"9": "Oktober",
"10": "November",
"11": "Desember"
},
"SHORTDAY": {
"0": "So",
"1": "Ma",
"2": "Di",
"3": "Wo",
"4": "Do",
"5": "Vr",
"6": "Sa"
},
"SHORTMONTH": {
"0": "Jan",
"1": "Feb",
"2": "Mar",
"3": "Apr",
"4": "Mei",
"5": "Jun",
"6": "Jul",
"7": "Aug",
"8": "Sep",
"9": "Okt",
"10": "Nov",
"11": "Des"
},
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
"mediumDate": "d MMM y",
"mediumTime": "HH:mm:ss",
"short": "yyyy-MM-dd HH:mm",
"shortDate": "yyyy-MM-dd",
"shortTime": "HH:mm"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "R",
"DECIMAL_SEP": ",",
"GROUP_SEP": " ",
"PATTERNS": {
"0": {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "-",
"negSuf": "",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "(\u00A4",
"negSuf": ")",
"posPre": "\u00A4",
"posSuf": ""
}
}
},
"id": "af-na",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "vm.",
"1": "nm."
},
"DAY": {
"0": "Sondag",
"1": "Maandag",
"2": "Dinsdag",
"3": "Woensdag",
"4": "Donderdag",
"5": "Vrydag",
"6": "Saterdag"
},
"MONTH": {
"0": "Januarie",
"1": "Februarie",
"2": "Maart",
"3": "April",
"4": "Mei",
"5": "Junie",
"6": "Julie",
"7": "Augustus",
"8": "September",
"9": "Oktober",
"10": "November",
"11": "Desember"
},
"SHORTDAY": {
"0": "So",
"1": "Ma",
"2": "Di",
"3": "Wo",
"4": "Do",
"5": "Vr",
"6": "Sa"
},
"SHORTMONTH": {
"0": "Jan",
"1": "Feb",
"2": "Mar",
"3": "Apr",
"4": "Mei",
"5": "Jun",
"6": "Jul",
"7": "Aug",
"8": "Sep",
"9": "Okt",
"10": "Nov",
"11": "Des"
},
"fullDate": "EEEE dd MMMM y",
"longDate": "dd MMMM y",
"medium": "dd MMM y h:mm:ss a",
"mediumDate": "dd MMM y",
"mediumTime": "h:mm:ss a",
"short": "yyyy-MM-dd h:mm a",
"shortDate": "yyyy-MM-dd",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "R",
"DECIMAL_SEP": ",",
"GROUP_SEP": " ",
"PATTERNS": {
"0": {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "-",
"negSuf": "",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "(\u00A4",
"negSuf": ")",
"posPre": "\u00A4",
"posSuf": ""
}
}
},
"id": "af-za",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "vm.",
"1": "nm."
},
"DAY": {
"0": "Sondag",
"1": "Maandag",
"2": "Dinsdag",
"3": "Woensdag",
"4": "Donderdag",
"5": "Vrydag",
"6": "Saterdag"
},
"MONTH": {
"0": "Januarie",
"1": "Februarie",
"2": "Maart",
"3": "April",
"4": "Mei",
"5": "Junie",
"6": "Julie",
"7": "Augustus",
"8": "September",
"9": "Oktober",
"10": "November",
"11": "Desember"
},
"SHORTDAY": {
"0": "So",
"1": "Ma",
"2": "Di",
"3": "Wo",
"4": "Do",
"5": "Vr",
"6": "Sa"
},
"SHORTMONTH": {
"0": "Jan",
"1": "Feb",
"2": "Mar",
"3": "Apr",
"4": "Mei",
"5": "Jun",
"6": "Jul",
"7": "Aug",
"8": "Sep",
"9": "Okt",
"10": "Nov",
"11": "Des"
},
"fullDate": "EEEE dd MMMM y",
"longDate": "dd MMMM y",
"medium": "dd MMM y h:mm:ss a",
"mediumDate": "dd MMM y",
"mediumTime": "h:mm:ss a",
"short": "yyyy-MM-dd h:mm a",
"shortDate": "yyyy-MM-dd",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "R",
"DECIMAL_SEP": ",",
"GROUP_SEP": " ",
"PATTERNS": {
"0": {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "-",
"negSuf": "",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "(\u00A4",
"negSuf": ")",
"posPre": "\u00A4",
"posSuf": ""
}
}
},
"id": "af",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+95 -1
View File
@@ -1,4 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {"NUMBER_FORMATS":{"DECIMAL_SEP":".","GROUP_SEP":",","PATTERNS":[{"minInt":1,"minFrac":0,"macFrac":0,"posPre":"","posSuf":"","negPre":"-","negSuf":"","gSize":3,"lgSize":3,"maxFrac":3},{"minInt":1,"minFrac":2,"macFrac":0,"posPre":"\u00A4","posSuf":"","negPre":"(\u00A4","negSuf":")","gSize":3,"lgSize":3,"maxFrac":2}],"CURRENCY_SYM":"Br"},"pluralCat":function (n) { if (n == 0 || n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;},"DATETIME_FORMATS":{"MONTH":["ጃንዩወሪ","ፌብሩወሪ","ማርች","ኤፕረል","ሜይ","ጁን","ጁላይ","ኦገስት","ሴፕቴምበር","ኦክተውበር","ኖቬምበር","ዲሴምበር"],"SHORTMONTH":["ጃንዩ","ፌብሩ","ማርች","ኤፕረ","ሜይ","ጁን","ጁላይ","ኦገስ","ሴፕቴ","ኦክተ","ኖቬም","ዲሴም"],"DAY":["እሑድ","ሰኞ","ማክሰኞ","ረቡዕ","ሐሙስ","ዓርብ","ቅዳሜ"],"SHORTDAY":["እሑድ","ሰኞ","ማክሰ","ረቡዕ","ሐሙስ","ዓርብ","ቅዳሜ"],"AMPMS":["ጡዋት","ከሳዓት"],"medium":"d MMM y h:mm:ss a","short":"dd/MM/yyyy h:mm a","fullDate":"EEEE, d MMMM y","longDate":"d MMMM y","mediumDate":"d MMM y","shortDate":"dd/MM/yyyy","mediumTime":"h:mm:ss a","shortTime":"h:mm a"},"id":"am-et"});
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ጡዋት",
"1": "ከሳዓት"
},
"DAY": {
"0": "እሑድ",
"1": "ሰኞ",
"2": "ማክሰኞ",
"3": "ረቡዕ",
"4": "ሐሙስ",
"5": "ዓርብ",
"6": "ቅዳሜ"
},
"MONTH": {
"0": "ጃንዩወሪ",
"1": "ፌብሩወሪ",
"2": "ማርች",
"3": "ኤፕረል",
"4": "ሜይ",
"5": "ጁን",
"6": "ጁላይ",
"7": "ኦገስት",
"8": "ሴፕቴምበር",
"9": "ኦክተውበር",
"10": "ኖቬምበር",
"11": "ዲሴምበር"
},
"SHORTDAY": {
"0": "እሑድ",
"1": "ሰኞ",
"2": "ማክሰ",
"3": "ረቡዕ",
"4": "ሐሙስ",
"5": "ዓርብ",
"6": "ቅዳሜ"
},
"SHORTMONTH": {
"0": "ጃንዩ",
"1": "ፌብሩ",
"2": "ማርች",
"3": "ኤፕረ",
"4": "ሜይ",
"5": "ጁን",
"6": "ጁላይ",
"7": "ኦገስ",
"8": "ሴፕቴ",
"9": "ኦክተ",
"10": "ኖቬም",
"11": "ዲሴም"
},
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y h:mm:ss a",
"mediumDate": "d MMM y",
"mediumTime": "h:mm:ss a",
"short": "dd/MM/yyyy h:mm a",
"shortDate": "dd/MM/yyyy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "Birr",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
"PATTERNS": {
"0": {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "-",
"negSuf": "",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "(\u00A4",
"negSuf": ")",
"posPre": "\u00A4",
"posSuf": ""
}
}
},
"id": "am-et",
"pluralCat": function (n) { if (n == 0 || n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+95 -1
View File
@@ -1,4 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {"DATETIME_FORMATS":{"MONTH":["ጃንዩወሪ","ፌብሩወሪ","ማርች","ኤፕረል","ሜይ","ጁን","ጁላይ","ኦገስት","ሴፕቴምበር","ኦክተውበር","ኖቬምበር","ዲሴምበር"],"SHORTMONTH":["ጃንዩ","ፌብሩ","ማርች","ኤፕረ","ሜይ","ጁን","ጁላይ","ኦገስ","ሴፕቴ","ኦክተ","ኖቬም","ዲሴም"],"DAY":["እሑድ","ሰኞ","ማክሰኞ","ረቡዕ","ሐሙስ","ዓርብ","ቅዳሜ"],"SHORTDAY":["እሑድ","ሰኞ","ማክሰ","ረቡዕ","ሐሙስ","ዓርብ","ቅዳሜ"],"AMPMS":["ጡዋት","ከሳዓት"],"medium":"d MMM y h:mm:ss a","short":"dd/MM/yyyy h:mm a","fullDate":"EEEE, d MMMM y","longDate":"d MMMM y","mediumDate":"d MMM y","shortDate":"dd/MM/yyyy","mediumTime":"h:mm:ss a","shortTime":"h:mm a"},"NUMBER_FORMATS":{"DECIMAL_SEP":".","GROUP_SEP":",","PATTERNS":[{"minInt":1,"minFrac":0,"macFrac":0,"posPre":"","posSuf":"","negPre":"-","negSuf":"","gSize":3,"lgSize":3,"maxFrac":3},{"minInt":1,"minFrac":2,"macFrac":0,"posPre":"\u00A4","posSuf":"","negPre":"(\u00A4","negSuf":")","gSize":3,"lgSize":3,"maxFrac":2}],"CURRENCY_SYM":"Br"},"pluralCat":function (n) { if (n == 0 || n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;},"id":"am"});
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ጡዋት",
"1": "ከሳዓት"
},
"DAY": {
"0": "እሑድ",
"1": "ሰኞ",
"2": "ማክሰኞ",
"3": "ረቡዕ",
"4": "ሐሙስ",
"5": "ዓርብ",
"6": "ቅዳሜ"
},
"MONTH": {
"0": "ጃንዩወሪ",
"1": "ፌብሩወሪ",
"2": "ማርች",
"3": "ኤፕረል",
"4": "ሜይ",
"5": "ጁን",
"6": "ጁላይ",
"7": "ኦገስት",
"8": "ሴፕቴምበር",
"9": "ኦክተውበር",
"10": "ኖቬምበር",
"11": "ዲሴምበር"
},
"SHORTDAY": {
"0": "እሑድ",
"1": "ሰኞ",
"2": "ማክሰ",
"3": "ረቡዕ",
"4": "ሐሙስ",
"5": "ዓርብ",
"6": "ቅዳሜ"
},
"SHORTMONTH": {
"0": "ጃንዩ",
"1": "ፌብሩ",
"2": "ማርች",
"3": "ኤፕረ",
"4": "ሜይ",
"5": "ጁን",
"6": "ጁላይ",
"7": "ኦገስ",
"8": "ሴፕቴ",
"9": "ኦክተ",
"10": "ኖቬም",
"11": "ዲሴም"
},
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y h:mm:ss a",
"mediumDate": "d MMM y",
"mediumTime": "h:mm:ss a",
"short": "dd/MM/yyyy h:mm a",
"shortDate": "dd/MM/yyyy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "Birr",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
"PATTERNS": {
"0": {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "-",
"negSuf": "",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "(\u00A4",
"negSuf": ")",
"posPre": "\u00A4",
"posSuf": ""
}
}
},
"id": "am",
"pluralCat": function (n) { if (n == 0 || n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "dd/MM/yyyy h:mm:ss a",
"mediumDate": "dd/MM/yyyy",
"mediumTime": "h:mm:ss a",
"short": "d/M/yyyy h:mm a",
"shortDate": "d/M/yyyy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar-001",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "dd/MM/yyyy h:mm:ss a",
"mediumDate": "dd/MM/yyyy",
"mediumTime": "h:mm:ss a",
"short": "d/M/yyyy h:mm a",
"shortDate": "d/M/yyyy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar-ae",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "dd/MM/yyyy h:mm:ss a",
"mediumDate": "dd/MM/yyyy",
"mediumTime": "h:mm:ss a",
"short": "d/M/yyyy h:mm a",
"shortDate": "d/M/yyyy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar-bh",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "yyyy/MM/dd h:mm:ss a",
"mediumDate": "yyyy/MM/dd",
"mediumTime": "h:mm:ss a",
"short": "yyyy/M/d h:mm a",
"shortDate": "yyyy/M/d",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar-dz",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+95 -1
View File
@@ -1,4 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {"NUMBER_FORMATS":{"DECIMAL_SEP":",","GROUP_SEP":".","PATTERNS":[{"minInt":1,"minFrac":0,"macFrac":0,"posPre":"","posSuf":"","negPre":"","negSuf":"-","gSize":3,"lgSize":3,"maxFrac":3},{"minInt":1,"minFrac":2,"macFrac":0,"posPre":"\u00A4 ","posSuf":"","negPre":"\u00A4 ","negSuf":"-","gSize":3,"lgSize":3,"maxFrac":2}],"CURRENCY_SYM":"£"},"pluralCat":function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if ((n % 100) >= 3 && (n % 100) <= 10 && n == Math.floor(n)) { return PLURAL_CATEGORY.FEW; } if ((n % 100) >= 11 && (n % 100) <= 99 && n == Math.floor(n)) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;},"DATETIME_FORMATS":{"MONTH":["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],"SHORTMONTH":["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],"DAY":["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],"SHORTDAY":["أحد","إثنين","ثلاثاء","أربعاء","خميس","جمعة","سبت"],"AMPMS":["ص","م"],"medium":"dd/MM/yyyy h:mm:ss a","short":"d/M/yyyy h:mm a","fullDate":"EEEE، d MMMM، y","longDate":"d MMMM، y","mediumDate":"dd/MM/yyyy","shortDate":"d/M/yyyy","mediumTime":"h:mm:ss a","shortTime":"h:mm a"},"id":"ar-eg"});
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "dd/MM/yyyy h:mm:ss a",
"mediumDate": "dd/MM/yyyy",
"mediumTime": "h:mm:ss a",
"short": "d/M/yyyy h:mm a",
"shortDate": "d/M/yyyy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar-eg",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "dd/MM/yyyy h:mm:ss a",
"mediumDate": "dd/MM/yyyy",
"mediumTime": "h:mm:ss a",
"short": "d/M/yyyy h:mm a",
"shortDate": "d/M/yyyy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar-iq",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "كانون الثاني",
"1": "شباط",
"2": "آذار",
"3": "نيسان",
"4": "أيار",
"5": "حزيران",
"6": "تموز",
"7": "آب",
"8": "أيلول",
"9": "تشرين الأول",
"10": "تشرين الثاني",
"11": "كانون الأول"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "كانون الثاني",
"1": "شباط",
"2": "آذار",
"3": "نيسان",
"4": "أيار",
"5": "حزيران",
"6": "تموز",
"7": "آب",
"8": "أيلول",
"9": "تشرين الأول",
"10": "تشرين الثاني",
"11": "كانون الأول"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "dd/MM/yyyy h:mm:ss a",
"mediumDate": "dd/MM/yyyy",
"mediumTime": "h:mm:ss a",
"short": "d/M/yyyy h:mm a",
"shortDate": "d/M/yyyy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar-jo",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "dd/MM/yyyy h:mm:ss a",
"mediumDate": "dd/MM/yyyy",
"mediumTime": "h:mm:ss a",
"short": "d/M/yyyy h:mm a",
"shortDate": "d/M/yyyy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar-kw",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "كانون الثاني",
"1": "شباط",
"2": "آذار",
"3": "نيسان",
"4": "أيار",
"5": "حزيران",
"6": "تموز",
"7": "آب",
"8": "أيلول",
"9": "تشرين الأول",
"10": "تشرين الثاني",
"11": "كانون الأول"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "كانون الثاني",
"1": "شباط",
"2": "آذار",
"3": "نيسان",
"4": "أيار",
"5": "حزيران",
"6": "تموز",
"7": "آب",
"8": "أيلول",
"9": "تشرين الأول",
"10": "تشرين الثاني",
"11": "كانون الأول"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "dd/MM/yyyy h:mm:ss a",
"mediumDate": "dd/MM/yyyy",
"mediumTime": "h:mm:ss a",
"short": "d/M/yyyy h:mm a",
"shortDate": "d/M/yyyy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar-lb",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "dd/MM/yyyy h:mm:ss a",
"mediumDate": "dd/MM/yyyy",
"mediumTime": "h:mm:ss a",
"short": "d/M/yyyy h:mm a",
"shortDate": "d/M/yyyy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar-ly",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "yyyy/MM/dd h:mm:ss a",
"mediumDate": "yyyy/MM/dd",
"mediumTime": "h:mm:ss a",
"short": "yyyy/M/d h:mm a",
"shortDate": "yyyy/M/d",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar-ma",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "dd/MM/yyyy h:mm:ss a",
"mediumDate": "dd/MM/yyyy",
"mediumTime": "h:mm:ss a",
"short": "d/M/yyyy h:mm a",
"shortDate": "d/M/yyyy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar-om",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "dd/MM/yyyy h:mm:ss a",
"mediumDate": "dd/MM/yyyy",
"mediumTime": "h:mm:ss a",
"short": "d/M/yyyy h:mm a",
"shortDate": "d/M/yyyy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar-qa",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "dd/MM/yyyy h:mm:ss a",
"mediumDate": "dd/MM/yyyy",
"mediumTime": "h:mm:ss a",
"short": "d/M/yyyy h:mm a",
"shortDate": "d/M/yyyy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar-sa",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "dd/MM/yyyy h:mm:ss a",
"mediumDate": "dd/MM/yyyy",
"mediumTime": "h:mm:ss a",
"short": "d/M/yyyy h:mm a",
"shortDate": "d/M/yyyy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar-sd",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "كانون الثاني",
"1": "شباط",
"2": "آذار",
"3": "نيسان",
"4": "أيار",
"5": "حزيران",
"6": "تموز",
"7": "آب",
"8": "أيلول",
"9": "تشرين الأول",
"10": "تشرين الثاني",
"11": "كانون الأول"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "كانون الثاني",
"1": "شباط",
"2": "آذار",
"3": "نيسان",
"4": "أيار",
"5": "حزيران",
"6": "تموز",
"7": "آب",
"8": "أيلول",
"9": "تشرين الأول",
"10": "تشرين الثاني",
"11": "كانون الأول"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "dd/MM/yyyy h:mm:ss a",
"mediumDate": "dd/MM/yyyy",
"mediumTime": "h:mm:ss a",
"short": "d/M/yyyy h:mm a",
"shortDate": "d/M/yyyy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar-sy",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "yyyy/MM/dd h:mm:ss a",
"mediumDate": "yyyy/MM/dd",
"mediumTime": "h:mm:ss a",
"short": "yyyy/M/d h:mm a",
"shortDate": "yyyy/M/d",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar-tn",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "dd/MM/yyyy h:mm:ss a",
"mediumDate": "dd/MM/yyyy",
"mediumTime": "h:mm:ss a",
"short": "d/M/yyyy h:mm a",
"shortDate": "d/M/yyyy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar-ye",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+95 -1
View File
@@ -1,4 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {"DATETIME_FORMATS":{"MONTH":["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],"SHORTMONTH":["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],"DAY":["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],"SHORTDAY":["أحد","إثنين","ثلاثاء","أربعاء","خميس","جمعة","سبت"],"AMPMS":["ص","م"],"medium":"dd/MM/yyyy h:mm:ss a","short":"d/M/yyyy h:mm a","fullDate":"EEEE، d MMMM، y","longDate":"d MMMM، y","mediumDate":"dd/MM/yyyy","shortDate":"d/M/yyyy","mediumTime":"h:mm:ss a","shortTime":"h:mm a"},"NUMBER_FORMATS":{"DECIMAL_SEP":",","GROUP_SEP":".","PATTERNS":[{"minInt":1,"minFrac":0,"macFrac":0,"posPre":"","posSuf":"","negPre":"","negSuf":"-","gSize":3,"lgSize":3,"maxFrac":3},{"minInt":1,"minFrac":2,"macFrac":0,"posPre":"\u00A4 ","posSuf":"","negPre":"\u00A4 ","negSuf":"-","gSize":3,"lgSize":3,"maxFrac":2}],"CURRENCY_SYM":"£"},"pluralCat":function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if ((n % 100) >= 3 && (n % 100) <= 10 && n == Math.floor(n)) { return PLURAL_CATEGORY.FEW; } if ((n % 100) >= 11 && (n % 100) <= 99 && n == Math.floor(n)) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;},"id":"ar"});
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "ص",
"1": "م"
},
"DAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"MONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"SHORTDAY": {
"0": "الأحد",
"1": "الاثنين",
"2": "الثلاثاء",
"3": "الأربعاء",
"4": "الخميس",
"5": "الجمعة",
"6": "السبت"
},
"SHORTMONTH": {
"0": "يناير",
"1": "فبراير",
"2": "مارس",
"3": "أبريل",
"4": "مايو",
"5": "يونيو",
"6": "يوليو",
"7": "أغسطس",
"8": "سبتمبر",
"9": "أكتوبر",
"10": "نوفمبر",
"11": "ديسمبر"
},
"fullDate": "EEEE، d MMMM، y",
"longDate": "d MMMM، y",
"medium": "dd/MM/yyyy h:mm:ss a",
"mediumDate": "dd/MM/yyyy",
"mediumTime": "h:mm:ss a",
"short": "d/M/yyyy h:mm a",
"shortDate": "d/M/yyyy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "£",
"DECIMAL_SEP": "٫",
"GROUP_SEP": "٬",
"PATTERNS": {
"0": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "",
"negSuf": "-",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "\u00A4 ",
"negSuf": "-",
"posPre": "\u00A4 ",
"posSuf": ""
}
}
},
"id": "ar",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+95 -1
View File
@@ -1,4 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {"NUMBER_FORMATS":{"DECIMAL_SEP":",","GROUP_SEP":" ","PATTERNS":[{"minInt":1,"minFrac":0,"macFrac":0,"posPre":"","posSuf":"","negPre":"-","negSuf":"","gSize":3,"lgSize":3,"maxFrac":3},{"minInt":1,"minFrac":2,"macFrac":0,"posPre":"","posSuf":" \u00A4","negPre":"-","negSuf":" \u00A4","gSize":3,"lgSize":3,"maxFrac":2}],"CURRENCY_SYM":"лв"},"pluralCat":function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;},"DATETIME_FORMATS":{"MONTH":["януари","февруари","март","април","май","юни","юли","август","септември","октомври","ноември","декември"],"SHORTMONTH":["ян.","февр.","март","апр.","май","юни","юли","авг.","септ.","окт.","ноем.","дек."],"DAY":["неделя","понеделник","вторник","сряда","четвъртък","петък","събота"],"SHORTDAY":["нд","пн","вт","ср","чт","пт","сб"],"AMPMS":["пр. об.","сл. об."],"medium":"dd.MM.yyyy HH:mm:ss","short":"dd.MM.yy HH:mm","fullDate":"dd MMMM y, EEEE","longDate":"dd MMMM y","mediumDate":"dd.MM.yyyy","shortDate":"dd.MM.yy","mediumTime":"HH:mm:ss","shortTime":"HH:mm"},"id":"bg-bg"});
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "пр. об.",
"1": "сл. об."
},
"DAY": {
"0": "неделя",
"1": "понеделник",
"2": "вторник",
"3": "сряда",
"4": "четвъртък",
"5": "петък",
"6": "събота"
},
"MONTH": {
"0": "януари",
"1": "февруари",
"2": "март",
"3": "април",
"4": "май",
"5": "юни",
"6": "юли",
"7": "август",
"8": "септември",
"9": "октомври",
"10": "ноември",
"11": "декември"
},
"SHORTDAY": {
"0": "нд",
"1": "пн",
"2": "вт",
"3": "ср",
"4": "чт",
"5": "пт",
"6": "сб"
},
"SHORTMONTH": {
"0": "ян.",
"1": "февр.",
"2": "март",
"3": "апр.",
"4": "май",
"5": "юни",
"6": "юли",
"7": "авг.",
"8": "септ.",
"9": "окт.",
"10": "ноем.",
"11": "дек."
},
"fullDate": "dd MMMM y, EEEE",
"longDate": "dd MMMM y",
"medium": "dd.MM.yyyy HH:mm:ss",
"mediumDate": "dd.MM.yyyy",
"mediumTime": "HH:mm:ss",
"short": "dd.MM.yy HH:mm",
"shortDate": "dd.MM.yy",
"shortTime": "HH:mm"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "lev",
"DECIMAL_SEP": ",",
"GROUP_SEP": " ",
"PATTERNS": {
"0": {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "-",
"negSuf": "",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "-",
"negSuf": " \u00A4",
"posPre": "",
"posSuf": " \u00A4"
}
}
},
"id": "bg-bg",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+95 -1
View File
@@ -1,4 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {"DATETIME_FORMATS":{"MONTH":["януари","февруари","март","април","май","юни","юли","август","септември","октомври","ноември","декември"],"SHORTMONTH":["ян.","февр.","март","апр.","май","юни","юли","авг.","септ.","окт.","ноем.","дек."],"DAY":["неделя","понеделник","вторник","сряда","четвъртък","петък","събота"],"SHORTDAY":["нд","пн","вт","ср","чт","пт","сб"],"AMPMS":["пр. об.","сл. об."],"medium":"dd.MM.yyyy HH:mm:ss","short":"dd.MM.yy HH:mm","fullDate":"dd MMMM y, EEEE","longDate":"dd MMMM y","mediumDate":"dd.MM.yyyy","shortDate":"dd.MM.yy","mediumTime":"HH:mm:ss","shortTime":"HH:mm"},"NUMBER_FORMATS":{"DECIMAL_SEP":",","GROUP_SEP":" ","PATTERNS":[{"minInt":1,"minFrac":0,"macFrac":0,"posPre":"","posSuf":"","negPre":"-","negSuf":"","gSize":3,"lgSize":3,"maxFrac":3},{"minInt":1,"minFrac":2,"macFrac":0,"posPre":"","posSuf":" \u00A4","negPre":"-","negSuf":" \u00A4","gSize":3,"lgSize":3,"maxFrac":2}],"CURRENCY_SYM":"лв"},"pluralCat":function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;},"id":"bg"});
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "пр. об.",
"1": "сл. об."
},
"DAY": {
"0": "неделя",
"1": "понеделник",
"2": "вторник",
"3": "сряда",
"4": "четвъртък",
"5": "петък",
"6": "събота"
},
"MONTH": {
"0": "януари",
"1": "февруари",
"2": "март",
"3": "април",
"4": "май",
"5": "юни",
"6": "юли",
"7": "август",
"8": "септември",
"9": "октомври",
"10": "ноември",
"11": "декември"
},
"SHORTDAY": {
"0": "нд",
"1": "пн",
"2": "вт",
"3": "ср",
"4": "чт",
"5": "пт",
"6": "сб"
},
"SHORTMONTH": {
"0": "ян.",
"1": "февр.",
"2": "март",
"3": "апр.",
"4": "май",
"5": "юни",
"6": "юли",
"7": "авг.",
"8": "септ.",
"9": "окт.",
"10": "ноем.",
"11": "дек."
},
"fullDate": "dd MMMM y, EEEE",
"longDate": "dd MMMM y",
"medium": "dd.MM.yyyy HH:mm:ss",
"mediumDate": "dd.MM.yyyy",
"mediumTime": "HH:mm:ss",
"short": "dd.MM.yy HH:mm",
"shortDate": "dd.MM.yy",
"shortTime": "HH:mm"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "lev",
"DECIMAL_SEP": ",",
"GROUP_SEP": " ",
"PATTERNS": {
"0": {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "-",
"negSuf": "",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "-",
"negSuf": " \u00A4",
"posPre": "",
"posSuf": " \u00A4"
}
}
},
"id": "bg",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+95 -1
View File
@@ -1,4 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {"NUMBER_FORMATS":{"DECIMAL_SEP":".","GROUP_SEP":",","PATTERNS":[{"minInt":1,"minFrac":0,"macFrac":0,"posPre":"","posSuf":"","negPre":"-","negSuf":"","gSize":2,"lgSize":3,"maxFrac":3},{"minInt":1,"minFrac":2,"macFrac":0,"posPre":"","posSuf":"\u00A4","negPre":"(","negSuf":"\u00A4)","gSize":2,"lgSize":3,"maxFrac":2}],"CURRENCY_SYM":"৳"},"pluralCat":function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;},"DATETIME_FORMATS":{"MONTH":["জানুয়ারী","ফেব্রুয়ারী","মার্চ","এপ্রিল","মে","জুন","জুলাই","আগস্ট","সেপ্টেম্বর","অক্টোবর","নভেম্বর","ডিসেম্বর"],"SHORTMONTH":["জানুয়ারী","ফেব্রুয়ারী","মার্চ","এপ্রিল","মে","জুন","জুলাই","আগস্ট","সেপ্টেম্বর","অক্টোবর","নভেম্বর","ডিসেম্বর"],"DAY":["রবিবার","সোমবার","মঙ্গলবার","বুধবার","বৃহষ্পতিবার","শুক্রবার","শনিবার"],"SHORTDAY":["রবি","সোম","মঙ্গল","বুধ","বৃহস্পতি","শুক্র","শনি"],"AMPMS":["am","pm"],"medium":"d MMM, y h:mm:ss a","short":"d/M/yy h:mm a","fullDate":"EEEE, d MMMM, y","longDate":"d MMMM, y","mediumDate":"d MMM, y","shortDate":"d/M/yy","mediumTime":"h:mm:ss a","shortTime":"h:mm a"},"id":"bn-bd"});
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "am",
"1": "pm"
},
"DAY": {
"0": "রবিবার",
"1": "সোমবার",
"2": "মঙ্গলবার",
"3": "বুধবার",
"4": "বৃহষ্পতিবার",
"5": "শুক্রবার",
"6": "শনিবার"
},
"MONTH": {
"0": "জানুয়ারী",
"1": "ফেব্রুয়ারী",
"2": "মার্চ",
"3": "এপ্রিল",
"4": "মে",
"5": "জুন",
"6": "জুলাই",
"7": "আগস্ট",
"8": "সেপ্টেম্বর",
"9": "অক্টোবর",
"10": "নভেম্বর",
"11": "ডিসেম্বর"
},
"SHORTDAY": {
"0": "রবি",
"1": "সোম",
"2": "মঙ্গল",
"3": "বুধ",
"4": "বৃহস্পতি",
"5": "শুক্র",
"6": "শনি"
},
"SHORTMONTH": {
"0": "জানুয়ারী",
"1": "ফেব্রুয়ারী",
"2": "মার্চ",
"3": "এপ্রিল",
"4": "মে",
"5": "জুন",
"6": "জুলাই",
"7": "আগস্ট",
"8": "সেপ্টেম্বর",
"9": "অক্টোবর",
"10": "নভেম্বর",
"11": "ডিসেম্বর"
},
"fullDate": "EEEE, d MMMM, y",
"longDate": "d MMMM, y",
"medium": "d MMM, y h:mm:ss a",
"mediumDate": "d MMM, y",
"mediumTime": "h:mm:ss a",
"short": "d/M/yy h:mm a",
"shortDate": "d/M/yy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "৳",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
"PATTERNS": {
"0": {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "-",
"negSuf": "",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "(",
"negSuf": "\u00A4)",
"posPre": "",
"posSuf": "\u00A4"
}
}
},
"id": "bn-bd",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
});
}]);
+98
View File
@@ -0,0 +1,98 @@
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
"AMPMS": {
"0": "am",
"1": "pm"
},
"DAY": {
"0": "রবিবার",
"1": "সোমবার",
"2": "মঙ্গলবার",
"3": "বুধবার",
"4": "বৃহষ্পতিবার",
"5": "শুক্রবার",
"6": "শনিবার"
},
"MONTH": {
"0": "জানুয়ারী",
"1": "ফেব্রুয়ারী",
"2": "মার্চ",
"3": "এপ্রিল",
"4": "মে",
"5": "জুন",
"6": "জুলাই",
"7": "আগস্ট",
"8": "সেপ্টেম্বর",
"9": "অক্টোবর",
"10": "নভেম্বর",
"11": "ডিসেম্বর"
},
"SHORTDAY": {
"0": "রবি",
"1": "সোম",
"2": "মঙ্গল",
"3": "বুধ",
"4": "বৃহস্পতি",
"5": "শুক্র",
"6": "শনি"
},
"SHORTMONTH": {
"0": "জানুয়ারী",
"1": "ফেব্রুয়ারী",
"2": "মার্চ",
"3": "এপ্রিল",
"4": "মে",
"5": "জুন",
"6": "জুলাই",
"7": "আগস্ট",
"8": "সেপ্টেম্বর",
"9": "অক্টোবর",
"10": "নভেম্বর",
"11": "ডিসেম্বর"
},
"fullDate": "EEEE, d MMMM, y",
"longDate": "d MMMM, y",
"medium": "d MMM, y h:mm:ss a",
"mediumDate": "d MMM, y",
"mediumTime": "h:mm:ss a",
"short": "d/M/yy h:mm a",
"shortDate": "d/M/yy",
"shortTime": "h:mm a"
},
"NUMBER_FORMATS": {
"CURRENCY_SYM": "৳",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
"PATTERNS": {
"0": {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
"maxFrac": 3,
"minFrac": 0,
"minInt": 1,
"negPre": "-",
"negSuf": "",
"posPre": "",
"posSuf": ""
},
"1": {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
"maxFrac": 2,
"minFrac": 2,
"minInt": 1,
"negPre": "(",
"negSuf": "\u00A4)",
"posPre": "",
"posSuf": "\u00A4"
}
}
},
"id": "bn-in",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
});
}]);

Some files were not shown because too many files have changed in this diff Show More