ngannotate-rails 0.9.2 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2dd7c00767bd1657fbdda31a2b51ceba108b0e24
4
- data.tar.gz: 31b2eb5ae4c37392f5f907da4eec8d3052114a3f
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NTU4MjFkOTczODkxOTFmZjMwYjhiYWJhNzJmNGU2YmU0OTNlZWQ5Yw==
5
+ data.tar.gz: !binary |-
6
+ MDdlMjViMzY1YzgwNmE3MWUxOWZiOTFmMTA0NjgxNWZkMzUyMTA0NQ==
5
7
  SHA512:
6
- metadata.gz: 1783b877d258c6fa88d1aa9a4999e8e7484857c3965777972ec9f896f5f7ce16a63ed355919503d3ea279e234426ec3b1804a8c5d67444dcb54bf55ff7f57feb
7
- data.tar.gz: 7bd95be1b3cb4bc7a4229124bc5a1a05c8ddbde5a66f575b0da6df832207bbbdc8c44639b7f3c20de8dc514aab46b5eedad933afbeb3510e887173c5a3108e24
8
+ metadata.gz: !binary |-
9
+ NzNmODlhNjg2MWMwNTJiOWQ2YmViNWUxZTUzZmM0YTAzNTBmYzU5OTE0YTkz
10
+ OTE5ZDk5N2RlMGFjNTI0ZjQxZTkzNjg0OWE1NDdmNGZjYjk0NjBmNmZmYjU4
11
+ ZTFhNThhMzkxNTRiZTEwYTYzNzBkNWMzMjZkM2RkOTQxNGUxMjk=
12
+ data.tar.gz: !binary |-
13
+ MmQ2N2Q4YzczMjJkMjM3OWM3NDNjYTIwMWRlMjY4YjhmYzhiZDQ3YzM1Mzc4
14
+ YzhkMzVkYjI4OWVhNTE5ZjgxODhlOTQyYWYyYThiMDczMWEzMjY0MTc1ZjFk
15
+ M2FkMTg1MTBhMTdmZDUxMDRlYmUxZmExNzE1ZmUzMjY5OTE5Y2E=
@@ -7,13 +7,37 @@ module Ngannotate
7
7
  end
8
8
 
9
9
  def prepare
10
+ return if skip
10
11
  ngannotate_source = File.open(File.join(File.dirname(__FILE__), '../../vendor/ngannotate.js')).read
11
12
  @context = ExecJS.compile "window = {};" + ngannotate_source
12
13
  end
13
14
 
15
+ #
16
+ # Skip processing in environments where it does not make sense
17
+ #
18
+ def skip
19
+ ::Rails.env.development? || ::Rails.env.test?
20
+ end
21
+
14
22
  def evaluate(context, locals)
15
- r = @context.call 'window.annotate', data, { add: true }
23
+ return data if skip
24
+
25
+ opt = { add: true }.merge!(parse_opt)
26
+ r = @context.call 'window.annotate', data, opt
16
27
  r['src']
17
28
  end
29
+
30
+ def parse_opt
31
+ opt = {}
32
+ opt_str = ENV['NG_OPT']
33
+ if opt_str
34
+ opt = Hash[opt_str.split(',').map { |e| e.split('=') }]
35
+ opt.symbolize_keys!
36
+ end
37
+ if ENV['NG_REGEXP']
38
+ opt[:regexp] = ENV['NG_REGEXP']
39
+ end
40
+ opt
41
+ end
18
42
  end
19
43
  end
@@ -1,5 +1,5 @@
1
1
  module Ngannotate
2
2
  module Rails
3
- VERSION = "0.9.2"
3
+ VERSION = "0.9.5"
4
4
  end
5
5
  end
@@ -1121,8 +1121,6 @@ function match(node, re, matchPlugins) {
1121
1121
  }
1122
1122
 
