@angular-wave/angular.ts 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +1 -0
- package/.eslintrc.cjs +29 -0
- package/.github/workflows/playwright.yml +27 -0
- package/CHANGELOG.md +17974 -0
- package/CODE_OF_CONDUCT.md +3 -0
- package/CONTRIBUTING.md +246 -0
- package/DEVELOPERS.md +488 -0
- package/LICENSE +22 -0
- package/Makefile +31 -0
- package/README.md +115 -0
- package/RELEASE.md +98 -0
- package/SECURITY.md +16 -0
- package/TRIAGING.md +135 -0
- package/css/angular.css +22 -0
- package/dist/angular-ts.cjs.js +36843 -0
- package/dist/angular-ts.esm.js +36841 -0
- package/dist/angular-ts.umd.js +36848 -0
- package/dist/build/angular-animate.js +4272 -0
- package/dist/build/angular-aria.js +426 -0
- package/dist/build/angular-message-format.js +1072 -0
- package/dist/build/angular-messages.js +829 -0
- package/dist/build/angular-mocks.js +3757 -0
- package/dist/build/angular-parse-ext.js +1275 -0
- package/dist/build/angular-resource.js +911 -0
- package/dist/build/angular-route.js +1266 -0
- package/dist/build/angular-sanitize.js +891 -0
- package/dist/build/angular-touch.js +368 -0
- package/dist/build/angular.js +36600 -0
- package/e2e/unit.spec.ts +15 -0
- package/images/android-chrome-192x192.png +0 -0
- package/images/android-chrome-512x512.png +0 -0
- package/images/apple-touch-icon.png +0 -0
- package/images/favicon-16x16.png +0 -0
- package/images/favicon-32x32.png +0 -0
- package/images/favicon.ico +0 -0
- package/images/site.webmanifest +1 -0
- package/index.html +104 -0
- package/package.json +47 -0
- package/playwright.config.ts +78 -0
- package/public/circle.html +1 -0
- package/public/my_child_directive.html +1 -0
- package/public/my_directive.html +1 -0
- package/public/my_other_directive.html +1 -0
- package/public/test.html +1 -0
- package/rollup.config.js +31 -0
- package/src/animations/animateCache.js +55 -0
- package/src/animations/animateChildrenDirective.js +105 -0
- package/src/animations/animateCss.js +1139 -0
- package/src/animations/animateCssDriver.js +291 -0
- package/src/animations/animateJs.js +367 -0
- package/src/animations/animateJsDriver.js +67 -0
- package/src/animations/animateQueue.js +851 -0
- package/src/animations/animation.js +506 -0
- package/src/animations/module.js +779 -0
- package/src/animations/ngAnimateSwap.js +119 -0
- package/src/animations/rafScheduler.js +50 -0
- package/src/animations/shared.js +378 -0
- package/src/constants.js +20 -0
- package/src/core/animate.js +845 -0
- package/src/core/animateCss.js +73 -0
- package/src/core/animateRunner.js +195 -0
- package/src/core/attributes.js +199 -0
- package/src/core/cache.js +45 -0
- package/src/core/compile.js +4727 -0
- package/src/core/controller.js +225 -0
- package/src/core/exceptionHandler.js +63 -0
- package/src/core/filter.js +146 -0
- package/src/core/interpolate.js +442 -0
- package/src/core/interval.js +188 -0
- package/src/core/intervalFactory.js +57 -0
- package/src/core/location.js +1086 -0
- package/src/core/parser/parse.js +2562 -0
- package/src/core/parser/parse.md +13 -0
- package/src/core/q.js +746 -0
- package/src/core/rootScope.js +1596 -0
- package/src/core/sanitizeUri.js +85 -0
- package/src/core/sce.js +1161 -0
- package/src/core/taskTrackerFactory.js +125 -0
- package/src/core/timeout.js +121 -0
- package/src/core/urlUtils.js +187 -0
- package/src/core/utils.js +1349 -0
- package/src/directive/a.js +37 -0
- package/src/directive/attrs.js +283 -0
- package/src/directive/bind.js +51 -0
- package/src/directive/bind.md +142 -0
- package/src/directive/change.js +12 -0
- package/src/directive/change.md +25 -0
- package/src/directive/cloak.js +12 -0
- package/src/directive/cloak.md +24 -0
- package/src/directive/events.js +75 -0
- package/src/directive/events.md +166 -0
- package/src/directive/form.js +725 -0
- package/src/directive/init.js +15 -0
- package/src/directive/init.md +41 -0
- package/src/directive/input.js +1783 -0
- package/src/directive/list.js +46 -0
- package/src/directive/list.md +22 -0
- package/src/directive/ngClass.js +249 -0
- package/src/directive/ngController.js +64 -0
- package/src/directive/ngCsp.js +82 -0
- package/src/directive/ngIf.js +134 -0
- package/src/directive/ngInclude.js +217 -0
- package/src/directive/ngModel.js +1356 -0
- package/src/directive/ngModelOptions.js +509 -0
- package/src/directive/ngOptions.js +670 -0
- package/src/directive/ngRef.js +90 -0
- package/src/directive/ngRepeat.js +650 -0
- package/src/directive/ngShowHide.js +255 -0
- package/src/directive/ngSwitch.js +178 -0
- package/src/directive/ngTransclude.js +98 -0
- package/src/directive/non-bindable.js +11 -0
- package/src/directive/non-bindable.md +17 -0
- package/src/directive/script.js +30 -0
- package/src/directive/select.js +624 -0
- package/src/directive/style.js +25 -0
- package/src/directive/style.md +23 -0
- package/src/directive/validators.js +329 -0
- package/src/exts/aria.js +544 -0
- package/src/exts/messages.js +852 -0
- package/src/filters/filter.js +207 -0
- package/src/filters/filter.md +69 -0
- package/src/filters/filters.js +239 -0
- package/src/filters/json.md +16 -0
- package/src/filters/limit-to.js +43 -0
- package/src/filters/limit-to.md +19 -0
- package/src/filters/order-by.js +183 -0
- package/src/filters/order-by.md +83 -0
- package/src/index.js +13 -0
- package/src/injector.js +1034 -0
- package/src/jqLite.js +1117 -0
- package/src/loader.js +1320 -0
- package/src/public.js +215 -0
- package/src/routeToRegExp.js +41 -0
- package/src/services/anchorScroll.js +135 -0
- package/src/services/browser.js +321 -0
- package/src/services/cacheFactory.js +398 -0
- package/src/services/cookieReader.js +72 -0
- package/src/services/document.js +64 -0
- package/src/services/http.js +1537 -0
- package/src/services/httpBackend.js +206 -0
- package/src/services/log.js +160 -0
- package/src/services/templateRequest.js +139 -0
- package/test/angular.spec.js +2153 -0
- package/test/aria/aria.spec.js +1245 -0
- package/test/binding.spec.js +504 -0
- package/test/build-test.html +14 -0
- package/test/injector.spec.js +2327 -0
- package/test/jasmine/jasmine-5.1.2/boot0.js +65 -0
- package/test/jasmine/jasmine-5.1.2/boot1.js +133 -0
- package/test/jasmine/jasmine-5.1.2/jasmine-html.js +963 -0
- package/test/jasmine/jasmine-5.1.2/jasmine.css +320 -0
- package/test/jasmine/jasmine-5.1.2/jasmine.js +10824 -0
- package/test/jasmine/jasmine-5.1.2/jasmine_favicon.png +0 -0
- package/test/jasmine/jasmine-browser.json +17 -0
- package/test/jasmine/jasmine.json +9 -0
- package/test/jqlite.spec.js +2133 -0
- package/test/loader.spec.js +219 -0
- package/test/messages/messages.spec.js +1146 -0
- package/test/min-err.spec.js +174 -0
- package/test/mock-test.html +13 -0
- package/test/module-test.html +15 -0
- package/test/ng/anomate.spec.js +606 -0
- package/test/ng/cache-factor.spec.js +334 -0
- package/test/ng/compile.spec.js +17956 -0
- package/test/ng/controller-provider.spec.js +227 -0
- package/test/ng/cookie-reader.spec.js +98 -0
- package/test/ng/directive/a.spec.js +192 -0
- package/test/ng/directive/bind.spec.js +334 -0
- package/test/ng/directive/boolean.spec.js +136 -0
- package/test/ng/directive/change.spec.js +71 -0
- package/test/ng/directive/class.spec.js +858 -0
- package/test/ng/directive/click.spec.js +38 -0
- package/test/ng/directive/cloak.spec.js +44 -0
- package/test/ng/directive/constoller.spec.js +194 -0
- package/test/ng/directive/element-style.spec.js +92 -0
- package/test/ng/directive/event.spec.js +282 -0
- package/test/ng/directive/form.spec.js +1518 -0
- package/test/ng/directive/href.spec.js +143 -0
- package/test/ng/directive/if.spec.js +402 -0
- package/test/ng/directive/include.spec.js +828 -0
- package/test/ng/directive/init.spec.js +68 -0
- package/test/ng/directive/input.spec.js +3810 -0
- package/test/ng/directive/list.spec.js +170 -0
- package/test/ng/directive/model-options.spec.js +1008 -0
- package/test/ng/directive/model.spec.js +1905 -0
- package/test/ng/directive/non-bindable.spec.js +55 -0
- package/test/ng/directive/options.spec.js +3583 -0
- package/test/ng/directive/ref.spec.js +575 -0
- package/test/ng/directive/repeat.spec.js +1675 -0
- package/test/ng/directive/script.spec.js +52 -0
- package/test/ng/directive/scrset.spec.js +67 -0
- package/test/ng/directive/select.spec.js +2541 -0
- package/test/ng/directive/show-hide.spec.js +253 -0
- package/test/ng/directive/src.spec.js +157 -0
- package/test/ng/directive/style.spec.js +178 -0
- package/test/ng/directive/switch.spec.js +647 -0
- package/test/ng/directive/validators.spec.js +717 -0
- package/test/ng/document.spec.js +52 -0
- package/test/ng/filter/filter.spec.js +714 -0
- package/test/ng/filter/filters.spec.js +35 -0
- package/test/ng/filter/limit-to.spec.js +251 -0
- package/test/ng/filter/order-by.spec.js +891 -0
- package/test/ng/filter.spec.js +149 -0
- package/test/ng/http-backend.spec.js +398 -0
- package/test/ng/http.spec.js +4071 -0
- package/test/ng/interpolate.spec.js +642 -0
- package/test/ng/interval.spec.js +343 -0
- package/test/ng/location.spec.js +3488 -0
- package/test/ng/on.spec.js +229 -0
- package/test/ng/parse.spec.js +4655 -0
- package/test/ng/prop.spec.js +805 -0
- package/test/ng/q.spec.js +2904 -0
- package/test/ng/root-element.spec.js +16 -0
- package/test/ng/sanitize-uri.spec.js +249 -0
- package/test/ng/sce.spec.js +660 -0
- package/test/ng/scope.spec.js +3442 -0
- package/test/ng/template-request.spec.js +236 -0
- package/test/ng/timeout.spec.js +351 -0
- package/test/ng/url-utils.spec.js +156 -0
- package/test/ng/utils.spec.js +144 -0
- package/test/original-test.html +21 -0
- package/test/public.spec.js +34 -0
- package/test/sanitize/bing-html.spec.js +36 -0
- package/test/server/express.js +158 -0
- package/test/test-utils.js +11 -0
- package/tsconfig.json +17 -0
- package/types/angular.d.ts +138 -0
- package/types/global.d.ts +9 -0
- package/types/index.d.ts +2357 -0
- package/types/jqlite.d.ts +558 -0
- package/vite.config.js +14 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isNumberNaN,
|
|
3
|
+
isString,
|
|
4
|
+
toInt,
|
|
5
|
+
minErr,
|
|
6
|
+
isUndefined,
|
|
7
|
+
} from "../core/utils";
|
|
8
|
+
import { REGEX_STRING_REGEXP } from "./attrs";
|
|
9
|
+
import { startingTag } from "../jqLite";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @ngdoc directive
|
|
13
|
+
* @name ngRequiredf
|
|
14
|
+
* @restrict A
|
|
15
|
+
*
|
|
16
|
+
* @param {String} ngRequired AngularJS expression. If it evaluates to `true`, it sets the
|
|
17
|
+
* `required` attribute to the element and adds the `required`
|
|
18
|
+
* {@link ngModel.NgModelController#$validators `validator`}.
|
|
19
|
+
*
|
|
20
|
+
* @description
|
|
21
|
+
*
|
|
22
|
+
* ngRequired adds the required {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.
|
|
23
|
+
* It is most often used for {@link input `input`} and {@link select `select`} controls, but can also be
|
|
24
|
+
* applied to custom controls.
|
|
25
|
+
*
|
|
26
|
+
* The directive sets the `required` attribute on the element if the AngularJS expression inside
|
|
27
|
+
* `ngRequired` evaluates to true. A special directive for setting `required` is necessary because we
|
|
28
|
+
* cannot use interpolation inside `required`. See the {@link guide/interpolation interpolation guide}
|
|
29
|
+
* for more info.
|
|
30
|
+
*
|
|
31
|
+
* The validator will set the `required` error key to true if the `required` attribute is set and
|
|
32
|
+
* calling {@link ngModel.NgModelController#$isEmpty `NgModelController.$isEmpty`} with the
|
|
33
|
+
* {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`} returns `true`. For example, the
|
|
34
|
+
* `$isEmpty()` implementation for `input[text]` checks the length of the `$viewValue`. When developing
|
|
35
|
+
* custom controls, `$isEmpty()` can be overwritten to account for a $viewValue that is not string-based.
|
|
36
|
+
*
|
|
37
|
+
*/
|
|
38
|
+
export const requiredDirective = [
|
|
39
|
+
"$parse",
|
|
40
|
+
($parse) => ({
|
|
41
|
+
restrict: "A",
|
|
42
|
+
require: "?ngModel",
|
|
43
|
+
link(scope, elm, attr, ctrl) {
|
|
44
|
+
if (!ctrl) return;
|
|
45
|
+
// For boolean attributes like required, presence means true
|
|
46
|
+
let value =
|
|
47
|
+
Object.prototype.hasOwnProperty.call(attr, "required") ||
|
|
48
|
+
$parse(attr.ngRequired)(scope);
|
|
49
|
+
|
|
50
|
+
if (!attr.ngRequired) {
|
|
51
|
+
// force truthy in case we are on non input element
|
|
52
|
+
// (input elements do this automatically for boolean attributes like required)
|
|
53
|
+
attr.required = true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
ctrl.$validators.required = function (modelValue, viewValue) {
|
|
57
|
+
return !value || !ctrl.$isEmpty(viewValue);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
attr.$observe("required", (newVal) => {
|
|
61
|
+
if (value !== newVal) {
|
|
62
|
+
value = newVal;
|
|
63
|
+
ctrl.$validate();
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
}),
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @ngdoc directive
|
|
72
|
+
* @name ngPattern
|
|
73
|
+
* @restrict A
|
|
74
|
+
*
|
|
75
|
+
* @param {String|RegExp} ngPattern AngularJS expression that must evaluate to a `RegExp` or a `String`
|
|
76
|
+
* parsable into a `RegExp`, or a `RegExp` literal. See above for
|
|
77
|
+
* more details.
|
|
78
|
+
*
|
|
79
|
+
* @description
|
|
80
|
+
*
|
|
81
|
+
* ngPattern adds the pattern {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.
|
|
82
|
+
* It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.
|
|
83
|
+
*
|
|
84
|
+
* The validator sets the `pattern` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}
|
|
85
|
+
* does not match a RegExp which is obtained from the `ngPattern` attribute value:
|
|
86
|
+
* - the value is an AngularJS expression:
|
|
87
|
+
* - If the expression evaluates to a RegExp object, then this is used directly.
|
|
88
|
+
* - If the expression evaluates to a string, then it will be converted to a RegExp after wrapping it
|
|
89
|
+
* in `^` and `$` characters. For instance, `"abc"` will be converted to `new RegExp('^abc$')`.
|
|
90
|
+
* - If the value is a RegExp literal, e.g. `ngPattern="/^\d+$/"`, it is used directly.
|
|
91
|
+
*
|
|
92
|
+
* <div class="alert alert-info">
|
|
93
|
+
* **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to
|
|
94
|
+
* start at the index of the last search's match, thus not taking the whole input value into
|
|
95
|
+
* account.
|
|
96
|
+
* </div>
|
|
97
|
+
*
|
|
98
|
+
* <div class="alert alert-info">
|
|
99
|
+
* **Note:** This directive is also added when the plain `pattern` attribute is used, with two
|
|
100
|
+
* differences:
|
|
101
|
+
* <ol>
|
|
102
|
+
* <li>
|
|
103
|
+
* `ngPattern` does not set the `pattern` attribute and therefore HTML5 constraint validation is
|
|
104
|
+
* not available.
|
|
105
|
+
* </li>
|
|
106
|
+
* <li>
|
|
107
|
+
* The `ngPattern` attribute must be an expression, while the `pattern` value must be
|
|
108
|
+
* interpolated.
|
|
109
|
+
* </li>
|
|
110
|
+
* </ol>
|
|
111
|
+
* </div>
|
|
112
|
+
*/
|
|
113
|
+
export const patternDirective = [
|
|
114
|
+
"$parse",
|
|
115
|
+
function ($parse) {
|
|
116
|
+
return {
|
|
117
|
+
restrict: "A",
|
|
118
|
+
require: "?ngModel",
|
|
119
|
+
compile: function (tElm, tAttr) {
|
|
120
|
+
var patternExp;
|
|
121
|
+
var parseFn;
|
|
122
|
+
|
|
123
|
+
if (tAttr.ngPattern) {
|
|
124
|
+
patternExp = tAttr.ngPattern;
|
|
125
|
+
|
|
126
|
+
// ngPattern might be a scope expression, or an inlined regex, which is not parsable.
|
|
127
|
+
// We get value of the attribute here, so we can compare the old and the new value
|
|
128
|
+
// in the observer to avoid unnecessary validations
|
|
129
|
+
if (
|
|
130
|
+
tAttr.ngPattern.charAt(0) === "/" &&
|
|
131
|
+
REGEX_STRING_REGEXP.test(tAttr.ngPattern)
|
|
132
|
+
) {
|
|
133
|
+
parseFn = function () {
|
|
134
|
+
return tAttr.ngPattern;
|
|
135
|
+
};
|
|
136
|
+
} else {
|
|
137
|
+
parseFn = $parse(tAttr.ngPattern);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return function (scope, elm, attr, ctrl) {
|
|
142
|
+
if (!ctrl) return;
|
|
143
|
+
|
|
144
|
+
var attrVal = attr.pattern;
|
|
145
|
+
|
|
146
|
+
if (attr.ngPattern) {
|
|
147
|
+
attrVal = parseFn(scope);
|
|
148
|
+
} else {
|
|
149
|
+
patternExp = attr.pattern;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
var regexp = parsePatternAttr(attrVal, patternExp, elm);
|
|
153
|
+
attr.$observe("pattern", function (newVal) {
|
|
154
|
+
var oldRegexp = regexp;
|
|
155
|
+
|
|
156
|
+
regexp = parsePatternAttr(newVal, patternExp, elm);
|
|
157
|
+
|
|
158
|
+
if (
|
|
159
|
+
(oldRegexp && oldRegexp.toString()) !==
|
|
160
|
+
(regexp && regexp.toString())
|
|
161
|
+
) {
|
|
162
|
+
ctrl.$validate();
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
ctrl.$validators.pattern = function (modelValue, viewValue) {
|
|
167
|
+
// HTML5 pattern constraint validates the input value, so we validate the viewValue
|
|
168
|
+
return (
|
|
169
|
+
ctrl.$isEmpty(viewValue) ||
|
|
170
|
+
isUndefined(regexp) ||
|
|
171
|
+
regexp.test(viewValue)
|
|
172
|
+
);
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
},
|
|
178
|
+
];
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* @ngdoc directive
|
|
182
|
+
* @name ngMaxlength
|
|
183
|
+
* @restrict A
|
|
184
|
+
*
|
|
185
|
+
* @param {String} ngMaxlength AngularJS expression that must evaluate to a `Number` or `String`
|
|
186
|
+
* parsable into a `Number`. Used as value for the `maxlength`
|
|
187
|
+
* {@link ngModel.NgModelController#$validators validator}.
|
|
188
|
+
*
|
|
189
|
+
* @description
|
|
190
|
+
*
|
|
191
|
+
* ngMaxlength adds the maxlength {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.
|
|
192
|
+
* It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.
|
|
193
|
+
*
|
|
194
|
+
* The validator sets the `maxlength` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}
|
|
195
|
+
* is longer than the integer obtained by evaluating the AngularJS expression given in the
|
|
196
|
+
* `ngMaxlength` attribute value.
|
|
197
|
+
*
|
|
198
|
+
* <div class="alert alert-info">
|
|
199
|
+
* **Note:** This directive is also added when the plain `maxlength` attribute is used, with two
|
|
200
|
+
* differences:
|
|
201
|
+
* <ol>
|
|
202
|
+
* <li>
|
|
203
|
+
* `ngMaxlength` does not set the `maxlength` attribute and therefore HTML5 constraint
|
|
204
|
+
* validation is not available.
|
|
205
|
+
* </li>
|
|
206
|
+
* <li>
|
|
207
|
+
* The `ngMaxlength` attribute must be an expression, while the `maxlength` value must be
|
|
208
|
+
* interpolated.
|
|
209
|
+
* </li>
|
|
210
|
+
* </ol>
|
|
211
|
+
* </div>
|
|
212
|
+
*
|
|
213
|
+
*/
|
|
214
|
+
export const maxlengthDirective = [
|
|
215
|
+
"$parse",
|
|
216
|
+
($parse) => ({
|
|
217
|
+
restrict: "A",
|
|
218
|
+
require: "?ngModel",
|
|
219
|
+
link(scope, elm, attr, ctrl) {
|
|
220
|
+
if (!ctrl) return;
|
|
221
|
+
|
|
222
|
+
let maxlength = attr.maxlength || $parse(attr.ngMaxlength)(scope);
|
|
223
|
+
let maxlengthParsed = parseLength(maxlength);
|
|
224
|
+
|
|
225
|
+
attr.$observe("maxlength", (value) => {
|
|
226
|
+
if (maxlength !== value) {
|
|
227
|
+
maxlengthParsed = parseLength(value);
|
|
228
|
+
maxlength = value;
|
|
229
|
+
ctrl.$validate();
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
ctrl.$validators.maxlength = function (modelValue, viewValue) {
|
|
233
|
+
return (
|
|
234
|
+
maxlengthParsed < 0 ||
|
|
235
|
+
ctrl.$isEmpty(viewValue) ||
|
|
236
|
+
viewValue.length <= maxlengthParsed
|
|
237
|
+
);
|
|
238
|
+
};
|
|
239
|
+
},
|
|
240
|
+
}),
|
|
241
|
+
];
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* @ngdoc directive
|
|
245
|
+
* @name ngMinlength
|
|
246
|
+
* @restrict A
|
|
247
|
+
*
|
|
248
|
+
* @param {string} ngMinlength AngularJS expression that must evaluate to a `Number` or `String`
|
|
249
|
+
* parsable into a `Number`. Used as value for the `minlength`
|
|
250
|
+
* {@link ngModel.NgModelController#$validators validator}.
|
|
251
|
+
*
|
|
252
|
+
* @description
|
|
253
|
+
*
|
|
254
|
+
* ngMinlength adds the minlength {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.
|
|
255
|
+
* It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.
|
|
256
|
+
*
|
|
257
|
+
* The validator sets the `minlength` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}
|
|
258
|
+
* is shorter than the integer obtained by evaluating the AngularJS expression given in the
|
|
259
|
+
* `ngMinlength` attribute value.
|
|
260
|
+
*
|
|
261
|
+
* <div class="alert alert-info">
|
|
262
|
+
* **Note:** This directive is also added when the plain `minlength` attribute is used, with two
|
|
263
|
+
* differences:
|
|
264
|
+
* <ol>
|
|
265
|
+
* <li>
|
|
266
|
+
* `ngMinlength` does not set the `minlength` attribute and therefore HTML5 constraint
|
|
267
|
+
* validation is not available.
|
|
268
|
+
* </li>
|
|
269
|
+
* <li>
|
|
270
|
+
* The `ngMinlength` value must be an expression, while the `minlength` value must be
|
|
271
|
+
* interpolated.
|
|
272
|
+
* </li>
|
|
273
|
+
* </ol>
|
|
274
|
+
* </div>
|
|
275
|
+
*
|
|
276
|
+
*/
|
|
277
|
+
export const minlengthDirective = [
|
|
278
|
+
"$parse",
|
|
279
|
+
function ($parse) {
|
|
280
|
+
return {
|
|
281
|
+
restrict: "A",
|
|
282
|
+
require: "?ngModel",
|
|
283
|
+
link(scope, elm, attr, ctrl) {
|
|
284
|
+
if (!ctrl) return;
|
|
285
|
+
|
|
286
|
+
let minlength = attr.minlength || $parse(attr.ngMinlength)(scope);
|
|
287
|
+
let minlengthParsed = parseLength(minlength) || -1;
|
|
288
|
+
|
|
289
|
+
attr.$observe("minlength", (value) => {
|
|
290
|
+
if (minlength !== value) {
|
|
291
|
+
minlengthParsed = parseLength(value) || -1;
|
|
292
|
+
minlength = value;
|
|
293
|
+
ctrl.$validate();
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
ctrl.$validators.minlength = function (modelValue, viewValue) {
|
|
297
|
+
return (
|
|
298
|
+
ctrl.$isEmpty(viewValue) || viewValue.length >= minlengthParsed
|
|
299
|
+
);
|
|
300
|
+
};
|
|
301
|
+
},
|
|
302
|
+
};
|
|
303
|
+
},
|
|
304
|
+
];
|
|
305
|
+
|
|
306
|
+
function parsePatternAttr(regex, patternExp, elm) {
|
|
307
|
+
if (!regex) return undefined;
|
|
308
|
+
|
|
309
|
+
if (isString(regex)) {
|
|
310
|
+
regex = new RegExp(`^${regex}$`);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (!regex.test) {
|
|
314
|
+
throw minErr("ngPattern")(
|
|
315
|
+
"noregexp",
|
|
316
|
+
"Expected {0} to be a RegExp but was {1}. Element: {2}",
|
|
317
|
+
patternExp,
|
|
318
|
+
regex,
|
|
319
|
+
startingTag(elm),
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return regex;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function parseLength(val) {
|
|
327
|
+
const intVal = toInt(val);
|
|
328
|
+
return isNumberNaN(intVal) ? -1 : intVal;
|
|
329
|
+
}
|