Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

fix($compile): exception when using "watch" as isolated scope binding variable in Firefox #11628

Closed
wants to merge 1 commit into from
Closed

fix($compile): exception when using "watch" as isolated scope binding variable in Firefox #11628

wants to merge 1 commit into from

Conversation

randing89
Copy link
Contributor

Firefox throws "Error: can't convert undefined to object" exception when using "watch" as a isolated scope binding
It is because in Firefox Object.prototype.watch is defined and the related code is not using hasOwnProperty to check property availability.

Closes #11627

@randing89 randing89 changed the title fix($compile): exception when using "watch" as isolated scope binding va... fix($compile): exception when using "watch" as isolated scope binding in Firefox Apr 17, 2015
@randing89 randing89 changed the title fix($compile): exception when using "watch" as isolated scope binding in Firefox fix($compile): exception when using "watch" as isolated scope binding variable in Firefox Apr 17, 2015
@lgalfaso
Copy link
Contributor

#11627 looks like a real issue and the diagnose also looks accurate, but this fix does not look right:

  • This patch only fixes the case that the property watch is optional, there should be a more comprehensive solution that also fixes this for non-optional bindings
  • It needs new tests that fail before the patch and pass with the patch

@randing89
Copy link
Contributor Author

@lgalfaso Thanks for your comment. I have revised my pull request and added few test cases.

@randing89
Copy link
Contributor Author

@lgalfaso
Hi. Can you please have a review when you got time?
Thanks.

@petebacondarwin petebacondarwin added this to the 1.4.x - jaracimrman-existence milestone May 6, 2015
switch (mode) {

case '@':
if (!attrs[attrName]) {
if (optional) {
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so if the value is optional and it does not have an initial value, then we are not observing the attribute? This implies that
<div attr-abc="{{abc}}" some-directive-that-binds-to-the-attribute-abc></div>
will stop working. This is a breaking change

@lgalfaso
Copy link
Contributor

On top, a test that breaks in Firefox using the property watch is missing

@lgalfaso
Copy link
Contributor

One more thing, please rebase and squash everything into one commit

Thanks!

@caitp
Copy link
Contributor

caitp commented May 11, 2015

I think we should just createMap the Attributes class' prototype so that we don't have to deal with non-standard Object.prototype properties. Unfortunately, doing that is a breaking change

@lgalfaso
Copy link
Contributor

I think we should just createMap the Attributes class' prototype so that we don't have to deal with non-standard Object.prototype properties. Unfortunately, doing that is a breaking change

This would make the code simpler, but given that it is a breaking change, I would like other opinions

@randing89
Copy link
Contributor Author

I have revised the patch. I set the attrs[attrName] to undefined in the case user defined a scope binding with same name as prototype method & attribute not presenting. So that the following code will never access to the actual method function.

@@ -2545,9 +2545,19 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
lastValue,
parentGet, parentSet, compare;

if ((attrName in attrs) && !attrs.hasOwnProperty(attrName)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change this to if (hasOwnProperty(attrs, attrName)) {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean hasOwnProperty.call(attrs, attrName), right ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gkalpak yep :)

@lgalfaso
Copy link
Contributor

Otherwise, LGTM

@randing89
Copy link
Contributor Author

Updated. Thanks for the review

@@ -2545,9 +2545,19 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
lastValue,
parentGet, parentSet, compare;

if ((attrName in attrs) && !hasOwnProperty.call(attrs, attrName)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is (attrName in attrs) && needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. In the case attrs === {} and attrName === 'watch' we want to make sure code in the switch below accessing attrs['watch'] instead of attrs.prototype.watch. So this is use to find out if attrName is in the prototype chain but not actually defined in attrs object.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, is if (!hasOwnProperty.call(attrs, attrName)) { good?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Em... Tried to run the test and seems all good. I've updated the commit. Thanks.

… variable in Firefox

Fix on all binding modes: '=', '@' and '&' as well as optional cases
Throw exception when user define 'hasOwnProperty' in binding.

Closes #11627
@lgalfaso
Copy link
Contributor

LGTM, will merge right after we cut the next release.

@lgalfaso
Copy link
Contributor

lgalfaso commented Jun 1, 2015

landed as a6339d3

@lgalfaso lgalfaso closed this Jun 1, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Exception when using "watch" as isolated scope binding variable in Firefox
7 participants