Skip to content
This repository was archived by the owner on Feb 9, 2020. It is now read-only.

Commit 56ad9c1

Browse files
committed
v0.8.7
1 parent 7f2d9bd commit 56ad9c1

File tree

3 files changed

+49
-18
lines changed

3 files changed

+49
-18
lines changed

dist/hint.js

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,7 +1663,7 @@ var getFunctionNames = function(str) {
16631663
// To fully fix these issues we would need a full blown expression parser.
16641664
var results = removeStringExp(str.replace(/\s+/g, ''))
16651665
.replace(/\(.*?\)/g, '')
1666-
.split(/[\+\-\/\|\<\>\^=&!%~;]/g).map(function(x) {
1666+
.split(/[\+\-\/\|\<\>\^=&!%~?:;]/g).map(function(x) {
16671667
if (isNaN(+x)) {
16681668
if (x.match(/\w+\(.*\)$/)){
16691669
return x.substr(0, x.indexOf('('));
@@ -1699,22 +1699,31 @@ function ngEventDirectivesDecorator(ngEventAttrName) {
16991699

17001700
return function ngEventHandler(scope, element, attrs) {
17011701
var boundFuncs = getFunctionNames(attrs[ngEventAttrName]);
1702-
boundFuncs.forEach(function(boundFn) {
1703-
var property, propChain, lastProp = '';
1704-
while((property = boundFn.match(/^.+?([^\.\[])*/)) !== null) {
1705-
property = property[0];
1706-
propChain = lastProp + property;
1707-
if ($parse(propChain)(scope) === undefined) {
1708-
angular.hint.emit(MODULE_NAME + ':undef', propChain + ' is undefined');
1709-
}
1710-
boundFn = boundFn.replace(property, '');
1711-
lastProp += property;
1712-
if(boundFn.charAt(0) === '.') {
1713-
lastProp += '.';
1714-
boundFn = boundFn.substr(1);
1702+
1703+
// guard against any parsing errors since the parsing code
1704+
// to split the expression is pretty simple and naive.
1705+
try {
1706+
boundFuncs.forEach(function(boundFn) {
1707+
var property, propChain, lastProp = '';
1708+
while((property = boundFn.match(/^.+?([^\.\[])*/)) !== null) {
1709+
property = property[0];
1710+
propChain = lastProp + property;
1711+
if ($parse(propChain)(scope) === undefined) {
1712+
angular.hint.emit(MODULE_NAME + ':undef', propChain + ' is undefined');
1713+
}
1714+
boundFn = boundFn.replace(property, '');
1715+
lastProp += property;
1716+
if(boundFn.charAt(0) === '.') {
1717+
lastProp += '.';
1718+
boundFn = boundFn.substr(1);
1719+
}
17151720
}
1716-
}
1717-
});
1721+
});
1722+
} catch (e) {
1723+
angular.hint.emit(MODULE_NAME + ':undef', '' +
1724+
'parsing error: please inform the angular-hint ' +
1725+
'or batarang teams. expression: ' + boundFuncs.join(''));
1726+
}
17181727

17191728
return linkFn.apply(this, arguments);
17201729
};
@@ -1863,14 +1872,36 @@ function decorateRootScope($delegate, $parse) {
18631872

18641873
var _watch = scopePrototype.$watch;
18651874
var _digestEvents = [];
1875+
var skipNextPerfWatchers = false;
18661876
scopePrototype.$watch = function (watchExpression, reactionFunction) {
1877+
// if `skipNextPerfWatchers` is true, this means the previous run of the
1878+
// `$watch` decorator was a one time binding expression and this invocation
1879+
// of the $watch function has the `oneTimeInterceptedExpression` (internal angular function)
1880+
// as the `watchExpression` parameter. If we decorate it with the performance
1881+
// timers function this will cause us to invoke `oneTimeInterceptedExpression`
1882+
// on subsequent digest loops and will update the one time bindings
1883+
// if anything mutated the property.
1884+
if (skipNextPerfWatchers) {
1885+
skipNextPerfWatchers = false;
1886+
return _watch.apply(this, arguments);
1887+
}
1888+
18671889
if (typeof watchExpression === 'string' &&
18681890
isOneTimeBindExp(watchExpression)) {
1891+
skipNextPerfWatchers = true;
18691892
return _watch.apply(this, arguments);
18701893
}
18711894
var watchStr = humanReadableWatchExpression(watchExpression);
18721895
var scopeId = this.$id;
1896+
var expressions = null;
18731897
if (typeof watchExpression === 'function') {
1898+
expressions = watchExpression.expressions;
1899+
if (Object.prototype.toString.call(expressions) === '[object Array]' &&
1900+
expressions.some(isOneTimeBindExp)) {
1901+
skipNextPerfWatchers = true;
1902+
return _watch.apply(this, arguments);
1903+
}
1904+
18741905
arguments[0] = function () {
18751906
var start = perf.now();
18761907
var ret = watchExpression.apply(this, arguments);

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "AngularJS Batarang",
3-
"version": "0.8.6",
3+
"version": "0.8.7",
44
"description": "Extends the Developer Tools, adding tools for debugging and profiling AngularJS applications.",
55
"devtools_page": "devtoolsBackground.html",
66
"manifest_version": 2,

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "angularjs-batarang",
3-
"version": "0.8.6",
3+
"version": "0.8.7",
44
"description": "chrome extension for inspecting angular apps",
55
"main": "hint.js",
66
"devDependencies": {

0 commit comments

Comments
 (0)