From f54db2ccda399f2677e4ca7588018cb31545a2b4 Mon Sep 17 00:00:00 2001
From: Igor Minar
Date: Thu, 8 Mar 2012 15:00:38 -0800
Subject: chore(directives,widgets): reorg the code under directive/ dir
---
src/directive/a.js | 29 +
src/directive/booleanAttrDirs.js | 282 +++++++++
src/directive/directives.js | 11 +
src/directive/form.js | 235 ++++++++
src/directive/input.js | 1171 ++++++++++++++++++++++++++++++++++++++
src/directive/ngBind.js | 249 ++++++++
src/directive/ngClass.js | 143 +++++
src/directive/ngCloak.js | 61 ++
src/directive/ngController.js | 103 ++++
src/directive/ngEventDirs.js | 222 ++++++++
src/directive/ngInclude.js | 119 ++++
src/directive/ngInit.js | 37 ++
src/directive/ngNonBindable.js | 34 ++
src/directive/ngPluralize.js | 204 +++++++
src/directive/ngRepeat.js | 182 ++++++
src/directive/ngShowHide.js | 80 +++
src/directive/ngStyle.js | 42 ++
src/directive/ngSwitch.js | 110 ++++
src/directive/ngTransclude.js | 58 ++
src/directive/ngView.js | 169 ++++++
src/directive/script.js | 42 ++
src/directive/select.js | 444 +++++++++++++++
src/directive/style.js | 6 +
src/directives.js | 1031 ---------------------------------
src/markups.js | 269 ---------
src/widget/form.js | 235 --------
src/widget/input.js | 1171 --------------------------------------
src/widget/select.js | 444 ---------------
src/widgets.js | 876 ----------------------------
29 files changed, 4033 insertions(+), 4026 deletions(-)
create mode 100644 src/directive/a.js
create mode 100644 src/directive/booleanAttrDirs.js
create mode 100644 src/directive/directives.js
create mode 100644 src/directive/form.js
create mode 100644 src/directive/input.js
create mode 100644 src/directive/ngBind.js
create mode 100644 src/directive/ngClass.js
create mode 100644 src/directive/ngCloak.js
create mode 100644 src/directive/ngController.js
create mode 100644 src/directive/ngEventDirs.js
create mode 100644 src/directive/ngInclude.js
create mode 100644 src/directive/ngInit.js
create mode 100644 src/directive/ngNonBindable.js
create mode 100644 src/directive/ngPluralize.js
create mode 100644 src/directive/ngRepeat.js
create mode 100644 src/directive/ngShowHide.js
create mode 100644 src/directive/ngStyle.js
create mode 100644 src/directive/ngSwitch.js
create mode 100644 src/directive/ngTransclude.js
create mode 100644 src/directive/ngView.js
create mode 100644 src/directive/script.js
create mode 100644 src/directive/select.js
create mode 100644 src/directive/style.js
delete mode 100644 src/directives.js
delete mode 100644 src/markups.js
delete mode 100644 src/widget/form.js
delete mode 100644 src/widget/input.js
delete mode 100644 src/widget/select.js
(limited to 'src')
diff --git a/src/directive/a.js b/src/directive/a.js
new file mode 100644
index 00000000..bd56f3be
--- /dev/null
+++ b/src/directive/a.js
@@ -0,0 +1,29 @@
+'use strict';
+
+/*
+ * Modifies the default behavior of html A tag, so that the default action is prevented when href
+ * attribute is empty.
+ *
+ * The reasoning for this change is to allow easy creation of action links with ng:click without
+ * changing the location or causing page reloads, e.g.:
+ * Save
+ */
+var htmlAnchorDirective = valueFn({
+ restrict: 'E',
+ compile: function(element, attr) {
+ // turn link into a link in IE
+ // but only if it doesn't have name attribute, in which case it's an anchor
+ if (!attr.href) {
+ attr.$set('href', '');
+ }
+
+ return function(scope, element) {
+ element.bind('click', function(event){
+ // if we have no href url, then don't navigate anywhere.
+ if (!element.attr('href')) {
+ event.preventDefault();
+ }
+ });
+ }
+ }
+});
diff --git a/src/directive/booleanAttrDirs.js b/src/directive/booleanAttrDirs.js
new file mode 100644
index 00000000..06b85823
--- /dev/null
+++ b/src/directive/booleanAttrDirs.js
@@ -0,0 +1,282 @@
+'use strict';
+
+/**
+ * @ngdoc directive
+ * @name angular.module.ng.$compileProvider.directive.ng:href
+ *
+ * @description
+ * Using markup like {{hash}} in an href attribute makes
+ * the page open to a wrong URL, if the user clicks that link before
+ * angular has a chance to replace the {{hash}} with actual URL, the
+ * link will be broken and will most likely return a 404 error.
+ * The `ng:href` solves this problem by placing the `href` in the
+ * `ng:` namespace.
+ *
+ * The buggy way to write it:
+ *
+ *
+ *
+ *
+ * The correct way to write it:
+ *
+ *
+ *
+ *
+ * @element ANY
+ * @param {template} template any string which can contain `{{}}` markup.
+ *
+ * @example
+ * This example uses `link` variable inside `href` attribute:
+
+
+
+ link 1 (link, don't reload)
+ link 2 (link, don't reload)
+ link 3 (link, reload!)
+ anchor (link, don't reload)
+ anchor (no link)
+ link (link, change hash)
+
+
+ it('should execute ng:click but not reload when href without value', function() {
+ element('#link-1').click();
+ expect(input('value').val()).toEqual('1');
+ expect(element('#link-1').attr('href')).toBe("");
+ });
+
+ it('should execute ng:click but not reload when href empty string', function() {
+ element('#link-2').click();
+ expect(input('value').val()).toEqual('2');
+ expect(element('#link-2').attr('href')).toBe("");
+ });
+
+ it('should execute ng:click and change url when ng:href specified', function() {
+ expect(element('#link-3').attr('href')).toBe("/123");
+
+ element('#link-3').click();
+ expect(browser().window().path()).toEqual('/123');
+ });
+
+ it('should execute ng:click but not reload when href empty string and name specified', function() {
+ element('#link-4').click();
+ expect(input('value').val()).toEqual('4');
+ expect(element('#link-4').attr('href')).toBe("");
+ });
+
+ it('should execute ng:click but not reload when no href but name specified', function() {
+ element('#link-5').click();
+ expect(input('value').val()).toEqual('5');
+ expect(element('#link-5').attr('href')).toBe("");
+ });
+
+ it('should only change url when only ng:href', function() {
+ input('value').enter('6');
+ expect(element('#link-6').attr('href')).toBe("/6");
+
+ element('#link-6').click();
+ expect(browser().window().path()).toEqual('/6');
+ });
+
+
+ */
+
+/**
+ * @ngdoc directive
+ * @name angular.module.ng.$compileProvider.directive.ng:src
+ *
+ * @description
+ * Using markup like `{{hash}}` in a `src` attribute doesn't
+ * work right: The browser will fetch from the URL with the literal
+ * text `{{hash}}` until replaces the expression inside
+ * `{{hash}}`. The `ng:src` attribute solves this problem by placing
+ * the `src` attribute in the `ng:` namespace.
+ *
+ * The buggy way to write it:
+ *
+ *
+ *
+ *
+ * The correct way to write it:
+ *
+ *
+ *
+ *
+ * @element ANY
+ * @param {template} template any string which can contain `{{}}` markup.
+ */
+
+/**
+ * @ngdoc directive
+ * @name angular.module.ng.$compileProvider.directive.ng:disabled
+ *
+ * @description
+ *
+ * The following markup will make the button enabled on Chrome/Firefox but not on IE8 and older IEs:
+ *
+ *
+ *
+ *
+ *
+ *
+ * The HTML specs do not require browsers to preserve the special attributes such as disabled.
+ * (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 ng:disabled.
+ *
+ * @example
+
+
+ Click me to toggle:
+
+
+
+ it('should toggle button', function() {
+ expect(element('.doc-example-live :button').prop('disabled')).toBeFalsy();
+ input('checked').check();
+ expect(element('.doc-example-live :button').prop('disabled')).toBeTruthy();
+ });
+
+
+ *
+ * @element ANY
+ * @param {template} template any string which can contain '{{}}' markup.
+ */
+
+
+/**
+ * @ngdoc directive
+ * @name angular.module.ng.$compileProvider.directive.ng:checked
+ *
+ * @description
+ * The HTML specs do not require browsers to preserve the special attributes such as checked.
+ * (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 ng:checked.
+ * @example
+
+
+ Check me to check both:
+
+
+
+ it('should check both checkBoxes', function() {
+ expect(element('.doc-example-live #checkSlave').prop('checked')).toBeFalsy();
+ input('master').check();
+ expect(element('.doc-example-live #checkSlave').prop('checked')).toBeTruthy();
+ });
+
+
+ *
+ * @element ANY
+ * @param {template} template any string which can contain '{{}}' markup.
+ */
+
+
+/**
+ * @ngdoc directive
+ * @name angular.module.ng.$compileProvider.directive.ng:multiple
+ *
+ * @description
+ * The HTML specs do not require browsers to preserve the special attributes such as multiple.
+ * (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 ng:multiple.
+ *
+ * @example
+
+
+ Check me check multiple:
+
+
+
+ it('should toggle multiple', function() {
+ expect(element('.doc-example-live #select').prop('multiple')).toBeFalsy();
+ input('checked').check();
+ expect(element('.doc-example-live #select').prop('multiple')).toBeTruthy();
+ });
+
+
+ *
+ * @element ANY
+ * @param {template} template any string which can contain '{{}}' markup.
+ */
+
+
+/**
+ * @ngdoc directive
+ * @name angular.module.ng.$compileProvider.directive.ng:readonly
+ *
+ * @description
+ * The HTML specs do not require browsers to preserve the special attributes such as readonly.
+ * (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 ng:readonly.
+ * @example
+
+
+ Check me to make text readonly:
+
+
+
+ it('should toggle readonly attr', function() {
+ expect(element('.doc-example-live :text').prop('readonly')).toBeFalsy();
+ input('checked').check();
+ expect(element('.doc-example-live :text').prop('readonly')).toBeTruthy();
+ });
+
+
+ *
+ * @element ANY
+ * @param {template} template any string which can contain '{{}}' markup.
+ */
+
+
+/**
+* @ngdoc directive
+* @name angular.module.ng.$compileProvider.directive.ng:selected
+*
+* @description
+* The HTML specs do not require browsers to preserve the special attributes such as selected.
+* (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 ng:selected.
+* @example
+
+
+ Check me to select:
+
+
+
+ it('should select Greetings!', function() {
+ expect(element('.doc-example-live #greet').prop('selected')).toBeFalsy();
+ input('checked').check();
+ expect(element('.doc-example-live #greet').prop('selected')).toBeTruthy();
+ });
+
+
+* @element ANY
+* @param {template} template any string which can contain '{{}}' markup.
+*/
+
+
+function ngAttributeAliasDirective(propName, attrName) {
+ ngAttributeAliasDirectives[directiveNormalize('ng-' + attrName)] = valueFn(
+ function(scope, element, attr) {
+ attr.$observe(directiveNormalize('ng-' + attrName), function(value) {
+ attr.$set(attrName, value);
+ });
+ }
+ );
+}
+
+var ngAttributeAliasDirectives = {};
+forEach(BOOLEAN_ATTR, ngAttributeAliasDirective);
+ngAttributeAliasDirective(null, 'src');
diff --git a/src/directive/directives.js b/src/directive/directives.js
new file mode 100644
index 00000000..123645f9
--- /dev/null
+++ b/src/directive/directives.js
@@ -0,0 +1,11 @@
+'use strict';
+
+function ngDirective(directive) {
+ if (isFunction(directive)) {
+ directive = {
+ link: directive
+ }
+ }
+ directive.restrict = directive.restrict || 'AC';
+ return valueFn(directive);
+};
diff --git a/src/directive/form.js b/src/directive/form.js
new file mode 100644
index 00000000..c3e6b21d
--- /dev/null
+++ b/src/directive/form.js
@@ -0,0 +1,235 @@
+'use strict';
+
+
+/**
+ * @ngdoc object
+ * @name angular.module.ng.$compileProvider.directive.form.FormController
+ *
+ * @property {boolean} pristine True if user has not interacted with the form yet.
+ * @property {boolean} dirty True if user has already interacted with the form.
+ * @property {boolean} valid True if all of the containg widgets are valid.
+ * @property {boolean} invalid True if at least one containing widget is invalid.
+ *
+ * @property {Object} error Is an object hash, containing references to all invalid widgets, where
+ *
+ * - keys are error ids (such as `REQUIRED`, `URL` or `EMAIL`),
+ * - values are arrays of widgets that are invalid with given error.
+ *
+ * @description
+ * `FormController` keeps track of all its widgets as well as state of them form, such as being valid/invalid or dirty/pristine.
+ *
+ * Each {@link angular.module.ng.$compileProvider.directive.form form} directive creates an instance
+ * of `FormController`.
+ *
+ */
+FormController.$inject = ['$scope', 'name'];
+function FormController($scope, name) {
+ var form = this,
+ errors = form.error = {};
+
+ // publish the form into scope
+ name(this);
+
+ $scope.$on('$destroy', function(event, widget) {
+ if (!widget) return;
+
+ if (widget.widgetId) {
+ delete form[widget.widgetId];
+ }
+ forEach(errors, removeWidget, widget);
+ });
+
+ $scope.$on('$valid', function(event, error, widget) {
+ removeWidget(errors[error], error, widget);
+
+ if (equals(errors, {})) {
+ form.valid = true;
+ form.invalid = false;
+ }
+ });
+
+ $scope.$on('$invalid', function(event, error, widget) {
+ addWidget(error, widget);
+
+ form.valid = false;
+ form.invalid = true;
+ });
+
+ $scope.$on('$viewTouch', function() {
+ form.dirty = true;
+ form.pristine = false;
+ });
+
+ // init state
+ form.dirty = false;
+ form.pristine = true;
+ form.valid = true;
+ form.invalid = false;
+
+ function removeWidget(queue, errorKey, widget) {
+ if (queue) {
+ widget = widget || this; // so that we can be used in forEach;
+ for (var i = 0, length = queue.length; i < length; i++) {
+ if (queue[i] === widget) {
+ queue.splice(i, 1);
+ if (!queue.length) {
+ delete errors[errorKey];
+ }
+ }
+ }
+ }
+ }
+
+ function addWidget(errorKey, widget) {
+ var queue = errors[errorKey];
+ if (queue) {
+ for (var i = 0, length = queue.length; i < length; i++) {
+ if (queue[i] === widget) {
+ return;
+ }
+ }
+ } else {
+ errors[errorKey] = queue = [];
+ }
+ queue.push(widget);
+ }
+}
+
+/**
+ * @ngdoc function
+ * @name angular.module.ng.$compileProvider.directive.form.FormController#registerWidget
+ * @methodOf angular.module.ng.$compileProvider.directive.form.FormController
+ * @function
+ *
+ * @param {Object} widget Widget to register (controller of a widget)
+ * @param {string=} alias Name alias of the widget.
+ * (If specified, widget will be accesible as a form property)
+ *
+ * @description
+ *
+ */
+FormController.prototype.registerWidget = function(widget, alias) {
+ if (alias && !this.hasOwnProperty(alias)) {
+ widget.widgetId = alias;
+ this[alias] = widget;
+ }
+};
+
+
+/**
+ * @ngdoc directive
+ * @name angular.module.ng.$compileProvider.directive.form
+ *
+ * @scope
+ * @description
+ * Directive that instantiates
+ * {@link angular.module.ng.$compileProvider.directive.form.FormController FormController}.
+ *
+ * If `name` attribute is specified, the controller is published to the scope as well.
+ *
+ * # Alias: `ng:form`
+ *
+ * In angular forms can be nested. This means that the outer form is valid when all of the child
+ * forms are valid as well. However browsers do not allow nesting of `