Skip to content

Commit e86c435

Browse files
mheveryIgorMinar
authored andcommitted
refactor(bindings): remove the decoration of the DOM with errors.
Only $exceptionHandler gets notified now.
1 parent 1942861 commit e86c435

4 files changed

Lines changed: 25 additions & 98 deletions

File tree

css/angular.css

Lines changed: 0 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Angular.js

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@ var _undefined = undefined,
7171
$value = 'value',
7272
$selected = 'selected',
7373
$undefined = 'undefined',
74-
NG_EXCEPTION = 'ng-exception',
75-
NG_VALIDATION_ERROR = 'ng-validation-error',
7674
NOOP = 'noop',
7775
Error = window.Error,
7876
/** holds major version number for IE or NaN for real browsers */
@@ -758,36 +756,6 @@ function setHtml(node, html) {
758756
}
759757
}
760758

761-
function isRenderableElement(element) {
762-
var name = element && element[0] && element[0].nodeName;
763-
return name && name.charAt(0) != '#' &&
764-
!includes(['TR', 'COL', 'COLGROUP', 'TBODY', 'THEAD', 'TFOOT'], name);
765-
}
766-
767-
function elementError(element, type, error) {
768-
var parent;
769-
770-
while (!isRenderableElement(element)) {
771-
parent = element.parent();
772-
if (parent.length) {
773-
element = element.parent();
774-
} else {
775-
return;
776-
}
777-
}
778-
779-
if (element[0]['$NG_ERROR'] !== error) {
780-
element[0]['$NG_ERROR'] = error;
781-
if (error) {
782-
element.addClass(type);
783-
element.attr(type, error.message || error);
784-
} else {
785-
element.removeClass(type);
786-
element.removeAttr(type);
787-
}
788-
}
789-
}
790-
791759
function concat(array1, array2, index) {
792760
return array1.concat(slice.call(array2, index));
793761
}

src/directives.js

Lines changed: 25 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -216,50 +216,46 @@ angularDirective("ng:bind", function(expression, element){
216216
element.addClass('ng-binding');
217217
var exprFn = parser(expression).statements();
218218
return function(element) {
219-
var lastValue = noop, lastError = noop;
219+
var lastValue = Number.NaN;
220220
this.$watch(function(scope) {
221221
// TODO(misko): remove error handling https://github.com/angular/angular.js/issues/347
222-
var error, value, html, isHtml, isDomElement,
222+
var value, html, isHtml, isDomElement,
223223
hadOwnElement = scope.hasOwnProperty('$element'),
224224
oldElement = scope.$element;
225225
// TODO(misko): get rid of $element https://github.com/angular/angular.js/issues/348
226226
scope.$element = element;
227227
try {
228228
value = exprFn(scope);
229+
// If we are HTML than save the raw HTML data so that we don't recompute sanitization since
230+
// it is expensive.
231+
// TODO(misko): turn this into a more generic way to compute this
232+
if ((isHtml = (value instanceof HTML)))
233+
value = (html = value).html;
234+
if (lastValue === value) return;
235+
isDomElement = isElement(value);
236+
if (!isHtml && !isDomElement && isObject(value)) {
237+
value = toJson(value, true);
238+
}
239+
if (value != lastValue) {
240+
lastValue = value;
241+
if (isHtml) {
242+
element.html(html.get());
243+
} else if (isDomElement) {
244+
element.html('');
245+
element.append(value);
246+
} else {
247+
element.text(value == undefined ? '' : value);
248+
}
249+
}
229250
} catch (e) {
230251
scope.$service('$exceptionHandler')(e);
231-
error = formatError(e);
232252
} finally {
233253
if (hadOwnElement) {
234254
scope.$element = oldElement;
235255
} else {
236256
delete scope.$element;
237257
}
238258
}
239-
// If we are HTML, then save the raw HTML data so that we don't
240-
// recompute sanitization since that is expensive.
241-
// TODO: turn this into a more generic way to compute this
242-
if ((isHtml = (value instanceof HTML)))
243-
value = (html = value).html;
244-
if (lastValue === value && lastError == error) return;
245-
isDomElement = isElement(value);
246-
if (!isHtml && !isDomElement && isObject(value)) {
247-
value = toJson(value, true);
248-
}
249-
if (value != lastValue || error != lastError) {
250-
lastValue = value;
251-
lastError = error;
252-
elementError(element, NG_EXCEPTION, error);
253-
if (error) value = error;
254-
if (isHtml) {
255-
element.html(html.get());
256-
} else if (isDomElement) {
257-
element.html('');
258-
element.append(value);
259-
} else {
260-
element.text(value == undefined ? '' : value);
261-
}
262-
}
263259
});
264260
};
265261
});
@@ -272,20 +268,8 @@ function compileBindTemplate(template){
272268
forEach(parseBindings(template), function(text){
273269
var exp = binding(text);
274270
bindings.push(exp
275-
? function(scope, element) {
276-
var error, value;
277-
try {
278-
value = scope.$eval(exp);
279-
} catch(e) {
280-
scope.$service('$exceptionHandler')(e);
281-
error = toJson(e);
282-
}
283-
elementError(element, NG_EXCEPTION, error);
284-
return error ? error : value;
285-
}
286-
: function() {
287-
return text;
288-
});
271+
? function(scope, element) { return scope.$eval(exp); }
272+
: function() { return text; });
289273
});
290274
bindTemplateCache[template] = fn = function(scope, element, prettyPrintJson) {
291275
var parts = [],

test/BinderSpec.js

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -270,39 +270,25 @@ describe('Binder', function(){
270270

271271
it('IfTextBindingThrowsErrorDecorateTheSpan', function(){
272272
var scope = this.compile('<div>{{error.throw()}}</div>', null, true);
273-
var doc = scope.$element;
274273
var errorLogs = scope.$service('$exceptionHandler').errors;
275274

276275
scope.error = {
277276
'throw': function(){throw "ErrorMsg1";}
278277
};
279278
scope.$apply();
280-
var span = childNode(doc, 0);
281-
assertTrue(span.hasClass('ng-exception'));
282-
assertTrue(!!span.text().match(/ErrorMsg1/));
283-
assertTrue(!!span.attr('ng-exception').match(/ErrorMsg1/));
284-
assertEquals(['ErrorMsg1'], errorLogs.shift());
285279

286280
scope.error['throw'] = function(){throw "MyError";};
287281
errorLogs.length = 0;
288282
scope.$apply();
289-
span = childNode(doc, 0);
290-
assertTrue(span.hasClass('ng-exception'));
291-
assertTrue(span.text(), span.text().match('MyError') !== null);
292-
assertEquals('MyError', span.attr('ng-exception'));
293283
assertEquals(['MyError'], errorLogs.shift());
294284

295285
scope.error['throw'] = function(){return "ok";};
296286
scope.$apply();
297-
assertFalse(span.hasClass('ng-exception'));
298-
assertEquals('ok', span.text());
299-
assertEquals(null, span.attr('ng-exception'));
300287
assertEquals(0, errorLogs.length);
301288
});
302289

303290
it('IfAttrBindingThrowsErrorDecorateTheAttribute', function(){
304291
var scope = this.compile('<div attr="before {{error.throw()}} after"></div>', null, true);
305-
var doc = scope.$element;
306292
var errorLogs = scope.$service('$exceptionHandler').errors;
307293
var count = 0;
308294

0 commit comments

Comments
 (0)