@angular-wave/angular.ts 0.0.72 → 0.1.0

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.
Files changed (58) hide show
  1. package/.github/workflows/types.yml +19 -0
  2. package/dist/angular-ts.esm.js +2 -2
  3. package/dist/angular-ts.umd.js +2 -2
  4. package/package.json +1 -1
  5. package/src/animations/animate-js.html +5 -2
  6. package/src/animations/animate-queue.js +1 -1
  7. package/src/animations/animate.js +1 -26
  8. package/src/core/compile/attributes.js +8 -1
  9. package/src/core/compile/compile.js +432 -368
  10. package/src/core/compile/compile.spec.js +0 -1
  11. package/src/core/controller/controller.js +9 -3
  12. package/src/core/interpolate/interpolate.js +14 -10
  13. package/src/core/q/q.js +2 -1
  14. package/src/directive/change/change.js +3 -1
  15. package/src/directive/form/form.js +4 -3
  16. package/src/directive/list/list.js +3 -3
  17. package/src/directive/messages/messages.js +177 -172
  18. package/src/directive/model/model.js +261 -471
  19. package/src/directive/switch/switch.js +4 -4
  20. package/src/router/directives/state-directives.js +2 -9
  21. package/src/router/hooks/core-resolvables.js +5 -3
  22. package/src/router/path/path-utils.js +1 -2
  23. package/src/router/resolve/resolve-context.js +15 -29
  24. package/src/router/state/state-builder.js +38 -13
  25. package/src/router/state/state-object.js +12 -22
  26. package/src/router/state/state-queue-manager.js +2 -3
  27. package/src/router/state/state-registry.js +2 -1
  28. package/src/router/state/state-service.js +2 -3
  29. package/src/router/transition/transition.js +5 -3
  30. package/src/router/url/url-rule.js +14 -2
  31. package/src/router/view/view.js +2 -8
  32. package/src/router/view/view.spec.js +1 -1
  33. package/src/shared/common.js +3 -8
  34. package/src/shared/common.spec.js +1 -19
  35. package/src/shared/hof.js +1 -8
  36. package/src/shared/jqlite/jqlite.js +1 -1
  37. package/src/shared/predicates.js +6 -2
  38. package/src/types.js +2 -3
  39. package/tsconfig.json +1 -1
  40. package/types/animations/animate-queue.d.ts +1 -1
  41. package/types/core/compile/attributes.d.ts +10 -1
  42. package/types/core/interpolate/interpolate.d.ts +5 -5
  43. package/types/core/q/q.d.ts +4 -2
  44. package/types/directive/form/form.d.ts +3 -1
  45. package/types/directive/messages/messages.d.ts +76 -0
  46. package/types/directive/model/model.d.ts +101 -239
  47. package/types/router/resolve/resolve-context.d.ts +0 -2
  48. package/types/router/state/state-object.d.ts +12 -9
  49. package/types/router/state/state-registry.d.ts +2 -2
  50. package/types/router/transition/transition.d.ts +1 -2
  51. package/types/router/url/url-rule.d.ts +6 -1
  52. package/types/shared/common.d.ts +0 -3
  53. package/types/shared/hof.d.ts +0 -1
  54. package/types/shared/jqlite/jqlite.d.ts +2 -2
  55. package/types/shared/predicates.d.ts +2 -0
  56. package/types/types.d.ts +4 -2
  57. package/src/router/injectables.js +0 -263
  58. package/types/router/injectables.d.ts +0 -1
