* `literal` is set to true if the expression's top-level is a JavaScript
literal (number, string, boolean, null/undefined, array, object), even
if it contains non-literals inside.
* `constant` is set to true if the expression is known to be made
entirely of constant values, i.e., evaluating it will always yield the
same result.
A consequence is that a JSON expression is guaranteed to be both literal
and constant.
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.
Add optional comparator function argument to $filter('filter')(array,
expression, comparator) such that the comparator function is used to
compare the values and predicates. When true, defaults to equality.
When missing defaults to substring matching.
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."
Expose $then and $resolved properties on resource action return values which
allow checking if a promise has been resolved already as well as registering
listeners at any time of the resource object life-cycle.
This commit replaces unreleased commit f3bff27460
which exposed unintuitive $q api instead and didn't expose important stuff
like http headers.
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
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
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
Add 'xsrfCookieName' and 'xsrfHeaderName' property to $httpProvider.defaults and
http config object, which give the name of the cookie the XSRF token is found
in, and the name of the header it is sent in, respectively.
This allows interop with servers with built-in XSRF support that use different
names.
The defaults match the current hard-coded values of 'XSRF-TOKEN' and
'X-XSRF-TOKEN'.
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
in 5ae63fd3 the comparison was made consistent but strict, so that
angular.equals({}, {foo: undefined}) // always returns false
this turns out to cause issues for data that is being roundtripped via network
and serialized via JSON because JSON.stringify serializes {foo: undefined} as {}.
Since angular.equals() behaved like this before the 5ae63fd3 in 50% of the cases,
changing the behavior in this way should not introduce any significant issues.
Closes#1648
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.
Fixed an issues with ngResource param substitution where it was incorrectly removing leading slash when param was followed by a non-slash character.
Ex:
'/:foo/:bar.baz/:aux'
params = {
foo: 'aaa',
bar: undefined,
aux: undefined
}
The above params were incorrectly producing '/aaa.baz' but now it results in '/aaa/.baz'.
The leak can occur when ngSwich is used inside ngRepeat or any other
directive which is destroyed while its transcluded content (which
includes ngSwitch) is not attached to the DOM.
Refactor ngSwitch to use controller instead of storing data on compile
node. This means that we don't need to clean up the jq data cache.
Controller reference is released when the linking fn is released.
Closes#1621
previously:
a = {};
b = {x:undefined};
angular.equals(a, b) == angular.equals(b, a) // returns false.
both should return false because these objects are not equal.
unlike in implemented in #1695 the comparison should be stricter
and return false not true. if we need to relax this in the future
we can always do so.
Closes#1648
If the $last property is calculated from the original collectionLength
on an object and properties starting with $ were filtered out, then $last
is never applied and $middle is applied erroniously.
Closes#1789
Commit 773ac4a broke support for route parameters that are not seperated
from other route parts by slashes, which this change fixes. It also adds
some documentation about path parameters to the when() method and
escapes all regular expression special characters in the URL, not just
some.
Support modifying the DOM structure in the post link function of a directive
by creating a defensive copy of the node list, as opposed to a live DOM list.
This is useful for directives to actually replace their entire DOM fragment,
e.g. with the HTML fragment generated by a 3rd party component (Closure, Bootstrap ...).
Fix the indentation of the compileNodes function (was one too little).
previously we were always parsing the string input as UTC which cased issues like:
{{ '2012-04-01' | date:'d MMM yyyy' }} renders as 31 Mar 2012
BREAKING CHANGE: string input without timezone info is now parsed as local time/date
Closes#847
The jQuery implementation of children only returns child nodes of the given element that are elements themselves. The previous jqLite implementation was returning all nodes except those that are text nodes. Use jQLite.contents() to get all the child nodes.
The jQuery implementation of contents returns [] if the object has no child nodes. The previous jqLite implementation was returning undefined, causing a stack overflow in test/testabilityPatch.js when it tried to `cleanup()` a window object.
The testabilityPatch was incorrectly using children() rather than contents() inside cleanup() to iterate down through all the child nodes of the element to clean up.
next() is supposed to return the next sibling *element* so it
should ignore text nodes. To achieve this, nextElementSibling()
should be used instead of nextSibling().
the warning is defunct (and the test is incorrect) so obviously nobody is using
it and it just takes up space.
also the browser behavior varies (ff and chrome allow up to 150 cookies, safari
even more), so it's not very useful.
Closes#1712
Routes like '/bar/foovalue/barvalue' matching '/bar/:foo/:bar'
now are well mapped in $routeParams to:
{bar:'barvalue', foo:'foovalue'}
Closes: #1501
Signed-off-by: Gonzalo Ruiz de Villa <gonzaloruizdevilla@gmail.com>
This is needed to prevent CORS preflight checks. The XSFR token
is quite useless for CORS requests anyway.
BREAKING CHANGE: X-XSFR-TOKEN is no longer send for cross domain
requests. This shouldn't affect any known production service.
Closes#1096
X-Requested-With header is rarely used in practice and by using
it all the time we are triggering preflight checks for crossdomain
requests.
We could try detecting if we are doing CORS requests or not, but
it doesn't look like it's worth the trouble.
BREAKING CHANGE: X-Requested-With header is not set by $http service
any more. If anyone actually uses this header it's quite easy to add
it back via:
```
myAppModule.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
}]);
```
Closes#1004
I'm reverting changes that were originally done to ngRepeat to fix#933,
because these are now not necessary after the previous changes to keep
ngModel always synced with the DOM.
in jQuery 1.8.x the data() data structure is changed and events are
not accessible via data().events. Since all we need is to trigger
all event handlers, we can do so via triggerHandler() api instead of
mocking with the internal jQuery data structures.
This fix was originally proposed by PeteAppleton via PR #1512.
Closes#1512
we need triggerHandler() to become jQuery 1.8.x compatible.
this is not fully featured triggerHandler() implementation - it doesn't
bother creating new DOM events and passing them into the event handlers.
this is intentional, we don't need access to the native DOM event for our
own purposes and creating these event objects is really tricky.
Today, calling e.g. $http(url, { params: { a: [1,2,3] } }) results in a query
string like "?a=%5B1%2C2%2C3%5D" which is undesirable. This commit enhances
buildURL to createa query string like "?a=1&a=2&a=3".
BREAKING CHANGE: if the server relied on the buggy behavior then either the
backend should be fixed or a simple serialization of the array should be done
on the client before calling the $http service.
Closes#1363
Having a $resource defined as:
var R = $resource('/Path', {}, {
get: {method: 'GET', params: {objId: '1'}},
perform: {method: 'GET'}
});
was causing both actions to call the same URI (if called in this order):
R.get({}); // => /Path?objId=1
R.perform({}); // => /Path?objId=1
window.SecurityPolicy.isActive() is now window.securityPolicy.isActive
since this is available only in Chrome Canary which has already been
updated, we can safely make this change without worrying about
backwards compatilibty.
Closes#1577
Bug caused by the use of the `||` operator to replace all non-truthy
values with an empty string. Changed to replace only `undefined` values.
Closes#1401
Prefixed attributes like data-ng-model and x-ng-model were not being
found by the Selector. It was only looking at ng: and ng- prefixed
attributes.
Added a few tests as well to ensure the aforementioned prefixed
attributes are being matched properly.
Closes#1020
This fixes the issue that caused two attr interpolation observers
to be registered for the same attribute as a result of isolate
scope definition with attr (@) property for this attribute.
Duplicate observers would then fight with each other updating the
model.
The issue occured only when this directive was used in a repeater
because that's when we clone the template node which caused the
two observers to point to two different sets of $attr instances.
Closes#1166, #836
IEEE 754 floating point sometimes results in values that are very small,
rather than zero. One example is 1.0 + 1.07 - 2.07, which returns
4.440892098500626e-16 instead of 0.
This change tweaks the number formatting logic so that an exponential
value with a negative exponent that is larger than the precision+1
returns 0 instead. For example: with precision 2, anything with an
exponent of -4, -5 or more would become 0. 9e-3 = 0.009 = 0.01, but 9e-4
= 0.0009 = 0.001 = 0.00. This detail is unlikely to matter since this
quirk is usually only triggered with values very close to zero.
Closes#1469
This was really corner case:
Watcher needs to return changed value, to notify that model might have changed and one more $digest cycle needs to be performed.
The watcher, that takes care of reference binding into an isolate scope ("="), did not return changed value, if the change was from the isolate scope to the parent.
If any other watcher returned change, it worked fine, as this change caused re-digest.
Closes#1272
Having one async queue per scope complicates the matters when users wish to do
partial scope updates, since many services put events on the rootScope. By
having single queue the programing model is simplified.
Current implementation of ngSrc may lead to empty src attribute when page is loading.
For example:
<img ng-src="{{image.url}}">
can be temporarily rendered as
<img src="">
before the image resource is loaded.
Some browser emits a request to the current page when seeing <img src=""> (Firefox13 and IE8 will, Chromium20 won't), which leads to performance problems.
Makes the time zone optional in the date filter
Problem with the current R_ISO8601_STR regex was that the time was optional, but the zone was not.
This results in the filter not formatting local date times, which it could easily do.
For example:
2012-08-30 -> formatted
2012-08-30T06:06:06.123Z -> formatted
2012-08-30T06:06:06.123 -> NOT formatted
A simple change in the regex fixes this. Arguably this is closer to the ISO8601 spec which specifies
local dates being in the "current time zone" and not requiring a Z. In any case it behaves more like
a user would expect.
Close#1212
when a param value was 0 (or false) it was ignored and removed from url.
after this fix that only happens if the value is undefined or null.
- $resource should handle multiple params with same name
- ignore slashes of undefined parameters
- fix default parameters issue, mentioned in #875Closes#875Closes#782
if an exception occurs during interpolation of a string
(e.g. name() in "Hello, {{name()}}!" throws an exception) we now print
an error message with the expression that was being evaluated when the
exception was thrown.
Since developers are allowed to customize start/end interpolation
strings, but third-party directive creators don't know about these
customizations, we should standardize on {{ }} in templates of
reusable (third-party) directives. During the compilation, these
templates are then denormalized to use whatever the custom
start/end symbol is, effectively translating the template into the
syntax of the runtime environment.
This addresses an issue raised at http://goo.gl/e8VPV
Existing code should not be affected by this change since project
that do use custom interpolation markers are not expected to use
{{ }} in existing directive templates.
previously we expected to find option elements only within select element and if
that was not the case we throw an error. This made it impossible to include datalist
element with nested option elements in the template.
Closes#1165
this fix ensures that we prevent the default action on form submission
(full page reload) even in cases when the form is being destroyed as
a result of the submit event handler (e.g. when route change is
triggered).
The fix is more complicated than I'd like it to be mainly because
we need to ensure that we don't create circular references between
js closures and dom elements via DOM event handlers that would then
result in a memory leak.
Also the differences between IE8, IE9 and normal browsers make testing
this ugly.
Closes#1238
the original test relied on incorrect assumptions about how jasmine async
tests work (when setTimeout is triggered) and how browser reloads a page
(the sequence of events) and thus the test passes even when the default
is not prevented.
this change fixes the test by registering an extra submit event handler
that checks if the default was prevented.
if the default was not prevented, the test will fail and the page will
be reloaded causing the test runner to panic.
When user clicks a link, $location needs to intercept this event. The <a> doesn't have to be target element of the DOM event, so it needs to traverse the DOM, to find first <a> parent.
If the target element was removed from DOM, during the same event, it would throw an exception. This fixes the issue.
Closes#1058
This is a second fix for a regression that was introduced by 92a2e180.
The fix addresses scenarios when the $location service is configured with
a hash prefix.
Closes#1037
Changed the isolate scope binding options to:
- @attr - attribute binding (including interpolation)
- =model - by-directional model binding
- &expr - expression execution binding
This change simplifies the terminology as well as
number of choices available to the developer. It
also supports local name aliasing from the parent.
BREAKING CHANGE: isolate scope bindings definition has changed and
the inject option for the directive controller injection was removed.
To migrate the code follow the example below:
Before:
scope: {
myAttr: 'attribute',
myBind: 'bind',
myExpression: 'expression',
myEval: 'evaluate',
myAccessor: 'accessor'
}
After:
scope: {
myAttr: '@',
myBind: '@',
myExpression: '&',
// myEval - usually not useful, but in cases where the expression is assignable, you can use '='
myAccessor: '=' // in directive's template change myAccessor() to myAccessor
}
The removed `inject` wasn't generaly useful for directives so there should be no code using it.
attr.$observe used to call function only if there was interpolation
on that attribute. We now call the observation function all the time
but we only save the reference to it if interpolation is present.
$timeout has a better name ($defer got often confused with something related to $q) and
is actually promise based with cancelation support.
With this commit the $defer service is deprecated and will be removed before 1.0.
Closes#704, #532
$position marker doesn't work well in cases when we have just one item
in the list because then the item is both the first and last. To solve
this properly we need to expose individual $first and $middle and $last
flags.
BREAKING CHANGE: $position is not exposed in repeater scopes any more
To update, search for $position and replace it with one of $first,
$middle or $last.
Closes#912
Since angular attaches scope/injector/controller
into DOM it should clean up after itself. No need
to complain about memory leaks, since they can
only happened on detached DOM. Detached DOM would
only be in tests, since in production the DOM
would be attached to render tree and removal
would automatically clear memory.
The url used for location parsing was quite strict and did not support
custom url schemes like "chrome-extension://". With this change the only
requirement for scheme is that it doesn't contain ":" character.
The real issue is in FF, see https://bugzilla.mozilla.org/show_bug.cgi?id=407172.
FF overly encodes stuff which breaks our expectations and then we fail .url() != currentUrl.absUrl()
comparison unexpectidly, which leads to infinite digest.
The workaround is to correct for this inconsistency in $browser and decode any single quotes in urls.
Closes#920
IE9 ignores setAttribute('src', val) calls on img if "ng:src" attribute
is present. It only fetches the image if element property is updated as well.
Closes#935
On IE9 the input event is not fired when backspace or delete key are pressed or when
cut is performed. This makes listening on the input event unreliable and therefore
it's better for us to just use keydown/change events instead.
Closes#879
This stuff was never documented and is an accidental leftover from the time
when the compiler was rewritten.
If any code depends on this, it should be rewritten to use ngTransclude directive
intead.
CSP (content security policy) forbids apps to use eval or
Function(string) generated functions (among other things). For us to be
compatible, we just need to implement the "getterFn" in $parse without
violating any of these restrictions.
We currently use Function(string) generated functions as a speed
optimization. With this change, it will be possible to opt into the CSP
compatible mode using the ngCsp directive. When this mode is on Angular
will evaluate all expressions up to 30% slower than in non-CSP mode, but
no security violations will be raised.
In order to use this feature put ngCsp directive on the root element of
the application. For example:
<!doctype html>
<html ng-app ng-csp>
...
...
</html>
Closes#893
Previously only when ngOptions was used, we correctly handled situations
when model was set to an unknown value. With this change, we'll add/remove
extra unknown option or reuse an existing empty option (option with value
set to "") when model is undefined.
previously we were doing all kinds of checks to see if we should rewrite the url or not and we
were missing many scenarios. not any more.
with this change, we rewrite the url unless:
- the href is not set
- link has target attribute
- the absolute url of the link doesn't match the absolute prefix for all urls in our app
This also means that ng-ext-link attribute which we previously used to distinguish external
links from app links is not necessary any more. apps can just set target=_self to prevent
rewriting.
BREAKING CHANGE: ng-ext-link directive was removed because it's unnecessary
apps that relied on ng-ext-link should simply replace it with target=_self
previously it would create a new instance which wasn't configured as the one in the app,
which resulted in incorrect values being returned in html5 mode with base url set
Often it is impossible to set the http defaults during the config phase,
because the config info is not available at this time.
A good example is authentication - often the app needs to bootstrap,
allow user to enter credentials and only then it gains access to
session token which then should be sent to the server with every request.
Without having the ability to set the defaults at runtime, the developer
either has to resort to hacks, or has to set the session token header
with every request made by the app.
Create build for other modules as well (ngResource, ngCookies):
- wrap into a function
- add license
- add version
Breaks `$sanitize` service, `ngBindHtml` directive and `linky` filter were moved to the `ngSanitize` module. Apps that depend on any of these will need to load `angular-sanitize.js` and include `ngSanitize` in their dependency list: `var myApp = angular.module('myApp', ['ngSanitize']);`
this was never meant to be a public api used by apps. I refactored
the code to hide the functionality.
BREAKING CHANGE: $browser.addJs method was removed
apps that depended on this functionality should either use many of the
existing script loaders or create a simple helper method specific to the
app.
Previously one had to write:
$routeProvider.when('/foo', {...});
$routeProvider.when('/bar', {...});
$routeProvider.otherwise({...});
After this change it's just:
$routeProvider.
when('/foo', {...}).
when('/bar', {...}).
otherwise({...});
Breaks #when which used to return the route definition object but now
returns self. Returning the route definition object is not very useful
so its likely that nobody ever used it.
The purpose of allowing the scope to be specified was to enable the $route service to work
together with ngInclude. However the functionality of creating scopes was in the recent past
moved from the $route service to the ngView directive, so currently there is no valid use case
for specifying the scope for ngInclude. In fact, allowing the scope to be defined can under
certain circumstances lead to memory leaks.
Breaks ngInclude does not have scope attribute anymore.
It turns out that listening only on "blur" event is not sufficient in many scenarios,
especially when you use form validation you always had to use ngModelnstant
e.g. if you want to disable a button based on valid/invalid form.
The feedback we got from our apps as well as external apps is that the
ngModelInstant should be the default.
In the future we might provide alternative ways of suppressing updates
on each key stroke, but it's not going to be the default behavior.
Apps already using the ngModelInstant can safely remove it from their
templates. Input fields without ngModelInstant directive will start propagating
the input changes into the model on each key stroke.
Previously if there was a white-space in fn: fn( ) {} we failed to infer no args.
This was originally reported by recht, but I decided to use a different fix.
Closes#829
We have many instances of this object and we clone them as well (e.g. ng-repeat).
This should save some memory and performance as well.
Double prefixed private properties of attr object:
attr.$element -> attr.$$element
attr.$observers -> attr.$$observers
Update shallowCopy to not copy $$ properties and allow passing optional destination object.
The `attr` object was only shallow copied which caused all observers to be shared.
Fixing similar issue in ng-* boolean attributes as well as ng-src and ng-href.
Instead of using our custom serializer we now use the native one and
use the replacer function to customize the serialization to preserve
most of the previous behavior (ignore $ and $$ properties as well
as window, document and scope instances).
Breaks angular.fromJson which doesn't deserialize date strings into date objects.
This was done to make fromJson compatible with JSON.parse.
If you do require the old behavior - if at all neeeded then because of
json deserialization of XHR responses - then please create a custom
$http transform:
$httpProvider.defaults.transformResponse.push(function(data) {
// recursively parse dates from data object here
// see code removed in this diff for hints
});
Closes#202
So that we can have non string values, e.g. ng-value="true" for radio inputs
Breaks boolean attrs are evaluated rather than interpolated
To migrate your code, change: <input ng-disabled="{{someBooleanVariable}}">
to: <input ng-disabled="someBooleanVariabla">
Affected directives:
* ng-multiple
* ng-selected
* ng-checked
* ng-disabled
* ng-readonly
* ng-required
This service has been accidentaly documented in the past, it should not be considered
to be public api.
I'm also removing fallback to Modernizr since we don't need it.
Breaks any app that depends on this service and its fallback to Modernizr, please
migrate to custom "Modernizr" service:
module.value('Modernizr', function() { return Modernizr; });
It's now possible to register controllers as:
.register('MyCtrl', function($scope) { ... });
// or
.register('MyCtrl', ['$scope', function($scope) { ... });
Additionally a module loader shortcut api was added as well:
myModule.controller('MyCtr', function($scope) { ... });
For typical app that has ng-app directive on the html element, we now can do:
angular.element(document).injector() or .injector()
angular.element(document).scope() or .scope()
instead of:
angular.element(document.getElementsByTagName('html')[0]).injector()
...
This makes for a much more flexible route matching:
- route /foo matches /foo and redirects /foo/ to /foo
- route /bar/ matches /bar/ and redirects /bar to /bar/
Closes#784
In IE window.console.log and friends are functions that don't have apply or call fns.
For this reason we have to treat them specially and do our best to log at least
something when running in this browser.
Closes#805
In ie7 all of the input fields are set to readonly and disabled, because ie7 enumerates over all attributes even if the are not declared on the element.
Added support of timezone in dates not just zulu timezone.
This fixes issues for date filter which uses json deserialization under the hood. (for now)
Closes #/800
Fixed an issue where a directive that uses transclusion (such as ngRepeat) failed to link if it was declared on the root element of the compilation tree. (For example ngView or ngInclude including template where ngRepeat was the top most element).
corrected omitted assignment of controller to the element data object. Without this fix the controller created by ngView is not accessible from the browser debugger.
this is to enable nicer tests:
describe('fooSvc', function() {
var fooSvc;
beforeEach(inject(function(_fooSvc_) {
fooSvc = _fooSvc_;
}));
it('should do this thing', function() {
//test fooSvc
});
});