WebReflection / hyperHTML

A Fast & Light Virtual DOM Alternative
ISC License
3.07k stars 112 forks source link

Use from XUL windows #311

Closed coreyfarrell closed 5 years ago

coreyfarrell commented 5 years ago

I'm experimenting with use of custom elements within an XUL based application run by firefox. Unfortunately document.createElement does not produce elements in the HTML namespace.

console.log(wire()`<label>Testing</label>`.constructor.name);
console.log(document.createElement('label').constructor.name);
console.log(document.createElementNS('http://www.w3.org/1999/xhtml', 'label').constructor.name);

When run from an xul:dialog window this logs:

Text
XULElement
HTMLLabelElement

I'm unsure why wire() produced a Text object instead of an XULElement, I was able to work-around this by modifying esm.js, I replaced all calls to createElement(tag) with createElementNS('http://www.w3.org/1999/xhtml', tag). If I really need to I can probably create a babel plugin to make the change but I'd prefer to avoid that. Would you be willing to make HyperHTML use createElementNS for html nodes? Or maybe just when html type is explicitly used by calls to wire?

WebReflection commented 5 years ago

hyperHTML doesn't use createElement, it uses the template element to create elements.

Moreover, if I go to the current test page and write this in console:

(hyperHTML.wire()`<label>Testing</label>`).constructor.name

I read HTMLLabelElement.

I believe the issue is that XUL doesn't understand the HTML template element, so that this produces nodes through the fallback or, it doesn't produce nodes at all.

Accordingly, I'm not sure what kind of fix you are proposing, or where ... neither I would know how to actually test such change.

Any hint welcome, but since I'm offline these days, as shown in the README badge, not much will happen before the 27th of December.

coreyfarrell commented 5 years ago

Thank you for the information, this has given me clues and I did some testing with console.log from my XUL application. The XUL namespace has a template element, but it is not compatible with the html template element. So hyperHTML is calling document.createElement('template'), this unfortunately creates an xul template. The PR I've submitted to @ungap/create-content fixes my major issue and allows hyperHTML to work from an XUL window without breaking existing tests.

It looks like domtagger/esm/constants.js is prefixing UID with _dt: - I'm unsure if this can result in any actual problem. Using document.createElementNS avoids adding the prefix to UID from my XUL application by forcing creation of an HTML template instead of an XUL template.

I have not yet investigated domtagger/esm/walker.js, I never put scripts inside hyperHTML templates. The XUL namespace does have a script element but it's slightly different from html:script. The specific difference I've found is that xul:script does not support the type="module" attribute. I'll investigate domtagger changes some more once basichtml correctly supports using createElementNS with the HTML namespace URL.

The issue issue with document.createElement can be demonstrated in the browser by creating and directly loading test.svg:

<svg:svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/1999/xhtml">
    <script>
        console.log(document.createElement('template').constructor.name);
        console.log(document.createElementNS('http://www.w3.org/1999/xhtml', 'template').constructor.name);
    </script>
</svg:svg>

This logs Element then HTMLTemplateElement. Although the default xmlns is HTML, document.createElement seems to create elements based on the namespace of the root node. An SVG document might be a way to test from within browsers though I haven't fully explored.

Not a rush for me, enjoy your time off. For now I'll just use a modified bundled copy of hyperhtml in my XUL application.

WebReflection commented 5 years ago

Thanks for tracking down all related changes, I'll have a look whenever I can.

However, do you mind telling me why are you using XUL in 2018?

It looks like domtagger/esm/constants.js is prefixing UID with _dt: - I'm unsure if this can result in any actual problem.

that is feature detected, but it shouldn't be an issue. Even with older hyperHTML the SVG would have warned without any real issue/consequence when some attribute would contain that, but in general it could be either _dt: value; or 0.1234% to avoid such warning in other browsers.

The specific difference I've found is that xul:script does not support the type="module" attribute

I think script is an edge case so I wouldn't worry/care much about such case for now, but it seems, eventually, an issue confined in the XUL world.

coreyfarrell commented 5 years ago

However, do you mind telling me why are you using XUL in 2018?

I'm using it in an application that was originally written in 8 years ago, must be compatible with Linux, Mac and Windows. It also starts a softphone in a separate process (WebRTC is not yet stable enough, I need to use SIP over UDP). I'm currently migrating as much as I can to standard HTML but in the short-term eliminating XUL entirely is not possible. Eventually I'd like to evaluate Electron or other HTML based application packaging methods but it's a process.

WebReflection commented 5 years ago

can you please let me know if latest 2.21.0 fixed your issue ? Thanks

coreyfarrell commented 5 years ago

Yes I just did a full clean and rebuild of my app using 2.21.0 and confirmed my issue is resolved. Thank you for accepting patches to deal with my abnormal setup and for your quick releases!