aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/content/api/angular.inputType.ngdoc16
-rw-r--r--docs/content/cookbook/advancedform.ngdoc61
-rw-r--r--docs/content/cookbook/deeplinking.ngdoc46
-rw-r--r--docs/content/cookbook/form.ngdoc18
-rw-r--r--docs/content/cookbook/helloworld.ngdoc4
-rw-r--r--docs/content/cookbook/mvc.ngdoc77
-rw-r--r--docs/content/guide/dev_guide.expressions.ngdoc16
-rw-r--r--docs/content/guide/dev_guide.forms.ngdoc72
-rw-r--r--docs/content/guide/dev_guide.overview.ngdoc6
-rw-r--r--docs/content/guide/dev_guide.templates.filters.creating_filters.ngdoc4
-rw-r--r--docs/src/templates/docs.js11
-rw-r--r--example/personalLog/personalLog.js20
-rw-r--r--example/personalLog/test/personalLogSpec.js105
-rw-r--r--src/directives.js69
-rw-r--r--src/scenario/Runner.js11
-rw-r--r--src/service/compiler.js2
-rw-r--r--src/service/filter/filters.js16
-rw-r--r--src/service/filter/limitTo.js6
-rw-r--r--src/service/filter/orderBy.js6
-rw-r--r--src/service/formFactory.js41
-rw-r--r--src/service/http.js29
-rw-r--r--src/service/route.js10
-rw-r--r--src/service/scope.js19
-rw-r--r--src/widget/form.js4
-rw-r--r--src/widget/input.js89
-rw-r--r--src/widget/select.js38
-rw-r--r--src/widgets.js20
-rw-r--r--test/directivesSpec.js84
-rw-r--r--test/scenario/RunnerSpec.js3
-rw-r--r--test/scenario/SpecRunnerSpec.js8
-rw-r--r--test/service/formFactorySpec.js22
-rw-r--r--test/service/routeSpec.js21
-rw-r--r--test/service/scopeSpec.js31
-rw-r--r--test/widgetsSpec.js8
34 files changed, 477 insertions, 516 deletions
diff --git a/docs/content/api/angular.inputType.ngdoc b/docs/content/api/angular.inputType.ngdoc
index 76a907d1..bfd5fe6f 100644
--- a/docs/content/api/angular.inputType.ngdoc
+++ b/docs/content/api/angular.inputType.ngdoc
@@ -40,8 +40,8 @@ All `inputType` widgets support:
<doc:example>
<doc:source>
<script>
- angular.inputType('json', function() {
- this.$parseView = function() {
+ angular.inputType('json', function(element, scope) {
+ scope.$parseView = function() {
try {
this.$modelValue = angular.fromJson(this.$viewValue);
if (this.$error.JSON) {
@@ -52,19 +52,19 @@ All `inputType` widgets support:
}
}
- this.$parseModel = function() {
+ scope.$parseModel = function() {
this.$viewValue = angular.toJson(this.$modelValue);
}
});
- function Ctrl() {
- this.data = {
+ function Ctrl($scope) {
+ $scope.data = {
framework:'angular',
codenames:'supper-powers'
}
- this.required = false;
- this.disabled = false;
- this.readonly = false;
+ $scope.required = false;
+ $scope.disabled = false;
+ $scope.readonly = false;
}
</script>
<div ng:controller="Ctrl">
diff --git a/docs/content/cookbook/advancedform.ngdoc b/docs/content/cookbook/advancedform.ngdoc
index e973e30f..58a8dfd5 100644
--- a/docs/content/cookbook/advancedform.ngdoc
+++ b/docs/content/cookbook/advancedform.ngdoc
@@ -8,10 +8,8 @@ detection, and preventing invalid form submission.
<doc:example>
<doc:source>
<script>
- function UserForm() {
- this.state = /^\w\w$/;
- this.zip = /^\d\d\d\d\d$/;
- this.master = {
+ function UserForm($scope) {
+ var master = {
name: 'John Smith',
address:{
line1: '123 Main St.',
@@ -23,40 +21,42 @@ detection, and preventing invalid form submission.
{type:'phone', value:'1(234) 555-1212'}
]
};
- this.cancel();
- }
- UserForm.prototype = {
- cancel: function() {
- this.form = angular.copy(this.master);
- },
+ $scope.state = /^\w\w$/;
+ $scope.zip = /^\d\d\d\d\d$/;
- save: function() {
- this.master = this.form;
- this.cancel();
- },
+ $scope.cancel = function() {
+ $scope.form = angular.copy(master);
+ };
- addContact: function() {
- this.form.contacts.push({type:'', value:''});
- },
+ $scope.save = function() {
+ master = $scope.form;
+ $scope.cancel();
+ };
+
+ $scope.addContact = function() {
+ $scope.form.contacts.push({type:'', value:''});
+ };
- removeContact: function(contact) {
- for ( var i = 0, ii = this.form.contacts.length; i < ii; i++) {
- if (contact === this.form.contacts[i]) {
- this.form.contacts.splice(i, 1);
+ $scope.removeContact = function(contact) {
+ var contacts = $scope.form.contacts;
+ for (var i = 0, ii = contacts.length; i < ii; i++) {
+ if (contact === contacts[i]) {
+ contacts.splice(i, 1);
}
}
- },
+ };
- isCancelDisabled: function() {
- return angular.equals(this.master, this.form);
- },
+ $scope.isCancelDisabled = function() {
+ return angular.equals(master, $scope.form);
+ };
- isSaveDisabled: function() {
- return this.myForm.$invalid || angular.equals(this.master, this.form);
- }
+ $scope.isSaveDisabled = function() {
+ return $scope.myForm.$invalid || angular.equals(master, $scope.form);
+ };
- };
+ $scope.cancel();
+ }
</script>
<div ng:controller="UserForm">
@@ -91,8 +91,7 @@ detection, and preventing invalid form submission.
<hr/>
Debug View:
- <pre>form={{form}}
- master={{master}}</pre>
+ <pre>form={{form}}</pre>
</div>
</doc:source>
<doc:scenario>
diff --git a/docs/content/cookbook/deeplinking.ngdoc b/docs/content/cookbook/deeplinking.ngdoc
index 2ef3da4a..a4dc3a9b 100644
--- a/docs/content/cookbook/deeplinking.ngdoc
+++ b/docs/content/cookbook/deeplinking.ngdoc
@@ -39,42 +39,38 @@ The two partials are defined in the following URLs:
<doc:example>
<doc:source jsfiddle="false">
<script>
- AppCntl.$inject = ['$route']
- function AppCntl($route) {
+ AppCntl.$inject = ['$scope', '$route']
+ function AppCntl($scope, $route) {
// define routes
$route.when("/welcome", {template:'./examples/welcome.html', controller:WelcomeCntl});
$route.when("/settings", {template:'./examples/settings.html', controller:SettingsCntl});
- $route.parent(this);
+ $route.parent($scope);
// initialize the model to something useful
- this.person = {
+ $scope.person = {
name:'anonymous',
contacts:[{type:'email', url:'anonymous@example.com'}]
};
}
- function WelcomeCntl($route){}
- WelcomeCntl.prototype = {
- greet: function() {
- alert("Hello " + this.person.name);
- }
- };
-
- SettingsCntl.$inject = ['$location'];
- function SettingsCntl($location){
- this.$location = $location;
- this.cancel();
+ function WelcomeCntl($scope) {
+ $scope.greet = function() {
+ alert("Hello " + $scope.person.name);
+ };
+ }
+
+ function SettingsCntl($scope, $location) {
+ $scope.cancel = function() {
+ $scope.form = angular.copy($scope.person);
+ };
+
+ $scope.save = function() {
+ angular.copy($scope.form, $scope.person);
+ $location.path('/welcome');
+ };
+
+ $scope.cancel();
}
- SettingsCntl.prototype = {
- cancel: function() {
- this.form = angular.copy(this.person);
- },
-
- save: function() {
- angular.copy(this.form, this.person);
- this.$location.path('/welcome');
- }
- };
</script>
<div ng:controller="AppCntl">
<h1>Your App Chrome</h1>
diff --git a/docs/content/cookbook/form.ngdoc b/docs/content/cookbook/form.ngdoc
index 80c23e94..9371da7a 100644
--- a/docs/content/cookbook/form.ngdoc
+++ b/docs/content/cookbook/form.ngdoc
@@ -10,23 +10,23 @@ allow a user to enter data.
<doc:example>
<doc:source>
<script>
- function FormController() {
- this.user = {
+ function FormController($scope) {
+ $scope.user = {
name: 'John Smith',
address:{line1: '123 Main St.', city:'Anytown', state:'AA', zip:'12345'},
contacts:[{type:'phone', value:'1(234) 555-1212'}]
};
- this.state = /^\w\w$/;
- this.zip = /^\d\d\d\d\d$/;
+ $scope.state = /^\w\w$/;
+ $scope.zip = /^\d\d\d\d\d$/;
- this.addContact = function() {
- this.user.contacts.push({type:'', value:''});
+ $scope.addContact = function() {
+ $scope.user.contacts.push({type:'', value:''});
};
- this.removeContact = function(contact) {
- for ( var i = 0, ii = this.user.contacts.length; i < ii; i++) {
+ $scope.removeContact = function(contact) {
+ for (var i = 0, ii = this.user.contacts.length; i < ii; i++) {
if (contact === this.user.contacts[i]) {
- this.user.contacts.splice(i, 1);
+ $scope.user.contacts.splice(i, 1);
}
}
};
diff --git a/docs/content/cookbook/helloworld.ngdoc b/docs/content/cookbook/helloworld.ngdoc
index e3d76d83..b6b5bcf7 100644
--- a/docs/content/cookbook/helloworld.ngdoc
+++ b/docs/content/cookbook/helloworld.ngdoc
@@ -5,8 +5,8 @@
<doc:example>
<doc:source>
<script>
- function HelloCntl() {
- this.name = 'World';
+ function HelloCntl($scope) {
+ $scope.name = 'World';
}
</script>
<div ng:controller="HelloCntl">
diff --git a/docs/content/cookbook/mvc.ngdoc b/docs/content/cookbook/mvc.ngdoc
index f566a541..71e771bd 100644
--- a/docs/content/cookbook/mvc.ngdoc
+++ b/docs/content/cookbook/mvc.ngdoc
@@ -14,9 +14,8 @@ no connection between the controller and the view.
<doc:example>
<doc:source>
<script>
- function TicTacToeCntl($location){
- this.$location = $location;
- this.cellStyle= {
+ function TicTacToeCntl($scope, $location) {
+ $scope.cellStyle= {
'height': '20px',
'width': '20px',
'border': '1px solid black',
@@ -24,30 +23,40 @@ no connection between the controller and the view.
'vertical-align': 'middle',
'cursor': 'pointer'
};
- this.reset();
- this.$watch('$location.search().board', this.readUrl);
- }
- TicTacToeCntl.prototype = {
- dropPiece: function(row, col) {
- if (!this.winner && !this.board[row][col]) {
- this.board[row][col] = this.nextMove;
- this.nextMove = this.nextMove == 'X' ? 'O' : 'X';
- this.setUrl();
- }
- },
- reset: function() {
- this.board = [
+
+ $scope.reset = function() {
+ $scope.board = [
['', '', ''],
['', '', ''],
['', '', '']
];
- this.nextMove = 'X';
- this.winner = '';
- this.setUrl();
- },
- grade: function() {
- var b = this.board;
- this.winner =
+ $scope.nextMove = 'X';
+ $scope.winner = '';
+ setUrl();
+ };
+
+ $scope.dropPiece = function(row, col) {
+ if (!$scope.winner && !$scope.board[row][col]) {
+ $scope.board[row][col] = $scope.nextMove;
+ $scope.nextMove = $scope.nextMove == 'X' ? 'O' : 'X';
+ setUrl();
+ }
+ };
+
+ $scope.reset();
+ $scope.$watch(function() { return $location.search().board;}, readUrl);
+
+ function setUrl() {
+ var rows = [];
+ angular.forEach($scope.board, function(row) {
+ rows.push(row.join(','));
+ });
+ $location.search({board: rows.join(';') + '/' + $scope.nextMove});
+ }
+
+ function grade() {
+ var b = $scope.board;
+ $scope.winner =
row(0) || row(1) || row(2) ||
col(0) || col(1) || col(2) ||
diagonal(-1) || diagonal(1);
@@ -55,25 +64,19 @@ no connection between the controller and the view.
function col(col) { return same(b[0][col], b[1][col], b[2][col]);}
function diagonal(i) { return same(b[0][1-i], b[1][1], b[2][1+i]);}
function same(a, b, c) { return (a==b && b==c) ? a : '';};
- },
- setUrl: function() {
- var rows = [];
- angular.forEach(this.board, function(row){
- rows.push(row.join(','));
- });
- this.$location.search({board: rows.join(';') + '/' + this.nextMove});
- },
- readUrl: function(scope, value) {
+ }
+
+ function readUrl(scope, value) {
if (value) {
value = value.split('/');
- this.nextMove = value[1];
+ $scope.nextMove = value[1];
angular.forEach(value[0].split(';'), function(row, col){
- this.board[col] = row.split(',');
- }, this);
- this.grade();
+ $scope.board[col] = row.split(',');
+ });
+ grade();
}
}
- };
+ }
</script>
<h3>Tic-Tac-Toe</h3>
diff --git a/docs/content/guide/dev_guide.expressions.ngdoc b/docs/content/guide/dev_guide.expressions.ngdoc
index 4df69d28..b7ecc521 100644
--- a/docs/content/guide/dev_guide.expressions.ngdoc
+++ b/docs/content/guide/dev_guide.expressions.ngdoc
@@ -51,14 +51,14 @@ You can try evaluating different expressions here:
<doc:example>
<doc:source>
<script>
- function Cntl2() {
- this.exprs = [];
- this.expr = '3*10|currency';
- this.addExp = function(expr) {
+ function Cntl2($scope) {
+ $scope.exprs = [];
+ $scope.expr = '3*10|currency';
+ $scope.addExp = function(expr) {
this.exprs.push(expr);
};
- this.removeExp = function(contact) {
+ $scope.removeExp = function(contact) {
for ( var i = 0, ii = this.exprs.length; i < ii; i++) {
if (contact === this.exprs[i]) {
this.exprs.splice(i, 1);
@@ -101,10 +101,10 @@ the global state (a common source of subtle bugs).
<doc:example>
<doc:source>
<script>
- function Cntl1($window){
- this.name = 'World';
+ function Cntl1($window, $scope){
+ $scope.name = 'World';
- this.greet = function() {
+ $scope.greet = function() {
($window.mockWindow || $window).alert('Hello ' + this.name);
}
}
diff --git a/docs/content/guide/dev_guide.forms.ngdoc b/docs/content/guide/dev_guide.forms.ngdoc
index b4e37abd..03d0e6f9 100644
--- a/docs/content/guide/dev_guide.forms.ngdoc
+++ b/docs/content/guide/dev_guide.forms.ngdoc
@@ -111,10 +111,10 @@ The following example demonstrates:
.ng-form {display: block;}
</style>
<script>
- function UserFormCntl() {
- this.state = /^\w\w$/;
- this.zip = /^\d\d\d\d\d$/;
- this.master = {
+ function UserFormCntl($scope) {
+ $scope.state = /^\w\w$/;
+ $scope.zip = /^\d\d\d\d\d$/;
+ $scope.master = {
customer: 'John Smith',
address:{
line1: '123 Main St.',
@@ -123,28 +123,26 @@ The following example demonstrates:
zip:'12345'
}
};
- this.cancel();
- }
- UserFormCntl.prototype = {
- cancel: function() {
- this.form = angular.copy(this.master);
- },
+ $scope.cancel = function() {
+ $scope.form = angular.copy($scope.master);
+ };
- save: function() {
- this.master = this.form;
- this.cancel();
- },
+ $scope.save = function() {
+ $scope.master = $scope.form;
+ $scope.cancel();
+ };
- isCancelDisabled: function() {
- return angular.equals(this.master, this.form);
- },
+ $scope.isCancelDisabled = function() {
+ return angular.equals($scope.master, $scope.form);
+ };
- isSaveDisabled: function() {
- return this.userForm.$invalid || angular.equals(this.master, this.form);
- }
+ $scope.isSaveDisabled = function() {
+ return $scope.userForm.$invalid || angular.equals($scope.master, $scope.form);
+ };
- };
+ $scope.cancel();
+ }
</script>
<div ng:controller="UserFormCntl">
@@ -282,15 +280,13 @@ This example shows how to implement a custom HTML editor widget in Angular.
<doc:example>
<doc:source>
<script>
- function EditorCntl() {
- this.htmlContent = '<b>Hello</b> <i>World</i>!';
+ function EditorCntl($scope) {
+ $scope.htmlContent = '<b>Hello</b> <i>World</i>!';
}
- HTMLEditorWidget.$inject = ['$element', 'htmlFilter'];
- function HTMLEditorWidget(element, htmlFilter) {
- var self = this;
-
- this.$parseModel = function() {
+ HTMLEditorWidget.$inject = ['$element', '$scope', 'htmlFilter'];
+ function HTMLEditorWidget(element, scope, htmlFilter) {
+ scope.$parseModel = function() {
// need to protect for script injection
try {
this.$viewValue = htmlFilter(
@@ -305,13 +301,13 @@ This example shows how to implement a custom HTML editor widget in Angular.
}
}
- this.$render = function() {
+ scope.$render = function() {
element.html(this.$viewValue);
}
element.bind('keyup', function() {
- self.$apply(function() {
- self.$emit('$viewChange', element.html());
+ scope.$apply(function() {
+ scope.$emit('$viewChange', element.html());
});
});
}
@@ -364,13 +360,13 @@ validation.
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.input1 = '';
- this.input2 = '';
- this.input3 = 'A';
- this.input4 = false;
- this.input5 = 'c';
- this.input6 = [];
+ function Ctrl($scope) {
+ $scope.input1 = '';
+ $scope.input2 = '';
+ $scope.input3 = 'A';
+ $scope.input4 = false;
+ $scope.input5 = 'c';
+ $scope.input6 = [];
}
</script>
<table style="font-size:.9em;" ng:controller="Ctrl">
diff --git a/docs/content/guide/dev_guide.overview.ngdoc b/docs/content/guide/dev_guide.overview.ngdoc
index 5d308167..faf40af5 100644
--- a/docs/content/guide/dev_guide.overview.ngdoc
+++ b/docs/content/guide/dev_guide.overview.ngdoc
@@ -43,9 +43,9 @@ easier a web developer's life can if they're using angular:
<doc:example>
<doc:source>
<script>
- function InvoiceCntl() {
- this.qty = 1;
- this.cost = 19.95;
+ function InvoiceCntl($scope) {
+ $scope.qty = 1;
+ $scope.cost = 19.95;
}
</script>
<div ng:controller="InvoiceCntl">
diff --git a/docs/content/guide/dev_guide.templates.filters.creating_filters.ngdoc b/docs/content/guide/dev_guide.templates.filters.creating_filters.ngdoc
index 98b41411..87894227 100644
--- a/docs/content/guide/dev_guide.templates.filters.creating_filters.ngdoc
+++ b/docs/content/guide/dev_guide.templates.filters.creating_filters.ngdoc
@@ -34,8 +34,8 @@ text upper-case and assigns color.
}
});
- function Ctrl() {
- this.greeting = 'hello';
+ function Ctrl($scope) {
+ $scope.greeting = 'hello';
}
</script>
diff --git a/docs/src/templates/docs.js b/docs/src/templates/docs.js
index 38a75236..bf279df5 100644
--- a/docs/src/templates/docs.js
+++ b/docs/src/templates/docs.js
@@ -1,9 +1,8 @@
-DocsController.$inject = ['$location', '$window', '$cookies', '$filter'];
-function DocsController($location, $window, $cookies, $filter) {
- window.$root = this.$root;
+DocsController.$inject = ['$scope', '$location', '$window', '$cookies', '$filter'];
+function DocsController(scope, $location, $window, $cookies, $filter) {
+ window.$root = scope.$root;
- var scope = this,
- OFFLINE_COOKIE_NAME = 'ng-offline',
+ var OFFLINE_COOKIE_NAME = 'ng-offline',
DOCS_PATH = /^\/(api)|(guide)|(cookbook)|(misc)|(tutorial)/,
INDEX_PATH = /^(\/|\/index[^\.]*.html)$/,
filter = $filter('filter');
@@ -160,6 +159,6 @@ angular.module('ngdocs', [], function($locationProvider, $filterProvider) {
return text && text.replace(/^angular\.module\.([^\.]+)(\.(.*))?$/, function(_, module, _0, name){
return 'Module ' + module + (name ? ' - ' + name : '');
});
- }
+ };
});
});
diff --git a/example/personalLog/personalLog.js b/example/personalLog/personalLog.js
index 7be233cb..4d182227 100644
--- a/example/personalLog/personalLog.js
+++ b/example/personalLog/personalLog.js
@@ -26,26 +26,26 @@ var LOGS = 'logs';
/**
* The controller for the personal log app.
*/
-function LogCtrl($cookieStore) {
- var self = this,
- logs = self.logs = $cookieStore.get(LOGS) || []; //main model
+function LogCtrl($cookieStore, $scope) {
+
+ var logs = $scope.logs = $cookieStore.get(LOGS) || []; //main model
/**
* Adds newMsg to the logs array as a log, persists it and clears newMsg.
* @param {string} msg Message to add (message is passed as parameter to make testing easier).
*/
- this.addLog = function(msg) {
- var newMsg = msg || self.newMsg;
+ $scope.addLog = function(msg) {
+ var newMsg = msg || $scope.newMsg;
if (!newMsg) return;
var log = {
at: new Date().getTime(),
msg: newMsg
- }
+ };
logs.push(log);
$cookieStore.put(LOGS, logs);
- self.newMsg = '';
+ $scope.newMsg = '';
};
@@ -53,7 +53,7 @@ function LogCtrl($cookieStore) {
* Persistently removes a log from logs.
* @param {object} log The log to remove.
*/
- this.rmLog = function(log) {
+ $scope.rmLog = function(log) {
for ( var i = 0; i < logs.length; i++) {
if (log === logs[i]) {
logs.splice(i, 1);
@@ -68,14 +68,14 @@ function LogCtrl($cookieStore) {
/**
* Persistently removes all logs.
*/
- this.rmLogs = function() {
+ $scope.rmLogs = function() {
logs.splice(0, logs.length);
$cookieStore.remove(LOGS);
};
}
//inject
-LogCtrl.$inject = ['$cookieStore'];
+LogCtrl.$inject = ['$cookieStore', '$scope'];
//export
example.personalLog.LogCtrl = LogCtrl;
diff --git a/example/personalLog/test/personalLogSpec.js b/example/personalLog/test/personalLogSpec.js
index 9393e047..ab2d98c9 100644
--- a/example/personalLog/test/personalLogSpec.js
+++ b/example/personalLog/test/personalLogSpec.js
@@ -1,63 +1,58 @@
describe('example.personalLog.LogCtrl', function() {
- var logCtrl;
-
- function createNotesCtrl() {
- var injector = angular.injector(['ng', 'ngMock']);
- var scope = injector.get('$rootScope');
- scope.$cookies = injector.get('$cookies');
- return scope.$new(example.personalLog.LogCtrl);
- }
-
+ var logScope;
beforeEach(function() {
- logCtrl = createNotesCtrl();
+ var injector = angular.injector(['ng', 'ngMock']);
+ logScope = injector.get('$rootScope');
+ logScope.$cookies = injector.get('$cookies');
+ injector.instantiate(example.personalLog.LogCtrl, {$scope: logScope});
});
it('should initialize notes with an empty array', function() {
- expect(logCtrl.logs).toEqual([]);
+ expect(logScope.logs).toEqual([]);
});
describe('addLog', function() {
beforeEach(function() {
- expect(logCtrl.logs).toEqual([]);
+ expect(logScope.logs).toEqual([]);
});
it('should add newMsg to logs as a log entry', function() {
- logCtrl.newMsg = 'first log message';
- logCtrl.addLog();
+ logScope.newMsg = 'first log message';
+ logScope.addLog();
- expect(logCtrl.logs.length).toBe(1);
- expect(logCtrl.logs[0].msg).toBe('first log message');
+ expect(logScope.logs.length).toBe(1);
+ expect(logScope.logs[0].msg).toBe('first log message');
//one more msg, this time passed in as param
- logCtrl.addLog('second log message');
+ logScope.addLog('second log message');
- expect(logCtrl.logs.length).toBe(2);
- expect(logCtrl.logs[0].msg).toBe('first log message');
- expect(logCtrl.logs[1].msg).toBe('second log message');
+ expect(logScope.logs.length).toBe(2);
+ expect(logScope.logs[0].msg).toBe('first log message');
+ expect(logScope.logs[1].msg).toBe('second log message');
});
it('should clear newMsg when log entry is persisted', function() {
- logCtrl.addLog('first log message');
- expect(logCtrl.newMsg).toBe('');
+ logScope.addLog('first log message');
+ expect(logScope.newMsg).toBe('');
});
it('should store logs in the logs cookie', function() {
- expect(logCtrl.$cookies.logs).not.toBeDefined();
- logCtrl.addLog('first log message');
- expect(logCtrl.$cookies.logs).toBeTruthy();
+ expect(logScope.$cookies.logs).not.toBeDefined();
+ logScope.addLog('first log message');
+ expect(logScope.$cookies.logs).toBeTruthy();
});
it('should do nothing if newMsg is empty', function() {
- logCtrl.addLog('');
- expect(logCtrl.logs.length).toBe(0);
+ logScope.addLog('');
+ expect(logScope.logs.length).toBe(0);
});
});
@@ -65,35 +60,35 @@ describe('example.personalLog.LogCtrl', function() {
describe('rmLog', function() {
beforeEach(function() {
- logCtrl.addLog('message1');
- logCtrl.addLog('message2');
- logCtrl.addLog('message3');
- logCtrl.addLog('message4');
- expect(logCtrl.logs.length).toBe(4);
+ logScope.addLog('message1');
+ logScope.addLog('message2');
+ logScope.addLog('message3');
+ logScope.addLog('message4');
+ expect(logScope.logs.length).toBe(4);
});
it('should delete a message identified by index', function() {
- logCtrl.rmLog(logCtrl.logs[1]);
- expect(logCtrl.logs.length).toBe(3);
+ logScope.rmLog(logScope.logs[1]);
+ expect(logScope.logs.length).toBe(3);
- logCtrl.rmLog(logCtrl.logs[2]);
- expect(logCtrl.logs.length).toBe(2);
- expect(logCtrl.logs[0].msg).toBe('message1');
- expect(logCtrl.logs[1].msg).toBe('message3');
+ logScope.rmLog(logScope.logs[2]);
+ expect(logScope.logs.length).toBe(2);
+ expect(logScope.logs[0].msg).toBe('message1');
+ expect(logScope.logs[1].msg).toBe('message3');
});
it('should update cookies when a log is deleted', function() {
- expect(logCtrl.$cookies.logs).toMatch(/\[\{.*?\}(,\{.*?\}){3}\]/);
+ expect(logScope.$cookies.logs).toMatch(/\[\{.*?\}(,\{.*?\}){3}\]/);
- logCtrl.rmLog(logCtrl.logs[1]);
- expect(logCtrl.$cookies.logs).toMatch(/\[\{.*?\}(,\{.*?\}){2}\]/);
+ logScope.rmLog(logScope.logs[1]);
+ expect(logScope.$cookies.logs).toMatch(/\[\{.*?\}(,\{.*?\}){2}\]/);
- logCtrl.rmLog(logCtrl.logs[0]);
- logCtrl.rmLog(logCtrl.logs[0]);
- logCtrl.rmLog(logCtrl.logs[0]);
- expect(logCtrl.$cookies.logs).toMatch(/\[\]/);
+ logScope.rmLog(logScope.logs[0]);
+ logScope.rmLog(logScope.logs[0]);
+ logScope.rmLog(logScope.logs[0]);
+ expect(logScope.$cookies.logs).toMatch(/\[\]/);
});
});
@@ -101,24 +96,24 @@ describe('example.personalLog.LogCtrl', function() {
describe('rmLogs', function() {
beforeEach(function() {
- logCtrl.addLog('message1');
- logCtrl.addLog('message2');
- logCtrl.addLog('message3');
- logCtrl.addLog('message4');
- expect(logCtrl.logs.length).toBe(4);
+ logScope.addLog('message1');
+ logScope.addLog('message2');
+ logScope.addLog('message3');
+ logScope.addLog('message4');
+ expect(logScope.logs.length).toBe(4);
});
it('should remove all logs', function() {
- logCtrl.rmLogs();
- expect(logCtrl.logs).toEqual([]);
+ logScope.rmLogs();
+ expect(logScope.logs).toEqual([]);
});
it('should remove logs cookie', function() {
- expect(logCtrl.$cookies.logs).toBeTruthy();
- logCtrl.rmLogs();
- expect(logCtrl.$cookies.logs).not.toBeDefined();
+ expect(logScope.$cookies.logs).toBeTruthy();
+ logScope.rmLogs();
+ expect(logScope.$cookies.logs).not.toBeDefined();
});
});
});
diff --git a/src/directives.js b/src/directives.js
index 1d5b36f2..53d03573 100644
--- a/src/directives.js
+++ b/src/directives.js
@@ -97,28 +97,30 @@ angularDirective("ng:init", function(expression){
<doc:example>
<doc:source>
<script type="text/javascript">
- function SettingsController() {
- this.name = "John Smith";
- this.contacts = [
+ function SettingsController($scope) {
+ $scope.name = "John Smith";
+ $scope.contacts = [
{type:'phone', value:'408 555 1212'},
{type:'email', value:'john.smith@example.org'} ];
- }
- SettingsController.prototype = {
- greet: function() {
+
+ $scope.greet = function() {
alert(this.name);
- },
- addContact: function() {
+ };
+
+ $scope.addContact = function() {
this.contacts.push({type:'email', value:'yourname@example.org'});
- },
- removeContact: function(contactToRemove) {
+ };
+
+ $scope.removeContact = function(contactToRemove) {
var index = this.contacts.indexOf(contactToRemove);
this.contacts.splice(index, 1);
- },
- clearContact: function(contact) {
+ };
+
+ $scope.clearContact = function(contact) {
contact.type = 'phone';
contact.value = '';
- }
- };
+ };
+ }
</script>
<div ng:controller="SettingsController">
Name: <input type="text" ng:model="name"/>
@@ -156,16 +158,15 @@ angularDirective("ng:init", function(expression){
</doc:scenario>
</doc:example>
*/
-angularDirective("ng:controller", function(expression){
- this.scope(function(scope){
- var Controller =
- getter(scope, expression, true) ||
- getter(window, expression, true);
+angularDirective("ng:controller", function(expression) {
+ this.scope(true);
+ return ['$injector', '$window', function($injector, $window) {
+ var scope = this,
+ Controller = getter(scope, expression, true) || getter($window, expression, true);
+
assertArgFn(Controller, expression);
- inferInjectionArgs(Controller);
- return Controller;
- });
- return noop;
+ $injector.instantiate(Controller, {$scope: scope});
+ }];
});
/**
@@ -189,8 +190,8 @@ angularDirective("ng:controller", function(expression){
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.name = 'Whirled';
+ function Ctrl($scope) {
+ $scope.name = 'Whirled';
}
</script>
<div ng:controller="Ctrl">
@@ -277,9 +278,9 @@ angularDirective("ng:bind", function(expression, element){
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.salutation = 'Hello';
- this.name = 'World';
+ function Ctrl($scope) {
+ $scope.salutation = 'Hello';
+ $scope.name = 'World';
}
</script>
<div ng:controller="Ctrl">
@@ -363,8 +364,8 @@ angularDirective("ng:bind-template", function(expression, element){
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.query = 'AngularJS';
+ function Ctrl($scope) {
+ $scope.query = 'AngularJS';
}
</script>
<div ng:controller="Ctrl">
@@ -470,10 +471,10 @@ angularDirective("ng:click", function(expression, element){
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.list = [];
- this.text = 'hello';
- this.submit = function() {
+ function Ctrl($scope) {
+ $scope.list = [];
+ $scope.text = 'hello';
+ $scope.submit = function() {
if (this.text) {
this.list.push(this.text);
this.text = '';
diff --git a/src/scenario/Runner.js b/src/scenario/Runner.js
index cfde1f64..06ad3aa1 100644
--- a/src/scenario/Runner.js
+++ b/src/scenario/Runner.js
@@ -152,7 +152,16 @@ angular.scenario.Runner.prototype.afterEach = function(body) {
* @param {Object} scope parent scope
*/
angular.scenario.Runner.prototype.createSpecRunner_ = function(scope) {
- return scope.$new(angular.scenario.SpecRunner);
+ var child = scope.$new();
+ var Cls = angular.scenario.SpecRunner;
+
+ // Export all the methods to child scope manually as now we don't mess controllers with scopes
+ // TODO(vojta): refactor scenario runner so that these objects are not tightly coupled as current
+ for (var name in Cls.prototype)
+ child[name] = angular.bind(child, Cls.prototype[name]);
+
+ Cls.call(child);
+ return child;
};
/**
diff --git a/src/service/compiler.js b/src/service/compiler.js
index 727f7983..adf1ffa9 100644
--- a/src/service/compiler.js
+++ b/src/service/compiler.js
@@ -22,7 +22,7 @@ function $CompileProvider(){
var childScope = scope,
locals = {$element: element};
if (this.newScope) {
- childScope = isFunction(this.newScope) ? scope.$new(this.newScope(scope)) : scope.$new();
+ childScope = scope.$new();
element.data($$scope, childScope);
}
forEach(this.linkFns, function(fn) {
diff --git a/src/service/filter/filters.js b/src/service/filter/filters.js
index 3e7f8e37..69bfbacf 100644
--- a/src/service/filter/filters.js
+++ b/src/service/filter/filters.js
@@ -18,8 +18,8 @@
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.amount = 1234.56;
+ function Ctrl($scope) {
+ $scope.amount = 1234.56;
}
</script>
<div ng:controller="Ctrl">
@@ -69,8 +69,8 @@ function currencyFilter($locale) {
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.val = 1234.56789;
+ function Ctrl($scope) {
+ $scope.val = 1234.56789;
}
</script>
<div ng:controller="Ctrl">
@@ -448,8 +448,8 @@ var uppercaseFilter = valueFn(uppercase);
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.snippet =
+ function Ctrl($scope) {
+ $scope.snippet =
'<p style="color:blue">an html\n' +
'<em onmouseover="this.textContent=\'PWN3D!\'">click here</em>\n' +
'snippet</p>';
@@ -538,8 +538,8 @@ function htmlFilter() {
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.snippet =
+ function Ctrl($scope) {
+ $scope.snippet =
'Pretty text with some links:\n'+
'http://angularjs.org/,\n'+
'mailto:us@somewhere.org,\n'+
diff --git a/src/service/filter/limitTo.js b/src/service/filter/limitTo.js
index a250bd3b..eb97fdad 100644
--- a/src/service/filter/limitTo.js
+++ b/src/service/filter/limitTo.js
@@ -25,9 +25,9 @@
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.numbers = [1,2,3,4,5,6,7,8,9];
- this.limit = 3;
+ function Ctrl($scope) {
+ $scope.numbers = [1,2,3,4,5,6,7,8,9];
+ $scope.limit = 3;
}
</script>
<div ng:controller="Ctrl">
diff --git a/src/service/filter/orderBy.js b/src/service/filter/orderBy.js
index 2e5a0286..c67d2769 100644
--- a/src/service/filter/orderBy.js
+++ b/src/service/filter/orderBy.js
@@ -32,14 +32,14 @@
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.friends =
+ function Ctrl($scope) {
+ $scope.friends =
[{name:'John', phone:'555-1212', age:10},
{name:'Mary', phone:'555-9876', age:19},
{name:'Mike', phone:'555-4321', age:21},
{name:'Adam', phone:'555-5678', age:35},
{name:'Julie', phone:'555-8765', age:29}]
- this.predicate = '-age';
+ $scope.predicate = '-age';
}
</script>
<div ng:controller="Ctrl">
diff --git a/src/service/formFactory.js b/src/service/formFactory.js
index 15a4733f..565b22a4 100644
--- a/src/service/formFactory.js
+++ b/src/service/formFactory.js
@@ -25,15 +25,13 @@
<doc:example>
<doc:source>
<script>
- function EditorCntl() {
- this.html = '<b>Hello</b> <i>World</i>!';
+ function EditorCntl($scope) {
+ $scope.html = '<b>Hello</b> <i>World</i>!';
}
- HTMLEditorWidget.$inject = ['$element', 'htmlFilter'];
- function HTMLEditorWidget(element, htmlFilter) {
- var self = this;
-
- this.$parseModel = function() {
+ HTMLEditorWidget.$inject = ['$element', '$scope', 'htmlFilter'];
+ function HTMLEditorWidget(element, scope, htmlFilter) {
+ scope.$parseModel = function() {
// need to protect for script injection
try {
this.$viewValue = htmlFilter(this.$modelValue || '').get();
@@ -47,13 +45,13 @@
}
}
- this.$render = function() {
+ scope.$render = function() {
element.html(this.$viewValue);
}
element.bind('keyup', function() {
- self.$apply(function() {
- self.$emit('$viewChange', element.html());
+ scope.$apply(function() {
+ scope.$emit('$viewChange', element.html());
});
});
}
@@ -104,7 +102,8 @@
function $FormFactoryProvider() {
var $parse;
- this.$get = ['$rootScope', '$parse', function($rootScope, $parse_) {
+ this.$get = ['$rootScope', '$parse', '$injector',
+ function($rootScope, $parse_, $injector) {
$parse = $parse_;
/**
* @ngdoc proprety
@@ -136,7 +135,9 @@ function $FormFactoryProvider() {
return formFactory;
function formFactory(parent) {
- return (parent || formFactory.rootForm).$new(FormController);
+ var scope = (parent || formFactory.rootForm).$new();
+ $injector.instantiate(FormController, {$scope: scope});
+ return scope;
}
}];
@@ -230,8 +231,11 @@ function $FormFactoryProvider() {
* @param {*} viewValue The new value for the view which will be assigned to `widget.$viewValue`.
*/
- function FormController() {
- var form = this,
+ FormController.$inject = ['$scope', '$injector'];
+ function FormController($scope, $injector) {
+ this.$injector = $injector;
+
+ var form = this.form = $scope,
$error = form.$error = {};
form.$on('$destroy', function(event){
@@ -257,6 +261,7 @@ function $FormFactoryProvider() {
});
propertiesUpdate(form);
+ form.$createWidget = bind(this, this.$createWidget);
function removeWidget(queue, errorKey, widget) {
if (queue) {
@@ -354,17 +359,19 @@ function $FormFactoryProvider() {
* @returns {Widget} Instance of a widget scope.
*/
FormController.prototype.$createWidget = function(params) {
- var form = this,
+ var form = this.form,
modelScope = params.scope,
onChange = params.onChange,
alias = params.alias,
scopeGet = $parse(params.model),
scopeSet = scopeGet.assign,
- widget = this.$new(params.controller, params.controllerArgs);
+ widget = form.$new();
+
+ this.$injector.instantiate(params.controller, extend({$scope: widget}, params.controllerArgs));
if (!scopeSet) {
throw Error("Expression '" + params.model + "' is not assignable!");
- };
+ }
widget.$error = {};
// Set the state to something we know will change to get the process going.
diff --git a/src/service/http.js b/src/service/http.js
index b008aa8e..9d57ed76 100644
--- a/src/service/http.js
+++ b/src/service/http.js
@@ -395,29 +395,28 @@ function $HttpProvider() {
<doc:example>
<doc:source jsfiddle="false">
<script>
- function FetchCtrl($http) {
- var self = this;
- this.method = 'GET';
- this.url = 'examples/http-hello.html';
+ function FetchCtrl($scope, $http) {
+ $scope.method = 'GET';
+ $scope.url = 'examples/http-hello.html';
- this.fetch = function() {
- self.code = null;
- self.response = null;
+ $scope.fetch = function() {
+ $scope.code = null;
+ $scope.response = null;
- $http({method: self.method, url: self.url}).
+ $http({method: $scope.method, url: $scope.url}).
success(function(data, status) {
- self.status = status;
- self.data = data;
+ $scope.status = status;
+ $scope.data = data;
}).
error(function(data, status) {
- self.data = data || "Request failed";
- self.status = status;
+ $scope.data = data || "Request failed";
+ $scope.status = status;
});
};
- this.updateModel = function(method, url) {
- self.method = method;
- self.url = url;
+ $scope.updateModel = function(method, url) {
+ $scope.method = method;
+ $scope.url = url;
};
}
</script>
diff --git a/src/service/route.js b/src/service/route.js
index 77d94e9c..04bcfdb6 100644
--- a/src/service/route.js
+++ b/src/service/route.js
@@ -63,8 +63,8 @@
</doc:example>
*/
function $RouteProvider(){
- this.$get = ['$rootScope', '$location', '$routeParams',
- function( $rootScope, $location, $routeParams) {
+ this.$get = ['$rootScope', '$location', '$routeParams', '$injector',
+ function( $rootScope, $location, $routeParams, $injector) {
/**
* @ngdoc event
* @name angular.module.ng.$route#$beforeRouteChange
@@ -278,8 +278,10 @@ function $RouteProvider(){
}
} else {
copy(next.params, $routeParams);
- (Controller = next.controller) && inferInjectionArgs(Controller);
- next.scope = parentScope.$new(Controller);
+ next.scope = parentScope.$new();
+ if (next.controller) {
+ $injector.instantiate(next.controller, {$scope: next.scope});
+ }
}
}
$rootScope.$broadcast('$afterRouteChange', next, last);
diff --git a/src/service/scope.js b/src/service/scope.js
index fe72c953..089e4a41 100644
--- a/src/service/scope.js
+++ b/src/service/scope.js
@@ -126,8 +126,9 @@ function $RootScopeProvider(){
* @function
*
* @description
- * Creates a new child {@link angular.module.ng.$rootScope.Scope scope}. The new scope can optionally behave as a
- * controller. The parent scope will propagate the {@link angular.module.ng.$rootScope.Scope#$digest $digest()} and
+ * Creates a new child {@link angular.module.ng.$rootScope.Scope scope}.
+ *
+ * The parent scope will propagate the {@link angular.module.ng.$rootScope.Scope#$digest $digest()} and
* {@link angular.module.ng.$rootScope.Scope#$digest $digest()} events. The scope can be removed from the scope
* hierarchy using {@link angular.module.ng.$rootScope.Scope#$destroy $destroy()}.
*
@@ -135,13 +136,10 @@ function $RootScopeProvider(){
* the scope and its child scopes to be permanently detached from the parent and thus stop
* participating in model change detection and listener notification by invoking.
*
- * @param {function()=} Class Constructor function which the scope should be applied to the scope.
- * @param {...*} curryArguments Any additional arguments which are curried into the constructor.
- * See {@link guide/dev_guide.di dependency injection}.
* @returns {Object} The newly created child scope.
*
*/
- $new: function(Class, curryArguments) {
+ $new: function() {
var Child = function() {}; // should be anonymous; This is so that when the minifier munges
// the name it does not become random set of chars. These will then show up as class
// name in the debugger.
@@ -161,15 +159,6 @@ function $RootScopeProvider(){
} else {
this.$$childHead = this.$$childTail = child;
}
- // short circuit if we have no class
- if (Class) {
- // can't use forEach, we need speed!
- var ClassPrototype = Class.prototype;
- for(var key in ClassPrototype) {
- child[key] = bind(child, ClassPrototype[key]);
- }
- $injector.invoke(Class, child, curryArguments);
- }
return child;
},
diff --git a/src/widget/form.js b/src/widget/form.js
index 49e3a545..f3134db4 100644
--- a/src/widget/form.js
+++ b/src/widget/form.js
@@ -52,8 +52,8 @@
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.text = 'guest';
+ function Ctrl($scope) {
+ $scope.text = 'guest';
}
</script>
<div ng:controller="Ctrl">
diff --git a/src/widget/input.js b/src/widget/input.js
index a744e567..5db52704 100644
--- a/src/widget/input.js
+++ b/src/widget/input.js
@@ -31,9 +31,9 @@ var INTEGER_REGEXP = /^\s*(\-|\+)?\d+\s*$/;
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.text = 'guest';
- this.word = /^\w*$/;
+ function Ctrl($scope) {
+ $scope.text = 'guest';
+ $scope.word = /^\w*$/;
}
</script>
<div ng:controller="Ctrl">
@@ -96,8 +96,8 @@ var INTEGER_REGEXP = /^\s*(\-|\+)?\d+\s*$/;
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.text = 'me@example.com';
+ function Ctrl($scope) {
+ $scope.text = 'me@example.com';
}
</script>
<div ng:controller="Ctrl">
@@ -136,9 +136,8 @@ var INTEGER_REGEXP = /^\s*(\-|\+)?\d+\s*$/;
</doc:scenario>
</doc:example>
*/
-angularInputType('email', function() {
- var widget = this;
- this.$on('$validate', function(event){
+angularInputType('email', function(element, widget) {
+ widget.$on('$validate', function(event) {
var value = widget.$viewValue;
widget.$emit(!value || value.match(EMAIL_REGEXP) ? "$valid" : "$invalid", "EMAIL");
});
@@ -170,8 +169,8 @@ angularInputType('email', function() {
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.text = 'http://google.com';
+ function Ctrl($scope) {
+ $scope.text = 'http://google.com';
}
</script>
<div ng:controller="Ctrl">
@@ -210,9 +209,8 @@ angularInputType('email', function() {
</doc:scenario>
</doc:example>
*/
-angularInputType('url', function() {
- var widget = this;
- this.$on('$validate', function(event){
+angularInputType('url', function(element, widget) {
+ widget.$on('$validate', function(event) {
var value = widget.$viewValue;
widget.$emit(!value || value.match(URL_REGEXP) ? "$valid" : "$invalid", "URL");
});
@@ -239,8 +237,8 @@ angularInputType('url', function() {
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.names = ['igor', 'misko', 'vojta'];
+ function Ctrl($scope) {
+ $scope.names = ['igor', 'misko', 'vojta'];
}
</script>
<div ng:controller="Ctrl">
@@ -270,7 +268,7 @@ angularInputType('url', function() {
</doc:scenario>
</doc:example>
*/
-angularInputType('list', function() {
+angularInputType('list', function(element, widget) {
function parse(viewValue) {
var list = [];
forEach(viewValue.split(/\s*,\s*/), function(value){
@@ -278,14 +276,14 @@ angularInputType('list', function() {
});
return list;
}
- this.$parseView = function() {
- isString(this.$viewValue) && (this.$modelValue = parse(this.$viewValue));
+ widget.$parseView = function() {
+ isString(widget.$viewValue) && (widget.$modelValue = parse(widget.$viewValue));
};
- this.$parseModel = function() {
- var modelValue = this.$modelValue;
+ widget.$parseModel = function() {
+ var modelValue = widget.$modelValue;
if (isArray(modelValue)
- && (!isString(this.$viewValue) || !equals(parse(this.$viewValue), modelValue))) {
- this.$viewValue = modelValue.join(', ');
+ && (!isString(widget.$viewValue) || !equals(parse(widget.$viewValue), modelValue))) {
+ widget.$viewValue = modelValue.join(', ');
}
};
});
@@ -318,8 +316,8 @@ angularInputType('list', function() {
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.value = 12;
+ function Ctrl($scope) {
+ $scope.value = 12;
}
</script>
<div ng:controller="Ctrl">
@@ -388,8 +386,8 @@ angularInputType('number', numericRegexpInputType(NUMBER_REGEXP, 'NUMBER'));
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.value = 12;
+ function Ctrl($scope) {
+ $scope.value = 12;
}
</script>
<div ng:controller="Ctrl">
@@ -449,9 +447,9 @@ angularInputType('integer', numericRegexpInputType(INTEGER_REGEXP, 'INTEGER'));
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.value1 = true;
- this.value2 = 'YES'
+ function Ctrl($scope) {
+ $scope.value1 = true;
+ $scope.value2 = 'YES'
}
</script>
<div ng:controller="Ctrl">
@@ -477,9 +475,8 @@ angularInputType('integer', numericRegexpInputType(INTEGER_REGEXP, 'INTEGER'));
</doc:scenario>
</doc:example>
*/
-angularInputType('checkbox', function(inputElement) {
- var widget = this,
- trueValue = inputElement.attr('ng:true-value'),
+angularInputType('checkbox', function(inputElement, widget) {
+ var trueValue = inputElement.attr('ng:true-value'),
falseValue = inputElement.attr('ng:false-value');
if (!isString(trueValue)) trueValue = true;
@@ -496,7 +493,7 @@ angularInputType('checkbox', function(inputElement) {
};
widget.$parseModel = function() {
- widget.$viewValue = this.$modelValue === trueValue;
+ widget.$viewValue = widget.$modelValue === trueValue;
};
widget.$parseView = function() {
@@ -522,8 +519,8 @@ angularInputType('checkbox', function(inputElement) {
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.color = 'blue';
+ function Ctrl($scope) {
+ $scope.color = 'blue';
}
</script>
<div ng:controller="Ctrl">
@@ -545,9 +542,7 @@ angularInputType('checkbox', function(inputElement) {
</doc:scenario>
</doc:example>
*/
-angularInputType('radio', function(inputElement) {
- var widget = this;
-
+angularInputType('radio', function(inputElement, widget) {
//correct the name
inputElement.attr('name', widget.$id + '@' + inputElement.attr('name'));
inputElement.bind('click', function() {
@@ -569,9 +564,8 @@ angularInputType('radio', function(inputElement) {
function numericRegexpInputType(regexp, error) {
- return ['$element', function(inputElement) {
- var widget = this,
- min = 1 * (inputElement.attr('min') || Number.MIN_VALUE),
+ return function(inputElement, widget) {
+ var min = 1 * (inputElement.attr('min') || Number.MIN_VALUE),
max = 1 * (inputElement.attr('max') || Number.MAX_VALUE);
widget.$on('$validate', function(event){
@@ -598,7 +592,7 @@ function numericRegexpInputType(regexp, error) {
? '' + widget.$modelValue
: '';
};
- }];
+ };
}
@@ -640,8 +634,8 @@ var HTML5_INPUTS_TYPES = makeMap(
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.user = {name: 'guest', last: 'visitor'};
+ function Ctrl($scope) {
+ $scope.user = {name: 'guest', last: 'visitor'};
}
</script>
<div ng:controller="Ctrl">
@@ -713,7 +707,8 @@ angularWidget('input', function(inputElement){
this.descend(true);
var modelExp = inputElement.attr('ng:model');
return modelExp &&
- ['$defer', '$formFactory', '$element', function($defer, $formFactory, inputElement){
+ ['$defer', '$formFactory', '$element',
+ function($defer, $formFactory, inputElement) {
var form = $formFactory.forElement(inputElement),
// We have to use .getAttribute, since jQuery tries to be smart and use the
// type property. Trouble is some browser change unknown to text.
@@ -762,7 +757,7 @@ angularWidget('input', function(inputElement){
}
//TODO(misko): setting $inject is a hack
- !TypeController.$inject && (TypeController.$inject = ['$element']);
+ !TypeController.$inject && (TypeController.$inject = ['$element', '$scope']);
widget = form.$createWidget({
scope: modelScope,
model: modelExp,
@@ -866,7 +861,7 @@ angularWidget('textarea', angularWidget('input'));
function watchElementProperty(modelScope, widget, name, element) {
var bindAttr = fromJson(element.attr('ng:bind-attr') || '{}'),
- match = /\s*{{(.*)}}\s*/.exec(bindAttr[name]),
+ match = /\s*\{\{(.*)\}\}\s*/.exec(bindAttr[name]),
isBoolean = BOOLEAN_ATTR[name];
widget['$' + name] = isBoolean
? ( // some browsers return true some '' when required is set without value.
diff --git a/src/widget/select.js b/src/widget/select.js
index d4be91d9..b0f5eac5 100644
--- a/src/widget/select.js
+++ b/src/widget/select.js
@@ -65,15 +65,15 @@
<doc:example>
<doc:source>
<script>
- function MyCntrl() {
- this.colors = [
+ function MyCntrl($scope) {
+ $scope.colors = [
{name:'black', shade:'dark'},
{name:'white', shade:'light'},
{name:'red', shade:'dark'},
{name:'blue', shade:'dark'},
{name:'yellow', shade:'light'}
];
- this.color = this.colors[2]; // red
+ $scope.color = $scope.colors[2]; // red
}
</script>
<div ng:controller="MyCntrl">
@@ -140,11 +140,11 @@ angularWidget('select', function(element){
optionsExp = selectElement.attr('ng:options'),
modelExp = selectElement.attr('ng:model'),
widget = form.$createWidget({
- scope: this,
+ scope: modelScope,
model: modelExp,
onChange: selectElement.attr('ng:change'),
alias: selectElement.attr('name'),
- controller: optionsExp ? Options : (multiple ? Multiple : Single)});
+ controller: ['$scope', optionsExp ? Options : (multiple ? Multiple : Single)]});
selectElement.bind('$destroy', function() { widget.$destroy(); });
@@ -174,11 +174,9 @@ angularWidget('select', function(element){
////////////////////////////
- function Multiple() {
- var widget = this;
-
- this.$render = function() {
- var items = new HashMap(this.$viewValue);
+ function Multiple(widget) {
+ widget.$render = function() {
+ var items = new HashMap(widget.$viewValue);
forEach(selectElement.children(), function(option){
option.selected = isDefined(items.get(option.value));
});
@@ -198,9 +196,7 @@ angularWidget('select', function(element){
}
- function Single() {
- var widget = this;
-
+ function Single(widget) {
widget.$render = function() {
selectElement.val(widget.$viewValue);
};
@@ -214,9 +210,8 @@ angularWidget('select', function(element){
widget.$viewValue = selectElement.val();
}
- function Options() {
- var widget = this,
- match;
+ function Options(widget) {
+ var match;
if (! (match = optionsExp.match(NG_OPTIONS_REGEXP))) {
throw Error(
@@ -224,8 +219,7 @@ angularWidget('select', function(element){
" but got '" + optionsExp + "'.");
}
- var widgetScope = this,
- displayFn = $parse(match[2] || match[1]),
+ var displayFn = $parse(match[2] || match[1]),
valueName = match[4] || match[6],
keyName = match[5],
groupByFn = $parse(match[3] || ''),
@@ -253,7 +247,7 @@ angularWidget('select', function(element){
selectElement.html(''); // clear contents
selectElement.bind('change', function() {
- widgetScope.$apply(function() {
+ widget.$apply(function() {
var optionGroup,
collection = valuesFn(modelScope) || [],
key = selectElement.val(),
@@ -288,13 +282,13 @@ angularWidget('select', function(element){
}
}
if (isDefined(value) && modelScope.$viewVal !== value) {
- widgetScope.$emit('$viewChange', value);
+ widget.$emit('$viewChange', value);
}
});
});
- widgetScope.$watch(render);
- widgetScope.$render = render;
+ widget.$watch(render);
+ widget.$render = render;
function render() {
var optionGroups = {'':[]}, // Temporary location for the option groups before we render them
diff --git a/src/widgets.js b/src/widgets.js
index 09a800de..6b3e93ee 100644
--- a/src/widgets.js
+++ b/src/widgets.js
@@ -54,11 +54,11 @@
<doc:example>
<doc:source jsfiddle="false">
<script>
- function Ctrl() {
- this.templates =
+ function Ctrl($scope) {
+ $scope.templates =
[ { name: 'template1.html', url: 'examples/ng-include/template1.html'}
, { name: 'template2.html', url: 'examples/ng-include/template2.html'} ];
- this.template = this.templates[0];
+ $scope.template = $scope.templates[0];
}
</script>
<div ng:controller="Ctrl">
@@ -171,9 +171,9 @@ angularWidget('ng:include', function(element){
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.items = ['settings', 'home', 'other'];
- this.selection = this.items[0];
+ function Ctrl($scope) {
+ $scope.items = ['settings', 'home', 'other'];
+ $scope.selection = $scope.items[0];
}
</script>
<div ng:controller="Ctrl">
@@ -701,10 +701,10 @@ angularWidget('ng:view', function(element) {
<doc:example>
<doc:source>
<script>
- function Ctrl() {
- this.person1 = 'Igor';
- this.person2 = 'Misko';
- this.personCount = 1;
+ function Ctrl($scope) {
+ $scope.person1 = 'Igor';
+ $scope.person2 = 'Misko';
+ $scope.personCount = 1;
}
</script>
<div ng:controller="Ctrl">
diff --git a/test/directivesSpec.js b/test/directivesSpec.js
index 1825dc49..7600a9c8 100644
--- a/test/directivesSpec.js
+++ b/test/directivesSpec.js
@@ -460,60 +460,66 @@ describe("directive", function() {
});
describe('ng:controller', function() {
+ var element;
- var temp;
+ beforeEach(inject(function($window) {
+ $window.Greeter = function($scope) {
+ // private stuff (not exported to scope)
+ this.prefix = 'Hello ';
- beforeEach(function() {
- temp = window.temp = {};
- temp.Greeter = function() {
- this.$root.greeter = this;
- this.greeting = 'hello';
- this.suffix = '!';
+ // public stuff (exported to scope)
+ var ctrl = this;
+ $scope.name = 'Misko';
+ $scope.greet = function(name) {
+ return ctrl.prefix + name + ctrl.suffix;
+ };
+
+ $scope.protoGreet = bind(this, this.protoGreet);
};
- temp.Greeter.prototype = {
- greet: function(name) {
- return this.greeting + ' ' + name + this.suffix;
+ $window.Greeter.prototype = {
+ suffix: '!',
+ protoGreet: function(name) {
+ return this.prefix + name + this.suffix;
}
};
- });
+
+ $window.Child = function($scope) {
+ $scope.name = 'Adam';
+ };
+ }));
afterEach(function() {
- window.temp = undefined;
+ dealoc(element);
});
- it('should bind', inject(function($rootScope, $compile) {
- var element = $compile('<div ng:controller="temp.Greeter"></div>')($rootScope);
- expect($rootScope.greeter.greeting).toEqual('hello');
- expect($rootScope.greeter.greet('misko')).toEqual('hello misko!');
+
+ it('should instantiate controller and bind methods', inject(function($compile, $rootScope) {
+ element = $compile('<div ng:controller="Greeter">{{greet(name)}}</div>')($rootScope);
+ $rootScope.$digest();
+ expect(element.text()).toBe('Hello Misko!');
}));
- it('should support nested controllers', inject(function($rootScope, $compile) {
- temp.ChildGreeter = function() {
- this.greeting = 'hey';
- this.$root.childGreeter = this;
- };
- temp.ChildGreeter.prototype = {
- greet: function() {
- return this.greeting + ' dude' + this.suffix;
- }
- };
- var element = $compile('<div ng:controller="temp.Greeter"><div ng:controller="temp.ChildGreeter">{{greet("misko")}}</div></div>')($rootScope);
- expect($rootScope.greeting).not.toBeDefined();
- expect($rootScope.greeter.greeting).toEqual('hello');
- expect($rootScope.greeter.greet('misko')).toEqual('hello misko!');
- expect($rootScope.greeter.greeting).toEqual('hello');
- expect($rootScope.childGreeter.greeting).toEqual('hey');
- expect($rootScope.childGreeter.$parent.greeting).toEqual('hello');
+
+ it('should allow nested controllers', inject(function($compile, $rootScope) {
+ element = $compile('<div ng:controller="Greeter"><div ng:controller="Child">{{greet(name)}}</div></div>')($rootScope);
+ $rootScope.$digest();
+ expect(element.text()).toBe('Hello Adam!');
+ dealoc(element);
+
+ element = $compile('<div ng:controller="Greeter"><div ng:controller="Child">{{protoGreet(name)}}</div></div>')($rootScope);
$rootScope.$digest();
- expect(element.text()).toEqual('hey dude!');
+ expect(element.text()).toBe('Hello Adam!');
}));
- it('should infer injection arguments', inject(function($rootScope, $compile, $http) {
- temp.MyController = function($http) {
- this.$root.someService = $http;
+
+ it('should instantiate controller defined on scope', inject(function($compile, $rootScope) {
+ $rootScope.Greeter = function($scope) {
+ $scope.name = 'Vojta';
};
- var element = $compile('<div ng:controller="temp.MyController"></div>')($rootScope);
- expect($rootScope.someService).toBe($http);
+
+ element = $compile('<div ng:controller="Greeter">{{name}}</div>')($rootScope);
+ $rootScope.$digest();
+ expect(element.text()).toBe('Vojta');
}));
});
diff --git a/test/scenario/RunnerSpec.js b/test/scenario/RunnerSpec.js
index 15bcc4b0..c4ad6f95 100644
--- a/test/scenario/RunnerSpec.js
+++ b/test/scenario/RunnerSpec.js
@@ -43,9 +43,6 @@ describe('angular.scenario.Runner', function() {
location: {}
};
runner = new angular.scenario.Runner($window);
- runner.createSpecRunner_ = function(scope) {
- return scope.$new(MockSpecRunner);
- };
runner.on('SpecError', angular.mock.rethrow);
runner.on('StepError', angular.mock.rethrow);
});
diff --git a/test/scenario/SpecRunnerSpec.js b/test/scenario/SpecRunnerSpec.js
index 4cffc63a..c104a9b7 100644
--- a/test/scenario/SpecRunnerSpec.js
+++ b/test/scenario/SpecRunnerSpec.js
@@ -40,7 +40,13 @@ describe('angular.scenario.SpecRunner', function() {
};
$root.application = new ApplicationMock($window);
$root.$window = $window;
- runner = $root.$new(angular.scenario.SpecRunner);
+ runner = $root.$new();
+
+ var Cls = angular.scenario.SpecRunner;
+ for (var name in Cls.prototype)
+ runner[name] = angular.bind(runner, Cls.prototype[name]);
+
+ Cls.call(runner);
}));
it('should bind futures to the spec', function() {
diff --git a/test/service/formFactorySpec.js b/test/service/formFactorySpec.js
index fbe601c6..1a23aa49 100644
--- a/test/service/formFactorySpec.js
+++ b/test/service/formFactorySpec.js
@@ -13,23 +13,24 @@ describe('$formFactory', function() {
var scope;
var log;
- function WidgetCtrl($formFactory){
- this.$formFactory = $formFactory;
+ function WidgetCtrl($formFactory, $scope) {
log += '<init>';
- this.$render = function() {
+ $scope.$render = function() {
log += '$render();';
};
- this.$on('$validate', function(e){
+ $scope.$on('$validate', function(e){
log += '$validate();';
});
+
+ this.$formFactory = $formFactory;
}
- WidgetCtrl.$inject = ['$formFactory'];
+ WidgetCtrl.$inject = ['$formFactory', '$scope'];
WidgetCtrl.prototype = {
- getFormFactory: function() {
- return this.$formFactory;
- }
+ getFormFactory: function() {
+ return this.$formFactory;
+ }
};
beforeEach(inject(function($rootScope, $formFactory) {
@@ -70,11 +71,6 @@ describe('$formFactory', function() {
expect(widget.$modelValue).toEqual('xyz');
}));
-
-
- it('should have controller prototype methods', inject(function($rootScope, $formFactory) {
- expect(widget.getFormFactory()).toEqual($formFactory);
- }));
});
diff --git a/test/service/routeSpec.js b/test/service/routeSpec.js
index 95560d29..1bb1312f 100644
--- a/test/service/routeSpec.js
+++ b/test/service/routeSpec.js
@@ -112,7 +112,7 @@ describe('$route', function() {
inject(function($route, $location, $rootScope) {
var onChangeSpy = jasmine.createSpy('onChange');
- function NotFoundCtrl() {this.notFoundProp = 'not found!';}
+ function NotFoundCtrl($scope) {$scope.notFoundProp = 'not found!';}
$route.when('/foo', {template: 'foo.html'});
$route.otherwise({template: '404.html', controller: NotFoundCtrl});
@@ -169,10 +169,11 @@ describe('$route', function() {
it('should infer arguments in injection', inject(function($route, $location, $rootScope) {
- $route.when('/test', {controller: function($route){ this.$route = $route; }});
+ var injectedRoute;
+ $route.when('/test', {controller: function($route) {injectedRoute = $route;}});
$location.path('/test');
$rootScope.$digest();
- expect($route.current.scope.$route).toBe($route);
+ expect(injectedRoute).toBe($route);
}));
@@ -304,9 +305,9 @@ describe('$route', function() {
$route.when('/foo', {controller: FooCtrl, reloadOnSearch: false});
$rootScope.$on('$beforeRouteChange', reloaded);
- function FooCtrl() {
+ function FooCtrl($scope) {
reloaded();
- this.$on('$routeUpdate', routeUpdateEvent);
+ $scope.$on('$routeUpdate', routeUpdateEvent);
}
expect(reloaded).not.toHaveBeenCalled();
@@ -368,8 +369,8 @@ describe('$route', function() {
$route.when('/foo', {controller: FooCtrl});
$route.when('/bar/:barId', {controller: FooCtrl, reloadOnSearch: false});
- function FooCtrl() {
- this.$watch(function() {
+ function FooCtrl($scope) {
+ $scope.$watch(function() {
return $route.current.params;
}, function(scope, value) {
routeParams(value);
@@ -414,10 +415,10 @@ describe('$route', function() {
}
function createController(name) {
- return function() {
+ return function($scope) {
log.push('init-' + name);
- this.$on('$destroy', logger('destroy-' + name));
- this.$on('$routeUpdate', logger('route-update'));
+ $scope.$on('$destroy', logger('destroy-' + name));
+ $scope.$on('$routeUpdate', logger('route-update'));
};
}
diff --git a/test/service/scopeSpec.js b/test/service/scopeSpec.js
index 96271bc9..68ef2834 100644
--- a/test/service/scopeSpec.js
+++ b/test/service/scopeSpec.js
@@ -53,35 +53,6 @@ describe('Scope', function() {
$rootScope.a = 123;
expect(child.a).toEqual(123);
}));
-
-
- it('should instantiate controller and bind functions', inject(function($rootScope) {
- function Cntl($browser, name) {
- this.$browser = $browser;
- this.callCount = 0;
- this.name = name;
- }
- Cntl.$inject = ['$browser', 'name'];
-
- Cntl.prototype = {
- myFn: function() {
- expect(this).toEqual(cntl);
- this.callCount++;
- }
- };
-
- var cntl = $rootScope.$new(Cntl, {name:'misko'});
-
- expect($rootScope.$browser).toBeUndefined();
- expect($rootScope.myFn).toBeUndefined();
-
- expect(cntl.$browser).toBeDefined();
- expect(cntl.name).toEqual('misko');
-
- cntl.myFn();
- cntl.$new().myFn();
- expect(cntl.callCount).toEqual(2);
- }));
});
@@ -341,7 +312,7 @@ describe('Scope', function() {
$rootScope.$digest();
expect(isNaN(log.shift())).toBe(true); //jasmine's toBe and toEqual don't work well with NaNs
expect(log).toEqual([undefined, '', false, {}, 23]);
- log = []
+ log = [];
$rootScope.$digest();
expect(log).toEqual([]);
}));
diff --git a/test/widgetsSpec.js b/test/widgetsSpec.js
index f119174f..88d9e1b8 100644
--- a/test/widgetsSpec.js
+++ b/test/widgetsSpec.js
@@ -713,12 +713,12 @@ describe('widget', function() {
$route.when('/foo', {controller: ParentCtrl, template: 'viewPartial.html'});
$rootScope.log = [];
- function ParentCtrl() {
- this.log.push('parent');
+ function ParentCtrl($scope) {
+ $scope.log.push('parent');
}
- $rootScope.ChildCtrl = function() {
- this.log.push('child');
+ $rootScope.ChildCtrl = function($scope) {
+ $scope.log.push('child');
};
$location.path('/foo');