@angular-wave/angular.ts 0.0.69 → 0.0.71
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/dist/angular-ts.esm.js +2 -2
- package/dist/angular-ts.umd.js +2 -2
- package/package.json +1 -1
- package/src/animations/shared.js +14 -5
- package/src/core/compile/attributes.js +326 -0
- package/src/core/compile/compile.js +76 -434
- package/src/core/compile/compile.spec.js +2 -2
- package/src/core/interpolate/interpolate.js +1 -12
- package/src/core/location/location.js +26 -4
- package/src/core/parser/parse.js +50 -47
- package/src/core/scope/scope.js +4 -8
- package/src/{exts → directive}/aria/aria.html +1 -1
- package/src/directive/aria/aria.js +382 -0
- package/src/{exts → directive}/aria/aria.spec.js +12 -12
- package/src/{exts → directive}/aria/aria.test.js +1 -1
- package/src/directive/form/form.js +3 -1
- package/src/directive/messages/messages.js +268 -274
- package/src/filters/filter.js +0 -3
- package/src/filters/limit-to.js +0 -1
- package/src/public.js +27 -3
- package/src/router/state/state-object.js +4 -9
- package/src/router/url/url-matcher.js +1 -1
- package/src/router/url/url-rule.js +5 -1
- package/src/router/url/url-service.js +1 -1
- package/src/shared/jqlite/jqlite.js +13 -1
- package/src/shared/utils.js +0 -2
- package/src/types.js +1 -1
- package/types/animations/shared.d.ts +11 -6
- package/types/core/compile/attributes.d.ts +101 -0
- package/types/core/compile/compile.d.ts +10 -67
- package/types/core/interpolate/interpolate.d.ts +1 -12
- package/types/core/location/location.d.ts +12 -2
- package/types/core/parser/parse.d.ts +10 -10
- package/types/core/scope/scope.d.ts +21 -22
- package/types/directive/aria/aria.d.ts +94 -0
- package/types/directive/form/form.d.ts +2 -11
- package/types/router/state/state-object.d.ts +0 -2
- package/types/router/url/url-matcher.d.ts +2 -2
- package/types/router/url/url-rule.d.ts +2 -1
- package/types/shared/jqlite/jqlite.d.ts +8 -4
- package/types/shared/utils.d.ts +0 -2
- package/types/types.d.ts +1 -1
- package/src/exts/aria/aria.js +0 -415
- package/types/exts/aria/aria.d.ts +0 -1
- /package/src/{exts → directive}/aria/aria.md +0 -0
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@angular-wave/angular.ts",
|
|
3
3
|
"description": "A modern, optimized and typesafe version of AngularJS",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.71",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/angular-ts.esm.js",
|
|
8
8
|
"browser": "dist/angular-ts.umd.js",
|
package/src/animations/shared.js
CHANGED
|
@@ -119,18 +119,23 @@ export function removeFromArray(arr, val) {
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
/**
|
|
123
|
+
*
|
|
124
|
+
* @param {JQLite|Node} element
|
|
125
|
+
* @returns {JQLite}
|
|
126
|
+
*/
|
|
122
127
|
export function stripCommentsFromElement(element) {
|
|
123
128
|
if (element instanceof JQLite) {
|
|
124
129
|
switch (element.length) {
|
|
125
130
|
case 0:
|
|
126
|
-
return element;
|
|
131
|
+
return /** @type {JQLite} */ (element);
|
|
127
132
|
|
|
128
133
|
case 1:
|
|
129
134
|
// there is no point of stripping anything if the element
|
|
130
135
|
// is the only element within the JQLite wrapper.
|
|
131
136
|
// (it's important that we retain the element instance.)
|
|
132
137
|
if (element[0].nodeType === Node.ELEMENT_NODE) {
|
|
133
|
-
return element;
|
|
138
|
+
return /** @type {JQLite} */ (element);
|
|
134
139
|
}
|
|
135
140
|
break;
|
|
136
141
|
|
|
@@ -139,14 +144,18 @@ export function stripCommentsFromElement(element) {
|
|
|
139
144
|
}
|
|
140
145
|
}
|
|
141
146
|
|
|
142
|
-
if (element.nodeType === Node.ELEMENT_NODE) {
|
|
147
|
+
if (/** @type {Node} */ (element).nodeType === Node.ELEMENT_NODE) {
|
|
143
148
|
return JQLite(element);
|
|
144
149
|
}
|
|
145
150
|
}
|
|
146
151
|
|
|
152
|
+
/**
|
|
153
|
+
* @param {JQLite|Node} element
|
|
154
|
+
* @returns {Node}
|
|
155
|
+
*/
|
|
147
156
|
export function extractElementNode(element) {
|
|
148
|
-
if (!element[0]) return element;
|
|
149
|
-
for (let i = 0; i < element.length; i++) {
|
|
157
|
+
if (!element[0]) return /** @type {Node} */ (element);
|
|
158
|
+
for (let i = 0; i < /** @type {JQLite} */ (element).length; i++) {
|
|
150
159
|
const elm = element[i];
|
|
151
160
|
if (elm.nodeType === Node.ELEMENT_NODE) {
|
|
152
161
|
return elm;
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import { getBooleanAttrName } from "../../shared/jqlite/jqlite";
|
|
2
|
+
import {
|
|
3
|
+
forEach,
|
|
4
|
+
isString,
|
|
5
|
+
snakeCase,
|
|
6
|
+
isUndefined,
|
|
7
|
+
arrayRemove,
|
|
8
|
+
minErr,
|
|
9
|
+
trim,
|
|
10
|
+
directiveNormalize,
|
|
11
|
+
} from "../../shared/utils";
|
|
12
|
+
import { ALIASED_ATTR } from "../../shared/constants";
|
|
13
|
+
|
|
14
|
+
const $compileMinErr = minErr("$compile");
|
|
15
|
+
const SIMPLE_ATTR_NAME = /^\w/;
|
|
16
|
+
const specialAttrHolder = window.document.createElement("div");
|
|
17
|
+
|
|
18
|
+
export class Attributes {
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
* @param {import('../scope/scope').Scope} $rootScope
|
|
22
|
+
* @param {*} $animate
|
|
23
|
+
* @param {import("../exception-handler").ExceptionHandlerProvider} $exceptionHandler
|
|
24
|
+
* @param {*} $sce
|
|
25
|
+
* @param {import('../../shared/jqlite/jqlite').JQLite} [element]
|
|
26
|
+
* @param {*} [attributesToCopy]
|
|
27
|
+
*/
|
|
28
|
+
constructor(
|
|
29
|
+
$rootScope,
|
|
30
|
+
$animate,
|
|
31
|
+
$exceptionHandler,
|
|
32
|
+
$sce,
|
|
33
|
+
element,
|
|
34
|
+
attributesToCopy,
|
|
35
|
+
) {
|
|
36
|
+
this.$rootScope = $rootScope;
|
|
37
|
+
this.$animate = $animate;
|
|
38
|
+
this.$exceptionHandler = $exceptionHandler;
|
|
39
|
+
this.$sce = $sce;
|
|
40
|
+
if (attributesToCopy) {
|
|
41
|
+
const keys = Object.keys(attributesToCopy);
|
|
42
|
+
for (let i = 0, l = keys.length; i < l; i++) {
|
|
43
|
+
const key = keys[i];
|
|
44
|
+
this[key] = attributesToCopy[key];
|
|
45
|
+
}
|
|
46
|
+
} else {
|
|
47
|
+
this.$attr = {};
|
|
48
|
+
}
|
|
49
|
+
this.$$element = element;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @ngdoc method
|
|
54
|
+
* @name $compile.directive.Attributes#$normalize
|
|
55
|
+
* @kind function
|
|
56
|
+
*
|
|
57
|
+
* @description
|
|
58
|
+
* Converts an attribute name (e.g. dash/colon/underscore-delimited string, optionally prefixed with `x-` or
|
|
59
|
+
* `data-`) to its normalized, camelCase form.
|
|
60
|
+
*
|
|
61
|
+
* Also there is special case for Moz prefix starting with upper case letter.
|
|
62
|
+
*
|
|
63
|
+
* For further information check out the guide on {@link guide/directive#matching-directives Matching Directives}
|
|
64
|
+
*
|
|
65
|
+
* @param {string} name Name to normalize
|
|
66
|
+
*/
|
|
67
|
+
$normalize = directiveNormalize;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @ngdoc method
|
|
71
|
+
* @name $compile.directive.Attributes#$addClass
|
|
72
|
+
* @kind function
|
|
73
|
+
*
|
|
74
|
+
* @description
|
|
75
|
+
* Adds the CSS class value specified by the classVal parameter to the element. If animations
|
|
76
|
+
* are enabled then an animation will be triggered for the class addition.
|
|
77
|
+
*
|
|
78
|
+
* @param {string} classVal The className value that will be added to the element
|
|
79
|
+
*/
|
|
80
|
+
$addClass(classVal) {
|
|
81
|
+
if (classVal && classVal.length > 0) {
|
|
82
|
+
this.$animate.addClass(this.$$element, classVal);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @ngdoc method
|
|
88
|
+
* @name $compile.directive.Attributes#$removeClass
|
|
89
|
+
* @kind function
|
|
90
|
+
*
|
|
91
|
+
* @description
|
|
92
|
+
* Removes the CSS class value specified by the classVal parameter from the element. If
|
|
93
|
+
* animations are enabled then an animation will be triggered for the class removal.
|
|
94
|
+
*
|
|
95
|
+
* @param {string} classVal The className value that will be removed from the element
|
|
96
|
+
*/
|
|
97
|
+
$removeClass(classVal) {
|
|
98
|
+
if (classVal && classVal.length > 0) {
|
|
99
|
+
this.$animate.removeClass(this.$$element, classVal);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @ngdoc method
|
|
105
|
+
* @name $compile.directive.Attributes#$updateClass
|
|
106
|
+
* @kind function
|
|
107
|
+
*
|
|
108
|
+
* @description
|
|
109
|
+
* Adds and removes the appropriate CSS class values to the element based on the difference
|
|
110
|
+
* between the new and old CSS class values (specified as newClasses and oldClasses).
|
|
111
|
+
*
|
|
112
|
+
* @param {string} newClasses The current CSS className value
|
|
113
|
+
* @param {string} oldClasses The former CSS className value
|
|
114
|
+
*/
|
|
115
|
+
$updateClass(newClasses, oldClasses) {
|
|
116
|
+
const toAdd = tokenDifference(newClasses, oldClasses);
|
|
117
|
+
if (toAdd && toAdd.length) {
|
|
118
|
+
this.$animate.addClass(this.$$element, toAdd);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const toRemove = tokenDifference(oldClasses, newClasses);
|
|
122
|
+
if (toRemove && toRemove.length) {
|
|
123
|
+
this.$animate.removeClass(this.$$element, toRemove);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Set a normalized attribute on the element in a way such that all directives
|
|
129
|
+
* can share the attribute. This function properly handles boolean attributes.
|
|
130
|
+
* @param {string} key Normalized key. (ie ngAttribute)
|
|
131
|
+
* @param {string|boolean} value The value to set. If `null` attribute will be deleted.
|
|
132
|
+
* @param {boolean=} writeAttr If false, does not write the value to DOM element attribute.
|
|
133
|
+
* Defaults to true.
|
|
134
|
+
* @param {string=} attrName Optional none normalized name. Defaults to key.
|
|
135
|
+
*/
|
|
136
|
+
$set(key, value, writeAttr, attrName) {
|
|
137
|
+
// TODO: decide whether or not to throw an error if "class"
|
|
138
|
+
// is set through this function since it may cause $updateClass to
|
|
139
|
+
// become unstable.
|
|
140
|
+
|
|
141
|
+
const node = this.$$element[0];
|
|
142
|
+
const booleanKey = getBooleanAttrName(node, key);
|
|
143
|
+
const aliasedKey = ALIASED_ATTR[key];
|
|
144
|
+
let observer = key;
|
|
145
|
+
|
|
146
|
+
if (booleanKey) {
|
|
147
|
+
this.$$element[0][key] = value;
|
|
148
|
+
attrName = booleanKey;
|
|
149
|
+
} else if (aliasedKey) {
|
|
150
|
+
this[aliasedKey] = value;
|
|
151
|
+
observer = aliasedKey;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
this[key] = value;
|
|
155
|
+
|
|
156
|
+
// translate normalized key to actual key
|
|
157
|
+
if (attrName) {
|
|
158
|
+
this.$attr[key] = attrName;
|
|
159
|
+
} else {
|
|
160
|
+
attrName = this.$attr[key];
|
|
161
|
+
if (!attrName) {
|
|
162
|
+
this.$attr[key] = attrName = snakeCase(key, "-");
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
let nodeName = this.$$element[0].nodeName.toLowerCase();
|
|
167
|
+
|
|
168
|
+
// Sanitize img[srcset] values.
|
|
169
|
+
if (nodeName === "img" && key === "srcset") {
|
|
170
|
+
this[key] = value = this.sanitizeSrcset(value, "$set('srcset', value)");
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (writeAttr !== false) {
|
|
174
|
+
if (value === null || isUndefined(value)) {
|
|
175
|
+
this.$$element[0].removeAttribute(attrName);
|
|
176
|
+
//
|
|
177
|
+
} else if (SIMPLE_ATTR_NAME.test(attrName)) {
|
|
178
|
+
// jQuery skips special boolean attrs treatment in XML nodes for
|
|
179
|
+
// historical reasons and hence AngularJS cannot freely call
|
|
180
|
+
// `.attr(attrName, false) with such attributes. To avoid issues
|
|
181
|
+
// in XHTML, call `removeAttr` in such cases instead.
|
|
182
|
+
// See https://github.com/jquery/jquery/issues/4249
|
|
183
|
+
if (booleanKey && value === false) {
|
|
184
|
+
this.$$element[0].removeAttribute(attrName);
|
|
185
|
+
} else {
|
|
186
|
+
this.$$element.attr(attrName, value);
|
|
187
|
+
}
|
|
188
|
+
} else {
|
|
189
|
+
this.setSpecialAttr(this.$$element[0], attrName, value);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// fire observers
|
|
194
|
+
const { $$observers } = this;
|
|
195
|
+
if ($$observers) {
|
|
196
|
+
forEach($$observers[observer], (fn) => {
|
|
197
|
+
try {
|
|
198
|
+
fn(value);
|
|
199
|
+
} catch (e) {
|
|
200
|
+
this.$exceptionHandler(e);
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Observes an interpolated attribute.
|
|
208
|
+
*
|
|
209
|
+
* The observer function will be invoked once during the next `$digest` following
|
|
210
|
+
* compilation. The observer is then invoked whenever the interpolated value
|
|
211
|
+
* changes.
|
|
212
|
+
*
|
|
213
|
+
* @param {string} key Normalized key. (ie ngAttribute) .
|
|
214
|
+
* @param {any} fn Function that will be called whenever
|
|
215
|
+
the interpolated value of the attribute changes.
|
|
216
|
+
* See the {@link guide/interpolation#how-text-and-attribute-bindings-work Interpolation
|
|
217
|
+
* guide} for more info.
|
|
218
|
+
* @returns {function()} Returns a deregistration function for this observer.
|
|
219
|
+
*/
|
|
220
|
+
$observe(key, fn) {
|
|
221
|
+
const $$observers =
|
|
222
|
+
this.$$observers || (this.$$observers = Object.create(null));
|
|
223
|
+
const listeners = $$observers[key] || ($$observers[key] = []);
|
|
224
|
+
|
|
225
|
+
listeners.push(fn);
|
|
226
|
+
this.$rootScope.$evalAsync(() => {
|
|
227
|
+
if (
|
|
228
|
+
!listeners.$$inter &&
|
|
229
|
+
Object.prototype.hasOwnProperty.call(this, key) &&
|
|
230
|
+
!isUndefined(this[key])
|
|
231
|
+
) {
|
|
232
|
+
// no one registered attribute interpolation function, so lets call it manually
|
|
233
|
+
fn(this[key]);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
return function () {
|
|
238
|
+
arrayRemove(listeners, fn);
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
setSpecialAttr(element, attrName, value) {
|
|
243
|
+
// Attributes names that do not start with letters (such as `(click)`) cannot be set using `setAttribute`
|
|
244
|
+
// so we have to jump through some hoops to get such an attribute
|
|
245
|
+
// https://github.com/angular/angular.js/pull/13318
|
|
246
|
+
specialAttrHolder.innerHTML = `<span ${attrName}>`;
|
|
247
|
+
const { attributes } = /** @type {Element} */ (
|
|
248
|
+
specialAttrHolder.firstChild
|
|
249
|
+
);
|
|
250
|
+
const attribute = attributes[0];
|
|
251
|
+
// We have to remove the attribute from its container element before we can add it to the destination element
|
|
252
|
+
attributes.removeNamedItem(attribute.name);
|
|
253
|
+
attribute.value = value;
|
|
254
|
+
element.attributes.setNamedItem(attribute);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
sanitizeSrcset(value, invokeType) {
|
|
258
|
+
if (!value) {
|
|
259
|
+
return value;
|
|
260
|
+
}
|
|
261
|
+
if (!isString(value)) {
|
|
262
|
+
throw $compileMinErr(
|
|
263
|
+
"srcset",
|
|
264
|
+
'Can\'t pass trusted values to `{0}`: "{1}"',
|
|
265
|
+
invokeType,
|
|
266
|
+
value.toString(),
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Such values are a bit too complex to handle automatically inside $sce.
|
|
271
|
+
// Instead, we sanitize each of the URIs individually, which works, even dynamically.
|
|
272
|
+
|
|
273
|
+
// It's not possible to work around this using `$sce.trustAsMediaUrl`.
|
|
274
|
+
// If you want to programmatically set explicitly trusted unsafe URLs, you should use
|
|
275
|
+
// `$sce.trustAsHtml` on the whole `img` tag and inject it into the DOM using the
|
|
276
|
+
// `ng-bind-html` directive.
|
|
277
|
+
|
|
278
|
+
var result = "";
|
|
279
|
+
|
|
280
|
+
// first check if there are spaces because it's not the same pattern
|
|
281
|
+
var trimmedSrcset = trim(value);
|
|
282
|
+
// ( 999x ,| 999w ,| ,|, )
|
|
283
|
+
var srcPattern = /(\s+\d+x\s*,|\s+\d+w\s*,|\s+,|,\s+)/;
|
|
284
|
+
var pattern = /\s/.test(trimmedSrcset) ? srcPattern : /(,)/;
|
|
285
|
+
|
|
286
|
+
// split srcset into tuple of uri and descriptor except for the last item
|
|
287
|
+
var rawUris = trimmedSrcset.split(pattern);
|
|
288
|
+
|
|
289
|
+
// for each tuples
|
|
290
|
+
var nbrUrisWith2parts = Math.floor(rawUris.length / 2);
|
|
291
|
+
for (var i = 0; i < nbrUrisWith2parts; i++) {
|
|
292
|
+
var innerIdx = i * 2;
|
|
293
|
+
// sanitize the uri
|
|
294
|
+
result += this.$sce.getTrustedMediaUrl(trim(rawUris[innerIdx]));
|
|
295
|
+
// add the descriptor
|
|
296
|
+
result += " " + trim(rawUris[innerIdx + 1]);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// split the last item into uri and descriptor
|
|
300
|
+
var lastTuple = trim(rawUris[i * 2]).split(/\s/);
|
|
301
|
+
|
|
302
|
+
// sanitize the last uri
|
|
303
|
+
result += this.$sce.getTrustedMediaUrl(trim(lastTuple[0]));
|
|
304
|
+
|
|
305
|
+
// and add the last descriptor if any
|
|
306
|
+
if (lastTuple.length === 2) {
|
|
307
|
+
result += " " + trim(lastTuple[1]);
|
|
308
|
+
}
|
|
309
|
+
return result;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function tokenDifference(str1, str2) {
|
|
314
|
+
let values = "";
|
|
315
|
+
const tokens1 = str1.split(/\s+/);
|
|
316
|
+
const tokens2 = str2.split(/\s+/);
|
|
317
|
+
|
|
318
|
+
outer: for (let i = 0; i < tokens1.length; i++) {
|
|
319
|
+
const token = tokens1[i];
|
|
320
|
+
for (let j = 0; j < tokens2.length; j++) {
|
|
321
|
+
if (token === tokens2[j]) continue outer;
|
|
322
|
+
}
|
|
323
|
+
values += (values.length > 0 ? " " : "") + token;
|
|
324
|
+
}
|
|
325
|
+
return values;
|
|
326
|
+
}
|