Compare commits
317 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d2a769e196 | |||
| 68a8c8907d | |||
| 701d61080a | |||
| a8cc449706 | |||
| 2aa212b19c | |||
| 1f23cfe9c7 | |||
| 0fa8e47fb5 | |||
| 8043784fd7 | |||
| 526a6b31e5 | |||
| 14fd064a62 | |||
| 3178afbf0c | |||
| ce3b616432 | |||
| 54a761905d | |||
| aa531d7bd1 | |||
| d7e9ae1215 | |||
| 6cf9ede88e | |||
| 6092291bd7 | |||
| 3d0f11212f | |||
| 6194e002e2 | |||
| 75545d4d1c | |||
| d67eb2f2db | |||
| 6b8153ff0f | |||
| fb132732f1 | |||
| 336b157497 | |||
| d16975a9de | |||
| 87f6b36bab | |||
| 43fccf5617 | |||
| a5b3bcf41c | |||
| 8801d9c286 | |||
| a8e114f351 | |||
| 9a3a9b46e5 | |||
| 934204ec18 | |||
| 7cb8f8fb44 | |||
| 8d34bf2fea | |||
| 8801e69dba | |||
| f4afa398a1 | |||
| 32063278bd | |||
| 92208d2f85 | |||
| ab7c74b4b9 | |||
| e283abe171 | |||
| d7620f68bb | |||
| 971d97e2ec | |||
| 559d5efc04 | |||
| 85042820fb | |||
| 24a2eec815 | |||
| d987a79ab1 | |||
| eba09353e6 | |||
| 297660c9a3 | |||
| 8343c05fd8 | |||
| 7c3d064786 | |||
| c2ccc1cbdf | |||
| 04e080660a | |||
| f3cca88384 | |||
| 978bbd2d49 | |||
| 652feebd86 | |||
| 16ccbc4f61 | |||
| 072d45fd01 | |||
| 4439e39319 | |||
| b49c3a1a1e | |||
| c7addd4886 | |||
| 6df60aff52 | |||
| e7a080d6e6 | |||
| 661a728764 | |||
| 89303fd2dc | |||
| 1f8be1ca66 | |||
| cbc2024092 | |||
| f0ff7023c3 | |||
| 6e8728a364 | |||
| f179a63dd4 | |||
| 3a71c1e595 | |||
| ef7a61a67e | |||
| a6b2ee785b | |||
| d5a1336e6b | |||
| d4312b731a | |||
| 66f051386e | |||
| 8b3f9684e0 | |||
| 331f32deac | |||
| bb80c96754 | |||
| 0d8e19c26f | |||
| ed2fd2d0ca | |||
| 7c60151cb8 | |||
| 965308a32c | |||
| 92c612a9de | |||
| a7b53abcad | |||
| d575e1f613 | |||
| 2ba458387d | |||
| 98489a1d0c | |||
| 51d501aab2 | |||
| 841bdf1c07 | |||
| 86cac55c7c | |||
| c0995399d4 | |||
| de6cc287e5 | |||
| afd6771163 | |||
| 4cda028609 | |||
| 8ecce7642b | |||
| d1d5761232 | |||
| 759cba1a8d | |||
| 23cd40a8ec | |||
| f3188c1d09 | |||
| 2f4967f100 | |||
| 4fe4e7457c | |||
| d4e7274d4b | |||
| cffa015554 | |||
| 1104c7d75b | |||
| 4c6b4447db | |||
| 741a37b338 | |||
| 1157c5d341 | |||
| e48adebfb7 | |||
| 0a61dcb486 | |||
| 4b51eaadf8 | |||
| e2457ca16d | |||
| bd62790080 | |||
| 53fdcafa44 | |||
| af6f2483be | |||
| d8522aa349 | |||
| bae3121683 | |||
| 54c0d464b0 | |||
| cf89e8653c | |||
| 0c3500f532 | |||
| c12f525df4 | |||
| e7ba830691 | |||
| 4eb0716711 | |||
| ed90f3b7ea | |||
| 14b19ecf5e | |||
| 644432a14c | |||
| a03e370a09 | |||
| 23677d3ddb | |||
| fc781560a3 | |||
| c9199ee663 | |||
| 6f18adedef | |||
| 6ad894cd58 | |||
| cde2f1a868 | |||
| 6a831495de | |||
| 6e2c38f54d | |||
| 00e7e31418 | |||
| ff4b3e20c1 | |||
| 269fb43b36 | |||
| 7530654328 | |||
| c7bd464384 | |||
| ef1874d1f3 | |||
| c6d8205fdd | |||
| 55150a669a | |||
| 1eb9e22d45 | |||
| c0de8fb737 | |||
| 557e3894d7 | |||
| 38a9695413 | |||
| 293e0336b0 | |||
| 1f5bc0a1cd | |||
| 1fe666192b | |||
| 29541e735d | |||
| f5b567d44b | |||
| 5ee3bbee90 | |||
| 80927c5811 | |||
| ca8b344e20 | |||
| 3dab93874d | |||
| 7550f90a57 | |||
| d78fea87d1 | |||
| 27cee7db0a | |||
| 60acba3840 | |||
| 51bed36370 | |||
| 6d940213ac | |||
| 494b527fa7 | |||
| 8ce84cb2ea | |||
| d981c2a3ec | |||
| 537e20065a | |||
| 97578b4dae | |||
| fa12564607 | |||
| 54bcb9ae25 | |||
| ad7ce0d402 | |||
| 085e0ea8ef | |||
| bb52c4e8d3 | |||
| 295af335c1 | |||
| 2c2e18c37a | |||
| adfb75e3c6 | |||
| 9bff5c60df | |||
| 3ba008d4b2 | |||
| 4e45a2f8e2 | |||
| 4dbd8452eb | |||
| 45a8db9c08 | |||
| d930a410fb | |||
| 66505ffc40 | |||
| 045de959b9 | |||
| 3ca11d5235 | |||
| d5d8ac01e3 | |||
| ace81c053c | |||
| 1e95c419b8 | |||
| 49ed63d26a | |||
| 6ff2685668 | |||
| c4573c04aa | |||
| d57abdb3f7 | |||
| 4050e89446 | |||
| b6620c737f | |||
| 0c8e908841 | |||
| 5595e196a8 | |||
| f92e4146d1 | |||
| 8b7108e3c9 | |||
| caf702cc88 | |||
| cf2c49ed7f | |||
| ccd52abf5d | |||
| 74c574015d | |||
| 1f1a6fb6d2 | |||
| 8632e893b0 | |||
| c2b6e127fa | |||
| 06eceeb09f | |||
| 8133d468b9 | |||
| 074a354fa9 | |||
| e191582a02 | |||
| 6fbe926cda | |||
| ebbc224e09 | |||
| 2c6aa4c300 | |||
| f7a8f17fc7 | |||
| 191efbb558 | |||
| bf873d6f02 | |||
| e741107c55 | |||
| 82f4b99d99 | |||
| 7210b7ae1d | |||
| afed23c001 | |||
| 1f69cc2989 | |||
| 3401833c83 | |||
| 06606e2816 | |||
| eba64e1f31 | |||
| 81dd1df1b1 | |||
| dbafbb0de5 | |||
| 1d0aa7b7c6 | |||
| afd02ca48c | |||
| 67db7616ad | |||
| 3d7c752e27 | |||
| f02833d634 | |||
| 0eb373e0e6 | |||
| fd3071843c | |||
| a631ceb223 | |||
| a713928210 | |||
| 05fa20df81 | |||
| 125573602f | |||
| ed5dfbcd66 | |||
| d2e52b2376 | |||
| a56aaa9877 | |||
| 79bb7b1f0b | |||
| b936e52874 | |||
| 0d52ff0f10 | |||
| baf52e902d | |||
| dffea9e2b7 | |||
| 4a411b8f82 | |||
| 278bfc4bb2 | |||
| 18731173f9 | |||
| d43fb404d7 | |||
| da984ad187 | |||
| 4015357ce5 | |||
| dc3d11ad19 | |||
| 0e1545eb04 | |||
| ec7cabf5c9 | |||
| 3051beba2f | |||
| 92304323b1 | |||
| c28123a872 | |||
| d798423813 | |||
| 2583e77cc7 | |||
| f66836fee4 | |||
| 0ccc445d53 | |||
| b7d5fa1cbe | |||
| 8bb3942453 | |||
| 51a79cebcb | |||
| 36bcf64008 | |||
| 5c6630605b | |||
| 125827406c | |||
| 62c21422a6 | |||
| 98d489712e | |||
| 2cab2d8ef1 | |||
| 8fa2bb72bc | |||
| d151f94937 | |||
| 5b74b7185b | |||
| 4f0be2ae4e | |||
| bb9badeb2a | |||
| c287c8361d | |||
| ade7127c79 | |||
| d341483f1f | |||
| b36acbc857 | |||
| a4fea38b94 | |||
| 300c5c0c99 | |||
| 152537c4e9 | |||
| 8b46bf6bc9 | |||
| aef861eb41 | |||
| f61d36861d | |||
| 2af0348cea | |||
| 78c5743494 | |||
| 2cb9fbd043 | |||
| e9dad5dbf4 | |||
| 54895fc2a1 | |||
| 60a12b4161 | |||
| cd7e58ba41 | |||
| 9391475dc3 | |||
| 7840803add | |||
| 7d77de2834 | |||
| ab044cada6 | |||
| d010e0cc7d | |||
| 40f728b1aa | |||
| 23abb26405 | |||
| fd55bc8e1d | |||
| 541aaa4e08 | |||
| f22c422547 | |||
| 0e461f0c07 | |||
| 5074448443 | |||
| 8d66af11e6 | |||
| 169948bb47 | |||
| 58d9469574 | |||
| 8d858a2360 | |||
| 5540748890 | |||
| f8a52be817 | |||
| 3b5f1105f6 | |||
| 663ccc5449 | |||
| 263f47819f | |||
| 6b75475ce3 | |||
| 07c354a8c0 | |||
| 1391579599 | |||
| 5d2bd1d84c | |||
| bf77e212af | |||
| eef2f9c31e | |||
| 438627c2c3 |
@@ -59,6 +59,25 @@ task :concat_scenario => :init do
|
||||
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
|
||||
@@ -98,7 +117,7 @@ end
|
||||
|
||||
|
||||
desc 'Minify JavaScript'
|
||||
task :minify => [:init, :concat, :concat_scenario] do
|
||||
task :minify => [:init, :concat, :concat_scenario, :concat_jstd_scenario_adapter] do
|
||||
[ 'angular.js',
|
||||
'angular-cookies.js',
|
||||
'angular-loader.js',
|
||||
|
||||
Vendored
+3651
-3687
File diff suppressed because it is too large
Load Diff
Vendored
+4
-2
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
1.8.2
|
||||
1.7.2
|
||||
|
||||
@@ -57,32 +57,12 @@ var /** holds major version number for IE or NaN for real browsers */
|
||||
push = [].push,
|
||||
toString = Object.prototype.toString,
|
||||
|
||||
|
||||
_angular = window.angular,
|
||||
/** @name angular */
|
||||
angular = window.angular || (window.angular = {}),
|
||||
angularModule,
|
||||
nodeName_,
|
||||
uid = ['0', '0', '0'];
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name angular.noConflict
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
* Restores the previous global value of angular and returns the current instance. Other libraries may already use the
|
||||
* angular namespace. Or a previous version of angular is already loaded on the page. In these cases you may want to
|
||||
* restore the previous namespace and keep a reference to angular.
|
||||
*
|
||||
* @return {Object} The current angular namespace
|
||||
*/
|
||||
function noConflict() {
|
||||
var a = window.angular;
|
||||
window.angular = _angular;
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name angular.forEach
|
||||
|
||||
@@ -48,8 +48,7 @@ function publishExternalAPI(angular){
|
||||
'isDate': isDate,
|
||||
'lowercase': lowercase,
|
||||
'uppercase': uppercase,
|
||||
'callbacks': {counter: 0},
|
||||
'noConflict': noConflict
|
||||
'callbacks': {counter: 0}
|
||||
});
|
||||
|
||||
angularModule = setupModuleLoader(window);
|
||||
|
||||
@@ -410,10 +410,9 @@ function createInjector(modulesToLoad) {
|
||||
decorator: decorator
|
||||
}
|
||||
},
|
||||
providerInjector = (providerCache.$injector =
|
||||
createInternalInjector(providerCache, function() {
|
||||
throw Error("Unknown provider: " + path.join(' <- '));
|
||||
})),
|
||||
providerInjector = createInternalInjector(providerCache, function() {
|
||||
throw Error("Unknown provider: " + path.join(' <- '));
|
||||
}),
|
||||
instanceCache = {},
|
||||
instanceInjector = (instanceCache.$injector =
|
||||
createInternalInjector(instanceCache, function(servicename) {
|
||||
@@ -490,7 +489,9 @@ function createInjector(modulesToLoad) {
|
||||
try {
|
||||
for(var invokeQueue = moduleFn._invokeQueue, i = 0, ii = invokeQueue.length; i < ii; i++) {
|
||||
var invokeArgs = invokeQueue[i],
|
||||
provider = providerInjector.get(invokeArgs[0]);
|
||||
provider = invokeArgs[0] == '$injector'
|
||||
? providerInjector
|
||||
: providerInjector.get(invokeArgs[0]);
|
||||
|
||||
provider[invokeArgs[1]].apply(provider, invokeArgs[2]);
|
||||
}
|
||||
|
||||
+3
-4
@@ -353,11 +353,11 @@ var JQLitePrototype = JQLite.prototype = {
|
||||
// value on get.
|
||||
//////////////////////////////////////////
|
||||
var BOOLEAN_ATTR = {};
|
||||
forEach('multiple,selected,checked,disabled,readOnly,required,open'.split(','), function(value) {
|
||||
forEach('multiple,selected,checked,disabled,readOnly,required'.split(','), function(value) {
|
||||
BOOLEAN_ATTR[lowercase(value)] = value;
|
||||
});
|
||||
var BOOLEAN_ELEMENTS = {};
|
||||
forEach('input,select,option,textarea,button,form,details'.split(','), function(value) {
|
||||
forEach('input,select,option,textarea,button,form'.split(','), function(value) {
|
||||
BOOLEAN_ELEMENTS[uppercase(value)] = true;
|
||||
});
|
||||
|
||||
@@ -659,9 +659,8 @@ forEach({
|
||||
|
||||
append: function(element, node) {
|
||||
forEach(new JQLite(node), function(child){
|
||||
if (element.nodeType === 1 || element.nodeType === 11) {
|
||||
if (element.nodeType === 1)
|
||||
element.appendChild(child);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* @returns {object} Newly created cache object with the following set of methods:
|
||||
*
|
||||
* - `{object}` `info()` — Returns id, size, and options of cache.
|
||||
* - `{{*}}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache and returns it.
|
||||
* - `{void}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache.
|
||||
* - `{{*}}` `get({string} key)` — Returns cached value for `key` or undefined for cache miss.
|
||||
* - `{void}` `remove({string} key)` — Removes a key-value pair from the cache.
|
||||
* - `{void}` `removeAll()` — Removes all cached values.
|
||||
@@ -53,8 +53,6 @@ function $CacheFactoryProvider() {
|
||||
if (size > capacity) {
|
||||
this.remove(staleEnd.key);
|
||||
}
|
||||
|
||||
return value;
|
||||
},
|
||||
|
||||
|
||||
|
||||
+1
-5
@@ -788,10 +788,6 @@ function $CompileProvider($provide) {
|
||||
scope[scopeName] = value;
|
||||
});
|
||||
attrs.$$observers[attrName].$$scope = parentScope;
|
||||
if( attrs[attrName] ) {
|
||||
// If the attribute has been provided then we trigger an interpolation to ensure the value is there for use in the link fn
|
||||
scope[scopeName] = $interpolate(attrs[attrName])(parentScope);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1090,7 +1086,7 @@ function $CompileProvider($provide) {
|
||||
interpolateFn = $interpolate(attr[name], true);
|
||||
}
|
||||
|
||||
attr[name] = interpolateFn(scope);
|
||||
attr[name] = undefined;
|
||||
($$observers[name] || ($$observers[name] = [])).$$inter = true;
|
||||
(attr.$$observers && attr.$$observers[name].$$scope || scope).
|
||||
$watch(interpolateFn, function interpolateFnWatchAction(value) {
|
||||
|
||||
@@ -272,37 +272,6 @@
|
||||
* @param {string} expression Angular expression that will be evaluated.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name ng.directive:ngOpen
|
||||
* @restrict A
|
||||
*
|
||||
* @description
|
||||
* The HTML specs do not require browsers to preserve the special attributes such as open.
|
||||
* (The presence of them means true and absence means false)
|
||||
* This prevents the angular compiler from correctly retrieving the binding expression.
|
||||
* To solve this problem, we introduce the `ngOpen` directive.
|
||||
*
|
||||
* @example
|
||||
<doc:example>
|
||||
<doc:source>
|
||||
Check me check multiple: <input type="checkbox" ng-model="open"><br/>
|
||||
<details id="details" ng-open="open">
|
||||
<summary>Show/Hide me</summary>
|
||||
</details>
|
||||
</doc:source>
|
||||
<doc:scenario>
|
||||
it('should toggle open', function() {
|
||||
expect(element('#details').prop('open')).toBeFalsy();
|
||||
input('open').check();
|
||||
expect(element('#details').prop('open')).toBeTruthy();
|
||||
});
|
||||
</doc:scenario>
|
||||
</doc:example>
|
||||
*
|
||||
* @element DETAILS
|
||||
* @param {string} expression Angular expression that will be evaluated.
|
||||
*/
|
||||
|
||||
var ngAttributeAliasDirectives = {};
|
||||
|
||||
|
||||
@@ -5,8 +5,7 @@ var nullFormCtrl = {
|
||||
$addControl: noop,
|
||||
$removeControl: noop,
|
||||
$setValidity: noop,
|
||||
$setDirty: noop,
|
||||
$setPristine: noop
|
||||
$setDirty: noop
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -38,8 +37,7 @@ function FormController(element, attrs) {
|
||||
var form = this,
|
||||
parentForm = element.parent().controller('form') || nullFormCtrl,
|
||||
invalidCount = 0, // used to easily determine if we are valid
|
||||
errors = form.$error = {},
|
||||
controls = [];
|
||||
errors = form.$error = {};
|
||||
|
||||
// init state
|
||||
form.$name = attrs.name;
|
||||
@@ -63,8 +61,6 @@ function FormController(element, attrs) {
|
||||
}
|
||||
|
||||
form.$addControl = function(control) {
|
||||
controls.push(control);
|
||||
|
||||
if (control.$name && !form.hasOwnProperty(control.$name)) {
|
||||
form[control.$name] = control;
|
||||
}
|
||||
@@ -77,8 +73,6 @@ function FormController(element, attrs) {
|
||||
forEach(errors, function(queue, validationToken) {
|
||||
form.$setValidity(validationToken, true, control);
|
||||
});
|
||||
|
||||
arrayRemove(controls, control);
|
||||
};
|
||||
|
||||
form.$setValidity = function(validationToken, isValid, control) {
|
||||
@@ -126,29 +120,6 @@ function FormController(element, attrs) {
|
||||
parentForm.$setDirty();
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name ng.directive:form.FormController#$setPristine
|
||||
* @methodOf ng.directive:form.FormController
|
||||
*
|
||||
* @description
|
||||
* Sets the form to its pristine state.
|
||||
*
|
||||
* This method can be called to remove the 'ng-dirty' class and set the form to its pristine
|
||||
* state (ng-pristine class). This method will also propagate to all the controls contained
|
||||
* in this form.
|
||||
*
|
||||
* Setting a form back to a pristine state is often useful when we want to 'reuse' a form after
|
||||
* saving or resetting it.
|
||||
*/
|
||||
form.$setPristine = function () {
|
||||
element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS);
|
||||
form.$dirty = false;
|
||||
form.$pristine = true;
|
||||
forEach(controls, function(control) {
|
||||
control.$setPristine();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,8 +28,6 @@ var inputType = {
|
||||
* patterns defined as scope expressions.
|
||||
* @param {string=} ngChange Angular expression to be executed when input changes due to user
|
||||
* interaction with the input element.
|
||||
* @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trimming the
|
||||
* input.
|
||||
*
|
||||
* @example
|
||||
<doc:example>
|
||||
@@ -37,12 +35,12 @@ var inputType = {
|
||||
<script>
|
||||
function Ctrl($scope) {
|
||||
$scope.text = 'guest';
|
||||
$scope.word = /^\s*\w*\s*$/;
|
||||
$scope.word = /^\w*$/;
|
||||
}
|
||||
</script>
|
||||
<form name="myForm" ng-controller="Ctrl">
|
||||
Single word: <input type="text" name="input" ng-model="text"
|
||||
ng-pattern="word" required ng-trim="false">
|
||||
ng-pattern="word" required>
|
||||
<span class="error" ng-show="myForm.input.$error.required">
|
||||
Required!</span>
|
||||
<span class="error" ng-show="myForm.input.$error.pattern">
|
||||
@@ -71,12 +69,6 @@ var inputType = {
|
||||
input('text').enter('hello world');
|
||||
expect(binding('myForm.input.$valid')).toEqual('false');
|
||||
});
|
||||
|
||||
it('should not be trimmed', function() {
|
||||
input('text').enter('untrimmed ');
|
||||
expect(binding('text')).toEqual('untrimmed ');
|
||||
expect(binding('myForm.input.$valid')).toEqual('true');
|
||||
});
|
||||
</doc:scenario>
|
||||
</doc:example>
|
||||
*/
|
||||
@@ -390,14 +382,7 @@ function isEmpty(value) {
|
||||
function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
||||
|
||||
var listener = function() {
|
||||
var value = element.val();
|
||||
|
||||
// By default we will trim the value
|
||||
// If the attribute ng-trim exists we will avoid trimming
|
||||
// e.g. <input ng-model="foo" ng-trim="false">
|
||||
if (toBoolean(attr.ngTrim || 'T')) {
|
||||
value = trim(value);
|
||||
}
|
||||
var value = trim(element.val());
|
||||
|
||||
if (ctrl.$viewValue !== value) {
|
||||
scope.$apply(function() {
|
||||
@@ -978,22 +963,6 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
||||
parentForm.$setValidity(validationErrorKey, isValid, this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name ng.directive:ngModel.NgModelController#$setPristine
|
||||
* @methodOf ng.directive:ngModel.NgModelController
|
||||
*
|
||||
* @description
|
||||
* Sets the control to its pristine state.
|
||||
*
|
||||
* This method can be called to remove the 'ng-dirty' class and set the control to its pristine
|
||||
* state (ng-pristine class).
|
||||
*/
|
||||
this.$setPristine = function () {
|
||||
this.$dirty = false;
|
||||
this.$pristine = true;
|
||||
$element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
*/
|
||||
var ngEventDirectives = {};
|
||||
forEach(
|
||||
'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup'.split(' '),
|
||||
'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave'.split(' '),
|
||||
function(name) {
|
||||
var directiveName = directiveNormalize('ng-' + name);
|
||||
ngEventDirectives[directiveName] = ['$parse', function($parse) {
|
||||
@@ -164,38 +164,6 @@ forEach(
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name ng.directive:ngKeydown
|
||||
*
|
||||
* @description
|
||||
* Specify custom behavior on keydown event.
|
||||
*
|
||||
* @element ANY
|
||||
* @param {expression} ngKeydown {@link guide/expression Expression} to evaluate upon
|
||||
* keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
|
||||
*
|
||||
* @example
|
||||
* See {@link ng.directive:ngClick ngClick}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name ng.directive:ngKeyup
|
||||
*
|
||||
* @description
|
||||
* Specify custom behavior on keyup event.
|
||||
*
|
||||
* @element ANY
|
||||
* @param {expression} ngKeyup {@link guide/expression Expression} to evaluate upon
|
||||
* keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
|
||||
*
|
||||
* @example
|
||||
* See {@link ng.directive:ngClick ngClick}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name ng.directive:ngSubmit
|
||||
|
||||
@@ -20,11 +20,8 @@
|
||||
* On child elments add:
|
||||
*
|
||||
* * `ngSwitchWhen`: the case statement to match against. If match then this
|
||||
* case will be displayed. If the same match appears multiple times, all the
|
||||
* elements will be displayed.
|
||||
* * `ngSwitchDefault`: the default case when no other case match. If there
|
||||
* are multiple default cases, all of them will be displayed when no other
|
||||
* case match.
|
||||
* case will be displayed.
|
||||
* * `ngSwitchDefault`: the default case when no other casses match.
|
||||
*
|
||||
* @example
|
||||
<doc:example>
|
||||
@@ -72,28 +69,22 @@ var ngSwitchDirective = valueFn({
|
||||
}],
|
||||
link: function(scope, element, attr, ctrl) {
|
||||
var watchExpr = attr.ngSwitch || attr.on,
|
||||
selectedTranscludes,
|
||||
selectedElements,
|
||||
selectedScopes = [];
|
||||
selectedTransclude,
|
||||
selectedElement,
|
||||
selectedScope;
|
||||
|
||||
scope.$watch(watchExpr, function ngSwitchWatchAction(value) {
|
||||
for (var i= 0, ii=selectedScopes.length; i<ii; i++) {
|
||||
selectedScopes[i].$destroy();
|
||||
selectedElements[i].remove();
|
||||
if (selectedElement) {
|
||||
selectedScope.$destroy();
|
||||
selectedElement.remove();
|
||||
selectedElement = selectedScope = null;
|
||||
}
|
||||
|
||||
selectedElements = [];
|
||||
selectedScopes = [];
|
||||
|
||||
if ((selectedTranscludes = ctrl.cases['!' + value] || ctrl.cases['?'])) {
|
||||
if ((selectedTransclude = ctrl.cases['!' + value] || ctrl.cases['?'])) {
|
||||
scope.$eval(attr.change);
|
||||
forEach(selectedTranscludes, function(selectedTransclude) {
|
||||
var selectedScope = scope.$new();
|
||||
selectedScopes.push(selectedScope);
|
||||
selectedTransclude(selectedScope, function(caseElement) {
|
||||
selectedElements.push(caseElement);
|
||||
element.append(caseElement);
|
||||
});
|
||||
selectedScope = scope.$new();
|
||||
selectedTransclude(selectedScope, function(caseElement) {
|
||||
selectedElement = caseElement;
|
||||
element.append(caseElement);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -106,8 +97,7 @@ var ngSwitchWhenDirective = ngDirective({
|
||||
require: '^ngSwitch',
|
||||
compile: function(element, attrs, transclude) {
|
||||
return function(scope, element, attr, ctrl) {
|
||||
ctrl.cases['!' + attrs.ngSwitchWhen] = (ctrl.cases['!' + attrs.ngSwitchWhen] || []);
|
||||
ctrl.cases['!' + attrs.ngSwitchWhen].push(transclude);
|
||||
ctrl.cases['!' + attrs.ngSwitchWhen] = transclude;
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -118,8 +108,7 @@ var ngSwitchDefaultDirective = ngDirective({
|
||||
require: '^ngSwitch',
|
||||
compile: function(element, attrs, transclude) {
|
||||
return function(scope, element, attr, ctrl) {
|
||||
ctrl.cases['?'] = (ctrl.cases['?'] || []);
|
||||
ctrl.cases['?'].push(transclude);
|
||||
ctrl.cases['?'] = transclude;
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
+16
-62
@@ -32,22 +32,6 @@
|
||||
* called for each element of `array`. The final result is an array of those elements that
|
||||
* the predicate returned true for.
|
||||
*
|
||||
* @param {function(expected, actual)|true|undefined} comparator Comparator which is used in
|
||||
* determining if the expected value (from the filter expression) and actual value (from
|
||||
* the object in the array) should be considered a match.
|
||||
*
|
||||
* Can be one of:
|
||||
*
|
||||
* - `function(expected, actual)`:
|
||||
* The function will be given the object value and the predicate value to compare and
|
||||
* should return true if the item should be included in filtered result.
|
||||
*
|
||||
* - `true`: A shorthand for `function(expected, actual) { return angular.equals(expected, actual)}`.
|
||||
* this is essentially strict comparison of expected and actual.
|
||||
*
|
||||
* - `false|undefined`: A short hand for a function which will look for a substring match in case
|
||||
* insensitive way.
|
||||
*
|
||||
* @example
|
||||
<doc:example>
|
||||
<doc:source>
|
||||
@@ -55,8 +39,7 @@
|
||||
{name:'Mary', phone:'800-BIG-MARY'},
|
||||
{name:'Mike', phone:'555-4321'},
|
||||
{name:'Adam', phone:'555-5678'},
|
||||
{name:'Julie', phone:'555-8765'},
|
||||
{name:'Juliette', phone:'555-5678'}]"></div>
|
||||
{name:'Julie', phone:'555-8765'}]"></div>
|
||||
|
||||
Search: <input ng-model="searchText">
|
||||
<table id="searchTextResults">
|
||||
@@ -70,10 +53,9 @@
|
||||
Any: <input ng-model="search.$"> <br>
|
||||
Name only <input ng-model="search.name"><br>
|
||||
Phone only <input ng-model="search.phone"å><br>
|
||||
Equality <input type="checkbox" ng-model="strict"><br>
|
||||
<table id="searchObjResults">
|
||||
<tr><th>Name</th><th>Phone</th><tr>
|
||||
<tr ng-repeat="friend in friends | filter:search:strict">
|
||||
<tr ng-repeat="friend in friends | filter:search">
|
||||
<td>{{friend.name}}</td>
|
||||
<td>{{friend.phone}}</td>
|
||||
<tr>
|
||||
@@ -93,19 +75,13 @@
|
||||
it('should search in specific fields when filtering with a predicate object', function() {
|
||||
input('search.$').enter('i');
|
||||
expect(repeater('#searchObjResults tr', 'friend in friends').column('friend.name')).
|
||||
toEqual(['Mary', 'Mike', 'Julie', 'Juliette']);
|
||||
});
|
||||
it('should use a equal comparison when comparator is true', function() {
|
||||
input('search.name').enter('Julie');
|
||||
input('strict').check();
|
||||
expect(repeater('#searchObjResults tr', 'friend in friends').column('friend.name')).
|
||||
toEqual(['Julie']);
|
||||
toEqual(['Mary', 'Mike', 'Julie']);
|
||||
});
|
||||
</doc:scenario>
|
||||
</doc:example>
|
||||
*/
|
||||
function filterFilter() {
|
||||
return function(array, expression, comperator) {
|
||||
return function(array, expression) {
|
||||
if (!isArray(array)) return array;
|
||||
var predicates = [];
|
||||
predicates.check = function(value) {
|
||||
@@ -116,43 +92,20 @@ function filterFilter() {
|
||||
}
|
||||
return true;
|
||||
};
|
||||
switch(typeof comperator) {
|
||||
case "function":
|
||||
break;
|
||||
case "boolean":
|
||||
if(comperator == true) {
|
||||
comperator = function(obj, text) {
|
||||
return angular.equals(obj, text);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
comperator = function(obj, text) {
|
||||
text = (''+text).toLowerCase();
|
||||
return (''+obj).toLowerCase().indexOf(text) > -1
|
||||
};
|
||||
}
|
||||
var search = function(obj, text){
|
||||
if (typeof text == 'string' && text.charAt(0) === '!') {
|
||||
if (text.charAt(0) === '!') {
|
||||
return !search(obj, text.substr(1));
|
||||
}
|
||||
switch (typeof obj) {
|
||||
case "boolean":
|
||||
case "number":
|
||||
case "string":
|
||||
return comperator(obj, text);
|
||||
return ('' + obj).toLowerCase().indexOf(text) > -1;
|
||||
case "object":
|
||||
switch (typeof text) {
|
||||
case "object":
|
||||
return comperator(obj, text);
|
||||
break;
|
||||
default:
|
||||
for ( var objKey in obj) {
|
||||
if (objKey.charAt(0) !== '$' && search(obj[objKey], text)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
for ( var objKey in obj) {
|
||||
if (objKey.charAt(0) !== '$' && search(obj[objKey], text)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case "array":
|
||||
@@ -175,18 +128,19 @@ function filterFilter() {
|
||||
for (var key in expression) {
|
||||
if (key == '$') {
|
||||
(function() {
|
||||
if (!expression[key]) return;
|
||||
var path = key
|
||||
var text = (''+expression[key]).toLowerCase();
|
||||
if (!text) return;
|
||||
predicates.push(function(value) {
|
||||
return search(value, expression[path]);
|
||||
return search(value, text);
|
||||
});
|
||||
})();
|
||||
} else {
|
||||
(function() {
|
||||
if (!expression[key]) return;
|
||||
var path = key;
|
||||
var text = (''+expression[key]).toLowerCase();
|
||||
if (!text) return;
|
||||
predicates.push(function(value) {
|
||||
return search(getter(value,path), expression[path]);
|
||||
return search(getter(value, path), text);
|
||||
});
|
||||
})();
|
||||
}
|
||||
|
||||
@@ -241,9 +241,6 @@ var DATE_FORMATS = {
|
||||
m: dateGetter('Minutes', 1),
|
||||
ss: dateGetter('Seconds', 2),
|
||||
s: dateGetter('Seconds', 1),
|
||||
// while ISO 8601 requires fractions to be prefixed with `.` or `,`
|
||||
// we can be just safely rely on using `sss` since we currently don't support single or two digit fractions
|
||||
sss: dateGetter('Milliseconds', 3),
|
||||
EEEE: dateStrGetter('Day'),
|
||||
EEE: dateStrGetter('Day', true),
|
||||
a: ampmGetter,
|
||||
@@ -282,7 +279,6 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
|
||||
* * `'m'`: Minute in hour (0-59)
|
||||
* * `'ss'`: Second in minute, padded (00-59)
|
||||
* * `'s'`: Second in minute (0-59)
|
||||
* * `'.sss' or ',sss'`: Millisecond in second, padded (000-999)
|
||||
* * `'a'`: am/pm marker
|
||||
* * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-1200)
|
||||
*
|
||||
@@ -339,22 +335,18 @@ function dateFilter($locale) {
|
||||
|
||||
|
||||
var R_ISO8601_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;
|
||||
// 1 2 3 4 5 6 7 8 9 10 11
|
||||
function jsonStringToDate(string) {
|
||||
function jsonStringToDate(string){
|
||||
var match;
|
||||
if (match = string.match(R_ISO8601_STR)) {
|
||||
var date = new Date(0),
|
||||
tzHour = 0,
|
||||
tzMin = 0,
|
||||
dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear,
|
||||
timeSetter = match[8] ? date.setUTCHours : date.setHours;
|
||||
|
||||
tzMin = 0;
|
||||
if (match[9]) {
|
||||
tzHour = int(match[9] + match[10]);
|
||||
tzMin = int(match[9] + match[11]);
|
||||
}
|
||||
dateSetter.call(date, int(match[1]), int(match[2]) - 1, int(match[3]));
|
||||
timeSetter.call(date, int(match[4]||0) - tzHour, int(match[5]||0) - tzMin, int(match[6]||0), int(match[7]||0));
|
||||
date.setUTCFullYear(int(match[1]), int(match[2]) - 1, int(match[3]));
|
||||
date.setUTCHours(int(match[4]||0) - tzHour, int(match[5]||0) - tzMin, int(match[6]||0), int(match[7]||0));
|
||||
return date;
|
||||
}
|
||||
return string;
|
||||
|
||||
+33
-50
@@ -6,20 +6,20 @@
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
* Creates a new array or string containing only a specified number of elements. The elements
|
||||
* are taken from either the beginning or the end of the source array or string, as specified by
|
||||
* the value and sign (positive or negative) of `limit`.
|
||||
* Creates a new array containing only a specified number of elements in an array. The elements
|
||||
* are taken from either the beginning or the end of the source array, as specified by the
|
||||
* value and sign (positive or negative) of `limit`.
|
||||
*
|
||||
* Note: This function is used to augment the `Array` type in Angular expressions. See
|
||||
* {@link ng.$filter} for more information about Angular arrays.
|
||||
*
|
||||
* @param {Array|string} input Source array or string to be limited.
|
||||
* @param {string|number} limit The length of the returned array or string. If the `limit` number
|
||||
* is positive, `limit` number of items from the beginning of the source array/string are copied.
|
||||
* If the number is negative, `limit` number of items from the end of the source array/string
|
||||
* are copied. The `limit` will be trimmed if it exceeds `array.length`
|
||||
* @returns {Array|string} A new sub-array or substring of length `limit` or less if input array
|
||||
* had less than `limit` elements.
|
||||
* @param {Array} array Source array to be limited.
|
||||
* @param {string|Number} limit The length of the returned array. If the `limit` number is
|
||||
* positive, `limit` number of items from the beginning of the source array are copied.
|
||||
* If the number is negative, `limit` number of items from the end of the source array are
|
||||
* copied. The `limit` will be trimmed if it exceeds `array.length`
|
||||
* @returns {Array} A new sub-array of length `limit` or less if input array had less than `limit`
|
||||
* elements.
|
||||
*
|
||||
* @example
|
||||
<doc:example>
|
||||
@@ -27,76 +27,59 @@
|
||||
<script>
|
||||
function Ctrl($scope) {
|
||||
$scope.numbers = [1,2,3,4,5,6,7,8,9];
|
||||
$scope.letters = "abcdefghi";
|
||||
$scope.numLimit = 3;
|
||||
$scope.letterLimit = 3;
|
||||
$scope.limit = 3;
|
||||
}
|
||||
</script>
|
||||
<div ng-controller="Ctrl">
|
||||
Limit {{numbers}} to: <input type="integer" ng-model="numLimit">
|
||||
<p>Output numbers: {{ numbers | limitTo:numLimit }}</p>
|
||||
Limit {{letters}} to: <input type="integer" ng-model="letterLimit">
|
||||
<p>Output letters: {{ letters | limitTo:letterLimit }}</p>
|
||||
Limit {{numbers}} to: <input type="integer" ng-model="limit">
|
||||
<p>Output: {{ numbers | limitTo:limit }}</p>
|
||||
</div>
|
||||
</doc:source>
|
||||
<doc:scenario>
|
||||
it('should limit the number array to first three items', function() {
|
||||
expect(element('.doc-example-live input[ng-model=numLimit]').val()).toBe('3');
|
||||
expect(element('.doc-example-live input[ng-model=letterLimit]').val()).toBe('3');
|
||||
expect(binding('numbers | limitTo:numLimit')).toEqual('[1,2,3]');
|
||||
expect(binding('letters | limitTo:letterLimit')).toEqual('abc');
|
||||
it('should limit the numer array to first three items', function() {
|
||||
expect(element('.doc-example-live input[ng-model=limit]').val()).toBe('3');
|
||||
expect(binding('numbers | limitTo:limit')).toEqual('[1,2,3]');
|
||||
});
|
||||
|
||||
it('should update the output when -3 is entered', function() {
|
||||
input('numLimit').enter(-3);
|
||||
input('letterLimit').enter(-3);
|
||||
expect(binding('numbers | limitTo:numLimit')).toEqual('[7,8,9]');
|
||||
expect(binding('letters | limitTo:letterLimit')).toEqual('ghi');
|
||||
input('limit').enter(-3);
|
||||
expect(binding('numbers | limitTo:limit')).toEqual('[7,8,9]');
|
||||
});
|
||||
|
||||
it('should not exceed the maximum size of input array', function() {
|
||||
input('numLimit').enter(100);
|
||||
input('letterLimit').enter(100);
|
||||
expect(binding('numbers | limitTo:numLimit')).toEqual('[1,2,3,4,5,6,7,8,9]');
|
||||
expect(binding('letters | limitTo:letterLimit')).toEqual('abcdefghi');
|
||||
input('limit').enter(100);
|
||||
expect(binding('numbers | limitTo:limit')).toEqual('[1,2,3,4,5,6,7,8,9]');
|
||||
});
|
||||
</doc:scenario>
|
||||
</doc:example>
|
||||
*/
|
||||
function limitToFilter(){
|
||||
return function(input, limit) {
|
||||
if (!isArray(input) && !isString(input)) return input;
|
||||
|
||||
return function(array, limit) {
|
||||
if (!(array instanceof Array)) return array;
|
||||
limit = int(limit);
|
||||
|
||||
if (isString(input)) {
|
||||
//NaN check on limit
|
||||
if (limit) {
|
||||
return limit >= 0 ? input.slice(0, limit) : input.slice(limit, input.length);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
var out = [],
|
||||
i, n;
|
||||
|
||||
// check that array is iterable
|
||||
if (!array || !(array instanceof Array))
|
||||
return out;
|
||||
|
||||
// if abs(limit) exceeds maximum length, trim it
|
||||
if (limit > input.length)
|
||||
limit = input.length;
|
||||
else if (limit < -input.length)
|
||||
limit = -input.length;
|
||||
if (limit > array.length)
|
||||
limit = array.length;
|
||||
else if (limit < -array.length)
|
||||
limit = -array.length;
|
||||
|
||||
if (limit > 0) {
|
||||
i = 0;
|
||||
n = limit;
|
||||
} else {
|
||||
i = input.length + limit;
|
||||
n = input.length;
|
||||
i = array.length + limit;
|
||||
n = array.length;
|
||||
}
|
||||
|
||||
for (; i<n; i++) {
|
||||
out.push(input[i]);
|
||||
out.push(array[i]);
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
+20
-82
@@ -29,43 +29,6 @@ function parseHeaders(headers) {
|
||||
}
|
||||
|
||||
|
||||
var IS_SAME_DOMAIN_URL_MATCH = /^(([^:]+):)?\/\/(\w+:{0,1}\w*@)?([\w\.-]*)?(:([0-9]+))?(.*)$/;
|
||||
|
||||
|
||||
/**
|
||||
* Parse a request and location URL and determine whether this is a same-domain request.
|
||||
*
|
||||
* @param {string} requestUrl The url of the request.
|
||||
* @param {string} locationUrl The current browser location url.
|
||||
* @returns {boolean} Whether the request is for the same domain.
|
||||
*/
|
||||
function isSameDomain(requestUrl, locationUrl) {
|
||||
var match = IS_SAME_DOMAIN_URL_MATCH.exec(requestUrl);
|
||||
// if requestUrl is relative, the regex does not match.
|
||||
if (match == null) return true;
|
||||
|
||||
var domain1 = {
|
||||
protocol: match[2],
|
||||
host: match[4],
|
||||
port: int(match[6]) || DEFAULT_PORTS[match[2]] || null,
|
||||
// IE8 sets unmatched groups to '' instead of undefined.
|
||||
relativeProtocol: match[2] === undefined || match[2] === ''
|
||||
};
|
||||
|
||||
match = URL_MATCH.exec(locationUrl);
|
||||
var domain2 = {
|
||||
protocol: match[1],
|
||||
host: match[3],
|
||||
port: int(match[5]) || DEFAULT_PORTS[match[1]] || null
|
||||
};
|
||||
|
||||
return (domain1.protocol == domain2.protocol || domain1.relativeProtocol) &&
|
||||
domain1.host == domain2.host &&
|
||||
(domain1.port == domain2.port || (domain1.relativeProtocol &&
|
||||
domain2.port == DEFAULT_PORTS[domain2.protocol]));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a function that provides access to parsed headers.
|
||||
*
|
||||
@@ -125,7 +88,7 @@ function $HttpProvider() {
|
||||
JSON_END = /[\}\]]\s*$/,
|
||||
PROTECTION_PREFIX = /^\)\]\}',?\n/;
|
||||
|
||||
var defaults = this.defaults = {
|
||||
var $config = this.defaults = {
|
||||
// transform incoming response data
|
||||
transformResponse: [function(data) {
|
||||
if (isString(data)) {
|
||||
@@ -145,14 +108,12 @@ function $HttpProvider() {
|
||||
// default headers
|
||||
headers: {
|
||||
common: {
|
||||
'Accept': 'application/json, text/plain, */*'
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
post: {'Content-Type': 'application/json;charset=utf-8'},
|
||||
put: {'Content-Type': 'application/json;charset=utf-8'}
|
||||
},
|
||||
|
||||
xsrfCookieName: 'XSRF-TOKEN',
|
||||
xsrfHeaderName: 'X-XSRF-TOKEN'
|
||||
}
|
||||
};
|
||||
|
||||
var providerResponseInterceptors = this.responseInterceptors = [];
|
||||
@@ -254,6 +215,7 @@ function $HttpProvider() {
|
||||
*
|
||||
* - `$httpProvider.defaults.headers.common` (headers that are common for all requests):
|
||||
* - `Accept: application/json, text/plain, * / *`
|
||||
* - `X-Requested-With: XMLHttpRequest`
|
||||
* - `$httpProvider.defaults.headers.post`: (header defaults for HTTP POST requests)
|
||||
* - `Content-Type: application/json`
|
||||
* - `$httpProvider.defaults.headers.put` (header defaults for HTTP PUT requests)
|
||||
@@ -386,10 +348,9 @@ function $HttpProvider() {
|
||||
* {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF} is a technique by which
|
||||
* an unauthorized site can gain your user's private data. Angular provides following mechanism
|
||||
* to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie
|
||||
* (by default, `XSRF-TOKEN`) and sets it as an HTTP header (`X-XSRF-TOKEN`). Since only
|
||||
* JavaScript that runs on your domain could read the cookie, your server can be assured that
|
||||
* the XHR came from JavaScript running on your domain. The header will not be set for
|
||||
* cross-domain requests.
|
||||
* called `XSRF-TOKEN` and sets it as the HTTP header `X-XSRF-TOKEN`. Since only JavaScript that
|
||||
* runs on your domain could read the cookie, your server can be assured that the XHR came from
|
||||
* JavaScript running on your domain.
|
||||
*
|
||||
* To take advantage of this, your server needs to set a token in a JavaScript readable session
|
||||
* cookie called `XSRF-TOKEN` on first HTTP GET request. On subsequent non-GET requests the
|
||||
@@ -399,9 +360,6 @@ function $HttpProvider() {
|
||||
* up its own tokens). We recommend that the token is a digest of your site's authentication
|
||||
* cookie with {@link http://en.wikipedia.org/wiki/Rainbow_table salt for added security}.
|
||||
*
|
||||
* The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName
|
||||
* properties of either $httpProvider.defaults, or the per-request config object.
|
||||
*
|
||||
*
|
||||
* @param {object} config Object describing the request to be made and how it should be
|
||||
* processed. The object has following properties:
|
||||
@@ -412,8 +370,6 @@ function $HttpProvider() {
|
||||
* `?key1=value1&key2=value2` after the url. If the value is not a string, it will be JSONified.
|
||||
* - **data** – `{string|Object}` – Data to be sent as the request message data.
|
||||
* - **headers** – `{Object}` – Map of strings representing HTTP headers to send to the server.
|
||||
* - **xsrfHeaderName** – `{string}` – Name of HTTP header to populate with the XSRF token.
|
||||
* - **xsrfCookieName** – `{string}` – Name of cookie containing the XSRF token.
|
||||
* - **transformRequest** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
|
||||
* transform function or an array of such functions. The transform function takes the http
|
||||
* request body and headers and returns its transformed (typically serialized) version.
|
||||
@@ -428,8 +384,6 @@ function $HttpProvider() {
|
||||
* - **withCredentials** - `{boolean}` - whether to to set the `withCredentials` flag on the
|
||||
* XHR object. See {@link https://developer.mozilla.org/en/http_access_control#section_5
|
||||
* requests with credentials} for more information.
|
||||
* - **responseType** - `{string}` - see {@link
|
||||
* https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType requestType}.
|
||||
*
|
||||
* @returns {HttpPromise} Returns a {@link ng.$q promise} object with the
|
||||
* standard `then` method and two http specific methods: `success` and `error`. The `then`
|
||||
@@ -522,17 +476,10 @@ function $HttpProvider() {
|
||||
function $http(config) {
|
||||
config.method = uppercase(config.method);
|
||||
|
||||
var xsrfHeader = {},
|
||||
xsrfCookieName = config.xsrfCookieName || defaults.xsrfCookieName,
|
||||
xsrfHeaderName = config.xsrfHeaderName || defaults.xsrfHeaderName,
|
||||
xsrfToken = isSameDomain(config.url, $browser.url()) ?
|
||||
$browser.cookies()[xsrfCookieName] : undefined;
|
||||
xsrfHeader[xsrfHeaderName] = xsrfToken;
|
||||
|
||||
var reqTransformFn = config.transformRequest || defaults.transformRequest,
|
||||
respTransformFn = config.transformResponse || defaults.transformResponse,
|
||||
defHeaders = defaults.headers,
|
||||
reqHeaders = extend(xsrfHeader,
|
||||
var reqTransformFn = config.transformRequest || $config.transformRequest,
|
||||
respTransformFn = config.transformResponse || $config.transformResponse,
|
||||
defHeaders = $config.headers,
|
||||
reqHeaders = extend({'X-XSRF-TOKEN': $browser.cookies()['XSRF-TOKEN']},
|
||||
defHeaders.common, defHeaders[lowercase(config.method)], config.headers),
|
||||
reqData = transformData(config.data, headersGetter(reqHeaders), reqTransformFn),
|
||||
promise;
|
||||
@@ -542,10 +489,6 @@ function $HttpProvider() {
|
||||
delete reqHeaders['Content-Type'];
|
||||
}
|
||||
|
||||
if (isUndefined(config.withCredentials) && !isUndefined(defaults.withCredentials)) {
|
||||
config.withCredentials = defaults.withCredentials;
|
||||
}
|
||||
|
||||
// send request
|
||||
promise = sendReq(config, reqData, reqHeaders);
|
||||
|
||||
@@ -677,11 +620,11 @@ function $HttpProvider() {
|
||||
*
|
||||
* @description
|
||||
* Runtime equivalent of the `$httpProvider.defaults` property. Allows configuration of
|
||||
* default headers, withCredentials as well as request and response transformations.
|
||||
* default headers as well as request and response transformations.
|
||||
*
|
||||
* See "Setting HTTP Headers" and "Transforming Requests and Responses" sections above.
|
||||
*/
|
||||
$http.defaults = defaults;
|
||||
$http.defaults = $config;
|
||||
|
||||
|
||||
return $http;
|
||||
@@ -716,7 +659,7 @@ function $HttpProvider() {
|
||||
* Makes the request
|
||||
*
|
||||
* !!! ACCESSES CLOSURE VARS:
|
||||
* $httpBackend, defaults, $log, $rootScope, defaultCache, $http.pendingRequests
|
||||
* $httpBackend, $config, $log, $rootScope, defaultCache, $http.pendingRequests
|
||||
*/
|
||||
function sendReq(config, reqData, reqHeaders) {
|
||||
var deferred = $q.defer(),
|
||||
@@ -757,7 +700,7 @@ function $HttpProvider() {
|
||||
// if we won't have the response in cache, send the request to the backend
|
||||
if (!cachedResp) {
|
||||
$httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout,
|
||||
config.withCredentials, config.responseType);
|
||||
config.withCredentials);
|
||||
}
|
||||
|
||||
return promise;
|
||||
@@ -812,15 +755,10 @@ function $HttpProvider() {
|
||||
var parts = [];
|
||||
forEachSorted(params, function(value, key) {
|
||||
if (value == null || value == undefined) return;
|
||||
if (!isArray(value)) value = [value];
|
||||
|
||||
forEach(value, function(v) {
|
||||
if (isObject(v)) {
|
||||
v = toJson(v);
|
||||
}
|
||||
parts.push(encodeUriQuery(key) + '=' +
|
||||
encodeUriQuery(v));
|
||||
});
|
||||
if (isObject(value)) {
|
||||
value = toJson(value);
|
||||
}
|
||||
parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
|
||||
});
|
||||
return url + ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&');
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ function $HttpBackendProvider() {
|
||||
|
||||
function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument, locationProtocol) {
|
||||
// TODO(vojta): fix the signature
|
||||
return function(method, url, post, callback, headers, timeout, withCredentials, responseType) {
|
||||
return function(method, url, post, callback, headers, timeout, withCredentials) {
|
||||
$browser.$$incOutstandingRequestCount();
|
||||
url = url || $browser.url();
|
||||
|
||||
@@ -87,7 +87,7 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
|
||||
}
|
||||
// end of the workaround.
|
||||
|
||||
completeRequest(callback, status || xhr.status, xhr.response || xhr.responseText,
|
||||
completeRequest(callback, status || xhr.status, xhr.responseText,
|
||||
responseHeaders);
|
||||
}
|
||||
};
|
||||
@@ -96,10 +96,6 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
|
||||
xhr.withCredentials = true;
|
||||
}
|
||||
|
||||
if (responseType) {
|
||||
xhr.responseType = responseType;
|
||||
}
|
||||
|
||||
xhr.send(post || '');
|
||||
|
||||
if (timeout > 0) {
|
||||
|
||||
+10
-16
@@ -52,7 +52,7 @@ function $InterpolateProvider() {
|
||||
};
|
||||
|
||||
|
||||
this.$get = ['$parse', '$exceptionHandler', function($parse, $exceptionHandler) {
|
||||
this.$get = ['$parse', function($parse) {
|
||||
var startSymbolLength = startSymbol.length,
|
||||
endSymbolLength = endSymbol.length;
|
||||
|
||||
@@ -124,24 +124,18 @@ function $InterpolateProvider() {
|
||||
if (!mustHaveExpression || hasInterpolation) {
|
||||
concat.length = length;
|
||||
fn = function(context) {
|
||||
try {
|
||||
for(var i = 0, ii = length, part; i<ii; i++) {
|
||||
if (typeof (part = parts[i]) == 'function') {
|
||||
part = part(context);
|
||||
if (part == null || part == undefined) {
|
||||
part = '';
|
||||
} else if (typeof part != 'string') {
|
||||
part = toJson(part);
|
||||
}
|
||||
for(var i = 0, ii = length, part; i<ii; i++) {
|
||||
if (typeof (part = parts[i]) == 'function') {
|
||||
part = part(context);
|
||||
if (part == null || part == undefined) {
|
||||
part = '';
|
||||
} else if (typeof part != 'string') {
|
||||
part = toJson(part);
|
||||
}
|
||||
concat[i] = part;
|
||||
}
|
||||
return concat.join('');
|
||||
}
|
||||
catch(err) {
|
||||
var newErr = new Error('Error while interpolating: ' + text + '\n' + err.toString());
|
||||
$exceptionHandler(newErr);
|
||||
concat[i] = part;
|
||||
}
|
||||
return concat.join('');
|
||||
};
|
||||
fn.exp = text;
|
||||
fn.parts = parts;
|
||||
|
||||
+1
-45
@@ -33,33 +33,7 @@
|
||||
</example>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc object
|
||||
* @name ng.$logProvider
|
||||
* @description
|
||||
* Use the `$logProvider` to configure how the application logs messages
|
||||
*/
|
||||
function $LogProvider(){
|
||||
var debug = true,
|
||||
self = this;
|
||||
|
||||
/**
|
||||
* @ngdoc property
|
||||
* @name ng.$logProvider#debugEnabled
|
||||
* @methodOf ng.$logProvider
|
||||
* @description
|
||||
* @param {string=} flag enable or disable debug level messages
|
||||
* @returns {*} current value if used as getter or itself (chaining) if used as setter
|
||||
*/
|
||||
this.debugEnabled = function(flag) {
|
||||
if (isDefined(flag)) {
|
||||
debug = flag;
|
||||
return this;
|
||||
} else {
|
||||
return debug;
|
||||
}
|
||||
};
|
||||
|
||||
this.$get = ['$window', function($window){
|
||||
return {
|
||||
/**
|
||||
@@ -100,25 +74,7 @@ function $LogProvider(){
|
||||
* @description
|
||||
* Write an error message
|
||||
*/
|
||||
error: consoleLog('error'),
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ng.$log#debug
|
||||
* @methodOf ng.$log
|
||||
*
|
||||
* @description
|
||||
* Write a debug message
|
||||
*/
|
||||
debug: (function () {
|
||||
var fn = consoleLog('debug');
|
||||
|
||||
return function() {
|
||||
if (debug) {
|
||||
fn.apply(self, arguments);
|
||||
}
|
||||
}
|
||||
}())
|
||||
error: consoleLog('error')
|
||||
};
|
||||
|
||||
function formatError(arg) {
|
||||
|
||||
+16
-53
@@ -20,8 +20,6 @@ var OPERATORS = {
|
||||
'%':function(self, locals, a,b){return a(self, locals)%b(self, locals);},
|
||||
'^':function(self, locals, a,b){return a(self, locals)^b(self, locals);},
|
||||
'=':noop,
|
||||
'===':function(self, locals, a, b){return a(self, locals)===b(self, locals);},
|
||||
'!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);},
|
||||
'==':function(self, locals, a,b){return a(self, locals)==b(self, locals);},
|
||||
'!=':function(self, locals, a,b){return a(self, locals)!=b(self, locals);},
|
||||
'<':function(self, locals, a,b){return a(self, locals)<b(self, locals);},
|
||||
@@ -72,14 +70,9 @@ function lex(text, csp){
|
||||
continue;
|
||||
} else {
|
||||
var ch2 = ch + peek(),
|
||||
ch3 = ch2 + peek(2),
|
||||
fn = OPERATORS[ch],
|
||||
fn2 = OPERATORS[ch2],
|
||||
fn3 = OPERATORS[ch3];
|
||||
if (fn3) {
|
||||
tokens.push({index:index, text:ch3, fn:fn3});
|
||||
index += 3;
|
||||
} else if (fn2) {
|
||||
fn2 = OPERATORS[ch2];
|
||||
if (fn2) {
|
||||
tokens.push({index:index, text:ch2, fn:fn2});
|
||||
index += 2;
|
||||
} else if (fn) {
|
||||
@@ -101,9 +94,8 @@ function lex(text, csp){
|
||||
return chars.indexOf(lastCh) != -1;
|
||||
}
|
||||
|
||||
function peek(i) {
|
||||
var num = i || 1;
|
||||
return index + num < text.length ? text.charAt(index + num) : false;
|
||||
function peek() {
|
||||
return index + 1 < text.length ? text.charAt(index + 1) : false;
|
||||
}
|
||||
function isNumber(ch) {
|
||||
return '0' <= ch && ch <= '9';
|
||||
@@ -303,8 +295,6 @@ function parser(text, json, $filter, csp){
|
||||
if (tokens.length !== 0) {
|
||||
throwError("is an unexpected token", tokens[0]);
|
||||
}
|
||||
value.literal = !!value.literal;
|
||||
value.constant = !!value.constant;
|
||||
return value;
|
||||
|
||||
///////////////////////////////////
|
||||
@@ -352,19 +342,15 @@ function parser(text, json, $filter, csp){
|
||||
}
|
||||
|
||||
function unaryFn(fn, right) {
|
||||
return extend(function(self, locals) {
|
||||
return function(self, locals) {
|
||||
return fn(self, locals, right);
|
||||
}, {
|
||||
constant:right.constant
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function binaryFn(left, fn, right) {
|
||||
return extend(function(self, locals) {
|
||||
return function(self, locals) {
|
||||
return fn(self, locals, left, right);
|
||||
}, {
|
||||
constant:left.constant && right.constant
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function statements() {
|
||||
@@ -470,7 +456,7 @@ function parser(text, json, $filter, csp){
|
||||
function equality() {
|
||||
var left = relational();
|
||||
var token;
|
||||
if ((token = expect('==','!=','===','!=='))) {
|
||||
if ((token = expect('==','!='))) {
|
||||
left = binaryFn(left, token.fn, equality());
|
||||
}
|
||||
return left;
|
||||
@@ -532,9 +518,6 @@ function parser(text, json, $filter, csp){
|
||||
if (!primary) {
|
||||
throwError("not a primary expression", token);
|
||||
}
|
||||
if (token.json) {
|
||||
primary.constant = primary.literal = true;
|
||||
}
|
||||
}
|
||||
|
||||
var next, context;
|
||||
@@ -623,32 +606,23 @@ function parser(text, json, $filter, csp){
|
||||
// This is used with json array declaration
|
||||
function arrayDeclaration () {
|
||||
var elementFns = [];
|
||||
var allConstant = true;
|
||||
if (peekToken().text != ']') {
|
||||
do {
|
||||
var elementFn = expression();
|
||||
elementFns.push(elementFn);
|
||||
if (!elementFn.constant) {
|
||||
allConstant = false;
|
||||
}
|
||||
elementFns.push(expression());
|
||||
} while (expect(','));
|
||||
}
|
||||
consume(']');
|
||||
return extend(function(self, locals){
|
||||
return function(self, locals){
|
||||
var array = [];
|
||||
for ( var i = 0; i < elementFns.length; i++) {
|
||||
array.push(elementFns[i](self, locals));
|
||||
}
|
||||
return array;
|
||||
}, {
|
||||
literal:true,
|
||||
constant:allConstant
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function object () {
|
||||
var keyValues = [];
|
||||
var allConstant = true;
|
||||
if (peekToken().text != '}') {
|
||||
do {
|
||||
var token = expect(),
|
||||
@@ -656,13 +630,10 @@ function parser(text, json, $filter, csp){
|
||||
consume(":");
|
||||
var value = expression();
|
||||
keyValues.push({key:key, value:value});
|
||||
if (!value.constant) {
|
||||
allConstant = false;
|
||||
}
|
||||
} while (expect(','));
|
||||
}
|
||||
consume('}');
|
||||
return extend(function(self, locals){
|
||||
return function(self, locals){
|
||||
var object = {};
|
||||
for ( var i = 0; i < keyValues.length; i++) {
|
||||
var keyValue = keyValues[i];
|
||||
@@ -670,10 +641,7 @@ function parser(text, json, $filter, csp){
|
||||
object[keyValue.key] = value;
|
||||
}
|
||||
return object;
|
||||
}, {
|
||||
literal:true,
|
||||
constant:allConstant
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -877,13 +845,8 @@ function getterFn(path, csp) {
|
||||
* * `locals` – `{object=}` – local variables context object, useful for overriding values in
|
||||
* `context`.
|
||||
*
|
||||
* The returned function also has the following properties:
|
||||
* * `literal` – `{boolean}` – whether the expression's top-level node is a JavaScript
|
||||
* literal.
|
||||
* * `constant` – `{boolean}` – whether the expression is made entirely of JavaScript
|
||||
* constant literals.
|
||||
* * `assign` – `{?function(context, value)}` – if the expression is assignable, this will be
|
||||
* set to a function to change its value on the given context.
|
||||
* The return function also has an `assign` property, if the expression is assignable, which
|
||||
* allows one to set values to expressions.
|
||||
*
|
||||
*/
|
||||
function $ParseProvider() {
|
||||
|
||||
+11
-19
@@ -197,6 +197,7 @@ function $RootScopeProvider(){
|
||||
child['this'] = child;
|
||||
child.$$listeners = {};
|
||||
child.$parent = this;
|
||||
child.$$asyncQueue = [];
|
||||
child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null;
|
||||
child.$$prevSibling = this.$$childTail;
|
||||
if (this.$$childHead) {
|
||||
@@ -300,14 +301,6 @@ function $RootScopeProvider(){
|
||||
watcher.fn = function(newVal, oldVal, scope) {listenFn(scope);};
|
||||
}
|
||||
|
||||
if (typeof watchExp == 'string' && get.constant) {
|
||||
var originalFn = watcher.fn;
|
||||
watcher.fn = function(newVal, oldVal, scope) {
|
||||
originalFn.call(this, newVal, oldVal, scope);
|
||||
arrayRemove(array, watcher);
|
||||
};
|
||||
}
|
||||
|
||||
if (!array) {
|
||||
array = scope.$$watchers = [];
|
||||
}
|
||||
@@ -371,7 +364,7 @@ function $RootScopeProvider(){
|
||||
$digest: function() {
|
||||
var watch, value, last,
|
||||
watchers,
|
||||
asyncQueue = this.$$asyncQueue,
|
||||
asyncQueue,
|
||||
length,
|
||||
dirty, ttl = TTL,
|
||||
next, current, target = this,
|
||||
@@ -380,19 +373,18 @@ function $RootScopeProvider(){
|
||||
|
||||
beginPhase('$digest');
|
||||
|
||||
do { // "while dirty" loop
|
||||
do {
|
||||
dirty = false;
|
||||
current = target;
|
||||
|
||||
while(asyncQueue.length) {
|
||||
try {
|
||||
current.$eval(asyncQueue.shift());
|
||||
} catch (e) {
|
||||
$exceptionHandler(e);
|
||||
do {
|
||||
asyncQueue = current.$$asyncQueue;
|
||||
while(asyncQueue.length) {
|
||||
try {
|
||||
current.$eval(asyncQueue.shift());
|
||||
} catch (e) {
|
||||
$exceptionHandler(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do { // "traverse the scopes" loop
|
||||
if ((watchers = current.$$watchers)) {
|
||||
// process our watches
|
||||
length = watchers.length;
|
||||
|
||||
+14
-51
@@ -23,18 +23,9 @@ function $RouteProvider(){
|
||||
* `$location.path` will be updated to add or drop the trailing slash to exactly match the
|
||||
* route definition.
|
||||
*
|
||||
* * `path` can contain named groups starting with a colon (`:name`). All characters up
|
||||
* to the next slash are matched and stored in `$routeParams` under the given `name`
|
||||
* when the route matches.
|
||||
* * `path` can contain named groups starting with a star (`*name`). All characters are
|
||||
* eagerly stored in `$routeParams` under the given `name` when the route matches.
|
||||
*
|
||||
* For example, routes like `/color/:color/largecode/*largecode/edit` will match
|
||||
* `/color/brown/largecode/code/with/slashs/edit` and extract:
|
||||
*
|
||||
* * `color: brown`
|
||||
* * `largecode: code/with/slashs`.
|
||||
*
|
||||
* `path` can contain named groups starting with a colon (`:name`). All characters up to the
|
||||
* next slash are matched and stored in `$routeParams` under the given `name` when the route
|
||||
* matches.
|
||||
*
|
||||
* @param {Object} route Mapping information to be assigned to `$route.current` on route
|
||||
* match.
|
||||
@@ -44,24 +35,12 @@ function $RouteProvider(){
|
||||
* - `controller` – `{(string|function()=}` – Controller fn that should be associated with newly
|
||||
* created scope or the name of a {@link angular.Module#controller registered controller}
|
||||
* if passed as a string.
|
||||
* - `template` – `{string=|function()=}` – html template as a string or function that returns
|
||||
* an html template as a string which should be used by {@link ng.directive:ngView ngView} or
|
||||
* - `template` – `{string=}` – html template as a string that should be used by
|
||||
* {@link ng.directive:ngView ngView} or
|
||||
* {@link ng.directive:ngInclude ngInclude} directives.
|
||||
* This property takes precedence over `templateUrl`.
|
||||
*
|
||||
* If `template` is a function, it will be called with the following parameters:
|
||||
*
|
||||
* - `{Array.<Object>}` - route parameters extracted from the current
|
||||
* `$location.path()` by applying the current route
|
||||
*
|
||||
* - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html
|
||||
* template that should be used by {@link ng.directive:ngView ngView}.
|
||||
*
|
||||
* If `templateUrl` is a function, it will be called with the following parameters:
|
||||
*
|
||||
* - `{Array.<Object>}` - route parameters extracted from the current
|
||||
* `$location.path()` by applying the current route
|
||||
*
|
||||
* this property takes precedence over `templateUrl`.
|
||||
* - `templateUrl` – `{string=}` – path to an html template that should be used by
|
||||
* {@link ng.directive:ngView ngView}.
|
||||
* - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
|
||||
* be injected into the controller. If any of these dependencies are promises, they will be
|
||||
* resolved and converted to a value before the controller is instantiated and the
|
||||
@@ -350,12 +329,12 @@ function $RouteProvider(){
|
||||
// regex only once and then reuse it
|
||||
|
||||
// Escape regexp special characters.
|
||||
when = '^' + when.replace(/[-\/\\^$:*+?.()|[\]{}]/g, "\\$&") + '$';
|
||||
when = '^' + when.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&") + '$';
|
||||
var regex = '',
|
||||
params = [],
|
||||
dst = {};
|
||||
|
||||
var re = /\\([:*])(\w+)/g,
|
||||
var re = /:(\w+)/g,
|
||||
paramMatch,
|
||||
lastMatchedIndex = 0;
|
||||
|
||||
@@ -363,15 +342,8 @@ function $RouteProvider(){
|
||||
// Find each :param in `when` and replace it with a capturing group.
|
||||
// Append all other sections of when unchanged.
|
||||
regex += when.slice(lastMatchedIndex, paramMatch.index);
|
||||
switch(paramMatch[1]) {
|
||||
case ':':
|
||||
regex += '([^\\/]*)';
|
||||
break;
|
||||
case '*':
|
||||
regex += '(.*)';
|
||||
break;
|
||||
}
|
||||
params.push(paramMatch[2]);
|
||||
regex += '([^\\/]*)';
|
||||
params.push(paramMatch[1]);
|
||||
lastMatchedIndex = re.lastIndex;
|
||||
}
|
||||
// Append trailing path part.
|
||||
@@ -423,18 +395,9 @@ function $RouteProvider(){
|
||||
values.push(isString(value) ? $injector.get(value) : $injector.invoke(value));
|
||||
});
|
||||
if (isDefined(template = next.template)) {
|
||||
if (isFunction(template)) {
|
||||
template = template(next.params);
|
||||
}
|
||||
} else if (isDefined(template = next.templateUrl)) {
|
||||
if (isFunction(template)) {
|
||||
template = template(next.params);
|
||||
}
|
||||
if (isDefined(template)) {
|
||||
next.loadedTemplateUrl = template;
|
||||
template = $http.get(template, {cache: $templateCache}).
|
||||
then(function(response) { return response.data; });
|
||||
}
|
||||
template = $http.get(template, {cache: $templateCache}).
|
||||
then(function(response) { return response.data; });
|
||||
}
|
||||
if (isDefined(template)) {
|
||||
keys.push('$template');
|
||||
|
||||
+6
-7
@@ -5,7 +5,6 @@
|
||||
*
|
||||
* @name ng.$sniffer
|
||||
* @requires $window
|
||||
* @requires $document
|
||||
*
|
||||
* @property {boolean} history Does the browser support html5 history api ?
|
||||
* @property {boolean} hashchange Does the browser support hashchange event ?
|
||||
@@ -14,10 +13,9 @@
|
||||
* This is very simple implementation of testing browser's features.
|
||||
*/
|
||||
function $SnifferProvider() {
|
||||
this.$get = ['$window', '$document', function($window, $document) {
|
||||
this.$get = ['$window', function($window) {
|
||||
var eventSupport = {},
|
||||
android = int((/android (\d+)/.exec(lowercase($window.navigator.userAgent)) || [])[1]),
|
||||
document = $document[0];
|
||||
android = int((/android (\d+)/.exec(lowercase($window.navigator.userAgent)) || [])[1]);
|
||||
|
||||
return {
|
||||
// Android has history.pushState, but it does not update location correctly
|
||||
@@ -27,7 +25,7 @@ function $SnifferProvider() {
|
||||
history: !!($window.history && $window.history.pushState && !(android < 4)),
|
||||
hashchange: 'onhashchange' in $window &&
|
||||
// IE8 compatible mode lies
|
||||
(!document.documentMode || document.documentMode > 7),
|
||||
(!$window.document.documentMode || $window.document.documentMode > 7),
|
||||
hasEvent: function(event) {
|
||||
// IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have
|
||||
// it. In particular the event is not fired when backspace or delete key are pressed or
|
||||
@@ -35,13 +33,14 @@ function $SnifferProvider() {
|
||||
if (event == 'input' && msie == 9) return false;
|
||||
|
||||
if (isUndefined(eventSupport[event])) {
|
||||
var divElm = document.createElement('div');
|
||||
var divElm = $window.document.createElement('div');
|
||||
eventSupport[event] = 'on' + event in divElm;
|
||||
}
|
||||
|
||||
return eventSupport[event];
|
||||
},
|
||||
csp: document.securityPolicy ? document.securityPolicy.isActive : false
|
||||
// TODO(i): currently there is no way to feature detect CSP without triggering alerts
|
||||
csp: false
|
||||
};
|
||||
}];
|
||||
}
|
||||
|
||||
Vendored
+36
-67
@@ -456,7 +456,6 @@ angular.mock.$LogProvider = function() {
|
||||
* newYearInBratislava.getDate() => 1;
|
||||
* newYearInBratislava.getHours() => 0;
|
||||
* newYearInBratislava.getMinutes() => 0;
|
||||
* newYearInBratislava.getSeconds() => 0;
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
@@ -513,10 +512,6 @@ angular.mock.$LogProvider = function() {
|
||||
return self.date.getSeconds();
|
||||
};
|
||||
|
||||
self.getMilliseconds = function() {
|
||||
return self.date.getMilliseconds();
|
||||
};
|
||||
|
||||
self.getTimezoneOffset = function() {
|
||||
return offset * 60;
|
||||
};
|
||||
@@ -567,7 +562,7 @@ angular.mock.$LogProvider = function() {
|
||||
}
|
||||
|
||||
//hide all methods not implemented in this mock that the Date prototype exposes
|
||||
var unimplementedMethods = ['getUTCDay',
|
||||
var unimplementedMethods = ['getMilliseconds', 'getUTCDay',
|
||||
'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds',
|
||||
'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear',
|
||||
'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds',
|
||||
@@ -1357,49 +1352,17 @@ function MockXhr() {
|
||||
* @description
|
||||
*
|
||||
* This service is just a simple decorator for {@link ng.$timeout $timeout} service
|
||||
* that adds a "flush" and "verifyNoPendingTasks" methods.
|
||||
*/
|
||||
* that adds a "flush" method.
|
||||
*/
|
||||
|
||||
angular.mock.$TimeoutDecorator = function($delegate, $browser) {
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ngMock.$timeout#flush
|
||||
* @methodOf ngMock.$timeout
|
||||
* @description
|
||||
*
|
||||
* Flushes the queue of pending tasks.
|
||||
*/
|
||||
$delegate.flush = function() {
|
||||
$browser.defer.flush();
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ngMock.$timeout#verifyNoPendingTasks
|
||||
* @methodOf ngMock.$timeout
|
||||
* @description
|
||||
*
|
||||
* Verifies that there are no pending tasks that need to be flushed.
|
||||
*/
|
||||
$delegate.verifyNoPendingTasks = function() {
|
||||
if ($browser.deferredFns.length) {
|
||||
throw Error('Deferred tasks to flush (' + $browser.deferredFns.length + '): ' +
|
||||
formatPendingTasksAsString($browser.deferredFns));
|
||||
}
|
||||
};
|
||||
|
||||
function formatPendingTasksAsString(tasks) {
|
||||
var result = [];
|
||||
angular.forEach(tasks, function(task) {
|
||||
result.push('{id: ' + task.id + ', ' + 'time: ' + task.time + '}');
|
||||
});
|
||||
|
||||
return result.join(', ');
|
||||
}
|
||||
|
||||
return $delegate;
|
||||
};
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ngMock.$timeout#flush
|
||||
* @methodOf ngMock.$timeout
|
||||
* @description
|
||||
*
|
||||
* Flushes the queue of pending tasks.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -1425,9 +1388,15 @@ angular.module('ngMock', ['ng']).provider({
|
||||
$httpBackend: angular.mock.$HttpBackendProvider,
|
||||
$rootElement: angular.mock.$RootElementProvider
|
||||
}).config(function($provide) {
|
||||
$provide.decorator('$timeout', angular.mock.$TimeoutDecorator);
|
||||
$provide.decorator('$timeout', function($delegate, $browser) {
|
||||
$delegate.flush = function() {
|
||||
$browser.defer.flush();
|
||||
};
|
||||
return $delegate;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @name ngMockE2E
|
||||
@@ -1641,20 +1610,14 @@ window.jstestdriver && (function(window) {
|
||||
})(window);
|
||||
|
||||
|
||||
(window.jasmine || window.mocha) && (function(window) {
|
||||
|
||||
var currentSpec = null;
|
||||
|
||||
beforeEach(function() {
|
||||
currentSpec = this;
|
||||
});
|
||||
window.jasmine && (function(window) {
|
||||
|
||||
afterEach(function() {
|
||||
var injector = currentSpec.$injector;
|
||||
var spec = getCurrentSpec();
|
||||
var injector = spec.$injector;
|
||||
|
||||
currentSpec.$injector = null;
|
||||
currentSpec.$modules = null;
|
||||
currentSpec = null;
|
||||
spec.$injector = null;
|
||||
spec.$modules = null;
|
||||
|
||||
if (injector) {
|
||||
injector.get('$rootElement').unbind();
|
||||
@@ -1676,8 +1639,13 @@ window.jstestdriver && (function(window) {
|
||||
angular.callbacks.counter = 0;
|
||||
});
|
||||
|
||||
function getCurrentSpec() {
|
||||
return jasmine.getEnv().currentSpec;
|
||||
}
|
||||
|
||||
function isSpecRunning() {
|
||||
return currentSpec && currentSpec.queue.running;
|
||||
var spec = getCurrentSpec();
|
||||
return spec && spec.queue.running;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1702,10 +1670,11 @@ window.jstestdriver && (function(window) {
|
||||
return isSpecRunning() ? workFn() : workFn;
|
||||
/////////////////////
|
||||
function workFn() {
|
||||
if (currentSpec.$injector) {
|
||||
var spec = getCurrentSpec();
|
||||
if (spec.$injector) {
|
||||
throw Error('Injector already created, can not register a module!');
|
||||
} else {
|
||||
var modules = currentSpec.$modules || (currentSpec.$modules = []);
|
||||
var modules = spec.$modules || (spec.$modules = []);
|
||||
angular.forEach(moduleFns, function(module) {
|
||||
modules.push(module);
|
||||
});
|
||||
@@ -1772,13 +1741,13 @@ window.jstestdriver && (function(window) {
|
||||
return isSpecRunning() ? workFn() : workFn;
|
||||
/////////////////////
|
||||
function workFn() {
|
||||
var modules = currentSpec.$modules || [];
|
||||
|
||||
var spec = getCurrentSpec();
|
||||
var modules = spec.$modules || [];
|
||||
modules.unshift('ngMock');
|
||||
modules.unshift('ng');
|
||||
var injector = currentSpec.$injector;
|
||||
var injector = spec.$injector;
|
||||
if (!injector) {
|
||||
injector = currentSpec.$injector = angular.injector(modules);
|
||||
injector = spec.$injector = angular.injector(modules);
|
||||
}
|
||||
for(var i = 0, ii = blockFns.length; i < ii; i++) {
|
||||
try {
|
||||
|
||||
+35
-97
@@ -19,13 +19,12 @@
|
||||
* the need to interact with the low level {@link ng.$http $http} service.
|
||||
*
|
||||
* @param {string} url A parameterized URL template with parameters prefixed by `:` as in
|
||||
* `/user/:username`. If you are using a URL with a port number (e.g.
|
||||
* `/user/:username`. If you are using a URL with a port number (e.g.
|
||||
* `http://example.com:8080/api`), you'll need to escape the colon character before the port
|
||||
* number, like this: `$resource('http://example.com\\:8080/api')`.
|
||||
*
|
||||
* @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in
|
||||
* `actions` methods. If any of the parameter value is a function, it will be executed every time
|
||||
* when a param value needs to be obtained for a request (unless the param was overriden).
|
||||
* `actions` methods.
|
||||
*
|
||||
* Each key value in the parameter object is first bound to url template if present and then any
|
||||
* excess keys are appended to the url search query after the `?`.
|
||||
@@ -37,40 +36,21 @@
|
||||
* the data object (useful for non-GET operations).
|
||||
*
|
||||
* @param {Object.<Object>=} actions Hash with declaration of custom action that should extend the
|
||||
* default set of resource actions. The declaration should be created in the format of {@link
|
||||
* ng.$http#Parameters $http.config}:
|
||||
* default set of resource actions. The declaration should be created in the following format:
|
||||
*
|
||||
* {action1: {method:?, params:?, isArray:?, headers:?, ...},
|
||||
* action2: {method:?, params:?, isArray:?, headers:?, ...},
|
||||
* {action1: {method:?, params:?, isArray:?},
|
||||
* action2: {method:?, params:?, isArray:?},
|
||||
* ...}
|
||||
*
|
||||
* Where:
|
||||
*
|
||||
* - **`action`** – {string} – The name of action. This name becomes the name of the method on your
|
||||
* - `action` – {string} – The name of action. This name becomes the name of the method on your
|
||||
* resource object.
|
||||
* - **`method`** – {string} – HTTP request method. Valid methods are: `GET`, `POST`, `PUT`, `DELETE`,
|
||||
* and `JSONP`.
|
||||
* - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of the
|
||||
* parameter value is a function, it will be executed every time when a param value needs to be
|
||||
* obtained for a request (unless the param was overriden).
|
||||
* - **`isArray`** – {boolean=} – If true then the returned object for this action is an array, see
|
||||
* - `method` – {string} – HTTP request method. Valid methods are: `GET`, `POST`, `PUT`, `DELETE`,
|
||||
* and `JSONP`
|
||||
* - `params` – {object=} – Optional set of pre-bound parameters for this action.
|
||||
* - isArray – {boolean=} – If true then the returned object for this action is an array, see
|
||||
* `returns` section.
|
||||
* - **`transformRequest`** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
|
||||
* transform function or an array of such functions. The transform function takes the http
|
||||
* request body and headers and returns its transformed (typically serialized) version.
|
||||
* - **`transformResponse`** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
|
||||
* transform function or an array of such functions. The transform function takes the http
|
||||
* response body and headers and returns its transformed (typically deserialized) version.
|
||||
* - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
|
||||
* GET request, otherwise if a cache instance built with
|
||||
* {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
|
||||
* caching.
|
||||
* - **`timeout`** – `{number}` – timeout in milliseconds.
|
||||
* - **`withCredentials`** - `{boolean}` - whether to to set the `withCredentials` flag on the
|
||||
* XHR object. See {@link https://developer.mozilla.org/en/http_access_control#section_5
|
||||
* requests with credentials} for more information.
|
||||
* - **`responseType`** - `{string}` - see {@link
|
||||
* https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType requestType}.
|
||||
*
|
||||
* @returns {Object} A resource "class" object with methods for the default set of resource actions
|
||||
* optionally extended with custom `actions`. The default set contains these actions:
|
||||
@@ -110,24 +90,6 @@
|
||||
* - non-GET instance actions: `instance.$action([parameters], [success], [error])`
|
||||
*
|
||||
*
|
||||
* The Resource instances and collection have these additional properties:
|
||||
*
|
||||
* - `$then`: the `then` method of a {@link ng.$q promise} derived from the underlying
|
||||
* {@link ng.$http $http} call.
|
||||
*
|
||||
* The success callback for the `$then` method will be resolved if the underlying `$http` requests
|
||||
* succeeds.
|
||||
*
|
||||
* The success callback is called with a single object which is the {@link ng.$http http response}
|
||||
* object extended with a new property `resource`. This `resource` property is a reference to the
|
||||
* result of the resource action — resource object or array of resources.
|
||||
*
|
||||
* The error callback is called with the {@link ng.$http http response} object when an http
|
||||
* error occurs.
|
||||
*
|
||||
* - `$resolved`: true if the promise has been resolved (either with success or rejection);
|
||||
* Knowing if the Resource has been resolved is useful in data-binding.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* # Credit card resource
|
||||
@@ -170,7 +132,7 @@
|
||||
* The object returned from this function execution is a resource "class" which has "static" method
|
||||
* for each action in the definition.
|
||||
*
|
||||
* Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and `headers`.
|
||||
* Calling these methods invoke `$http` on the `url` template with the given `method` and `params`.
|
||||
* When the data is returned from the server then the object is an instance of the resource type and
|
||||
* all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD
|
||||
* operations (create, read, update, delete) on server-side data.
|
||||
@@ -316,7 +278,7 @@ angular.module('ngResource', ['ng']).
|
||||
}
|
||||
|
||||
Route.prototype = {
|
||||
setUrlParams: function(config, params) {
|
||||
url: function(params) {
|
||||
var self = this,
|
||||
url = this.template,
|
||||
val,
|
||||
@@ -339,17 +301,16 @@ angular.module('ngResource', ['ng']).
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// set the url
|
||||
config.url = url.replace(/\/?#$/, '').replace(/\/*$/, '');
|
||||
|
||||
// set params - delegate param encoding to $http
|
||||
url = url.replace(/\/?#$/, '');
|
||||
var query = [];
|
||||
forEach(params, function(value, key){
|
||||
if (!self.urlParams[key]) {
|
||||
config.params = config.params || {};
|
||||
config.params[key] = value;
|
||||
query.push(encodeUriQuery(key) + '=' + encodeUriQuery(value));
|
||||
}
|
||||
});
|
||||
query.sort();
|
||||
url = url.replace(/\/*$/, '');
|
||||
return url + (query.length ? '?' + query.join('&') : '');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -363,7 +324,6 @@ angular.module('ngResource', ['ng']).
|
||||
var ids = {};
|
||||
actionParams = extend({}, paramDefaults, actionParams);
|
||||
forEach(actionParams, function(value, key){
|
||||
if (isFunction(value)) { value = value(); }
|
||||
ids[key] = value.charAt && value.charAt(0) == '@' ? getter(data, value.substr(1)) : value;
|
||||
});
|
||||
return ids;
|
||||
@@ -381,8 +341,6 @@ angular.module('ngResource', ['ng']).
|
||||
var data;
|
||||
var success = noop;
|
||||
var error = null;
|
||||
var promise;
|
||||
|
||||
switch(arguments.length) {
|
||||
case 4:
|
||||
error = a4;
|
||||
@@ -418,45 +376,25 @@ angular.module('ngResource', ['ng']).
|
||||
}
|
||||
|
||||
var value = this instanceof Resource ? this : (action.isArray ? [] : new Resource(data));
|
||||
var httpConfig = {},
|
||||
promise;
|
||||
$http({
|
||||
method: action.method,
|
||||
url: route.url(extend({}, extractParams(data, action.params || {}), params)),
|
||||
data: data
|
||||
}).then(function(response) {
|
||||
var data = response.data;
|
||||
|
||||
forEach(action, function(value, key) {
|
||||
if (key != 'params' && key != 'isArray' ) {
|
||||
httpConfig[key] = copy(value);
|
||||
}
|
||||
});
|
||||
httpConfig.data = data;
|
||||
route.setUrlParams(httpConfig, extend({}, extractParams(data, action.params || {}), params));
|
||||
|
||||
function markResolved() { value.$resolved = true; }
|
||||
|
||||
promise = $http(httpConfig);
|
||||
value.$resolved = false;
|
||||
|
||||
promise.then(markResolved, markResolved);
|
||||
value.$then = promise.then(function(response) {
|
||||
var data = response.data;
|
||||
var then = value.$then, resolved = value.$resolved;
|
||||
|
||||
if (data) {
|
||||
if (action.isArray) {
|
||||
value.length = 0;
|
||||
forEach(data, function(item) {
|
||||
value.push(new Resource(item));
|
||||
});
|
||||
} else {
|
||||
copy(data, value);
|
||||
value.$then = then;
|
||||
value.$resolved = resolved;
|
||||
if (data) {
|
||||
if (action.isArray) {
|
||||
value.length = 0;
|
||||
forEach(data, function(item) {
|
||||
value.push(new Resource(item));
|
||||
});
|
||||
} else {
|
||||
copy(data, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(success||noop)(value, response.headers);
|
||||
|
||||
response.resource = value;
|
||||
return response;
|
||||
}, error).then;
|
||||
(success||noop)(value, response.headers);
|
||||
}, error);
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
* plain email address links.
|
||||
*
|
||||
* @param {string} text Input text.
|
||||
* @param {string} target Window (_blank|_self|_parent|_top) or named frame to open links in.
|
||||
* @returns {string} Html-linkified text.
|
||||
*
|
||||
* @usage
|
||||
@@ -25,7 +24,6 @@
|
||||
'mailto:us@somewhere.org,\n'+
|
||||
'another@somewhere.org,\n'+
|
||||
'and one more: ftp://127.0.0.1/.';
|
||||
$scope.snippetWithTarget = 'http://angularjs.org/';
|
||||
}
|
||||
</script>
|
||||
<div ng-controller="Ctrl">
|
||||
@@ -45,15 +43,6 @@
|
||||
<div ng-bind-html="snippet | linky"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="linky-target">
|
||||
<td>linky target</td>
|
||||
<td>
|
||||
<pre><div ng-bind-html="snippetWithTarget | linky:'_blank'"><br></div></pre>
|
||||
</td>
|
||||
<td>
|
||||
<div ng-bind-html="snippetWithTarget | linky:'_blank'"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="escaped-html">
|
||||
<td>no filter</td>
|
||||
<td><pre><div ng-bind="snippet"><br></div></pre></td>
|
||||
@@ -86,11 +75,6 @@
|
||||
toBe('new <a href="http://link">http://link</a>.');
|
||||
expect(using('#escaped-html').binding('snippet')).toBe('new http://link.');
|
||||
});
|
||||
|
||||
it('should work with the target property', function() {
|
||||
expect(using('#linky-target').binding("snippetWithTarget | linky:'_blank'")).
|
||||
toBe('<a target="_blank" href="http://angularjs.org/">http://angularjs.org/</a>');
|
||||
});
|
||||
</doc:scenario>
|
||||
</doc:example>
|
||||
*/
|
||||
@@ -98,7 +82,7 @@ angular.module('ngSanitize').filter('linky', function() {
|
||||
var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.\;\,\(\)\{\}\<\>]/,
|
||||
MAILTO_REGEXP = /^mailto:/;
|
||||
|
||||
return function(text, target) {
|
||||
return function(text) {
|
||||
if (!text) return text;
|
||||
var match;
|
||||
var raw = text;
|
||||
@@ -107,10 +91,6 @@ angular.module('ngSanitize').filter('linky', function() {
|
||||
var writer = htmlSanitizeWriter(html);
|
||||
var url;
|
||||
var i;
|
||||
var properties = {};
|
||||
if (angular.isDefined(target)) {
|
||||
properties.target = target;
|
||||
}
|
||||
while ((match = raw.match(LINKY_URL_REGEXP))) {
|
||||
// We can not end in these as they are sometimes found at the end of the sentence
|
||||
url = match[0];
|
||||
@@ -118,8 +98,7 @@ angular.module('ngSanitize').filter('linky', function() {
|
||||
if (match[2] == match[3]) url = 'mailto:' + url;
|
||||
i = match.index;
|
||||
writer.chars(raw.substr(0, i));
|
||||
properties.href = url;
|
||||
writer.start('a', properties);
|
||||
writer.start('a', {href:url});
|
||||
writer.chars(match[0].replace(MAILTO_REGEXP, ''));
|
||||
writer.end('a');
|
||||
raw = raw.substring(i + match[0].length);
|
||||
|
||||
@@ -123,7 +123,7 @@ var START_TAG_REGEXP = /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:
|
||||
BEGING_END_TAGE_REGEXP = /^<\s*\//,
|
||||
COMMENT_REGEXP = /<!--(.*?)-->/g,
|
||||
CDATA_REGEXP = /<!\[CDATA\[(.*?)]]>/g,
|
||||
URI_REGEXP = /^((ftp|https?):\/\/|mailto:|tel:|#)/,
|
||||
URI_REGEXP = /^((ftp|https?):\/\/|mailto:|#)/,
|
||||
NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g; // Match everything outside of normal chars and " (quote character)
|
||||
|
||||
|
||||
|
||||
@@ -298,8 +298,6 @@ angular.scenario.dsl('select', function() {
|
||||
option = select.find('option:contains("' + value + '")');
|
||||
if (option.length) {
|
||||
select.val(option.val());
|
||||
} else {
|
||||
return done("option '" + value + "' not found");
|
||||
}
|
||||
}
|
||||
select.trigger('change');
|
||||
@@ -327,7 +325,6 @@ angular.scenario.dsl('select', function() {
|
||||
* Usage:
|
||||
* element(selector, label).count() get the number of elements that match selector
|
||||
* element(selector, label).click() clicks an element
|
||||
* element(selector, label).mouseover() mouseover an element
|
||||
* element(selector, label).query(fn) executes fn(selectedElements, done)
|
||||
* element(selector, label).{method}() gets the value (as defined by jQuery, ex. val)
|
||||
* element(selector, label).{method}(value) sets the value (as defined by jQuery, ex. val)
|
||||
@@ -368,30 +365,6 @@ angular.scenario.dsl('element', function() {
|
||||
});
|
||||
};
|
||||
|
||||
chain.dblclick = function() {
|
||||
return this.addFutureAction("element '" + this.label + "' dblclick", function($window, $document, done) {
|
||||
var elements = $document.elements();
|
||||
var href = elements.attr('href');
|
||||
var eventProcessDefault = elements.trigger('dblclick')[0];
|
||||
|
||||
if (href && elements[0].nodeName.toUpperCase() === 'A' && eventProcessDefault) {
|
||||
this.application.navigateTo(href, function() {
|
||||
done();
|
||||
}, done);
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
chain.mouseover = function() {
|
||||
return this.addFutureAction("element '" + this.label + "' mouseover", function($window, $document, done) {
|
||||
var elements = $document.elements();
|
||||
elements.trigger('mouseover');
|
||||
done();
|
||||
});
|
||||
};
|
||||
|
||||
chain.query = function(fn) {
|
||||
return this.addFutureAction('element ' + this.label + ' custom query', function($window, $document, done) {
|
||||
fn.call(this, $document.elements(), done);
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* JSTestDriver adapter for angular scenario tests
|
||||
*
|
||||
* Example of jsTestDriver.conf for running scenario tests with JSTD:
|
||||
<pre>
|
||||
server: http://localhost:9877
|
||||
|
||||
load:
|
||||
- lib/angular-scenario.js
|
||||
- lib/jstd-scenario-adapter-config.js
|
||||
- lib/jstd-scenario-adapter.js
|
||||
# your test files go here #
|
||||
|
||||
proxy:
|
||||
- {matcher: "/your-prefix/*", server: "http://localhost:8000/"}
|
||||
</pre>
|
||||
*
|
||||
* For more information on how to configure jstd proxy, see {@link http://code.google.com/p/js-test-driver/wiki/Proxy}
|
||||
* Note the order of files - it's important !
|
||||
*
|
||||
* Example of jstd-scenario-adapter-config.js
|
||||
<pre>
|
||||
var jstdScenarioAdapter = {
|
||||
relativeUrlPrefix: '/your-prefix/'
|
||||
};
|
||||
</pre>
|
||||
*
|
||||
* Whenever you use <code>browser().navigateTo('relativeUrl')</code> in your scenario test, the relativeUrlPrefix will be prepended.
|
||||
* You have to configure this to work together with JSTD proxy.
|
||||
*
|
||||
* Let's assume you are using the above configuration (jsTestDriver.conf and jstd-scenario-adapter-config.js):
|
||||
* Now, when you call <code>browser().navigateTo('index.html')</code> in your scenario test, the browser will open /your-prefix/index.html.
|
||||
* That matches the proxy, so JSTD will proxy this request to http://localhost:8000/index.html.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Custom type of test case
|
||||
*
|
||||
* @const
|
||||
* @see jstestdriver.TestCaseInfo
|
||||
*/
|
||||
var SCENARIO_TYPE = 'scenario';
|
||||
|
||||
/**
|
||||
* Plugin for JSTestDriver
|
||||
* Connection point between scenario's jstd output and jstestdriver.
|
||||
*
|
||||
* @see jstestdriver.PluginRegistrar
|
||||
*/
|
||||
function JstdPlugin() {
|
||||
var nop = function() {};
|
||||
|
||||
this.reportResult = nop;
|
||||
this.reportEnd = nop;
|
||||
this.runScenario = nop;
|
||||
|
||||
this.name = 'Angular Scenario Adapter';
|
||||
|
||||
/**
|
||||
* Called for each JSTD TestCase
|
||||
*
|
||||
* Handles only SCENARIO_TYPE test cases. There should be only one fake TestCase.
|
||||
* Runs all scenario tests (under one fake TestCase) and report all results to JSTD.
|
||||
*
|
||||
* @param {jstestdriver.TestRunConfiguration} configuration
|
||||
* @param {Function} onTestDone
|
||||
* @param {Function} onAllTestsComplete
|
||||
* @returns {boolean} True if this type of test is handled by this plugin, false otherwise
|
||||
*/
|
||||
this.runTestConfiguration = function(configuration, onTestDone, onAllTestsComplete) {
|
||||
if (configuration.getTestCaseInfo().getType() != SCENARIO_TYPE) return false;
|
||||
|
||||
this.reportResult = onTestDone;
|
||||
this.reportEnd = onAllTestsComplete;
|
||||
this.runScenario();
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
this.getTestRunsConfigurationFor = function(testCaseInfos, expressions, testRunsConfiguration) {
|
||||
testRunsConfiguration.push(
|
||||
new jstestdriver.TestRunConfiguration(
|
||||
new jstestdriver.TestCaseInfo(
|
||||
'Angular Scenario Tests', function() {}, SCENARIO_TYPE), []));
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Singleton instance of the plugin
|
||||
* Accessed using closure by:
|
||||
* - jstd output (reports to this plugin)
|
||||
* - initScenarioAdapter (register the plugin to jstd)
|
||||
*/
|
||||
var plugin = new JstdPlugin();
|
||||
|
||||
/**
|
||||
* Initialise scenario jstd-adapter
|
||||
* (only if jstestdriver is defined)
|
||||
*
|
||||
* @param {Object} jstestdriver Undefined when run from browser (without jstd)
|
||||
* @param {Function} initScenarioAndRun Function that inits scenario and runs all the tests
|
||||
* @param {Object=} config Configuration object, supported properties:
|
||||
* - relativeUrlPrefix: prefix for all relative links when navigateTo()
|
||||
*/
|
||||
function initScenarioAdapter(jstestdriver, initScenarioAndRun, config) {
|
||||
if (jstestdriver) {
|
||||
// create and register ScenarioPlugin
|
||||
jstestdriver.pluginRegistrar.register(plugin);
|
||||
plugin.runScenario = initScenarioAndRun;
|
||||
|
||||
/**
|
||||
* HACK (angular.scenario.Application.navigateTo)
|
||||
*
|
||||
* We need to navigate to relative urls when running from browser (without JSTD),
|
||||
* because we want to allow running scenario tests without creating its own virtual host.
|
||||
* For example: http://angular.local/build/docs/docs-scenario.html
|
||||
*
|
||||
* On the other hand, when running with JSTD, we need to navigate to absolute urls,
|
||||
* because of JSTD proxy. (proxy, because of same domain policy)
|
||||
*
|
||||
* So this hack is applied only if running with JSTD and change all relative urls to absolute.
|
||||
*/
|
||||
var appProto = angular.scenario.Application.prototype,
|
||||
navigateTo = appProto.navigateTo,
|
||||
relativeUrlPrefix = config && config.relativeUrlPrefix || '/';
|
||||
|
||||
appProto.navigateTo = function(url, loadFn, errorFn) {
|
||||
if (url.charAt(0) != '/' && url.charAt(0) != '#' &&
|
||||
url != 'about:blank' && !url.match(/^https?/)) {
|
||||
url = relativeUrlPrefix + url;
|
||||
}
|
||||
|
||||
return navigateTo.call(this, url, loadFn, errorFn);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds proper TestResult object from given model spec
|
||||
*
|
||||
* TODO(vojta) report error details
|
||||
*
|
||||
* @param {angular.scenario.ObjectModel.Spec} spec
|
||||
* @returns {jstestdriver.TestResult}
|
||||
*/
|
||||
function createTestResultFromSpec(spec) {
|
||||
var map = {
|
||||
success: 'PASSED',
|
||||
error: 'ERROR',
|
||||
failure: 'FAILED'
|
||||
};
|
||||
|
||||
return new jstestdriver.TestResult(
|
||||
spec.fullDefinitionName,
|
||||
spec.name,
|
||||
jstestdriver.TestResult.RESULT[map[spec.status]],
|
||||
spec.error || '',
|
||||
spec.line || '',
|
||||
spec.duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates JSTD output (jstestdriver.TestResult)
|
||||
*/
|
||||
angular.scenario.output('jstd', function(context, runner, model) {
|
||||
model.on('SpecEnd', function(spec) {
|
||||
plugin.reportResult(createTestResultFromSpec(spec));
|
||||
});
|
||||
|
||||
model.on('RunnerEnd', function() {
|
||||
plugin.reportEnd();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* @license AngularJS v"NG_VERSION_FULL"
|
||||
* (c) 2010-2012 Google, Inc. http://angularjs.org
|
||||
* License: MIT
|
||||
*/
|
||||
(function(window) {
|
||||
@@ -0,0 +1,2 @@
|
||||
initScenarioAdapter(window.jstestdriver, angular.scenario.setUpAndRun, window.jstdScenarioAdapter);
|
||||
})(window);
|
||||
@@ -737,27 +737,4 @@ describe('angular', function() {
|
||||
expect(toJson({key: $rootScope})).toEqual('{"key":"$SCOPE"}');
|
||||
}));
|
||||
});
|
||||
|
||||
describe('noConflict', function() {
|
||||
var globalAngular;
|
||||
beforeEach(function() {
|
||||
globalAngular = angular;
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
angular = globalAngular;
|
||||
});
|
||||
|
||||
it('should return angular', function() {
|
||||
var a = angular.noConflict();
|
||||
expect(a).toBe(globalAngular);
|
||||
});
|
||||
|
||||
it('should restore original angular', function() {
|
||||
var a = angular.noConflict();
|
||||
expect(angular).toBeUndefined();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
+1
-1
@@ -175,7 +175,7 @@ describe('Binder', function() {
|
||||
$rootScope.error['throw'] = function() {throw 'MyError';};
|
||||
errorLogs.length = 0;
|
||||
$rootScope.$apply();
|
||||
expect(errorLogs.shift().message).toBe('Error while interpolating: {{error.throw()}}\nMyError');
|
||||
expect(errorLogs.shift()).toBe('MyError');
|
||||
|
||||
$rootScope.error['throw'] = function() {return 'ok';};
|
||||
$rootScope.$apply();
|
||||
|
||||
@@ -3,13 +3,11 @@
|
||||
describe('injector', function() {
|
||||
var providers;
|
||||
var injector;
|
||||
var providerInjector;
|
||||
|
||||
beforeEach(module(function($provide, $injector) {
|
||||
beforeEach(module(function($provide) {
|
||||
providers = function(name, factory, annotations) {
|
||||
$provide.factory(name, extend(factory, annotations||{}));
|
||||
};
|
||||
providerInjector = $injector;
|
||||
}));
|
||||
beforeEach(inject(function($injector){
|
||||
injector = $injector;
|
||||
@@ -74,11 +72,6 @@ describe('injector', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should create a new $injector for the run phase', inject(function($injector) {
|
||||
expect($injector).not.toBe(providerInjector);
|
||||
}));
|
||||
|
||||
|
||||
describe('invoke', function() {
|
||||
var args;
|
||||
|
||||
@@ -556,26 +549,26 @@ describe('injector', function() {
|
||||
|
||||
|
||||
it('should decorate the missing service error with module name', function() {
|
||||
angular.module('TestModule', [], function(xyzzy) {});
|
||||
angular.module('TestModule', [], function($injector) {});
|
||||
expect(function() {
|
||||
createInjector(['TestModule']);
|
||||
}).toThrow('Unknown provider: xyzzy from TestModule');
|
||||
}).toThrow('Unknown provider: $injector from TestModule');
|
||||
});
|
||||
|
||||
|
||||
it('should decorate the missing service error with module function', function() {
|
||||
function myModule(xyzzy){}
|
||||
function myModule($injector){}
|
||||
expect(function() {
|
||||
createInjector([myModule]);
|
||||
}).toThrow('Unknown provider: xyzzy from ' + myModule);
|
||||
}).toThrow('Unknown provider: $injector from ' + myModule);
|
||||
});
|
||||
|
||||
|
||||
it('should decorate the missing service error with module array function', function() {
|
||||
function myModule(xyzzy){}
|
||||
function myModule($injector){}
|
||||
expect(function() {
|
||||
createInjector([['xyzzy', myModule]]);
|
||||
}).toThrow('Unknown provider: xyzzy from ' + myModule);
|
||||
createInjector([['$injector', myModule]]);
|
||||
}).toThrow('Unknown provider: $injector from ' + myModule);
|
||||
});
|
||||
|
||||
|
||||
|
||||
+1
-6
@@ -955,14 +955,9 @@ describe('jqLite', function() {
|
||||
expect(root.append('text')).toEqual(root);
|
||||
expect(root.html()).toEqual('text');
|
||||
});
|
||||
it('should append to document fragment', function() {
|
||||
it('should not append anything if parent node is not of type element', function() {
|
||||
var root = jqLite(document.createDocumentFragment());
|
||||
expect(root.append('<p>foo</p>')).toBe(root);
|
||||
expect(root.children().length).toBe(1);
|
||||
});
|
||||
it('should not append anything if parent node is not of type element or docfrag', function() {
|
||||
var root = jqLite('<p>some text node</p>').contents();
|
||||
expect(root.append('<p>foo</p>')).toBe(root);
|
||||
expect(root.children().length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -104,12 +104,6 @@ describe('$cacheFactory', function() {
|
||||
cache.remove(123);
|
||||
expect(cache.info().size).toBe(0);
|
||||
}));
|
||||
|
||||
|
||||
it("should return value from put", inject(function($cacheFactory) {
|
||||
var obj = {};
|
||||
expect(cache.put('k1', obj)).toBe(obj);
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
|
||||
+14
-9
@@ -1421,10 +1421,9 @@ describe('$compile', function() {
|
||||
}));
|
||||
|
||||
|
||||
it('should set interpolated attrs to initial interpolation value', inject(function($rootScope, $compile) {
|
||||
$rootScope.whatever = 'test value';
|
||||
it('should set interpolated attrs to undefined', inject(function($rootScope, $compile) {
|
||||
$compile('<div some-attr="{{whatever}}" observer></div>')($rootScope);
|
||||
expect(directiveAttrs.someAttr).toBe($rootScope.whatever);
|
||||
expect(directiveAttrs.someAttr).toBeUndefined();
|
||||
}));
|
||||
|
||||
|
||||
@@ -1853,21 +1852,27 @@ describe('$compile', function() {
|
||||
describe('attribute', function() {
|
||||
it('should copy simple attribute', inject(function() {
|
||||
compile('<div><span my-component attr="some text">');
|
||||
expect(componentScope.attr).toEqual(undefined);
|
||||
expect(componentScope.attrAlias).toEqual(undefined);
|
||||
|
||||
$rootScope.$apply();
|
||||
|
||||
expect(componentScope.attr).toEqual('some text');
|
||||
expect(componentScope.attrAlias).toEqual('some text');
|
||||
expect(componentScope.attrAlias).toEqual(componentScope.attr);
|
||||
}));
|
||||
|
||||
it('should set up the interpolation before it reaches the link function', inject(function() {
|
||||
$rootScope.name = 'misko';
|
||||
compile('<div><span my-component attr="hello {{name}}">');
|
||||
expect(componentScope.attr).toEqual('hello misko');
|
||||
expect(componentScope.attrAlias).toEqual('hello misko');
|
||||
}));
|
||||
|
||||
it('should update when interpolated attribute updates', inject(function() {
|
||||
compile('<div><span my-component attr="hello {{name}}">');
|
||||
expect(componentScope.attr).toEqual(undefined);
|
||||
expect(componentScope.attrAlias).toEqual(undefined);
|
||||
|
||||
$rootScope.name = 'misko';
|
||||
$rootScope.$apply();
|
||||
|
||||
expect(componentScope.attr).toEqual('hello misko');
|
||||
expect(componentScope.attrAlias).toEqual('hello misko');
|
||||
|
||||
$rootScope.name = 'igor';
|
||||
$rootScope.$apply();
|
||||
|
||||
@@ -74,16 +74,6 @@ describe('boolean attr directives', function() {
|
||||
$rootScope.$digest();
|
||||
expect(element.attr('multiple')).toBeTruthy();
|
||||
}));
|
||||
|
||||
it('should bind open', inject(function($rootScope, $compile) {
|
||||
element = $compile('<details ng-open="isOpen"></details>')($rootScope)
|
||||
$rootScope.isOpen=false;
|
||||
$rootScope.$digest();
|
||||
expect(element.attr('open')).toBeFalsy();
|
||||
$rootScope.isOpen=true;
|
||||
$rootScope.$digest();
|
||||
expect(element.attr('open')).toBeTruthy();
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -430,110 +430,4 @@ describe('form', function() {
|
||||
expect(doc).toBeDirty();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('$setPristine', function() {
|
||||
|
||||
it('should reset pristine state of form and controls', function() {
|
||||
|
||||
doc = $compile(
|
||||
'<form name="testForm">' +
|
||||
'<input ng-model="named1" name="foo">' +
|
||||
'<input ng-model="named2" name="bar">' +
|
||||
'</form>')(scope);
|
||||
|
||||
scope.$digest();
|
||||
|
||||
var form = doc,
|
||||
formCtrl = scope.testForm,
|
||||
input1 = form.find('input').eq(0),
|
||||
input1Ctrl = input1.controller('ngModel'),
|
||||
input2 = form.find('input').eq(1),
|
||||
input2Ctrl = input2.controller('ngModel');
|
||||
|
||||
input1Ctrl.$setViewValue('xx');
|
||||
input2Ctrl.$setViewValue('yy');
|
||||
scope.$apply();
|
||||
expect(form).toBeDirty();
|
||||
expect(input1).toBeDirty();
|
||||
expect(input2).toBeDirty();
|
||||
|
||||
formCtrl.$setPristine();
|
||||
expect(form).toBePristine();
|
||||
expect(formCtrl.$pristine).toBe(true);
|
||||
expect(formCtrl.$dirty).toBe(false);
|
||||
expect(input1).toBePristine();
|
||||
expect(input1Ctrl.$pristine).toBe(true);
|
||||
expect(input1Ctrl.$dirty).toBe(false);
|
||||
expect(input2).toBePristine();
|
||||
expect(input2Ctrl.$pristine).toBe(true);
|
||||
expect(input2Ctrl.$dirty).toBe(false);
|
||||
});
|
||||
|
||||
|
||||
it('should reset pristine state of anonymous form controls', function() {
|
||||
|
||||
doc = $compile(
|
||||
'<form name="testForm">' +
|
||||
'<input ng-model="anonymous">' +
|
||||
'</form>')(scope);
|
||||
|
||||
scope.$digest();
|
||||
|
||||
var form = doc,
|
||||
formCtrl = scope.testForm,
|
||||
input = form.find('input').eq(0),
|
||||
inputCtrl = input.controller('ngModel');
|
||||
|
||||
inputCtrl.$setViewValue('xx');
|
||||
scope.$apply();
|
||||
expect(form).toBeDirty();
|
||||
expect(input).toBeDirty();
|
||||
|
||||
formCtrl.$setPristine();
|
||||
expect(form).toBePristine();
|
||||
expect(formCtrl.$pristine).toBe(true);
|
||||
expect(formCtrl.$dirty).toBe(false);
|
||||
expect(input).toBePristine();
|
||||
expect(inputCtrl.$pristine).toBe(true);
|
||||
expect(inputCtrl.$dirty).toBe(false);
|
||||
});
|
||||
|
||||
|
||||
it('should reset pristine state of nested forms', function() {
|
||||
|
||||
doc = $compile(
|
||||
'<form name="testForm">' +
|
||||
'<div ng-form>' +
|
||||
'<input ng-model="named" name="foo">' +
|
||||
'</div>' +
|
||||
'</form>')(scope);
|
||||
|
||||
scope.$digest();
|
||||
|
||||
var form = doc,
|
||||
formCtrl = scope.testForm,
|
||||
nestedForm = form.find('div'),
|
||||
nestedFormCtrl = nestedForm.controller('form'),
|
||||
nestedInput = form.find('input').eq(0),
|
||||
nestedInputCtrl = nestedInput.controller('ngModel');
|
||||
|
||||
nestedInputCtrl.$setViewValue('xx');
|
||||
scope.$apply();
|
||||
expect(form).toBeDirty();
|
||||
expect(nestedForm).toBeDirty();
|
||||
expect(nestedInput).toBeDirty();
|
||||
|
||||
formCtrl.$setPristine();
|
||||
expect(form).toBePristine();
|
||||
expect(formCtrl.$pristine).toBe(true);
|
||||
expect(formCtrl.$dirty).toBe(false);
|
||||
expect(nestedForm).toBePristine();
|
||||
expect(nestedFormCtrl.$pristine).toBe(true);
|
||||
expect(nestedFormCtrl.$dirty).toBe(false);
|
||||
expect(nestedInput).toBePristine();
|
||||
expect(nestedInputCtrl.$pristine).toBe(true);
|
||||
expect(nestedInputCtrl.$dirty).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -117,18 +117,6 @@ describe('NgModelController', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('setPristine', function() {
|
||||
|
||||
it('should set control to its pristine state', function() {
|
||||
ctrl.$setViewValue('edit');
|
||||
expect(ctrl.$dirty).toBe(true);
|
||||
expect(ctrl.$pristine).toBe(false);
|
||||
|
||||
ctrl.$setPristine();
|
||||
expect(ctrl.$dirty).toBe(false);
|
||||
expect(ctrl.$pristine).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('view -> model', function() {
|
||||
|
||||
@@ -394,14 +382,6 @@ describe('input', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should update the model and not trim the value', function() {
|
||||
compileInput('<input type="text" ng-model="name" name="alias" ng-trim="false" />');
|
||||
|
||||
changeInputValueTo(' a ');
|
||||
expect(scope.name).toEqual(' a ');
|
||||
});
|
||||
|
||||
|
||||
it('should allow complex reference binding', function() {
|
||||
compileInput('<input type="text" ng-model="obj[\'abc\'].name"/>');
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('ngKeyup and ngKeydown directives', function() {
|
||||
var element;
|
||||
|
||||
afterEach(function() {
|
||||
dealoc(element);
|
||||
});
|
||||
|
||||
it('should get called on a keyup', inject(function($rootScope, $compile) {
|
||||
element = $compile('<input ng-keyup="touched = true">')($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect($rootScope.touched).toBeFalsy();
|
||||
|
||||
browserTrigger(element, 'keyup');
|
||||
expect($rootScope.touched).toEqual(true);
|
||||
}));
|
||||
|
||||
it('should get called on a keydown', inject(function($rootScope, $compile) {
|
||||
element = $compile('<input ng-keydown="touched = true">')($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect($rootScope.touched).toBeFalsy();
|
||||
|
||||
browserTrigger(element, 'keydown');
|
||||
expect($rootScope.touched).toEqual(true);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
@@ -36,36 +36,6 @@ describe('ngSwitch', function() {
|
||||
}));
|
||||
|
||||
|
||||
it('should show all switch-whens that match the current value', inject(function($rootScope, $compile) {
|
||||
element = $compile(
|
||||
'<ul ng-switch="select">' +
|
||||
'<li ng-switch-when="1">first:{{name}}</li>' +
|
||||
'<li ng-switch-when="1">, first too:{{name}}</li>' +
|
||||
'<li ng-switch-when="2">second:{{name}}</li>' +
|
||||
'<li ng-switch-when="true">true:{{name}}</li>' +
|
||||
'</ul>')($rootScope);
|
||||
expect(element.html()).toEqual('<!-- ngSwitchWhen: 1 -->' +
|
||||
'<!-- ngSwitchWhen: 1 -->' +
|
||||
'<!-- ngSwitchWhen: 2 -->' +
|
||||
'<!-- ngSwitchWhen: true -->');
|
||||
$rootScope.select = 1;
|
||||
$rootScope.$apply();
|
||||
expect(element.text()).toEqual('first:, first too:');
|
||||
$rootScope.name="shyam";
|
||||
$rootScope.$apply();
|
||||
expect(element.text()).toEqual('first:shyam, first too:shyam');
|
||||
$rootScope.select = 2;
|
||||
$rootScope.$apply();
|
||||
expect(element.text()).toEqual('second:shyam');
|
||||
$rootScope.name = 'misko';
|
||||
$rootScope.$apply();
|
||||
expect(element.text()).toEqual('second:misko');
|
||||
$rootScope.select = true;
|
||||
$rootScope.$apply();
|
||||
expect(element.text()).toEqual('true:misko');
|
||||
}));
|
||||
|
||||
|
||||
it('should switch on switch-when-default', inject(function($rootScope, $compile) {
|
||||
element = $compile(
|
||||
'<ng:switch on="select">' +
|
||||
@@ -80,21 +50,6 @@ describe('ngSwitch', function() {
|
||||
}));
|
||||
|
||||
|
||||
it('should show all switch-when-default', inject(function($rootScope, $compile) {
|
||||
element = $compile(
|
||||
'<ul ng-switch="select">' +
|
||||
'<li ng-switch-when="1">one</li>' +
|
||||
'<li ng-switch-default>other</li>' +
|
||||
'<li ng-switch-default>, other too</li>' +
|
||||
'</ul>')($rootScope);
|
||||
$rootScope.$apply();
|
||||
expect(element.text()).toEqual('other, other too');
|
||||
$rootScope.select = 1;
|
||||
$rootScope.$apply();
|
||||
expect(element.text()).toEqual('one');
|
||||
}));
|
||||
|
||||
|
||||
it('should call change on switch', inject(function($rootScope, $compile) {
|
||||
element = $compile(
|
||||
'<ng:switch on="url" change="name=\'works\'">' +
|
||||
|
||||
@@ -66,57 +66,4 @@ describe('Filter: filter', function() {
|
||||
expect(filter(items, '!isk').length).toBe(1);
|
||||
expect(filter(items, '!isk')[0]).toEqual(items[1]);
|
||||
});
|
||||
|
||||
describe('should support comparator', function() {
|
||||
|
||||
it('as equality when true', function() {
|
||||
var items = ['misko', 'adam', 'adamson'];
|
||||
var expr = 'adam';
|
||||
expect(filter(items, expr, true)).toEqual([items[1]]);
|
||||
expect(filter(items, expr, false)).toEqual([items[1], items[2]]);
|
||||
|
||||
var items = [
|
||||
{key: 'value1', nonkey: 1},
|
||||
{key: 'value2', nonkey: 2},
|
||||
{key: 'value12', nonkey: 3},
|
||||
{key: 'value1', nonkey:4},
|
||||
{key: 'Value1', nonkey:5}
|
||||
];
|
||||
var expr = {key: 'value1'};
|
||||
expect(filter(items, expr, true)).toEqual([items[0], items[3]]);
|
||||
|
||||
var items = [
|
||||
{key: 1, nonkey: 1},
|
||||
{key: 2, nonkey: 2},
|
||||
{key: 12, nonkey: 3},
|
||||
{key: 1, nonkey:4}
|
||||
];
|
||||
var expr = { key: 1 };
|
||||
expect(filter(items, expr, true)).toEqual([items[0], items[3]]);
|
||||
|
||||
var expr = 12;
|
||||
expect(filter(items, expr, true)).toEqual([items[2]]);
|
||||
});
|
||||
|
||||
it('and use the function given to compare values', function() {
|
||||
var items = [
|
||||
{key: 1, nonkey: 1},
|
||||
{key: 2, nonkey: 2},
|
||||
{key: 12, nonkey: 3},
|
||||
{key: 1, nonkey:14}
|
||||
];
|
||||
var expr = {key: 10};
|
||||
var comparator = function (obj,value) {
|
||||
return obj > value;
|
||||
}
|
||||
expect(filter(items, expr, comparator)).toEqual([items[2]]);
|
||||
|
||||
expr = 10;
|
||||
expect(filter(items, expr, comparator)).toEqual([items[2], items[3]]);
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -173,9 +173,9 @@ describe('filters', function() {
|
||||
|
||||
describe('date', function() {
|
||||
|
||||
var morning = new angular.mock.TzDate(+5, '2010-09-03T12:05:08.001Z'); //7am
|
||||
var noon = new angular.mock.TzDate(+5, '2010-09-03T17:05:08.012Z'); //12pm
|
||||
var midnight = new angular.mock.TzDate(+5, '2010-09-03T05:05:08.123Z'); //12am
|
||||
var morning = new angular.mock.TzDate(+5, '2010-09-03T12:05:08.000Z'); //7am
|
||||
var noon = new angular.mock.TzDate(+5, '2010-09-03T17:05:08.000Z'); //12pm
|
||||
var midnight = new angular.mock.TzDate(+5, '2010-09-03T05:05:08.000Z'); //12am
|
||||
var earlyDate = new angular.mock.TzDate(+5, '0001-09-03T05:05:08.000Z');
|
||||
|
||||
var date;
|
||||
@@ -203,24 +203,15 @@ describe('filters', function() {
|
||||
expect(date(morning, "yy-MM-dd HH:mm:ss")).
|
||||
toEqual('10-09-03 07:05:08');
|
||||
|
||||
expect(date(morning, "yy-MM-dd HH:mm:ss.sss")).
|
||||
toEqual('10-09-03 07:05:08.001');
|
||||
|
||||
expect(date(midnight, "yyyy-M-d h=H:m:saZ")).
|
||||
toEqual('2010-9-3 12=0:5:8AM-0500');
|
||||
|
||||
expect(date(midnight, "yyyy-MM-dd hh=HH:mm:ssaZ")).
|
||||
toEqual('2010-09-03 12=00:05:08AM-0500');
|
||||
|
||||
expect(date(midnight, "yyyy-MM-dd hh=HH:mm:ss.sssaZ")).
|
||||
toEqual('2010-09-03 12=00:05:08.123AM-0500');
|
||||
|
||||
expect(date(noon, "yyyy-MM-dd hh=HH:mm:ssaZ")).
|
||||
toEqual('2010-09-03 12=12:05:08PM-0500');
|
||||
|
||||
expect(date(noon, "yyyy-MM-dd hh=HH:mm:ss.sssaZ")).
|
||||
toEqual('2010-09-03 12=12:05:08.012PM-0500');
|
||||
|
||||
expect(date(noon, "EEE, MMM d, yyyy")).
|
||||
toEqual('Fri, Sep 3, 2010');
|
||||
|
||||
@@ -289,37 +280,32 @@ describe('filters', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should support various iso8061 date strings with timezone as input', function() {
|
||||
var format = 'yyyy-MM-dd ss';
|
||||
it('should support various iso8061 date strings as input', function() {
|
||||
var format = 'yyyy-MM ss';
|
||||
|
||||
//full ISO8061
|
||||
expect(date('2003-09-10T13:02:03.000Z', format)).toEqual('2003-09-10 03');
|
||||
expect(date('2003-09-10T13:02:03.000Z', format)).toEqual('2003-09 03');
|
||||
|
||||
expect(date('2003-09-10T13:02:03.000+00:00', format)).toEqual('2003-09-10 03');
|
||||
expect(date('2003-09-10T13:02:03.000+00:00', format)).toEqual('2003-09 03');
|
||||
|
||||
expect(date('20030910T033203-0930', format)).toEqual('2003-09-10 03');
|
||||
expect(date('2003-09-10T13:02:03-08:00', format)).toEqual('2003-09 03');
|
||||
|
||||
expect(date('20030910T033203-0930', format)).toEqual('2003-09 03');
|
||||
|
||||
//no timezone
|
||||
expect(date('2003-09-10T13:02:03.000', format)).toEqual('2003-09 03');
|
||||
|
||||
//no millis
|
||||
expect(date('2003-09-10T13:02:03Z', format)).toEqual('2003-09-10 03');
|
||||
expect(date('2003-09-10T13:02:03Z', format)).toEqual('2003-09 03');
|
||||
|
||||
//no seconds
|
||||
expect(date('2003-09-10T13:02Z', format)).toEqual('2003-09-10 00');
|
||||
expect(date('2003-09-10T13:02Z', format)).toEqual('2003-09 00');
|
||||
|
||||
//no minutes
|
||||
expect(date('2003-09-10T13Z', format)).toEqual('2003-09-10 00');
|
||||
});
|
||||
|
||||
|
||||
it('should parse iso8061 date strings without timezone as local time', function() {
|
||||
var format = 'yyyy-MM-dd HH-mm-ss';
|
||||
|
||||
//full ISO8061 without timezone
|
||||
expect(date('2003-09-10T03:02:04.000', format)).toEqual('2003-09-10 03-02-04');
|
||||
|
||||
expect(date('20030910T030204', format)).toEqual('2003-09-10 03-02-04');
|
||||
expect(date('2003-09-10T13Z', format)).toEqual('2003-09 00');
|
||||
|
||||
//no time
|
||||
expect(date('2003-09-10', format)).toEqual('2003-09-10 00-00-00');
|
||||
expect(date('2003-09-10', format)).toEqual('2003-09 00');
|
||||
});
|
||||
|
||||
it('should support different degrees of subsecond precision', function () {
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
|
||||
describe('Filter: limitTo', function() {
|
||||
var items;
|
||||
var str
|
||||
var limitTo;
|
||||
|
||||
beforeEach(inject(function($filter) {
|
||||
items = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
|
||||
str = "tuvwxyz";
|
||||
limitTo = $filter('limitTo');
|
||||
}));
|
||||
|
||||
@@ -15,16 +13,12 @@ describe('Filter: limitTo', function() {
|
||||
it('should return the first X items when X is positive', function() {
|
||||
expect(limitTo(items, 3)).toEqual(['a', 'b', 'c']);
|
||||
expect(limitTo(items, '3')).toEqual(['a', 'b', 'c']);
|
||||
expect(limitTo(str, 3)).toEqual("tuv");
|
||||
expect(limitTo(str, '3')).toEqual("tuv");
|
||||
});
|
||||
|
||||
|
||||
it('should return the last X items when X is negative', function() {
|
||||
expect(limitTo(items, -3)).toEqual(['f', 'g', 'h']);
|
||||
expect(limitTo(items, '-3')).toEqual(['f', 'g', 'h']);
|
||||
expect(limitTo(str, -3)).toEqual("xyz");
|
||||
expect(limitTo(str, '-3')).toEqual("xyz");
|
||||
});
|
||||
|
||||
|
||||
@@ -36,17 +30,11 @@ describe('Filter: limitTo', function() {
|
||||
expect(limitTo(items, undefined)).toEqual([]);
|
||||
});
|
||||
|
||||
it('should return an empty string when X cannot be parsed', function() {
|
||||
expect(limitTo(str, 'bogus')).toEqual("");
|
||||
expect(limitTo(str, 'null')).toEqual("");
|
||||
expect(limitTo(str, 'undefined')).toEqual("");
|
||||
expect(limitTo(str, null)).toEqual("");
|
||||
expect(limitTo(str, undefined)).toEqual("");
|
||||
});
|
||||
|
||||
|
||||
it('should return input if not String or Array', function() {
|
||||
expect(limitTo(1,1)).toEqual(1);
|
||||
it('should return an empty array when input is not Array type', function() {
|
||||
expect(limitTo('bogus', 1)).toEqual('bogus');
|
||||
expect(limitTo(null, 1)).toEqual(null);
|
||||
expect(limitTo(undefined, 1)).toEqual(undefined);
|
||||
expect(limitTo(null, 1)).toEqual(null);
|
||||
expect(limitTo(undefined, 1)).toEqual(undefined);
|
||||
expect(limitTo({}, 1)).toEqual({});
|
||||
@@ -54,18 +42,11 @@ describe('Filter: limitTo', function() {
|
||||
|
||||
|
||||
it('should return a copy of input array if X is exceeds array length', function () {
|
||||
expect(limitTo(items, 9)).toEqual(items);
|
||||
expect(limitTo(items, 19)).toEqual(items);
|
||||
expect(limitTo(items, '9')).toEqual(items);
|
||||
expect(limitTo(items, -9)).toEqual(items);
|
||||
expect(limitTo(items, '-9')).toEqual(items);
|
||||
|
||||
expect(limitTo(items, 9)).not.toBe(items);
|
||||
});
|
||||
|
||||
it('should return the entire string if X exceeds input length', function() {
|
||||
expect(limitTo(str, 9)).toEqual(str);
|
||||
expect(limitTo(str, '9')).toEqual(str);
|
||||
expect(limitTo(str, -9)).toEqual(str);
|
||||
expect(limitTo(str, '-9')).toEqual(str);
|
||||
})
|
||||
});
|
||||
|
||||
@@ -138,24 +138,6 @@ describe('$httpBackend', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should set responseType and return xhr.response', function() {
|
||||
$backend('GET', '/whatever', null, callback, {}, null, null, 'blob');
|
||||
|
||||
var xhrInstance = MockXhr.$$lastInstance;
|
||||
expect(xhrInstance.responseType).toBe('blob');
|
||||
|
||||
callback.andCallFake(function(status, response) {
|
||||
expect(response).toBe(xhrInstance.response);
|
||||
});
|
||||
|
||||
xhrInstance.response = {some: 'object'};
|
||||
xhrInstance.readyState = 4;
|
||||
xhrInstance.onreadystatechange();
|
||||
|
||||
expect(callback).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
|
||||
describe('JSONP', function() {
|
||||
|
||||
var SCRIPT_URL = /([^\?]*)\?cb=angular\.callbacks\.(.*)/;
|
||||
|
||||
+13
-88
@@ -144,26 +144,9 @@ describe('$http', function() {
|
||||
|
||||
|
||||
it('should jsonify objects in params map', inject(function($httpBackend, $http) {
|
||||
$httpBackend.expect('GET', '/url?a=1&b=%7B%22c%22:3%7D').respond('');
|
||||
$httpBackend.expect('GET', '/url?a=1&b=%7B%22c%22%3A3%7D').respond('');
|
||||
$http({url: '/url', params: {a:1, b:{c:3}}, method: 'GET'});
|
||||
}));
|
||||
|
||||
|
||||
it('should expand arrays in params map', inject(function($httpBackend, $http) {
|
||||
$httpBackend.expect('GET', '/url?a=1&a=2&a=3').respond('');
|
||||
$http({url: '/url', params: {a: [1,2,3]}, method: 'GET'});
|
||||
}));
|
||||
|
||||
|
||||
it('should not encode @ in url params', function() {
|
||||
//encodeURIComponent is too agressive and doesn't follow http://www.ietf.org/rfc/rfc3986.txt
|
||||
//with regards to the character set (pchar) allowed in path segments
|
||||
//so we need this test to make sure that we don't over-encode the params and break stuff
|
||||
//like buzz api which uses @self
|
||||
|
||||
$httpBackend.expect('GET', '/Path?!do%26h=g%3Da+h&:bar=$baz@1').respond('');
|
||||
$http({url: '/Path', params: {':bar': '$baz@1', '!do&h': 'g=a h'}, method: 'GET'});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -388,7 +371,8 @@ describe('$http', function() {
|
||||
|
||||
it('should set default headers for GET request', function() {
|
||||
$httpBackend.expect('GET', '/url', undefined, function(headers) {
|
||||
return headers['Accept'] == 'application/json, text/plain, */*';
|
||||
return headers['Accept'] == 'application/json, text/plain, */*' &&
|
||||
headers['X-Requested-With'] == 'XMLHttpRequest';
|
||||
}).respond('');
|
||||
|
||||
$http({url: '/url', method: 'GET', headers: {}});
|
||||
@@ -399,6 +383,7 @@ describe('$http', function() {
|
||||
it('should set default headers for POST request', function() {
|
||||
$httpBackend.expect('POST', '/url', 'messageBody', function(headers) {
|
||||
return headers['Accept'] == 'application/json, text/plain, */*' &&
|
||||
headers['X-Requested-With'] == 'XMLHttpRequest' &&
|
||||
headers['Content-Type'] == 'application/json;charset=utf-8';
|
||||
}).respond('');
|
||||
|
||||
@@ -410,6 +395,7 @@ describe('$http', function() {
|
||||
it('should set default headers for PUT request', function() {
|
||||
$httpBackend.expect('PUT', '/url', 'messageBody', function(headers) {
|
||||
return headers['Accept'] == 'application/json, text/plain, */*' &&
|
||||
headers['X-Requested-With'] == 'XMLHttpRequest' &&
|
||||
headers['Content-Type'] == 'application/json;charset=utf-8';
|
||||
}).respond('');
|
||||
|
||||
@@ -420,7 +406,8 @@ describe('$http', function() {
|
||||
|
||||
it('should set default headers for custom HTTP method', function() {
|
||||
$httpBackend.expect('FOO', '/url', undefined, function(headers) {
|
||||
return headers['Accept'] == 'application/json, text/plain, */*';
|
||||
return headers['Accept'] == 'application/json, text/plain, */*' &&
|
||||
headers['X-Requested-With'] == 'XMLHttpRequest';
|
||||
}).respond('');
|
||||
|
||||
$http({url: '/url', method: 'FOO', headers: {}});
|
||||
@@ -431,6 +418,7 @@ describe('$http', function() {
|
||||
it('should override default headers with custom', function() {
|
||||
$httpBackend.expect('POST', '/url', 'messageBody', function(headers) {
|
||||
return headers['Accept'] == 'Rewritten' &&
|
||||
headers['X-Requested-With'] == 'XMLHttpRequest' &&
|
||||
headers['Content-Type'] == 'Rewritten';
|
||||
}).respond('');
|
||||
|
||||
@@ -441,17 +429,6 @@ describe('$http', function() {
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('should not set XSRF cookie for cross-domain requests', inject(function($browser) {
|
||||
$browser.cookies('XSRF-TOKEN', 'secret');
|
||||
$browser.url('http://host.com/base');
|
||||
$httpBackend.expect('GET', 'http://www.test.com/url', undefined, function(headers) {
|
||||
return headers['X-XSRF-TOKEN'] === undefined;
|
||||
}).respond('');
|
||||
|
||||
$http({url: 'http://www.test.com/url', method: 'GET', headers: {}});
|
||||
$httpBackend.flush();
|
||||
}));
|
||||
|
||||
|
||||
it('should not send Content-Type header if request data/body is undefined', function() {
|
||||
$httpBackend.expect('POST', '/url', undefined, function(headers) {
|
||||
@@ -464,27 +441,22 @@ describe('$http', function() {
|
||||
|
||||
|
||||
it('should set the XSRF cookie into a XSRF header', inject(function($browser) {
|
||||
function checkXSRF(secret, header) {
|
||||
function checkXSRF(secret) {
|
||||
return function(headers) {
|
||||
return headers[header || 'X-XSRF-TOKEN'] == secret;
|
||||
return headers['X-XSRF-TOKEN'] == secret;
|
||||
};
|
||||
}
|
||||
|
||||
$browser.cookies('XSRF-TOKEN', 'secret');
|
||||
$browser.cookies('aCookie', 'secret2');
|
||||
$httpBackend.expect('GET', '/url', undefined, checkXSRF('secret')).respond('');
|
||||
$httpBackend.expect('POST', '/url', undefined, checkXSRF('secret')).respond('');
|
||||
$httpBackend.expect('PUT', '/url', undefined, checkXSRF('secret')).respond('');
|
||||
$httpBackend.expect('DELETE', '/url', undefined, checkXSRF('secret')).respond('');
|
||||
$httpBackend.expect('GET', '/url', undefined, checkXSRF('secret', 'aHeader')).respond('');
|
||||
$httpBackend.expect('GET', '/url', undefined, checkXSRF('secret2')).respond('');
|
||||
|
||||
$http({url: '/url', method: 'GET'});
|
||||
$http({url: '/url', method: 'POST', headers: {'S-ome': 'Header'}});
|
||||
$http({url: '/url', method: 'PUT', headers: {'Another': 'Header'}});
|
||||
$http({url: '/url', method: 'DELETE', headers: {}});
|
||||
$http({url: '/url', method: 'GET', xsrfHeaderName: 'aHeader'})
|
||||
$http({url: '/url', method: 'GET', xsrfCookieName: 'aCookie'})
|
||||
|
||||
$httpBackend.flush();
|
||||
}));
|
||||
@@ -987,13 +959,12 @@ describe('$http', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should pass timeout, withCredentials and responseType', function() {
|
||||
it('should pass timeout and withCredentials', function() {
|
||||
var $httpBackend = jasmine.createSpy('$httpBackend');
|
||||
|
||||
$httpBackend.andCallFake(function(m, u, d, c, h, timeout, withCredentials, responseType) {
|
||||
$httpBackend.andCallFake(function(m, u, d, c, h, timeout, withCredentials) {
|
||||
expect(timeout).toBe(12345);
|
||||
expect(withCredentials).toBe(true);
|
||||
expect(responseType).toBe('json');
|
||||
});
|
||||
|
||||
module(function($provide) {
|
||||
@@ -1001,56 +972,10 @@ describe('$http', function() {
|
||||
});
|
||||
|
||||
inject(function($http) {
|
||||
$http({
|
||||
method: 'GET', url: 'some.html', timeout: 12345, withCredentials: true, responseType: 'json'
|
||||
});
|
||||
$http({method: 'GET', url: 'some.html', timeout: 12345, withCredentials: true});
|
||||
expect($httpBackend).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
$httpBackend.verifyNoOutstandingExpectation = noop;
|
||||
});
|
||||
|
||||
|
||||
it('should use withCredentials from default', function() {
|
||||
var $httpBackend = jasmine.createSpy('$httpBackend');
|
||||
|
||||
$httpBackend.andCallFake(function(m, u, d, c, h, timeout, withCredentials, responseType) {
|
||||
expect(withCredentials).toBe(true);
|
||||
});
|
||||
|
||||
module(function($provide) {
|
||||
$provide.value('$httpBackend', $httpBackend);
|
||||
});
|
||||
|
||||
inject(function($http) {
|
||||
$http.defaults.withCredentials = true;
|
||||
$http({
|
||||
method: 'GET', url: 'some.html', timeout: 12345, responseType: 'json'
|
||||
});
|
||||
expect($httpBackend).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
$httpBackend.verifyNoOutstandingExpectation = noop;
|
||||
});
|
||||
|
||||
describe('isSameDomain', function() {
|
||||
it('should support various combinations of urls', function() {
|
||||
expect(isSameDomain('path/morepath',
|
||||
'http://www.adomain.com')).toBe(true);
|
||||
expect(isSameDomain('http://www.adomain.com/path',
|
||||
'http://www.adomain.com')).toBe(true);
|
||||
expect(isSameDomain('//www.adomain.com/path',
|
||||
'http://www.adomain.com')).toBe(true);
|
||||
expect(isSameDomain('//www.adomain.com/path',
|
||||
'https://www.adomain.com')).toBe(true);
|
||||
expect(isSameDomain('//www.adomain.com/path',
|
||||
'http://www.adomain.com:1234')).toBe(false);
|
||||
expect(isSameDomain('https://www.adomain.com/path',
|
||||
'http://www.adomain.com')).toBe(false);
|
||||
expect(isSameDomain('http://www.adomain.com:1234/path',
|
||||
'http://www.adomain.com')).toBe(false);
|
||||
expect(isSameDomain('http://www.anotherdomain.com/path',
|
||||
'http://www.adomain.com')).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,29 +26,6 @@ describe('$interpolate', function() {
|
||||
expect($interpolate('{{ false }}')()).toEqual('false');
|
||||
}));
|
||||
|
||||
it('should rethrow exceptions', inject(function($interpolate, $rootScope) {
|
||||
$rootScope.err = function () {
|
||||
throw new Error('oops');
|
||||
};
|
||||
expect(function () {
|
||||
$interpolate('{{err()}}')($rootScope);
|
||||
}).toThrow('Error while interpolating: {{err()}}\nError: oops');
|
||||
}));
|
||||
|
||||
it('should stop interpolation when encountering an exception', inject(function($interpolate, $compile, $rootScope) {
|
||||
$rootScope.err = function () {
|
||||
throw new Error('oops');
|
||||
};
|
||||
var dom = jqLite('<div>{{1 + 1}}</div><div>{{err()}}</div><div>{{1 + 2}}</div>');
|
||||
$compile(dom)($rootScope);
|
||||
expect(function () {
|
||||
$rootScope.$apply();
|
||||
}).toThrow('Error while interpolating: {{err()}}\nError: oops');
|
||||
expect(dom[0].innerHTML).toEqual('2');
|
||||
expect(dom[1].innerHTML).toEqual('{{err()}}');
|
||||
expect(dom[2].innerHTML).toEqual('{{1 + 2}}');
|
||||
}));
|
||||
|
||||
|
||||
it('should return interpolation function', inject(function($interpolate, $rootScope) {
|
||||
$rootScope.name = 'Misko';
|
||||
|
||||
+8
-45
@@ -1,24 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
function initService(debugEnabled) {
|
||||
return module(function($logProvider){
|
||||
$logProvider.debugEnabled(debugEnabled);
|
||||
});
|
||||
}
|
||||
|
||||
describe('$log', function() {
|
||||
var $window, logger, log, warn, info, error, debug;
|
||||
var $window, logger, log, warn, info, error;
|
||||
|
||||
|
||||
|
||||
beforeEach(module(function($provide){
|
||||
$window = {navigator: {}, document: {}};
|
||||
$window = {navigator: {}};
|
||||
logger = '';
|
||||
log = function() { logger+= 'log;'; };
|
||||
warn = function() { logger+= 'warn;'; };
|
||||
info = function() { logger+= 'info;'; };
|
||||
error = function() { logger+= 'error;'; };
|
||||
debug = function() { logger+= 'debug;'; };
|
||||
|
||||
$provide.provider('$log', $LogProvider);
|
||||
$provide.value('$exceptionHandler', angular.mock.rethrow);
|
||||
@@ -30,16 +23,14 @@ describe('$log', function() {
|
||||
$window.console = {log: log,
|
||||
warn: warn,
|
||||
info: info,
|
||||
error: error,
|
||||
debug: debug};
|
||||
error: error};
|
||||
},
|
||||
function($log) {
|
||||
$log.log();
|
||||
$log.warn();
|
||||
$log.info();
|
||||
$log.error();
|
||||
$log.debug();
|
||||
expect(logger).toEqual('log;warn;info;error;debug;');
|
||||
expect(logger).toEqual('log;warn;info;error;');
|
||||
}
|
||||
));
|
||||
|
||||
@@ -53,8 +44,7 @@ describe('$log', function() {
|
||||
$log.warn();
|
||||
$log.info();
|
||||
$log.error();
|
||||
$log.debug();
|
||||
expect(logger).toEqual('log;log;log;log;log;');
|
||||
expect(logger).toEqual('log;log;log;log;');
|
||||
}
|
||||
));
|
||||
|
||||
@@ -65,7 +55,6 @@ describe('$log', function() {
|
||||
$log.warn();
|
||||
$log.info();
|
||||
$log.error();
|
||||
$log.debug();
|
||||
}
|
||||
));
|
||||
|
||||
@@ -75,48 +64,22 @@ describe('$log', function() {
|
||||
log.apply = log.call =
|
||||
warn.apply = warn.call =
|
||||
info.apply = info.call =
|
||||
error.apply = error.call =
|
||||
debug.apply = debug.call = null;
|
||||
error.apply = error.call = null;
|
||||
|
||||
$window.console = {log: log,
|
||||
warn: warn,
|
||||
info: info,
|
||||
error: error,
|
||||
debug: debug};
|
||||
error: error};
|
||||
},
|
||||
function($log) {
|
||||
$log.log.apply($log);
|
||||
$log.warn.apply($log);
|
||||
$log.info.apply($log);
|
||||
$log.error.apply($log);
|
||||
$log.debug.apply($log);
|
||||
expect(logger).toEqual('log;warn;info;error;debug;');
|
||||
expect(logger).toEqual('log;warn;info;error;');
|
||||
})
|
||||
);
|
||||
|
||||
describe("$log.debug", function () {
|
||||
|
||||
beforeEach(initService(false));
|
||||
|
||||
it("should skip debugging output if disabled", inject(
|
||||
function(){
|
||||
$window.console = {log: log,
|
||||
warn: warn,
|
||||
info: info,
|
||||
error: error,
|
||||
debug: debug};
|
||||
},
|
||||
function($log) {
|
||||
$log.log();
|
||||
$log.warn();
|
||||
$log.info();
|
||||
$log.error();
|
||||
$log.debug();
|
||||
expect(logger).toEqual('log;warn;info;error;');
|
||||
}
|
||||
));
|
||||
|
||||
});
|
||||
|
||||
describe('$log.error', function() {
|
||||
var e, $log, errorArgs;
|
||||
|
||||
+3
-81
@@ -91,8 +91,8 @@ describe('parser', function() {
|
||||
expect(tokens[1].text).toEqual('b');
|
||||
});
|
||||
|
||||
it('should tokenize relation and equality', function() {
|
||||
var tokens = lex("! == != < > <= >= === !==");
|
||||
it('should tokenize relation', function() {
|
||||
var tokens = lex("! == != < > <= >=");
|
||||
expect(tokens[0].text).toEqual('!');
|
||||
expect(tokens[1].text).toEqual('==');
|
||||
expect(tokens[2].text).toEqual('!=');
|
||||
@@ -100,8 +100,6 @@ describe('parser', function() {
|
||||
expect(tokens[4].text).toEqual('>');
|
||||
expect(tokens[5].text).toEqual('<=');
|
||||
expect(tokens[6].text).toEqual('>=');
|
||||
expect(tokens[7].text).toEqual('===');
|
||||
expect(tokens[8].text).toEqual('!==');
|
||||
});
|
||||
|
||||
it('should tokenize statements', function() {
|
||||
@@ -199,20 +197,12 @@ describe('parser', function() {
|
||||
expect(scope.$eval("false")).toBeFalsy();
|
||||
expect(scope.$eval("!true")).toBeFalsy();
|
||||
expect(scope.$eval("1==1")).toBeTruthy();
|
||||
expect(scope.$eval("1==true")).toBeTruthy();
|
||||
expect(scope.$eval("1===1")).toBeTruthy();
|
||||
expect(scope.$eval("1==='1'")).toBeFalsy();
|
||||
expect(scope.$eval("1===true")).toBeFalsy();
|
||||
expect(scope.$eval("'true'===true")).toBeFalsy();
|
||||
expect(scope.$eval("1!==2")).toBeTruthy();
|
||||
expect(scope.$eval("1!=='1'")).toBeTruthy();
|
||||
expect(scope.$eval("1!=2")).toBeTruthy();
|
||||
expect(scope.$eval("1<2")).toBeTruthy();
|
||||
expect(scope.$eval("1<=1")).toBeTruthy();
|
||||
expect(scope.$eval("1>2")).toEqual(1>2);
|
||||
expect(scope.$eval("2>=1")).toEqual(2>=1);
|
||||
expect(scope.$eval("true==2<3")).toEqual(true == 2<3);
|
||||
expect(scope.$eval("true===2<3")).toEqual(true === 2<3);
|
||||
expect(scope.$eval("true==2<3")).toEqual(true === 2<3);
|
||||
});
|
||||
|
||||
it('should parse logical', function() {
|
||||
@@ -671,74 +661,6 @@ describe('parser', function() {
|
||||
expect($parse('a.b')({a: {b: 0}}, {a: null})).toEqual(undefined);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('literal', function() {
|
||||
it('should mark scalar value expressions as literal', inject(function($parse) {
|
||||
expect($parse('0').literal).toBe(true);
|
||||
expect($parse('"hello"').literal).toBe(true);
|
||||
expect($parse('true').literal).toBe(true);
|
||||
expect($parse('false').literal).toBe(true);
|
||||
expect($parse('null').literal).toBe(true);
|
||||
expect($parse('undefined').literal).toBe(true);
|
||||
}));
|
||||
|
||||
it('should mark array expressions as literal', inject(function($parse) {
|
||||
expect($parse('[]').literal).toBe(true);
|
||||
expect($parse('[1, 2, 3]').literal).toBe(true);
|
||||
expect($parse('[1, identifier]').literal).toBe(true);
|
||||
}));
|
||||
|
||||
it('should mark object expressions as literal', inject(function($parse) {
|
||||
expect($parse('{}').literal).toBe(true);
|
||||
expect($parse('{x: 1}').literal).toBe(true);
|
||||
expect($parse('{foo: bar}').literal).toBe(true);
|
||||
}));
|
||||
|
||||
it('should not mark function calls or operator expressions as literal', inject(function($parse) {
|
||||
expect($parse('1 + 1').literal).toBe(false);
|
||||
expect($parse('call()').literal).toBe(false);
|
||||
expect($parse('[].length').literal).toBe(false);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('constant', function() {
|
||||
it('should mark scalar value expressions as constant', inject(function($parse) {
|
||||
expect($parse('12.3').constant).toBe(true);
|
||||
expect($parse('"string"').constant).toBe(true);
|
||||
expect($parse('true').constant).toBe(true);
|
||||
expect($parse('false').constant).toBe(true);
|
||||
expect($parse('null').constant).toBe(true);
|
||||
expect($parse('undefined').constant).toBe(true);
|
||||
}));
|
||||
|
||||
it('should mark arrays as constant if they only contain constant elements', inject(function($parse) {
|
||||
expect($parse('[]').constant).toBe(true);
|
||||
expect($parse('[1, 2, 3]').constant).toBe(true);
|
||||
expect($parse('["string", null]').constant).toBe(true);
|
||||
expect($parse('[[]]').constant).toBe(true);
|
||||
expect($parse('[1, [2, 3], {4: 5}]').constant).toBe(true);
|
||||
}));
|
||||
|
||||
it('should not mark arrays as constant if they contain any non-constant elements', inject(function($parse) {
|
||||
expect($parse('[foo]').constant).toBe(false);
|
||||
expect($parse('[x + 1]').constant).toBe(false);
|
||||
expect($parse('[bar[0]]').constant).toBe(false);
|
||||
}));
|
||||
|
||||
it('should mark complex expressions involving constant values as constant', inject(function($parse) {
|
||||
expect($parse('!true').constant).toBe(true);
|
||||
expect($parse('1 - 1').constant).toBe(true);
|
||||
expect($parse('"foo" + "bar"').constant).toBe(true);
|
||||
expect($parse('5 != null').constant).toBe(true);
|
||||
expect($parse('{standard: 4/3, wide: 16/9}').constant).toBe(true);
|
||||
}));
|
||||
|
||||
it('should not mark any expression involving variables or function calls as constant', inject(function($parse) {
|
||||
expect($parse('true.toString()').constant).toBe(false);
|
||||
expect($parse('foo(1, 2, 3)').constant).toBe(false);
|
||||
expect($parse('"name" + id').constant).toBe(false);
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -99,14 +99,6 @@ describe('Scope', function() {
|
||||
expect(spy).wasCalled();
|
||||
}));
|
||||
|
||||
it('should not keep constant expressions on watch queue', inject(function($rootScope) {
|
||||
$rootScope.$watch('1 + 1', function() {});
|
||||
expect($rootScope.$$watchers.length).toEqual(1);
|
||||
$rootScope.$digest();
|
||||
|
||||
expect($rootScope.$$watchers.length).toEqual(0);
|
||||
}));
|
||||
|
||||
|
||||
it('should delegate exceptions', function() {
|
||||
module(function($exceptionHandlerProvider) {
|
||||
@@ -127,14 +119,10 @@ describe('Scope', function() {
|
||||
var log = '';
|
||||
$rootScope.$watch('a', function() { log += 'a'; });
|
||||
$rootScope.$watch('b', function() { log += 'b'; });
|
||||
// constant expressions have slightly different handling,
|
||||
// let's ensure they are kept in the same list as others
|
||||
$rootScope.$watch('1', function() { log += '1'; });
|
||||
$rootScope.$watch('c', function() { log += 'c'; });
|
||||
$rootScope.$watch('2', function() { log += '2'; });
|
||||
$rootScope.a = $rootScope.b = $rootScope.c = 1;
|
||||
$rootScope.$digest();
|
||||
expect(log).toEqual('ab1c2');
|
||||
expect(log).toEqual('abc');
|
||||
}));
|
||||
|
||||
|
||||
@@ -469,7 +457,7 @@ describe('Scope', function() {
|
||||
child.$evalAsync(function(scope) { log += 'child.async;'; });
|
||||
child.$watch('value', function() { log += 'child.$digest;'; });
|
||||
$rootScope.$digest();
|
||||
expect(log).toEqual('parent.async;child.async;parent.$digest;child.$digest;');
|
||||
expect(log).toEqual('parent.async;parent.$digest;child.async;child.$digest;');
|
||||
}));
|
||||
|
||||
it('should cause a $digest rerun', inject(function($rootScope) {
|
||||
|
||||
@@ -59,63 +59,6 @@ describe('$route', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should route and fire change event when catch-all params are used', function() {
|
||||
var log = '',
|
||||
lastRoute,
|
||||
nextRoute;
|
||||
|
||||
module(function($routeProvider) {
|
||||
$routeProvider.when('/Book1/:book/Chapter/:chapter/*highlight/edit',
|
||||
{controller: noop, templateUrl: 'Chapter.html'});
|
||||
$routeProvider.when('/Book2/:book/*highlight/Chapter/:chapter',
|
||||
{controller: noop, templateUrl: 'Chapter.html'});
|
||||
$routeProvider.when('/Blank', {});
|
||||
});
|
||||
inject(function($route, $location, $rootScope) {
|
||||
$rootScope.$on('$routeChangeStart', function(event, next, current) {
|
||||
log += 'before();';
|
||||
expect(current).toBe($route.current);
|
||||
lastRoute = current;
|
||||
nextRoute = next;
|
||||
});
|
||||
$rootScope.$on('$routeChangeSuccess', function(event, current, last) {
|
||||
log += 'after();';
|
||||
expect(current).toBe($route.current);
|
||||
expect(lastRoute).toBe(last);
|
||||
expect(nextRoute).toBe(current);
|
||||
});
|
||||
|
||||
$location.path('/Book1/Moby/Chapter/Intro/one/edit').search('p=123');
|
||||
$rootScope.$digest();
|
||||
$httpBackend.flush();
|
||||
expect(log).toEqual('before();after();');
|
||||
expect($route.current.params).toEqual({book:'Moby', chapter:'Intro', highlight:'one', p:'123'});
|
||||
|
||||
log = '';
|
||||
$location.path('/Blank').search('ignore');
|
||||
$rootScope.$digest();
|
||||
expect(log).toEqual('before();after();');
|
||||
expect($route.current.params).toEqual({ignore:true});
|
||||
|
||||
log = '';
|
||||
$location.path('/Book1/Moby/Chapter/Intro/one/two/edit').search('p=123');
|
||||
$rootScope.$digest();
|
||||
expect(log).toEqual('before();after();');
|
||||
expect($route.current.params).toEqual({book:'Moby', chapter:'Intro', highlight:'one/two', p:'123'});
|
||||
|
||||
log = '';
|
||||
$location.path('/Book2/Moby/one/two/Chapter/Intro').search('p=123');
|
||||
$rootScope.$digest();
|
||||
expect(log).toEqual('before();after();');
|
||||
expect($route.current.params).toEqual({book:'Moby', chapter:'Intro', highlight:'one/two', p:'123'});
|
||||
|
||||
log = '';
|
||||
$location.path('/NONE');
|
||||
$rootScope.$digest();
|
||||
expect(log).toEqual('before();after();');
|
||||
expect($route.current).toEqual(null);
|
||||
});
|
||||
});
|
||||
|
||||
it('should not change route when location is canceled', function() {
|
||||
module(function($routeProvider) {
|
||||
@@ -772,53 +715,6 @@ describe('$route', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should allow using a function as a template', function() {
|
||||
var customTemplateWatcher = jasmine.createSpy('customTemplateWatcher');
|
||||
|
||||
function customTemplateFn(routePathParams) {
|
||||
customTemplateWatcher(routePathParams);
|
||||
expect(routePathParams).toEqual({id: 'id3'});
|
||||
return '<h1>' + routePathParams.id + '</h1>';
|
||||
}
|
||||
|
||||
module(function($routeProvider){
|
||||
$routeProvider.when('/bar/:id/:subid/:subsubid', {templateUrl: 'bar.html'});
|
||||
$routeProvider.when('/foo/:id', {template: customTemplateFn});
|
||||
});
|
||||
|
||||
inject(function($route, $location, $rootScope) {
|
||||
$location.path('/foo/id3');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(customTemplateWatcher).toHaveBeenCalledWith({id: 'id3'});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should allow using a function as a templateUrl', function() {
|
||||
var customTemplateUrlWatcher = jasmine.createSpy('customTemplateUrlWatcher');
|
||||
|
||||
function customTemplateUrlFn(routePathParams) {
|
||||
customTemplateUrlWatcher(routePathParams);
|
||||
expect(routePathParams).toEqual({id: 'id3'});
|
||||
return 'foo.html';
|
||||
}
|
||||
|
||||
module(function($routeProvider){
|
||||
$routeProvider.when('/bar/:id/:subid/:subsubid', {templateUrl: 'bar.html'});
|
||||
$routeProvider.when('/foo/:id', {templateUrl: customTemplateUrlFn});
|
||||
});
|
||||
|
||||
inject(function($route, $location, $rootScope) {
|
||||
$location.path('/foo/id3');
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(customTemplateUrlWatcher).toHaveBeenCalledWith({id: 'id3'});
|
||||
expect($route.current.loadedTemplateUrl).toEqual('foo.html');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('reload', function() {
|
||||
|
||||
it('should reload even if reloadOnSearch is false', function() {
|
||||
|
||||
+6
-24
@@ -2,10 +2,9 @@
|
||||
|
||||
describe('$sniffer', function() {
|
||||
|
||||
function sniffer($window, $document) {
|
||||
function sniffer($window) {
|
||||
$window.navigator = {};
|
||||
$document = jqLite($document || {});
|
||||
return new $SnifferProvider().$get[2]($window, $document);
|
||||
return new $SnifferProvider().$get[1]($window);
|
||||
}
|
||||
|
||||
describe('history', function() {
|
||||
@@ -21,15 +20,15 @@ describe('$sniffer', function() {
|
||||
|
||||
describe('hashchange', function() {
|
||||
it('should be true if onhashchange property defined', function() {
|
||||
expect(sniffer({onhashchange: true}, {}).hashchange).toBe(true);
|
||||
expect(sniffer({onhashchange: true, document: {}}).hashchange).toBe(true);
|
||||
});
|
||||
|
||||
it('should be false if onhashchange property not defined', function() {
|
||||
expect(sniffer({}, {}).hashchange).toBe(false);
|
||||
expect(sniffer({document: {}}).hashchange).toBe(false);
|
||||
});
|
||||
|
||||
it('should be false if documentMode is 7 (IE8 comp mode)', function() {
|
||||
expect(sniffer({onhashchange: true}, {documentMode: 7}).hashchange).toBe(false);
|
||||
expect(sniffer({onhashchange: true, document: {documentMode: 7}}).hashchange).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -43,7 +42,7 @@ describe('$sniffer', function() {
|
||||
if (elm === 'div') return mockDivElement;
|
||||
});
|
||||
|
||||
$sniffer = sniffer({}, mockDocument);
|
||||
$sniffer = sniffer({document: mockDocument});
|
||||
});
|
||||
|
||||
|
||||
@@ -79,21 +78,4 @@ describe('$sniffer', function() {
|
||||
expect($sniffer.hasEvent('input')).toBe((msie == 9) ? false : true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('csp', function() {
|
||||
it('should be false if document.securityPolicy.isActive not available', function() {
|
||||
expect(sniffer({}, {}).csp).toBe(false);
|
||||
});
|
||||
|
||||
|
||||
it('should use document.securityPolicy.isActive if available', function() {
|
||||
var createDocumentWithCSP = function(csp) {
|
||||
return {securityPolicy: {isActive: csp}};
|
||||
};
|
||||
|
||||
expect(sniffer({}, createDocumentWithCSP(false)).csp).toBe(false);
|
||||
expect(sniffer({}, createDocumentWithCSP(true)).csp).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Vendored
-24
@@ -109,13 +109,6 @@ describe('ngMock', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should fake getMilliseconds method', function() {
|
||||
expect(new angular.mock.TzDate(0, '2010-09-03T23:05:08.003Z').getMilliseconds()).toBe(3);
|
||||
expect(new angular.mock.TzDate(0, '2010-09-03T23:05:08.023Z').getMilliseconds()).toBe(23);
|
||||
expect(new angular.mock.TzDate(0, '2010-09-03T23:05:08.123Z').getMilliseconds()).toBe(123);
|
||||
});
|
||||
|
||||
|
||||
it('should create a date representing new year in Bratislava', function() {
|
||||
var newYearInBratislava = new angular.mock.TzDate(-1, '2009-12-31T23:00:00.000Z');
|
||||
expect(newYearInBratislava.getTimezoneOffset()).toBe(-60);
|
||||
@@ -124,7 +117,6 @@ describe('ngMock', function() {
|
||||
expect(newYearInBratislava.getDate()).toBe(1);
|
||||
expect(newYearInBratislava.getHours()).toBe(0);
|
||||
expect(newYearInBratislava.getMinutes()).toBe(0);
|
||||
expect(newYearInBratislava.getSeconds()).toBe(0);
|
||||
});
|
||||
|
||||
|
||||
@@ -335,22 +327,6 @@ describe('ngMock', function() {
|
||||
$timeout.flush();
|
||||
expect(logger).toEqual(['t1', 't3', 't2']);
|
||||
}));
|
||||
|
||||
|
||||
it('should throw an exception when not flushed', inject(function($timeout){
|
||||
$timeout(noop);
|
||||
|
||||
var expectedError = 'Deferred tasks to flush (1): {id: 0, time: 0}';
|
||||
expect(function() {$timeout.verifyNoPendingTasks();}).toThrow(expectedError);
|
||||
}));
|
||||
|
||||
|
||||
it('should do nothing when all tasks have been flushed', inject(function($timeout) {
|
||||
$timeout(noop);
|
||||
|
||||
$timeout.flush();
|
||||
expect(function() {$timeout.verifyNoPendingTasks();}).not.toThrow();
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -14,14 +14,7 @@ describe("resource", function() {
|
||||
},
|
||||
patch: {
|
||||
method: 'PATCH'
|
||||
},
|
||||
conditionalPut: {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'If-None-Match': '*'
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
callback = jasmine.createSpy();
|
||||
}));
|
||||
@@ -119,21 +112,14 @@ describe("resource", function() {
|
||||
|
||||
|
||||
it('should not encode @ in url params', function() {
|
||||
//encodeURIComponent is too agressive and doesn't follow http://www.ietf.org/rfc/rfc3986.txt
|
||||
//with regards to the character set (pchar) allowed in path segments
|
||||
//so we need this test to make sure that we don't over-encode the params and break stuff like
|
||||
//buzz api which uses @self
|
||||
//encodeURIComponent is too agressive and doesn't follow http://www.ietf.org/rfc/rfc3986.txt
|
||||
//with regards to the character set (pchar) allowed in path segments
|
||||
//so we need this test to make sure that we don't over-encode the params and break stuff like
|
||||
//buzz api which uses @self
|
||||
|
||||
var R = $resource('/Path/:a');
|
||||
$httpBackend.expect('GET', '/Path/doh@fo%20o?!do%26h=g%3Da+h&:bar=$baz@1').respond('{}');
|
||||
R.get({a: 'doh@fo o', ':bar': '$baz@1', '!do&h': 'g=a h'});
|
||||
});
|
||||
|
||||
|
||||
it('should encode array params', function() {
|
||||
var R = $resource('/Path/:a');
|
||||
$httpBackend.expect('GET', '/Path/doh&foo?bar=baz1&bar=baz2').respond('{}');
|
||||
R.get({a: 'doh&foo', bar: ['baz1', 'baz2']});
|
||||
$httpBackend.expect('GET', '/Path/doh@fo%20o?!do%26h=g%3Da+h&:bar=$baz@1').respond('{}');
|
||||
R.get({a: 'doh@fo o', ':bar': '$baz@1', '!do&h': 'g=a h'});
|
||||
});
|
||||
|
||||
it('should allow relative paths in resource url', function () {
|
||||
@@ -239,15 +225,6 @@ describe("resource", function() {
|
||||
});
|
||||
|
||||
|
||||
it('should send correct headers', function() {
|
||||
$httpBackend.expectPUT('/CreditCard/123', undefined, function(headers) {
|
||||
return headers['If-None-Match'] == "*";
|
||||
}).respond({id:123});
|
||||
|
||||
CreditCard.conditionalPut({id: {key:123}});
|
||||
});
|
||||
|
||||
|
||||
it("should read partial resource", function() {
|
||||
$httpBackend.expect('GET', '/CreditCard').respond([{id:{key:123}}]);
|
||||
var ccs = CreditCard.query();
|
||||
@@ -283,7 +260,7 @@ describe("resource", function() {
|
||||
$httpBackend.expect('GET', '/CreditCard?key=value').respond([{id: 1}, {id: 2}]);
|
||||
|
||||
var ccs = CreditCard.query({key: 'value'}, callback);
|
||||
expect(ccs).toEqualData([]);
|
||||
expect(ccs).toEqual([]);
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
|
||||
$httpBackend.flush();
|
||||
@@ -400,35 +377,6 @@ describe("resource", function() {
|
||||
});
|
||||
|
||||
|
||||
it('should support dynamic default parameters (global)', function() {
|
||||
var currentGroup = 'students',
|
||||
Person = $resource('/Person/:group/:id', { group: function() { return currentGroup; }});
|
||||
|
||||
|
||||
$httpBackend.expect('GET', '/Person/students/fedor').respond({id: 'fedor', email: 'f@f.com'});
|
||||
|
||||
var fedor = Person.get({id: 'fedor'});
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(fedor).toEqualData({id: 'fedor', email: 'f@f.com'});
|
||||
});
|
||||
|
||||
|
||||
it('should support dynamic default parameters (action specific)', function() {
|
||||
var currentGroup = 'students',
|
||||
Person = $resource('/Person/:group/:id', {}, {
|
||||
fetch: {method: 'GET', params: {group: function() { return currentGroup; }}}
|
||||
});
|
||||
|
||||
$httpBackend.expect('GET', '/Person/students/fedor').respond({id: 'fedor', email: 'f@f.com'});
|
||||
|
||||
var fedor = Person.fetch({id: 'fedor'});
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(fedor).toEqualData({id: 'fedor', email: 'f@f.com'});
|
||||
});
|
||||
|
||||
|
||||
it('should exercise full stack', function() {
|
||||
var Person = $resource('/Person/:id');
|
||||
|
||||
@@ -439,210 +387,6 @@ describe("resource", function() {
|
||||
});
|
||||
|
||||
|
||||
describe('promise api', function() {
|
||||
|
||||
var $rootScope;
|
||||
|
||||
|
||||
beforeEach(inject(function(_$rootScope_) {
|
||||
$rootScope = _$rootScope_;
|
||||
}));
|
||||
|
||||
|
||||
describe('single resource', function() {
|
||||
|
||||
it('should add promise $then method to the result object', function() {
|
||||
$httpBackend.expect('GET', '/CreditCard/123').respond({id: 123, number: '9876'});
|
||||
var cc = CreditCard.get({id: 123});
|
||||
|
||||
cc.$then(callback);
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
|
||||
$httpBackend.flush();
|
||||
|
||||
var response = callback.mostRecentCall.args[0];
|
||||
|
||||
expect(response).toEqualData({
|
||||
data: {id: 123, number: '9876'},
|
||||
status: 200,
|
||||
config: {method: 'GET', data: undefined, url: '/CreditCard/123'},
|
||||
resource: {id: 123, number: '9876', $resolved: true}
|
||||
});
|
||||
expect(typeof response.resource.$save).toBe('function');
|
||||
});
|
||||
|
||||
|
||||
it('should keep $then around after promise resolution', function() {
|
||||
$httpBackend.expect('GET', '/CreditCard/123').respond({id: 123, number: '9876'});
|
||||
var cc = CreditCard.get({id: 123});
|
||||
|
||||
cc.$then(callback);
|
||||
$httpBackend.flush();
|
||||
|
||||
var response = callback.mostRecentCall.args[0];
|
||||
|
||||
callback.reset();
|
||||
|
||||
cc.$then(callback);
|
||||
$rootScope.$apply(); //flush async queue
|
||||
|
||||
expect(callback).toHaveBeenCalledOnceWith(response);
|
||||
});
|
||||
|
||||
|
||||
it('should allow promise chaining via $then method', function() {
|
||||
$httpBackend.expect('GET', '/CreditCard/123').respond({id: 123, number: '9876'});
|
||||
var cc = CreditCard.get({id: 123});
|
||||
|
||||
cc.$then(function(response) { return 'new value'; }).then(callback);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(callback).toHaveBeenCalledOnceWith('new value');
|
||||
});
|
||||
|
||||
|
||||
it('should allow error callback registration via $then method', function() {
|
||||
$httpBackend.expect('GET', '/CreditCard/123').respond(404, 'resource not found');
|
||||
var cc = CreditCard.get({id: 123});
|
||||
|
||||
cc.$then(null, callback);
|
||||
$httpBackend.flush();
|
||||
|
||||
var response = callback.mostRecentCall.args[0];
|
||||
|
||||
expect(response).toEqualData({
|
||||
data : 'resource not found',
|
||||
status : 404,
|
||||
config : { method : 'GET', data : undefined, url : '/CreditCard/123' }
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should add $resolved boolean field to the result object', function() {
|
||||
$httpBackend.expect('GET', '/CreditCard/123').respond({id: 123, number: '9876'});
|
||||
var cc = CreditCard.get({id: 123});
|
||||
|
||||
expect(cc.$resolved).toBe(false);
|
||||
|
||||
cc.$then(callback);
|
||||
expect(cc.$resolved).toBe(false);
|
||||
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(cc.$resolved).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
it('should set $resolved field to true when an error occurs', function() {
|
||||
$httpBackend.expect('GET', '/CreditCard/123').respond(404, 'resource not found');
|
||||
var cc = CreditCard.get({id: 123});
|
||||
|
||||
cc.$then(null, callback);
|
||||
$httpBackend.flush();
|
||||
expect(callback).toHaveBeenCalledOnce();
|
||||
expect(cc.$resolved).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('resource collection', function() {
|
||||
|
||||
it('should add promise $then method to the result object', function() {
|
||||
$httpBackend.expect('GET', '/CreditCard?key=value').respond([{id: 1}, {id: 2}]);
|
||||
var ccs = CreditCard.query({key: 'value'});
|
||||
|
||||
ccs.$then(callback);
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
|
||||
$httpBackend.flush();
|
||||
|
||||
var response = callback.mostRecentCall.args[0];
|
||||
|
||||
expect(response).toEqualData({
|
||||
data: [{id: 1}, {id :2}],
|
||||
status: 200,
|
||||
config: {method: 'GET', data: undefined, url: '/CreditCard', params: {key: 'value'}},
|
||||
resource: [ { id : 1 }, { id : 2 } ]
|
||||
});
|
||||
expect(typeof response.resource[0].$save).toBe('function');
|
||||
expect(typeof response.resource[1].$save).toBe('function');
|
||||
});
|
||||
|
||||
|
||||
it('should keep $then around after promise resolution', function() {
|
||||
$httpBackend.expect('GET', '/CreditCard?key=value').respond([{id: 1}, {id: 2}]);
|
||||
var ccs = CreditCard.query({key: 'value'});
|
||||
|
||||
ccs.$then(callback);
|
||||
$httpBackend.flush();
|
||||
|
||||
var response = callback.mostRecentCall.args[0];
|
||||
|
||||
callback.reset();
|
||||
|
||||
ccs.$then(callback);
|
||||
$rootScope.$apply(); //flush async queue
|
||||
|
||||
expect(callback).toHaveBeenCalledOnceWith(response);
|
||||
});
|
||||
|
||||
|
||||
it('should allow promise chaining via $then method', function() {
|
||||
$httpBackend.expect('GET', '/CreditCard?key=value').respond([{id: 1}, {id: 2}]);
|
||||
var ccs = CreditCard.query({key: 'value'});
|
||||
|
||||
ccs.$then(function(response) { return 'new value'; }).then(callback);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(callback).toHaveBeenCalledOnceWith('new value');
|
||||
});
|
||||
|
||||
|
||||
it('should allow error callback registration via $then method', function() {
|
||||
$httpBackend.expect('GET', '/CreditCard?key=value').respond(404, 'resource not found');
|
||||
var ccs = CreditCard.query({key: 'value'});
|
||||
|
||||
ccs.$then(null, callback);
|
||||
$httpBackend.flush();
|
||||
|
||||
var response = callback.mostRecentCall.args[0];
|
||||
|
||||
expect(response).toEqualData({
|
||||
data : 'resource not found',
|
||||
status : 404,
|
||||
config : { method : 'GET', data : undefined, url : '/CreditCard', params: {key: 'value'}}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should add $resolved boolean field to the result object', function() {
|
||||
$httpBackend.expect('GET', '/CreditCard?key=value').respond([{id: 1}, {id: 2}]);
|
||||
var ccs = CreditCard.query({key: 'value'}, callback);
|
||||
|
||||
expect(ccs.$resolved).toBe(false);
|
||||
|
||||
ccs.$then(callback);
|
||||
expect(ccs.$resolved).toBe(false);
|
||||
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(ccs.$resolved).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
it('should set $resolved field to true when an error occurs', function() {
|
||||
$httpBackend.expect('GET', '/CreditCard?key=value').respond(404, 'resource not found');
|
||||
var ccs = CreditCard.query({key: 'value'});
|
||||
|
||||
ccs.$then(null, callback);
|
||||
$httpBackend.flush();
|
||||
expect(callback).toHaveBeenCalledOnce();
|
||||
expect(ccs.$resolved).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('failure mode', function() {
|
||||
var ERROR_CODE = 500,
|
||||
ERROR_RESPONSE = 'Server Error',
|
||||
@@ -675,26 +419,4 @@ describe("resource", function() {
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should transform request/response', function() {
|
||||
var Person = $resource('/Person/:id', {}, {
|
||||
save: {
|
||||
method: 'POST',
|
||||
params: {id: '@id'},
|
||||
transformRequest: function(data) {
|
||||
return angular.toJson({ __id: data.id });
|
||||
},
|
||||
transformResponse: function(data) {
|
||||
return { id: data.__id };
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$httpBackend.expect('POST', '/Person/123', { __id: 123 }).respond({ __id: 456 });
|
||||
var person = new Person({id:123});
|
||||
person.$save();
|
||||
$httpBackend.flush();
|
||||
expect(person.id).toEqual(456);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -24,11 +24,4 @@ describe('linky', function() {
|
||||
expect(linky("send email to me@example.com, but")).
|
||||
toEqual('send email to <a href="mailto:me@example.com">me@example.com</a>, but');
|
||||
});
|
||||
|
||||
it('should handle target:', function() {
|
||||
expect(linky("http://example.com", "_blank")).
|
||||
toEqual('<a target="_blank" href="http://example.com">http://example.com</a>')
|
||||
expect(linky("http://example.com", "someNamedIFrame")).
|
||||
toEqual('<a target="someNamedIFrame" href="http://example.com">http://example.com</a>')
|
||||
});
|
||||
});
|
||||
|
||||
@@ -188,7 +188,7 @@ describe('HTML', function() {
|
||||
expect(html).toEqual('<div>');
|
||||
});
|
||||
|
||||
describe('explicitly disallow', function() {
|
||||
describe('explicitly dissallow', function() {
|
||||
it('should not allow attributes', function() {
|
||||
writer.start('div', {id:'a', name:'a', style:'a'});
|
||||
expect(html).toEqual('<div>');
|
||||
@@ -230,11 +230,10 @@ describe('HTML', function() {
|
||||
expect(isUri('https://abc')).toBeTruthy();
|
||||
expect(isUri('ftp://abc')).toBeTruthy();
|
||||
expect(isUri('mailto:me@example.com')).toBeTruthy();
|
||||
expect(isUri('tel:123-123-1234')).toBeTruthy();
|
||||
expect(isUri('#anchor')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should not be URI', function() {
|
||||
it('should not be UIR', function() {
|
||||
expect(isUri('')).toBeFalsy();
|
||||
expect(isUri('javascript:alert')).toBeFalsy();
|
||||
});
|
||||
|
||||
@@ -270,16 +270,6 @@ describe("angular.scenario.dsl", function() {
|
||||
expect($root.futureError).toMatch(/did not match/);
|
||||
});
|
||||
|
||||
it('should fail to select an option that does not exist', function(){
|
||||
doc.append(
|
||||
'<select ng-model="test">' +
|
||||
' <option value=A>one</option>' +
|
||||
' <option value=B selected>two</option>' +
|
||||
'</select>'
|
||||
);
|
||||
$root.dsl.select('test').option('three');
|
||||
expect($root.futureError).toMatch(/not found/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Element', function() {
|
||||
@@ -315,58 +305,6 @@ describe("angular.scenario.dsl", function() {
|
||||
dealoc(elm);
|
||||
});
|
||||
|
||||
it('should execute dblclick', function() {
|
||||
var clicked;
|
||||
// Hash is important, otherwise we actually
|
||||
// go to a different page and break the runner
|
||||
doc.append('<a href="#"></a>');
|
||||
doc.find('a').dblclick(function() {
|
||||
clicked = true;
|
||||
});
|
||||
$root.dsl.element('a').dblclick();
|
||||
});
|
||||
|
||||
it('should navigate page if dblclick on anchor', function() {
|
||||
expect($window.location).not.toEqual('#foo');
|
||||
doc.append('<a href="#foo"></a>');
|
||||
$root.dsl.element('a').dblclick();
|
||||
expect($window.location).toMatch(/#foo$/);
|
||||
});
|
||||
|
||||
it('should not navigate if dblclick event was cancelled', function() {
|
||||
var initLocation = $window.location,
|
||||
elm = jqLite('<a href="#foo"></a>');
|
||||
|
||||
doc.append(elm);
|
||||
elm.bind('dblclick', function(event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
$root.dsl.element('a').dblclick();
|
||||
expect($window.location).toBe(initLocation);
|
||||
dealoc(elm);
|
||||
});
|
||||
|
||||
it('should execute mouseover', function() {
|
||||
var mousedOver;
|
||||
doc.append('<div></div>');
|
||||
doc.find('div').mouseover(function() {
|
||||
mousedOver = true;
|
||||
});
|
||||
$root.dsl.element('div').mouseover();
|
||||
expect(mousedOver).toBe(true);
|
||||
});
|
||||
|
||||
it('should bubble up the mouseover event', function() {
|
||||
var mousedOver;
|
||||
doc.append('<div id="outer"><div id="inner"></div></div>');
|
||||
doc.find('#outer').mouseover(function() {
|
||||
mousedOver = true;
|
||||
});
|
||||
$root.dsl.element('#inner').mouseover();
|
||||
expect(mousedOver).toBe(true);
|
||||
});
|
||||
|
||||
it('should count matching elements', function() {
|
||||
doc.append('<span></span><span></span>');
|
||||
$root.dsl.element('span').count();
|
||||
|
||||
@@ -13,7 +13,7 @@ var util = require('util');
|
||||
|
||||
|
||||
var MAX_LENGTH = 70;
|
||||
var PATTERN = /^(?:fixup!\s*)?(\w*)(\(([\w\$\.\-\*/]*)\))?\: (.*)$/;
|
||||
var PATTERN = /^(\w*)(\(([\w\$\.\-\*/]*)\))?\: (.*)$/;
|
||||
var IGNORED = /^WIP\:/;
|
||||
var TYPES = {
|
||||
feat: true,
|
||||
@@ -51,7 +51,7 @@ var validateMessage = function(message) {
|
||||
var match = PATTERN.exec(message);
|
||||
|
||||
if (!match) {
|
||||
error('does not match "<type>(<scope>): <subject>" ! was: ' + message);
|
||||
error('does not match "<type>(<scope>): <subject>" !');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ describe('validate-commit-msg.js', function() {
|
||||
describe('validateMessage', function() {
|
||||
|
||||
it('should be valid', function() {
|
||||
expect(m.validateMessage('fixup! fix($compile): something')).toBe(VALID);
|
||||
expect(m.validateMessage('fix($compile): something')).toBe(VALID);
|
||||
expect(m.validateMessage('feat($location): something')).toBe(VALID);
|
||||
expect(m.validateMessage('docs($filter): something')).toBe(VALID);
|
||||
@@ -51,7 +50,7 @@ describe('validate-commit-msg.js', function() {
|
||||
var msg = 'not correct format';
|
||||
|
||||
expect(m.validateMessage(msg)).toBe(INVALID);
|
||||
expect(errors).toEqual(['INVALID COMMIT MSG: does not match "<type>(<scope>): <subject>" ! was: not correct format']);
|
||||
expect(errors).toEqual(['INVALID COMMIT MSG: does not match "<type>(<scope>): <subject>" !']);
|
||||
});
|
||||
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
# AngularJS build config file
|
||||
---
|
||||
version: 1.1.3
|
||||
codename: radioactive-gargle
|
||||
stable: 1.0.4
|
||||
version: 1.0.5
|
||||
codename: flatulent-propulsion
|
||||
stable: 1.0.5
|
||||
|
||||
Reference in New Issue
Block a user