@@ -733,13 +733,13 @@ export function $CompileProvider($provide, $$sanitizeUriProvider) {
733
733
  * functions return values - the linking functions - are combined into a composite linking
734
734
  * function, which is the a linking function for the node.
735
735
  *
736
- * @param {NodeList} nodeList an array of nodes or NodeList to compile
736
+ * @param {NodeList|JQLite} nodeList an array of nodes or NodeList to compile
737
737
  * @param {*} transcludeFn A linking function, where the
738
738
  * scope argument is auto-generated to the new child of the transcluded parent scope.
739
- * @param {Element=} $rootElement If the nodeList is the root of the compilation tree then
739
+ * @param {JQLite} [$rootElement] If the nodeList is the root of the compilation tree then
740
740
  * the rootElement must be set the JQLite collection of the compile root. This is
741
741
  * needed so that the JQLite collection items can be replaced with widgets.
742
- * @param {number=} maxPriority Max directive priority.
742
+ * @param {number=} [maxPriority] Max directive priority.
743
743
  * @param {*} [ignoreDirective]
744
744
  * @param {*} [previousCompileContext]
745
745
  * @returns {Function} A composite linking function of all of the matched directives or null.
@@ -755,6 +755,9 @@ export function $CompileProvider($provide, $$sanitizeUriProvider) {
755
755
  const linkFns = [];
756
756
  let attrs;
757
757
  let directives;
758
+ /**
759
+ * @type {any}
760
+ */
758
761
  var nodeLinkFn;
759
762
  let childNodes;
760
763
  let childLinkFn;
@@ -947,8 +950,9 @@ export function $CompileProvider($provide, $$sanitizeUriProvider) {
947
950
  * @param {Element} node Node to search.
948
951
  * @param directives An array to which the directives are added to. This array is sorted before
949
952
  * the function returns.
950
- * @param {Attributes} attrs The shared attrs object which is used to populate the normalized attributes.
953
+ * @param {Attributes|import("./attributes").AttributeLike} attrs The shared attrs object which is used to populate the normalized attributes.
951
954
  * @param {number=} maxPriority Max directive priority.
955
+ * @param {boolean=} ignoreDirective
952
956
  */
953
957
  function collectDirectives(
954
958
  node,
@@ -987,7 +991,10 @@ export function $CompileProvider($provide, $$sanitizeUriProvider) {
987
991
  j < jj;
988
992
  j++
989
993
  ) {
994
+ /** @type {string|boolean} */
990
995
  let attrStartName = false;
996
+
997
+ /** @type {string|boolean} */
991
998
  let attrEndName = false;
992
999
 
993
1000
  let isNgAttr = false;
@@ -1243,12 +1250,288 @@ export function $CompileProvider($provide, $$sanitizeUriProvider) {
1243
1250
  let directiveName;
1244
1251
  let $template;
1245
1252
  let replaceDirective = originalReplaceDirective;
1253
+ /** @type {any} */
1246
1254
  let childTranscludeFn = transcludeFn;
1247
1255
  let linkFn;
1248
1256
  let didScanForMultipleTransclusion = false;
1249
1257
  let mightHaveMultipleTransclusionError = false;
1250
1258
  let directiveValue;
1251
1259
 
1260
+ /** @type {any} */
1261
+ let nodeLinkFn = function (
1262
+ childLinkFn,
1263
+ scope,
1264
+ linkNode,
1265
+ $rootElement,
1266
+ boundTranscludeFn,
1267
+ ) {
1268
+ let i;
1269
+ let ii;
1270
+ /** @type {import("../../types").Directive|any} */
1271
+ let linkFn;
1272
+ let isolateScope;
1273
+ let controllerScope;
1274
+ let elementControllers;
1275
+ /** @type {import("../../types").TranscludeFunctionObject|any} */
1276
+ let transcludeFn;
1277
+ let $element;
1278
+ let attrs;
1279
+ let scopeBindingInfo;
1280
+
1281
+ if (compileNode === linkNode) {
1282
+ attrs = templateAttrs;
1283
+ $element = templateAttrs.$$element;
1284
+ } else {
1285
+ $element = JQLite(linkNode);
1286
+ attrs = new Attributes(
1287
+ $rootScope,
1288
+ $animate,
1289
+ $exceptionHandler,
1290
+ $sce,
1291
+ $element,
1292
+ templateAttrs,
1293
+ );
1294
+ }
1295
+
1296
+ controllerScope = scope;
1297
+ if (newIsolateScopeDirective) {
1298
+ isolateScope = scope.$new(true);
1299
+ } else if (newScopeDirective) {
1300
+ controllerScope = scope.$parent;
1301
+ }
1302
+
1303
+ if (boundTranscludeFn) {
1304
+ // track `boundTranscludeFn` so it can be unwrapped if `transcludeFn`
1305
+ // is later passed as `parentBoundTranscludeFn` to `publicLinkFn`
1306
+ transcludeFn = controllersBoundTransclude;
1307
+ transcludeFn.$$boundTransclude = boundTranscludeFn;
1308
+ // expose the slots on the `$transclude` function
1309
+ transcludeFn.isSlotFilled = function (slotName) {
1310
+ return !!boundTranscludeFn.$$slots[slotName];
1311
+ };
1312
+ }
1313
+
1314
+ if (controllerDirectives) {
1315
+ elementControllers = setupControllers(
1316
+ $element,
1317
+ attrs,
1318
+ transcludeFn,
1319
+ controllerDirectives,
1320
+ isolateScope,
1321
+ scope,
1322
+ newIsolateScopeDirective,
1323
+ );
1324
+ }
1325
+
1326
+ if (newIsolateScopeDirective) {
1327
+ isolateScope.$$isolateBindings =
1328
+ newIsolateScopeDirective.$$isolateBindings;
1329
+ scopeBindingInfo = initializeDirectiveBindings(
1330
+ scope,
1331
+ attrs,
1332
+ isolateScope,
1333
+ isolateScope.$$isolateBindings,
1334
+ newIsolateScopeDirective,
1335
+ );
1336
+ if (scopeBindingInfo.removeWatches) {
1337
+ isolateScope.$on("$destroy", scopeBindingInfo.removeWatches);
1338
+ }
1339
+ }
1340
+
1341
+ // Initialize bindToController bindings
1342
+ for (const name in elementControllers) {
1343
+ const controllerDirective = controllerDirectives[name];
1344
+ const controller = elementControllers[name];
1345
+ const bindings = controllerDirective.$$bindings.bindToController;
1346
+
1347
+ controller.instance = controller();
1348
+ $element.data(
1349
+ `$${controllerDirective.name}Controller`,
1350
+ controller.instance,
1351
+ );
1352
+ controller.bindingInfo = initializeDirectiveBindings(
1353
+ controllerScope,
1354
+ attrs,
1355
+ controller.instance,
1356
+ bindings,
1357
+ controllerDirective,
1358
+ );
1359
+ }
1360
+
1361
+ // Bind the required controllers to the controller, if `require` is an object and `bindToController` is truthy
1362
+ forEach(controllerDirectives, (controllerDirective, name) => {
1363
+ const { require } = controllerDirective;
1364
+ if (
1365
+ controllerDirective.bindToController &&
1366
+ !Array.isArray(require) &&
1367
+ isObject(require)
1368
+ ) {
1369
+ extend(
1370
+ elementControllers[name].instance,
1371
+ getControllers(name, require, $element, elementControllers),
1372
+ );
1373
+ }
1374
+ });
1375
+
1376
+ // Handle the init and destroy lifecycle hooks on all controllers that have them
1377
+ forEach(elementControllers, (controller) => {
1378
+ const controllerInstance = controller.instance;
1379
+ if (isFunction(controllerInstance.$onChanges)) {
1380
+ try {
1381
+ controllerInstance.$onChanges(
1382
+ controller.bindingInfo.initialChanges,
1383
+ );
1384
+ } catch (e) {
1385
+ $exceptionHandler(e);
1386
+ }
1387
+ }
1388
+ if (isFunction(controllerInstance.$onInit)) {
1389
+ try {
1390
+ controllerInstance.$onInit();
1391
+ } catch (e) {
1392
+ $exceptionHandler(e);
1393
+ }
1394
+ }
1395
+ if (isFunction(controllerInstance.$doCheck)) {
1396
+ controllerScope.$watch(() => {
1397
+ controllerInstance.$doCheck();
1398
+ });
1399
+ controllerInstance.$doCheck();
1400
+ }
1401
+ if (isFunction(controllerInstance.$onDestroy)) {
1402
+ controllerScope.$on("$destroy", () => {
1403
+ controllerInstance.$onDestroy();
1404
+ });
1405
+ }
1406
+ });
1407
+
1408
+ // PRELINKING
1409
+ for (i = 0, ii = preLinkFns.length; i < ii; i++) {
1410
+ linkFn = preLinkFns[i];
1411
+ invokeLinkFn(
1412
+ linkFn,
1413
+ linkFn.isolateScope ? isolateScope : scope,
1414
+ $element,
1415
+ attrs,
1416
+ linkFn.require &&
1417
+ getControllers(
1418
+ linkFn.directiveName,
1419
+ linkFn.require,
1420
+ $element,
1421
+ elementControllers,
1422
+ ),
1423
+ transcludeFn,
1424
+ );
1425
+ }
1426
+
1427
+ // RECURSION
1428
+ // We only pass the isolate scope, if the isolate directive has a template,
1429
+ // otherwise the child elements do not belong to the isolate directive.
1430
+ var scopeToChild = scope;
1431
+ if (
1432
+ newIsolateScopeDirective &&
1433
+ (newIsolateScopeDirective.template ||
1434
+ newIsolateScopeDirective.templateUrl === null)
1435
+ ) {
1436
+ scopeToChild = isolateScope;
1437
+ }
1438
+ if (childLinkFn) {
1439
+ childLinkFn(
1440
+ scopeToChild,
1441
+ linkNode.childNodes,
1442
+ undefined,
1443
+ boundTranscludeFn,
1444
+ );
1445
+ }
1446
+
1447
+ // POSTLINKING
1448
+ for (i = postLinkFns.length - 1; i >= 0; i--) {
1449
+ linkFn = postLinkFns[i];
1450
+ invokeLinkFn(
1451
+ linkFn,
1452
+ linkFn.isolateScope ? isolateScope : scope,
1453
+ $element,
1454
+ attrs,
1455
+ linkFn.require &&
1456
+ getControllers(
1457
+ linkFn.directiveName,
1458
+ linkFn.require,
1459
+ $element,
1460
+ elementControllers,
1461
+ ),
1462
+ transcludeFn,
1463
+ );
1464
+ }
1465
+
1466
+ // Trigger $postLink lifecycle hooks
1467
+ forEach(elementControllers, (controller) => {
1468
+ const controllerInstance = controller.instance;
1469
+ if (isFunction(controllerInstance.$postLink)) {
1470
+ controllerInstance.$postLink();
1471
+ }
1472
+ });
1473
+
1474
+ // This is the function that is injected as `$transclude`.
1475
+ // Note: all arguments are optional!
1476
+ function controllersBoundTransclude(
1477
+ scope,
1478
+ cloneAttachFn,
1479
+ futureParentElement,
1480
+ slotName,
1481
+ ) {
1482
+ let transcludeControllers;
1483
+ // No scope passed in:
1484
+ if (!isScope(scope)) {
1485
+ slotName = futureParentElement;
1486
+ futureParentElement = cloneAttachFn;
1487
+ cloneAttachFn = scope;
1488
+ scope = undefined;
1489
+ }
1490
+
1491
+ if (hasElementTranscludeDirective) {
1492
+ transcludeControllers = elementControllers;
1493
+ }
1494
+ if (!futureParentElement) {
1495
+ futureParentElement = hasElementTranscludeDirective
1496
+ ? $element.parent()
1497
+ : $element;
1498
+ }
1499
+ if (slotName) {
1500
+ // slotTranscludeFn can be one of three things:
1501
+ // * a transclude function - a filled slot
1502
+ // * `null` - an optional slot that was not filled
1503
+ // * `undefined` - a slot that was not declared (i.e. invalid)
1504
+ const slotTranscludeFn = boundTranscludeFn.$$slots[slotName];
1505
+ if (slotTranscludeFn) {
1506
+ return slotTranscludeFn(
1507
+ scope,
1508
+ cloneAttachFn,
1509
+ transcludeControllers,
1510
+ futureParentElement,
1511
+ scopeToChild,
1512
+ );
1513
+ }
1514
+ if (isUndefined(slotTranscludeFn)) {
1515
+ throw $compileMinErr(
1516
+ "noslot",
1517
+ 'No parent directive that requires a transclusion with slot name "{0}". ' +
1518
+ "Element: {1}",
1519
+ slotName,
1520
+ startingTag($element),
1521
+ );
1522
+ }
1523
+ } else {
1524
+ return boundTranscludeFn(
1525
+ scope,
1526
+ cloneAttachFn,
1527
+ transcludeControllers,
1528
+ futureParentElement,
1529
+ scopeToChild,
1530
+ );
1531
+ }
1532
+ }
1533
+ };
1534
+
1252
1535
  // executes all directives on the current element
1253
1536
  for (let i = 0, ii = directives.length; i < ii; i++) {
1254
1537
  directive = directives[i];
@@ -1528,6 +1811,7 @@ export function $CompileProvider($provide, $$sanitizeUriProvider) {
1528
1811
 
1529
1812
  replaceWith(jqCollection, $compileNode, compileNode);
1530
1813
 
1814
+ /** @type {import("./attributes").AttributeLike} */
1531
1815
  const newTemplateAttrs = { $attr: {} };
1532
1816
 
1533
1817
  // combine directives from the original node and from the template:
@@ -1536,7 +1820,7 @@ export function $CompileProvider($provide, $$sanitizeUriProvider) {
1536
1820
  // - collect directives from the template and sort them by priority
1537
1821
  // - combine directives as: processed + template + unprocessed
1538
1822
  const templateDirectives = collectDirectives(
1539
- compileNode,
1823
+ /** @type {Element} */ (compileNode),
1540
1824
  [],
1541
1825
  newTemplateAttrs,
1542
1826
  );
@@ -1569,376 +1853,104 @@ export function $CompileProvider($provide, $$sanitizeUriProvider) {
1569
1853
  if (directive.templateUrl) {
1570
1854
  hasTemplate = true;
1571
1855
  assertNoDuplicate(
1572
- "template",
1573
- templateDirective,
1574
- directive,
1575
- $compileNode,
1576
- );
1577
- templateDirective = directive;
1578
-
1579
- if (directive.replace) {
1580
- replaceDirective = directive;
1581
- }
1582
-
1583
- nodeLinkFn = compileTemplateUrl(
1584
- directives.splice(i, directives.length - i),
1585
- $compileNode,
1586
- templateAttrs,
1587
- jqCollection,
1588
- hasTranscludeDirective && childTranscludeFn,
1589
- preLinkFns,
1590
- postLinkFns,
1591
- {
1592
- controllerDirectives,
1593
- newScopeDirective:
1594
- newScopeDirective !== directive && newScopeDirective,
1595
- newIsolateScopeDirective,
1596
- templateDirective,
1597
- nonTlbTranscludeDirective,
1598
- },
1599
- );
1600
- ii = directives.length;
1601
- } else if (directive.compile) {
1602
- try {
1603
- linkFn = directive.compile(
1604
- $compileNode,
1605
- templateAttrs,
1606
- childTranscludeFn,
1607
- );
1608
- const context = directive.$$originalDirective || directive;
1609
- if (isFunction(linkFn)) {
1610
- addLinkFns(null, bind(context, linkFn), attrStart, attrEnd);
1611
- } else if (linkFn) {
1612
- addLinkFns(
1613
- bind(context, linkFn.pre),
1614
- bind(context, linkFn.post),
1615
- attrStart,
1616
- attrEnd,
1617
- );
1618
- }
1619
- } catch (e) {
1620
- $exceptionHandler(e, startingTag($compileNode));
1621
- }
1622
- }
1623
-
1624
- if (directive.terminal) {
1625
- nodeLinkFn.terminal = true;
1626
- terminalPriority = Math.max(terminalPriority, directive.priority);
1627
- }
1628
- }
1629
-
1630
- nodeLinkFn.scope =
1631
- newScopeDirective && newScopeDirective.scope === true;
1632
- nodeLinkFn.transcludeOnThisElement = hasTranscludeDirective;
1633
- nodeLinkFn.templateOnThisElement = hasTemplate;
1634
- nodeLinkFn.transclude = childTranscludeFn;
1635
-
1636
- previousCompileContext.hasElementTranscludeDirective =
1637
- hasElementTranscludeDirective;
1638
-
1639
- // might be normal or delayed nodeLinkFn depending on if templateUrl is present
1640
- return nodeLinkFn;
1641
-
1642
- /// /////////////////
1643
-
1644
- function addLinkFns(pre, post, attrStart, attrEnd) {
1645
- if (pre) {
1646
- if (attrStart)
1647
- pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd);
1648
- pre.require = directive.require;
1649
- pre.directiveName = directiveName;
1650
- if (
1651
- newIsolateScopeDirective === directive ||
1652
- directive.$$isolateScope
1653
- ) {
1654
- pre = cloneAndAnnotateFn(pre, { isolateScope: true });
1655
- }
1656
- preLinkFns.push(pre);
1657
- }
1658
- if (post) {
1659
- if (attrStart)
1660
- post = groupElementsLinkFnWrapper(post, attrStart, attrEnd);
1661
- post.require = directive.require;
1662
- post.directiveName = directiveName;
1663
- if (
1664
- newIsolateScopeDirective === directive ||
1665
- directive.$$isolateScope
1666
- ) {
1667
- post = cloneAndAnnotateFn(post, { isolateScope: true });
1668
- }
1669
- postLinkFns.push(post);
1670
- }
1671
- }
1672
-
1673
- function nodeLinkFn(
1674
- childLinkFn,
1675
- scope,
1676
- linkNode,
1677
- $rootElement,
1678
- boundTranscludeFn,
1679
- ) {
1680
- let i;
1681
- let ii;
1682
- let linkFn;
1683
- let isolateScope;
1684
- let controllerScope;
1685
- let elementControllers;
1686
- let transcludeFn;
1687
- let $element;
1688
- let attrs;
1689
- let scopeBindingInfo;
1690
-
1691
- if (compileNode === linkNode) {
1692
- attrs = templateAttrs;
1693
- $element = templateAttrs.$$element;
1694
- } else {
1695
- $element = JQLite(linkNode);
1696
- attrs = new Attributes(
1697
- $rootScope,
1698
- $animate,
1699
- $exceptionHandler,
1700
- $sce,
1701
- $element,
1702
- templateAttrs,
1703
- );
1704
- }
1705
-
1706
- controllerScope = scope;
1707
- if (newIsolateScopeDirective) {
1708
- isolateScope = scope.$new(true);
1709
- } else if (newScopeDirective) {
1710
- controllerScope = scope.$parent;
1711
- }
1712
-
1713
- if (boundTranscludeFn) {
1714
- // track `boundTranscludeFn` so it can be unwrapped if `transcludeFn`
1715
- // is later passed as `parentBoundTranscludeFn` to `publicLinkFn`
1716
- transcludeFn = controllersBoundTransclude;
1717
- transcludeFn.$$boundTransclude = boundTranscludeFn;
1718
- // expose the slots on the `$transclude` function
1719
- transcludeFn.isSlotFilled = function (slotName) {
1720
- return !!boundTranscludeFn.$$slots[slotName];
1721
- };
1722
- }
1723
-
1724
- if (controllerDirectives) {
1725
- elementControllers = setupControllers(
1726
- $element,
1727
- attrs,
1728
- transcludeFn,
1729
- controllerDirectives,
1730
- isolateScope,
1731
- scope,
1732
- newIsolateScopeDirective,
1733
- );
1734
- }
1735
-
1736
- if (newIsolateScopeDirective) {
1737
- isolateScope.$$isolateBindings =
1738
- newIsolateScopeDirective.$$isolateBindings;
1739
- scopeBindingInfo = initializeDirectiveBindings(
1740
- scope,
1741
- attrs,
1742
- isolateScope,
1743
- isolateScope.$$isolateBindings,
1744
- newIsolateScopeDirective,
1745
- );
1746
- if (scopeBindingInfo.removeWatches) {
1747
- isolateScope.$on("$destroy", scopeBindingInfo.removeWatches);
1748
- }
1749
- }
1750
-
1751
- // Initialize bindToController bindings
1752
- for (const name in elementControllers) {
1753
- const controllerDirective = controllerDirectives[name];
1754
- const controller = elementControllers[name];
1755
- const bindings = controllerDirective.$$bindings.bindToController;
1756
-
1757
- controller.instance = controller();
1758
- $element.data(
1759
- `$${controllerDirective.name}Controller`,
1760
- controller.instance,
1761
- );
1762
- controller.bindingInfo = initializeDirectiveBindings(
1763
- controllerScope,
1764
- attrs,
1765
- controller.instance,
1766
- bindings,
1767
- controllerDirective,
1856
+ "template",
1857
+ templateDirective,
1858
+ directive,
1859
+ $compileNode,
1768
1860
  );
1769
- }
1861
+ templateDirective = directive;
1770
1862
 
1771
- // Bind the required controllers to the controller, if `require` is an object and `bindToController` is truthy
1772
- forEach(controllerDirectives, (controllerDirective, name) => {
1773
- const { require } = controllerDirective;
1774
- if (
1775
- controllerDirective.bindToController &&
1776
- !Array.isArray(require) &&
1777
- isObject(require)
1778
- ) {
1779
- extend(
1780
- elementControllers[name].instance,
1781
- getControllers(name, require, $element, elementControllers),
1782
- );
1863
+ if (directive.replace) {
1864
+ replaceDirective = directive;
1783
1865
  }
1784
- });
1785
1866
 
1786
- // Handle the init and destroy lifecycle hooks on all controllers that have them
1787
- forEach(elementControllers, (controller) => {
1788
- const controllerInstance = controller.instance;
1789
- if (isFunction(controllerInstance.$onChanges)) {
1790
- try {
1791
- controllerInstance.$onChanges(
1792
- controller.bindingInfo.initialChanges,
1867
+ nodeLinkFn = compileTemplateUrl(
1868
+ directives.splice(i, directives.length - i),
1869
+ $compileNode,
1870
+ templateAttrs,
1871
+ jqCollection,
1872
+ hasTranscludeDirective && childTranscludeFn,
1873
+ preLinkFns,
1874
+ postLinkFns,
1875
+ {
1876
+ controllerDirectives,
1877
+ newScopeDirective:
1878
+ newScopeDirective !== directive && newScopeDirective,
1879
+ newIsolateScopeDirective,
1880
+ templateDirective,
1881
+ nonTlbTranscludeDirective,
1882
+ },
1883
+ );
1884
+ ii = directives.length;
1885
+ } else if (directive.compile) {
1886
+ try {
1887
+ linkFn = directive.compile(
1888
+ $compileNode,
1889
+ templateAttrs,
1890
+ childTranscludeFn,
1891
+ );
1892
+ const context = directive.$$originalDirective || directive;
1893
+ if (isFunction(linkFn)) {
1894
+ addLinkFns(null, bind(context, linkFn), attrStart, attrEnd);
1895
+ } else if (linkFn) {
1896
+ addLinkFns(
1897
+ bind(context, linkFn.pre),
1898
+ bind(context, linkFn.post),
1899
+ attrStart,
1900
+ attrEnd,
1793
1901
  );
1794
- } catch (e) {
1795
- $exceptionHandler(e);
1796
1902
  }
1903
+ } catch (e) {
1904
+ $exceptionHandler(e, startingTag($compileNode));
1797
1905
  }
1798
- if (isFunction(controllerInstance.$onInit)) {
1799
- try {
1800
- controllerInstance.$onInit();
1801
- } catch (e) {
1802
- $exceptionHandler(e);
1803
- }
1804
- }
1805
- if (isFunction(controllerInstance.$doCheck)) {
1806
- controllerScope.$watch(() => {
1807
- controllerInstance.$doCheck();
1808
- });
1809
- controllerInstance.$doCheck();
1810
- }
1811
- if (isFunction(controllerInstance.$onDestroy)) {
1812
- controllerScope.$on("$destroy", () => {
1813
- controllerInstance.$onDestroy();
1814
- });
1815
- }
1816
- });
1817
-
1818
- // PRELINKING
1819
- for (i = 0, ii = preLinkFns.length; i < ii; i++) {
1820
- linkFn = preLinkFns[i];
1821
- invokeLinkFn(
1822
- linkFn,
1823
- linkFn.isolateScope ? isolateScope : scope,
1824
- $element,
1825
- attrs,
1826
- linkFn.require &&
1827
- getControllers(
1828
- linkFn.directiveName,
1829
- linkFn.require,
1830
- $element,
1831
- elementControllers,
1832
- ),
1833
- transcludeFn,
1834
- );
1835
1906
  }
1836
1907
 
1837
- // RECURSION
1838
- // We only pass the isolate scope, if the isolate directive has a template,
1839
- // otherwise the child elements do not belong to the isolate directive.
1840
- var scopeToChild = scope;
1841
- if (
1842
- newIsolateScopeDirective &&
1843
- (newIsolateScopeDirective.template ||
1844
- newIsolateScopeDirective.templateUrl === null)
1845
- ) {
1846
- scopeToChild = isolateScope;
1847
- }
1848
- if (childLinkFn) {
1849
- childLinkFn(
1850
- scopeToChild,
1851
- linkNode.childNodes,
1852
- undefined,
1853
- boundTranscludeFn,
1854
- );
1908
+ if (directive.terminal) {
1909
+ nodeLinkFn.terminal = true;
1910
+ terminalPriority = Math.max(terminalPriority, directive.priority);
1855
1911
  }
1912
+ }
1856
1913
 
1857
- // POSTLINKING
1858
- for (i = postLinkFns.length - 1; i >= 0; i--) {
1859
- linkFn = postLinkFns[i];
1860
- invokeLinkFn(
1861
- linkFn,
1862
- linkFn.isolateScope ? isolateScope : scope,
1863
- $element,
1864
- attrs,
1865
- linkFn.require &&
1866
- getControllers(
1867
- linkFn.directiveName,
1868
- linkFn.require,
1869
- $element,
1870
- elementControllers,
1871
- ),
1872
- transcludeFn,
1873
- );
1874
- }
1914
+ nodeLinkFn.scope =
1915
+ newScopeDirective && newScopeDirective.scope === true;
1916
+ nodeLinkFn.transcludeOnThisElement = hasTranscludeDirective;
1917
+ nodeLinkFn.templateOnThisElement = hasTemplate;
1918
+ nodeLinkFn.transclude = childTranscludeFn;
1875
1919
 
1876
- // Trigger $postLink lifecycle hooks
1877
- forEach(elementControllers, (controller) => {
1878
- const controllerInstance = controller.instance;
1879
- if (isFunction(controllerInstance.$postLink)) {
1880
- controllerInstance.$postLink();
1881
- }
1882
- });
1920
+ previousCompileContext.hasElementTranscludeDirective =
1921
+ hasElementTranscludeDirective;
1883
1922
 
1884
- // This is the function that is injected as `$transclude`.
1885
- // Note: all arguments are optional!
1886
- function controllersBoundTransclude(
1887
- scope,
1888
- cloneAttachFn,
1889
- futureParentElement,
1890
- slotName,
1891
- ) {
1892
- let transcludeControllers;
1893
- // No scope passed in:
1894
- if (!isScope(scope)) {
1895
- slotName = futureParentElement;
1896
- futureParentElement = cloneAttachFn;
1897
- cloneAttachFn = scope;
1898
- scope = undefined;
1899
- }
1923
+ // might be normal or delayed nodeLinkFn depending on if templateUrl is present
1924
+ return nodeLinkFn;
1900
1925
 
1901
- if (hasElementTranscludeDirective) {
1902
- transcludeControllers = elementControllers;
1903
- }
1904
- if (!futureParentElement) {
1905
- futureParentElement = hasElementTranscludeDirective
1906
- ? $element.parent()
1907
- : $element;
1926
+ /// /////////////////
1927
+
1928
+ function addLinkFns(pre, post, attrStart, attrEnd) {
1929
+ if (pre) {
1930
+ if (attrStart)
1931
+ pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd);
1932
+ pre.require = directive.require;
1933
+ pre.directiveName = directiveName;
1934
+ if (
1935
+ newIsolateScopeDirective === directive ||
1936
+ directive.$$isolateScope
1937
+ ) {
1938
+ pre = cloneAndAnnotateFn(pre, { isolateScope: true });
1908
1939
  }
1909
- if (slotName) {
1910
- // slotTranscludeFn can be one of three things:
1911
- // * a transclude function - a filled slot
1912
- // * `null` - an optional slot that was not filled
1913
- // * `undefined` - a slot that was not declared (i.e. invalid)
1914
- const slotTranscludeFn = boundTranscludeFn.$$slots[slotName];
1915
- if (slotTranscludeFn) {
1916
- return slotTranscludeFn(
1917
- scope,
1918
- cloneAttachFn,
1919
- transcludeControllers,
1920
- futureParentElement,
1921
- scopeToChild,
1922
- );
1923
- }
1924
- if (isUndefined(slotTranscludeFn)) {
1925
- throw $compileMinErr(
1926
- "noslot",
1927
- 'No parent directive that requires a transclusion with slot name "{0}". ' +
1928
- "Element: {1}",
1929
- slotName,
1930
- startingTag($element),
1931
- );
1932
- }
1933
- } else {
1934
- return boundTranscludeFn(
1935
- scope,
1936
- cloneAttachFn,
1937
- transcludeControllers,
1938
- futureParentElement,
1939
- scopeToChild,
1940
- );
1940
+ preLinkFns.push(pre);
1941
+ }
1942
+ if (post) {
1943
+ if (attrStart)
1944
+ post = groupElementsLinkFnWrapper(post, attrStart, attrEnd);
1945
+ post.require = directive.require;
1946
+ post.directiveName = directiveName;
1947
+ if (
1948
+ newIsolateScopeDirective === directive ||
1949
+ directive.$$isolateScope
1950
+ ) {
1951
+ post = cloneAndAnnotateFn(post, { isolateScope: true });
1941
1952
  }
1953
+ postLinkFns.push(post);
1942
1954
  }
1943
1955
  }
1944
1956
  }
@@ -2223,6 +2235,7 @@ export function $CompileProvider($provide, $$sanitizeUriProvider) {
2223
2235
  previousCompileContext,
2224
2236
  ) {
2225
2237
  let linkQueue = [];
2238
+ /** @type {any} */
2226
2239
  let afterTemplateNodeLinkFn;
2227
2240
  let afterTemplateChildLinkFn;
2228
2241
  const beforeTemplateCompileNode = $compileNode[0];
@@ -2518,6 +2531,61 @@ export function $CompileProvider($provide, $$sanitizeUriProvider) {
2518
2531
  return sanitizeSrcset($sce.valueOf(value), "ng-prop-srcset");
2519
2532
  }
2520
2533
 
2534
+ function sanitizeSrcset(value, invokeType) {
2535
+ if (!value) {
2536
+ return value;
2537
+ }
2538
+ if (!isString(value)) {
2539
+ throw $compileMinErr(
2540
+ "srcset",
2541
+ 'Can\'t pass trusted values to `{0}`: "{1}"',
2542
+ invokeType,
2543
+ value.toString(),
2544
+ );
2545
+ }
2546
+
2547
+ // Such values are a bit too complex to handle automatically inside $sce.
2548
+ // Instead, we sanitize each of the URIs individually, which works, even dynamically.
2549
+
2550
+ // It's not possible to work around this using `$sce.trustAsMediaUrl`.
2551
+ // If you want to programmatically set explicitly trusted unsafe URLs, you should use
2552
+ // `$sce.trustAsHtml` on the whole `img` tag and inject it into the DOM using the
2553
+ // `ng-bind-html` directive.
2554
+
2555
+ var result = "";
2556
+
2557
+ // first check if there are spaces because it's not the same pattern
2558
+ var trimmedSrcset = trim(value);
2559
+ // ( 999x ,| 999w ,| ,|, )
2560
+ var srcPattern = /(\s+\d+x\s*,|\s+\d+w\s*,|\s+,|,\s+)/;
2561
+ var pattern = /\s/.test(trimmedSrcset) ? srcPattern : /(,)/;
2562
+
2563
+ // split srcset into tuple of uri and descriptor except for the last item
2564
+ var rawUris = trimmedSrcset.split(pattern);
2565
+
2566
+ // for each tuples
2567
+ var nbrUrisWith2parts = Math.floor(rawUris.length / 2);
2568
+ for (var i = 0; i < nbrUrisWith2parts; i++) {
2569
+ var innerIdx = i * 2;
2570
+ // sanitize the uri
2571
+ result += $sce.getTrustedMediaUrl(trim(rawUris[innerIdx]));
2572
+ // add the descriptor
2573
+ result += " " + trim(rawUris[innerIdx + 1]);
2574
+ }
2575
+
2576
+ // split the last item into uri and descriptor
2577
+ var lastTuple = trim(rawUris[i * 2]).split(/\s/);
2578
+
2579
+ // sanitize the last uri
2580
+ result += $sce.getTrustedMediaUrl(trim(lastTuple[0]));
2581
+
2582
+ // and add the last descriptor if any
2583
+ if (lastTuple.length === 2) {
2584
+ result += " " + trim(lastTuple[1]);
2585
+ }
2586
+ return result;
2587
+ }
2588
+
2521
2589
  function addPropertyDirective(node, directives, attrName, propName) {
2522
2590
  if (EVENT_HANDLER_ATTR_REGEXP.test(propName)) {
2523
2591
  throw $compileMinErr(
@@ -2699,13 +2767,6 @@ export function $CompileProvider($provide, $$sanitizeUriProvider) {
2699
2767
  }
2700
2768
  }
2701
2769
  $rootElement.length -= removeCount - 1;
2702
-
2703
- // If the replaced element is also the jQuery .context then replace it
2704
- // .context is a deprecated jQuery api, so we should set it only when jQuery set it
2705
- // http://api.jquery.com/context/
2706
- if ($rootElement.context === firstElementToRemove) {
2707
- $rootElement.context = newNode;
2708
- }
2709
2770
  break;
2710
2771
  }
2711
2772
  }
@@ -2728,7 +2789,10 @@ export function $CompileProvider($provide, $$sanitizeUriProvider) {
2728
2789
  // Copy over user data (that includes AngularJS's $scope etc.). Don't copy private
2729
2790
  // data here because there's no public interface in jQuery to do that and copying over
2730
2791
  // event listeners (which is the main use of private data) wouldn't work anyway.
2731
- getOrSetCacheData(newNode, getOrSetCacheData(firstElementToRemove));
2792
+ getOrSetCacheData(
2793
+ /** @type {Element} */ (newNode),
2794
+ getOrSetCacheData(firstElementToRemove),
2795
+ );
2732
2796
 
2733
2797
  // Remove $destroy event listeners from `firstElementToRemove`
2734
2798
  JQLite(firstElementToRemove).off("$destroy");
@@ -2807,7 +2871,7 @@ export function $CompileProvider($provide, $$sanitizeUriProvider) {
2807
2871
 
2808
2872
  switch (mode) {
2809
2873
  case "@":
2810
- if (!optional && !hasOwnProperty.call(attrs, attrName)) {
2874
+ if (!optional && !Object.hasOwnProperty.call(attrs, attrName)) {
2811
2875
  strictBindingsCheck(attrName, directive.name);
2812
2876
  destination[scopeName] = attrs[attrName] = undefined;
2813
2877
  }