1123
1123
  function matchDirectiveReturnObject(node) {
1124
- // TODO make these more strict by checking that we're inside an angular module?
1125
-
1126
1124
  // return { .. controller: function($scope, $timeout), ...}
1127
1125
 
1128
1126
  return node.type === "ReturnStatement" &&
@@ -1131,8 +1129,6 @@ function matchDirectiveReturnObject(node) {
1131
1129
  }
1132
1130
 
1133
1131
  function matchProviderGet(node) {
1134
- // TODO make these more strict by checking that we're inside an angular module?
1135
-
1136
1132
  // (this|self|that).$get = function($scope, $timeout)
1137
1133
  // { ... $get: function($scope, $timeout), ...}
1138
1134
  var memberExpr;
@@ -1194,7 +1190,7 @@ function matchNgUi(node) {
1194
1190
  // onExit: function($scope)
1195
1191
  // });
1196
1192
  // $stateProvider.state("myState", {... resolve: {f: function($scope) {}, ..} ..})
1197
- // $stateProvider.state("myState", {... views: {... somename: {... controller: fn, templateProvider: fn, resolve: {f: fn}}}})
1193
+ // $stateProvider.state("myState", {... views: {... somename: {... controller: fn, controllerProvider: fn, templateProvider: fn, resolve: {f: fn}}}})
1198
1194
  //
1199
1195
  // $urlRouterProvider.when(.., function($scope) {})
1200
1196
  //
@@ -1263,6 +1259,7 @@ function matchNgUi(node) {
1263
1259
  viewObject.properties.forEach(function(prop) {
1264
1260
  if (prop.value.type === "ObjectExpression") {
1265
1261
  res.push(matchProp("controller", prop.value.properties));
1262
+ res.push(matchProp("controllerProvider", prop.value.properties));
1266
1263
  res.push(matchProp("templateProvider", prop.value.properties));
1267
1264
  res.push.apply(res, matchResolve(prop.value.properties));
1268
1265
  }
@@ -1306,9 +1303,14 @@ function matchRegular(node, re) {
1306
1303
  }
1307
1304
 
1308
1305
  var args = node.arguments;
1309
- return (is.someof(method.name, ["config", "run"]) ?
1306
+ var target = (is.someof(method.name, ["config", "run"]) ?
1310
1307
  args.length === 1 && args[0] :
1311
1308
  args.length === 2 && args[0].type === "Literal" && is.string(args[0].value) && args[1]);
1309
+
1310
+ if (target) {
1311
+ target.$always = true;
1312
+ }
1313
+ return target;
1312
1314
  }
1313
1315
 
1314
1316
  // Short form: *.controller("MyCtrl", function($scope, $timeout) {});
@@ -1406,21 +1408,46 @@ function removeArray(array, fragments) {
1406
1408
  });
1407
1409
  }
1408
1410
 
1409
- function replaceRemoveOrInsertArrayForTarget(target, ctx) {
1411
+ function judgeSuspects(ctx) {
1412
+ var suspects = ctx.suspects;
1410
1413
  var mode = ctx.mode;
1411
1414
  var fragments = ctx.fragments;
1412
1415
  var quot = ctx.quot;
1413
1416
 
1414
- if (mode === "rebuild" && isAnnotatedArray(target)) {
1415
- replaceArray(target, fragments, quot);
1416
- } else if (mode === "remove" && isAnnotatedArray(target)) {
1417
- removeArray(target, fragments);
1418
- } else if (is.someof(mode, ["add", "rebuild"]) && isFunctionExpressionWithArgs(target)) {
1419
- insertArray(target, fragments, quot);
1420
- } else {
1421
- return false;
1417
+ for (var i = 0; i < suspects.length; i++) {
1418
+ var target = suspects[i];
1419
+
1420
+ if (target.$once) {
1421
+ continue;
1422
+ }
1423
+ target.$once = true;
1424
+
1425
+ if (!target.$always) {
1426
+ var $caller = target.$caller;
1427
+ for (; $caller && $caller.$chained !== chainedRegular; $caller = $caller.$caller) {
1428
+ }
1429
+ if (!$caller) {
1430
+ continue;
1431
+ }
1432
+ }
1433
+
1434
+ if (mode === "rebuild" && isAnnotatedArray(target)) {
1435
+ replaceArray(target, fragments, quot);
1436
+ } else if (mode === "remove" && isAnnotatedArray(target)) {
1437
+ removeArray(target, fragments);
1438
+ } else if (is.someof(mode, ["add", "rebuild"]) && isFunctionExpressionWithArgs(target)) {
1439
+ insertArray(target, fragments, quot);
1440
+ }
1422
1441
  }
1423
- return true;
1442
+ }
1443
+
1444
+ function addModuleContextDependentSuspect(target, ctx) {
1445
+ ctx.suspects.push(target);
1446
+ }
1447
+
1448
+ function addModuleContextIndependentSuspect(target, ctx) {
1449
+ target.$always = true;
1450
+ ctx.suspects.push(target);
1424
1451
  }
1425
1452
 
1426
1453
  function isAnnotatedArray(node) {
@@ -1485,6 +1512,14 @@ window.annotate = function ngAnnotate(src, options) {
1485
1512
  // first node at (or after) a certain pos
1486
1513
  var triggers = new Heap();
1487
1514
 
1515
+ // suspects is built up with suspect nodes by match.
1516
+ // A suspect node will get annotations added / removed if it
1517
+ // fulfills the arrayexpression or functionexpression look,
1518
+ // and if it is in the correct context (inside an angular
1519
+ // module definition) - alternatively is forced to ignore
1520
+ // context with node.$always = true
1521
+ var suspects = [];
1522
+
1488
1523
  var ctx = {
1489
1524
  mode: mode,
1490
1525
  quot: quot,
@@ -1492,10 +1527,12 @@ window.annotate = function ngAnnotate(src, options) {
1492
1527
  comments: comments,
1493
1528
  fragments: fragments,
1494
1529
  triggers: triggers,
1530
+ suspects: suspects,
1495
1531
  isFunctionExpressionWithArgs: isFunctionExpressionWithArgs,
1496
1532
  isFunctionDeclarationWithArgs: isFunctionDeclarationWithArgs,
1497
1533
  isAnnotatedArray: isAnnotatedArray,
1498
- replaceRemoveOrInsertArrayForTarget: replaceRemoveOrInsertArrayForTarget,
1534
+ addModuleContextDependentSuspect: addModuleContextDependentSuspect,
1535
+ addModuleContextIndependentSuspect: addModuleContextIndependentSuspect,
1499
1536
  stringify: stringify,
1500
1537
  };
1501
1538
 
@@ -1516,13 +1553,26 @@ window.annotate = function ngAnnotate(src, options) {
1516
1553
  plugin.init(ctx);
1517
1554
  });
1518
1555
 
1556
+ var recentCaller = undefined; // micro-optimization
1557
+ var callerIds = [];
1519
1558
  traverse(ast, {pre: function(node) {
1559
+ node.$caller = recentCaller;
1560
+ if (node.type === "CallExpression") {
1561
+ callerIds.push(node);
1562
+ recentCaller = node;
1563
+ }
1564
+
1520
1565
  var pos = node.range[0];
1521
1566
  while (pos >= triggers.pos) {
1522
1567
  var trigger = triggers.getAndRemoveNext();
1523
1568
  trigger.fn.call(null, node, trigger.ctx);
1524
1569
  }
1525
1570
  }, post: function(node) {
1571
+ if (node === recentCaller) {
1572
+ callerIds.pop();
1573
+ recentCaller = last(callerIds);
1574
+ }
1575
+
1526
1576
  var targets = match(node, re, matchPluginsOrNull);
1527
1577
  if (!targets) {
1528
1578
  return;
@@ -1531,12 +1581,13 @@ window.annotate = function ngAnnotate(src, options) {
1531
1581
  targets = [targets];
1532
1582
  }
1533
1583
 
1534
- // TODO add something to know that node has been altered so it won't happen again
1535
1584
  for (var i = 0; i < targets.length; i++) {
1536
- replaceRemoveOrInsertArrayForTarget(targets[i], ctx);
1585
+ addModuleContextDependentSuspect(targets[i], ctx);
1537
1586
  }
1538
1587
  }});
1539
1588
 
1589
+ judgeSuspects(ctx);
1590
+
1540
1591
  var out = alter(src, fragments);
1541
1592
 
1542
1593
  return {
@@ -1573,27 +1624,59 @@ function ngInjectCommentsInit(ctx) {
1573
1624
  ctx.triggers.addMany(triggers);
1574
1625
  }
1575
1626
 
1627
+ function nestedObjectValues(node, res) {
1628
+ res = res || [];
1629
+
1630
+ node.properties.forEach(function(prop) {
1631
+ var v = prop.value;
1632
+ if (is.someof(v.type, ["FunctionExpression", "ArrayExpression"])) {
1633
+ res.push(v);
1634
+ } else if (v.type === "ObjectExpression") {
1635
+ nestedObjectValues(v, res);
1636
+ }
1637
+ });
1638
+
1639
+ return res;
1640
+ }
1641
+
1576
1642
  function visitNodeFollowingNgInjectComment(node, ctx) {
1577
- // TODO objectliteral (if add or remove)
1643
+ // handle most common case: /*@ngInject*/ prepended to an array or function expression
1644
+ if (node.type === "ArrayExpression" || node.type === "FunctionExpression") {
1645
+ ctx.addModuleContextIndependentSuspect(node, ctx);
1646
+ return;
1647
+ }
1578
1648
 
1579
- if (ctx.replaceRemoveOrInsertArrayForTarget(node, ctx)) {
1649
+ if (node.type === "ObjectExpression") {
1650
+ nestedObjectValues(node).forEach(function(n) {
1651
+ ctx.addModuleContextIndependentSuspect(n, ctx);
1652
+ });
1580
1653
  return;
1581
1654
  }
1582
1655
 
1583
- // var foo = function($scope) {}
1656
+ // /*@ngInject*/ var foo = function($scope) {} and
1657
+ // /*@ngInject*/ function foo($scope) {}
1584
1658
  var d0 = null;
1585
1659
  var nr1 = node.range[1];
1586
1660
  if (node.type === "VariableDeclaration" && node.declarations.length === 1 &&
1587
1661
  (d0 = node.declarations[0]).init && ctx.isFunctionExpressionWithArgs(d0.init)) {
1588
1662
  var isSemicolonTerminated = (ctx.src[nr1 - 1] === ";");
1589
- addRemoveInjectsArray(d0.init.params, isSemicolonTerminated ? nr1 : d0.init.range[1], d0.id.name);
1663
+ addRemoveInjectArray(d0.init.params, isSemicolonTerminated ? nr1 : d0.init.range[1], d0.id.name);
1590
1664
  } else if (ctx.isFunctionDeclarationWithArgs(node)) {
1591
- addRemoveInjectsArray(node.params, nr1, node.id.name);
1665
+ addRemoveInjectArray(node.params, nr1, node.id.name);
1592
1666
  }
1593
1667
 
1668
+ function getIndent(pos) {
1669
+ var src = ctx.src;
1670
+ var lineStart = src.lastIndexOf("\n", pos - 1) + 1;
1671
+ var i = lineStart;
1672
+ for (; src[i] === " " || src[i] === "\t"; i++) {
1673
+ }
1674
+ return src.slice(lineStart, i);
1675
+ }
1594
1676
 
1595
- function addRemoveInjectsArray(params, posAfterFunctionDeclaration, name) {
1596
- var str = fmt("\n{0}.$injects = {1};", name, ctx.stringify(params, ctx.quot));
1677
+ function addRemoveInjectArray(params, posAfterFunctionDeclaration, name) {
1678
+ var indent = getIndent(posAfterFunctionDeclaration);
1679
+ var str = fmt("\n{0}{1}.$inject = {2};", indent, name, ctx.stringify(params, ctx.quot));
1597
1680
 
1598
1681
  ctx.triggers.add({
1599
1682
  pos: posAfterFunctionDeclaration,
@@ -1603,24 +1686,24 @@ function visitNodeFollowingNgInjectComment(node, ctx) {
1603
1686
  function visitNodeFollowingFunctionDeclaration(nextNode) {
1604
1687
  var assignment = nextNode.expression;
1605
1688
  var lvalue;
1606
- var hasInjectsArray = (nextNode.type === "ExpressionStatement" && assignment.type === "AssignmentExpression" &&
1689
+ var hasInjectArray = (nextNode.type === "ExpressionStatement" && assignment.type === "AssignmentExpression" &&
1607
1690
  assignment.operator === "=" &&
1608
1691
  (lvalue = assignment.left).type === "MemberExpression" &&
1609
- lvalue.computed === false && lvalue.object.name === name && lvalue.property.name === "$injects");
1692
+ lvalue.computed === false && lvalue.object.name === name && lvalue.property.name === "$inject");
1610
1693
 
1611
- if (ctx.mode === "rebuild" && hasInjectsArray) {
1694
+ if (ctx.mode === "rebuild" && hasInjectArray) {
1612
1695
  ctx.fragments.push({
1613
1696
  start: posAfterFunctionDeclaration,
1614
1697
  end: nextNode.range[1],
1615
1698
  str: str,
1616
1699
  });
1617
- } else if (ctx.mode === "remove" && hasInjectsArray) {
1700
+ } else if (ctx.mode === "remove" && hasInjectArray) {
1618
1701
  ctx.fragments.push({
1619
1702
  start: posAfterFunctionDeclaration,
1620
1703
  end: nextNode.range[1],
1621
1704
  str: "",
1622
1705
  });
1623
- } else if (is.someof(ctx.mode, ["add", "rebuild"]) && !hasInjectsArray) {
1706
+ } else if (is.someof(ctx.mode, ["add", "rebuild"]) && !hasInjectArray) {
1624
1707
  ctx.fragments.push({
1625
1708
  start: posAfterFunctionDeclaration,
1626
1709
  end: posAfterFunctionDeclaration,
@@ -3196,8 +3279,6 @@ parseStatement: true, parseSourceElement: true */
3196
3279
  }
3197
3280
  }
3198
3281
 
3199
- peek();
3200
-
3201
3282
  if (extra.trailingComments.length > 0) {
3202
3283
  if (extra.trailingComments[0].range[0] >= node.range[1]) {
3203
3284
  trailingComments = extra.trailingComments;
@@ -5521,7 +5602,7 @@ parseStatement: true, parseSourceElement: true */
5521
5602
  }
5522
5603
 
5523
5604
  // Sync with *.json manifests.
5524
- exports.version = '1.2.1';
5605
+ exports.version = '1.2.2';
5525
5606
 
5526
5607
  exports.tokenize = tokenize;
5527
5608
 
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ngannotate-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.9.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kari Ikonen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-21 00:00:00.000000000 Z
11
+ date: 2014-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ! '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '3.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ! '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.1'
27
27
  - !ruby/object:Gem::Dependency
@@ -42,14 +42,14 @@ dependencies:
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ! '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ! '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  description: Use ngannotate in the Rails asset pipeline.
@@ -82,17 +82,17 @@ require_paths:
82
82
  - lib
83
83
  required_ruby_version: !ruby/object:Gem::Requirement
84
84
  requirements:
85
- - - '>='
85
+ - - ! '>='
86
86
  - !ruby/object:Gem::Version
87
87
  version: '0'
88
88
  required_rubygems_version: !ruby/object:Gem::Requirement
89
89
  requirements:
90
- - - '>='
90
+ - - ! '>='
91
91
  - !ruby/object:Gem::Version
92
92
  version: '0'
93
93
  requirements: []
94
94
  rubyforge_project:
95
- rubygems_version: 2.0.3
95
+ rubygems_version: 2.2.2
96
96
  signing_key:
97
97
  specification_version: 4
98
98
  summary: Use ngannotate in the Rails asset pipeline.