closure-compiler icon indicating copy to clipboard operation
closure-compiler copied to clipboard

Types mismatch in Document.prototype.documentElement externs

Open roman01la opened this issue 4 years ago • 2 comments

The following JS input

new DOMParser()
  .parseFromString(`<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 300 300"></svg>`, "image/svg+xml")
  .documentElement
  .width
  .baseVal

compiles into this under advanced optimizations

new DOMParser()
  .parseFromString(`<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 300 300"></svg>`, "image/svg+xml")
  .documentElement
  .width
  .g

The baseVal property gets minified and the following warning is printed WARNING - [JSC_INEXISTENT_PROPERTY] Property width never defined on HTMLHtmlElement.

As per externs, DOMParser.prototype.parseFromString return type is Document https://github.com/google/closure-compiler/blob/7ff6e25843097791416d1544c88dc8711f6be64a/externs/browser/gecko_xml.js#L73, whose documentElement property type is indeed HTMLHtmlElement https://github.com/google/closure-compiler/blob/7ff6e25843097791416d1544c88dc8711f6be64a/externs/browser/w3c_dom1.js#L339

But in case when parsing SVG the documentElement property refers to an element of type SVGSVGElement, which is correctly covered with externs https://github.com/google/closure-compiler/blob/7ff6e25843097791416d1544c88dc8711f6be64a/contrib/externs/svg.js#L6555

roman01la avatar Nov 26 '21 14:11 roman01la

https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString The parseFromString can return either HTMLDocument or XMLDocument depending on the mimeType parameter value. This means that the documentElement property can be either HTMLHtmlElement or SVGSVGElement.

So is the right fix to make the documentElement be of the broader type Element?

rishipal avatar Dec 01 '21 01:12 rishipal

I'm not sure how type inference works in Closure, but looks like SVGSVGElement is a subtype of Element. Would that work to make sure that baseVal property, which is unique to SVGSVGElement type, is covered?

roman01la avatar Dec 01 '21 09:12 roman01la