pvorb / clone

deeply clone arbitrary objects in javascript
https://www.npmjs.com/package/clone
MIT License
781 stars 130 forks source link

TypeError: The HTMLDivElement.align setter can only be used on instances of HTMLDivElement #78

Open k-j-kim opened 7 years ago

k-j-kim commented 7 years ago

When copying a DOM object, following line fails:

child[i] = _clone(parent[i], depth - 1); https://github.com/pvorb/clone/blob/e3f252d1eb24f4e269337098295604e266719d4d/clone.js#L156

TypeError: The HTMLDivElement.align setter can only be used on instances of HTMLDivElement

It seems like calling Object.getPrototypeOf on a DOM element gives HTMLDivElementPrototype which has a slightly different behavior than HtmlDivElement.

Reproducible in Safari Version 10.0 (10602.1.50.0.10)

rictic commented 7 years ago

Hm, maybe we should use the cloneNode method when dealing with document nodes?

Can confirm that this fails in Safari 10.1:

Object.create(Object.getPrototypeOf(document.createElement('div'))).align = 'foo'

but this does not:

document.createElement('div').cloneNode().align = 'foo'

We'd want to copy over properties afterwards. I don't think we can clone event listeners.

k-j-kim commented 7 years ago

btw, Object.create( Object.getPrototypeOf(document.createElement('div'))).align = 'foo' will fail in Chrome (Version 57.0.2987.133 (64-bit)) as well, although with a different error message: Uncaught TypeError: Illegal invocation.

Agree that with document nodes, cloneNode should be used.

kermit-the-frog commented 6 years ago

Any updates on this?

tomhooijenga commented 6 years ago

There are more cases where Object.create(Object.getPrototypeOf(...)) fails. For example: const url = clone(new URL('http://example.com')) throws the same Uncaught TypeError: Illegal invocation in chrome and TypeError: 'set href' called on an object that does not implement interface URL. in Firefox