ibm-js / delite

HTML Custom Element / Widget infrastructure
http://ibm-js.github.io/delite/
Other
68 stars 28 forks source link

delite not working in Safari 12.1 #509

Closed lindgr3n closed 5 years ago

lindgr3n commented 5 years ago

Error

Unhandled Promise Rejection: ReferenceError: Can't find variable: presentation" When using <template role="presentation">

Version

Using the code up to commit https://github.com/ibm-js/delite.git#76850a773aaf57f62fcb7eed6207da9e3bfce3c1 (17 Oct 2018)

Background

After the latest Safari release 12.1 it looks like document.createElement have changed. Have not validated on a older version. Delite worked on 12.0.

var chromeConsole = document.createElement('div')
// chromeConsole.role => undefined
var safariConsole = document.createElement('div')
// safariConsole.role => null

Where it happens?

The problem is when Widget.js tries to render this_templateHandle = this.template(this.ownerDocument) if will fail on "Unhandled Promise Rejection: ReferenceError: Can't find variable: presentation"

Why?

The change in document.createElement makes Template.js elementCache[tag] = document.createElement(tag); // tag = "template" gets the propertie role and some others that Chrome don't set.

This gives a problem in handlebars.js parseValueAttribute where Template.getProp(tag, name) // tag = "template", name="role" returns "role" and typeof elem[propName] // propName="role" returns "object"

While Chrome returns undefined / "undefined" and will use toJs

My fix right now is to check if elem[propName] exist. Not sure if its the best approach.

if (elem[propName] != null && propName && propType !== "string" && !/{{/.test(value) && propName !== "style.cssText") {...}         
wkeese commented 5 years ago

Good catch. Thanks for letting us know.

That's a weird one, especially how Element#role is initially of type "object" instead of type "string" (but then the type changes to "string" once you set a value). In other words this seems like a safari bug rather than a design problem with delite, so we should fix it with that in mind.

I suppose that your suggestion of checking for elem[propName] != null will work, as there probably aren't any properties on native HTML Elements that are null. I'm not sure if it's the best approach either. Maybe just a special case for "role" might be better. Hmm.

wkeese commented 5 years ago

Johan - I tried your fix but getAttribute("role") still returns undefined rather than "presentation". There's some weirdness going on because this simple test works as expected:

var div = document.createElement("div");
div.role = "presentation";
div.getAttribute("role")    // --> "presentation"

Anyway, since that's not working I will check in a different fix that does.